App-PDFLibrarian
view release on metacpan or search on metacpan
bin/pdf-lbr-query-ads view on Meta::CPAN
Send the I<query> to the Astrophysics Data System.
=item B<--set-api-token>|B<-s> I<token>
In order to query the Astrophysics Data System, you must set up an ADS account; see L<https://ui.adsabs.harvard.edu/#user/account/login>.
From the account page you can find your personal ADS API token.
Finally you must run B<pdf-lbr-query-ads> with this option to store the API token in the configuration file.
=back
=head1 PART OF
App::PDFLibrarian
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2016--2026 Karl Wette. Licensed under the GNU General Public License, version 3 or later.
=cut
# handle help options
my ($version, $help, $query, $api_token);
GetOptions(
"version" => \$version,
"help|h" => \$help,
"query|q=s" => \$query,
"set-api-token|s=s" => \$api_token,
) or croak "$Script: could not parse options";
if ($version) { print "App::PDFLibrarian version $App::PDFLibrarian::VERSION\n"; exit 1; }
pod2usage(-verbose => 2, -exitval => 1) if ($help);
# get location of configuration file
my $cfgfile = File::Spec->catfile($cfgdir, 'ads.ini');
# read configuration file
my $cfg = Config::IniFiles->new();
if (-f $cfgfile) {
$cfg->SetFileName($cfgfile);
$cfg->ReadConfig();
}
# set ADS API token
if ($api_token) {
$cfg->newval('ads', 'api_token', $api_token);
$cfg->WriteConfig($cfgfile);
}
# return if no query
exit 0 unless defined($query);
# get ADS API token
$api_token = $cfg->val('ads', 'api_token');
croak "$Script: missing personal ADS API token" unless defined($api_token);
# user agent for web queries
my $useragent = LWP::UserAgent->new;
$useragent->agent("App::PDFLibrarian v$App::PDFLibrarian::VERSION");
# escape any colons and parentheses in query value
$query =~ s{^([^:]*):(.*)$}{ my $k = $1; my $v = $2; $v =~ s|:|\\:|g; "$k:$v" }e;
$query =~ s/([()])/\\$1/g;
# send query to ADS
my $querycontent;
{
my $adsuri = URI->new('https://api.adsabs.harvard.edu/v1/search/query');
$adsuri->query_form(rows => 1, fl => 'bibcode', 'q' => $query);
my $request = HTTP::Request->new('GET', $adsuri);
$request->header('Authorization' => "Bearer $api_token");
my $result = $useragent->request($request);
if (!$result->is_success) {
my $status = $result->status_line;
croak "$Script: ADS query failed: $status";
}
$querycontent = $result->content;
}
# parse ADS query response from JSON
my $queryjson;
eval {
$queryjson = decode_json($querycontent);
1;
} or do {
croak "$Script: could not parse ADS query response from JSON: $@";
};
croak "$Script: could not understand ADS query response" unless defined($queryjson->{response}) && defined($queryjson->{response}->{numFound});
croak "$Script: ADS query failed, no records returned" unless $queryjson->{response}->{numFound} && defined($queryjson->{response}->{docs});
croak "$Script: could not understand ADS query response" unless @{$queryjson->{response}->{docs}} > 0 && defined($queryjson->{response}->{docs}->[0]->{bibcode});
# construct ADS export request into JSON
my $exportcontent;
eval {
$exportcontent = encode_json({ bibcode => [$queryjson->{response}->{docs}->[0]->{bibcode}]});
1;
} or do {
croak "$Script: could not construct ADS export request: $@";
};
# export BibTeX record from ADS
{
my $adsuri = URI->new('https://api.adsabs.harvard.edu/v1/export/bibtex');
my $request = HTTP::Request->new('POST', $adsuri);
$request->header('Authorization' => "Bearer $api_token");
$request->header('Content-Type' => 'application/json');
$request->content($exportcontent);
my $result = $useragent->request($request);
if (!$result->is_success) {
my $status = $result->status_line;
croak "$Script: ADS export failed: $status";
}
$exportcontent = $result->content;
}
# parse ADS export response from JSON
my $exportjson;
eval {
$exportjson = decode_json($exportcontent);
1;
} or do {
( run in 1.212 second using v1.01-cache-2.11-cpan-59e3e3084b8 )