所以我必须更新一个 perl 脚本,它会遍历 json 文件,获取名为“items”的键,并将这些项目转换为 perl 输出。
总的来说,我是 Perl/编码方面的菜鸟,所以请耐心等待🥺。 offset 变量在每个 url 被迭代时设置。将一个curl命令传递到终端,将文件放入“@lines”数组中,最后,$data中存储的任何json数据都会被解码和转换。在下面的 block 中(其中 # populate %manager_to_directs、# populate %user_to_management_chain 和 # populate %manager_to_followers 被注释)是 fetch_json 被调用的地方,也是哈希变量从解码的 json 中获取数据的地方。 (***如果我错误地解释了此代码,请随时纠正我)
存在一个问题,即每次执行该程序时 $cmd 都不考虑 HTTP 响应。我只希望当且仅当程序获得http 200(OK)或http 204(NO_CONTENT)时才处理结果,因为程序将运行并且有时会部分刷新我们的json端点(下面终端的curl命令输出中的url),或者有时甚至根本不刷新。
我所假设的是,我可能必须导入 HTTP::Response pragma 并以某种方式将其从 fetch_json 中运行的命令中提取出来,但我没有其他线索从那里开始。
我是否必须更新 $cmd 才能提取 http 代码?如果是这样,如果收到 200 或 204 以外的任何内容,我将如何在 fetch_json 子中解释它以退出进程?
哦,还有,我如何将上次执行的输出保存在备份文件中?
如果我能在这里得到任何帮助,我将不胜感激!
参见下面的代码:
从测试运行中提取此内容:
curl -o filename -w "HTTP CODE: %{http_code}\n" --insecure --key <YOUR KEY> --cert <YOUR CERT> https://xxxxxxxxxx-xxxxxx-xxxx.xxx.xxxxxxxxxx.com:443/api/v1/reports/active/week > http.out
#!/usr/bin/env perl
use warnings;
use strict;
use JSON qw(decode_json);
use autodie qw(open close chmod unlink);
use File::Basename;
use File::Path qw(make_path rmtree);
use Cwd qw(abs_path);
use Data::Dumper;
use feature qw(state);
sub get_fetched_dir {
return "$ENV{HOME}/tmp/mule_user_fetched";
}
# fetch from mulesoft server and save local copy
sub fetch_json {
state $now = time();
my ($url) = @_;
my $dir = get_fetched_dir();
if (!-e $dir) {
make_path($dir);
chmod 0700, $dir;
}
my ($offset) = $url =~ m{offset=(\d+)};
if (!defined $offset) {
$offset = 0;
}
$offset = sprintf ("%03d", $offset);
my $filename = "$dir/offset${offset}.json";
print "$filename\n";
my @fields = stat $filename;
my $size = $fields[7];
my $mtime = $fields[9];
if (!$size || !$mtime || $now-$mtime > 24*60*60) {
my $cmd = qq(curl \\
--insecure \\
--silent \\
--key $ENV{KEY} \\
--cert $ENV{CERT} \\
$url > $filename
);
#print $cmd;
system($cmd);
chmod 0700, $filename;
}
open my $fh, "<", $filename;
my @lines = <$fh>;
close $fh;
return undef if !@lines;
my $data;
eval {
$data = decode_json (join('',@lines));
};
if ($@) {
unlink $filename;
print "Bad JSON detected in $filename.\n";
print "I have deleted $filename.\n";
print "Please re-run script.\n";
exit(1);
}
return $data;
}
die "Usage:\n KEY=key_file CERT=cert_file mule_to_jira.pl\n"
if !defined $ENV{KEY} || !defined $ENV{CERT};
print "fetching data from mulesoft\n";
# populate %manager_to_directs
my %manager_to_directs;
my %user_to_manager;
my @users;
my $url = "https://enterprise-worker-data.eip.vzbuilders.com/api/v1/reports/active/week";
while ($url && $url ne "Null") {
my $data = fetch_json($url);
last if !defined $data;
$url = $data->{next};
#print $url;
my $items = $data->{items};
foreach my $item (@$items) {
my $shortId = $item->{shortId};
my $manager = $item->{organization}{manager};
push @users, $shortId;
next if !$manager;
$user_to_manager{$shortId} = $manager;
push @{$manager_to_directs{$manager}}, $shortId;
}
}
# populate %user_to_management_chain
# populate %manager_to_followers
my %user_to_management_chain;
my %manager_to_followers;
foreach my $user (keys %user_to_manager) {
my $manager = $user_to_manager{$user};
my $prev = $user;
while ($manager && $prev ne $manager) {
push @{$manager_to_followers{$manager}}, $user;
push @{$user_to_management_chain{$user}}, $manager;
$prev = $manager;
$manager = $user_to_manager{$manager}; # manager's manager
}
}
# write backyard.txt
open my $backyard_fh, ">", "backyard.txt";
foreach my $user (sort keys %user_to_management_chain) {
my $chain = join ',', @{$user_to_management_chain{$user}};
print $backyard_fh "$user:$chain\n";
}
close $backyard_fh;
# write teams.txt
open my $team_fh, ">", "teams.txt";
foreach my $user (sort @users) {
my $followers = $manager_to_followers{$user};
my $followers_joined = $followers ? join (',', sort @$followers) : "";
print $team_fh "$user:$followers_joined\n";
}
close $team_fh;
my $dir = get_fetched_dir();
rmtree $dir, {safe => 1};
最佳答案
因此,如果您希望保持 Web 获取和 Perl 处理解耦,您可以修改 curl
命令,以便通过添加 -i 在输出中包含响应 header
选项。这意味着必须修改 Perl 才能在到达正文之前读取和处理 header 。成功的 http.out
看起来像这样:
HTTP/1.1 200 OK
Server: somedomain.com
Date: <date retrieved>
Content-Type: application/json; charset=utf-8
Content-Length: <size of JSON>
Status: 200 OK
Maybe: More Headers
Blank: Line signals start of body
{
JSON object here
}
不成功的 curl 将在 HTTP/1.1 旁边的第一行显示 200 OK 以外的内容,因此您可以判断出了问题。
或者,您可以让 Perl 执行实际的 HTTP 获取,而不是依赖于curl;您可以使用LWP::UserAgent或 Perl 中的任何其他 HTTP 客户端库,它将为您提供整个响应,而不仅仅是正文。
关于json - 检查 fetch_json sub 中的 HTTP 代码/保存以前的输出以在 Perl 中进行备份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61925598/