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 )