# perl_arXiv_parsing_example.pl
#
# This sample script illustrates a basic arXiv api call
# followed by parsing of the results using the XML::Atom
# module.
#
# Please see the documentation at 
# http://export.arxiv.org/api_help/docs/user-manual.html
# for more information, or email the arXiv api 
# mailing list at arxiv-api@googlegroups.com.
#
# LWP, and XML::Atom can be gotten from cpan.org
#
# Author: Julius B. Lucks
#
# This is free software.  Feel free to do what you want
# with it, but please play nice with the arXiv API!

use LWP;
use XML::Atom::Feed;
use strict;

# Base api query url
my $base_url = 'http://export.arxiv.org/api/query?';

# Search parameters
my $search_query = 'all:electron'; # search for electron in all fields
my $start = 0; # retreive the first 5 results
my $max_results = 5;

# Construct the query with the search parameters
my $query = "search_query=$search_query&start=$start&max_results=$max_results";

# set up an LWP browser
my $browser = LWP::UserAgent->new();

# perform a GET request using the $base_url and $query
my $response = $browser->get($base_url.$query);

# parse the response using XML::Atom.
my $feed = XML::Atom::Feed->new(\$response->content());

# print out feed information
print "Feed title: ",$feed->title(),"\n";
print "Feed last updated: ",$feed->updated(),"\n";

# opensearch metadata such as totalResults, startIndex, 
# and itemsPerPage live in the opensearch namespase
my $opensearch_ns = XML::Atom::Namespace->new(opensearch =>
                       'http://a9.com/-/spec/opensearch/1.1/');
                       
print "totalResults for this query: ",$feed->get($opensearch_ns,'totalResults'),"\n";
print "startIndex for these results: ",$feed->get($opensearch_ns,'startIndex'),"\n";
print "itemsPerPage for these results: ",$feed->get($opensearch_ns,'itemsPerPage'),"\n";

print "\n";

# Run through each entry, and print out information
# some entry metadata lives in the arXiv namespace
my $arxiv_ns = XML::Atom::Namespace->new(arxiv =>
                       'http://arxiv.org/schemas/atom');

foreach my $entry ($feed->entries()) {
    print "e-print metadata\n";
    
    # split the id line to get just the arxiv id
    my @temp =  split('/abs/',$entry->id());
    print "arxiv-id: ",$temp[-1],"\n";
    
    print "Published: ",$entry->published(),"\n";
    print "Title: ",$entry->title(),"\n";
    
    # gather a list of authors and affiliations
    #   affiliations are under the arxiv namespace if present
    print "Authors: \n";
    foreach my $author ($entry->author()) {
        print "    ",$author->name();
        if (my @affil_list = $author->getlist($arxiv_ns,'affiliation')) {
            print " (",join(', ',@affil_list),")\n";
        } else {
            print "\n";
        }
    }
        
    # get the links to the abs page and pdf for this e-print
    my @links = $entry->link();
    for my $link (@links) {
        if ($link->rel() eq 'alternate') {
            print "abs page link: ",$link->href(),"\n";
        } elsif ($link->title() eq 'pdf') {
            print "pdf link: ",$link->href(),"\n";
        }
    }
    
    # The journal reference, comments and primary_category sections live under 
    # the arxiv namespace
    my $journal_ref = $entry->get($arxiv_ns,'journal_ref') || 'No journal ref found';
    print "Journal Reference: $journal_ref\n";
    
    my $comments = $entry->get($arxiv_ns,'comment') || 'No comments found';
    print "Comments: $comments\n";
    
    # Since the primary_category element has no value, only attributes,
    # we have to use get_object.  XML::Atom is a little funny here because it
    # requires we put the namespace as a string instead of an 
    # XML::Atom::Namespace object
    my $primary_category = $entry->get_object('http://arxiv.org/schemas/atom',
                                              'primary_category',
                                              'XML::Atom::Category');
    
    print "Primary Category: ",$primary_category->term(),"\n";
    
    # Lets get all the categories
    my @all_categories = ();
    for my $category ($entry->category()) {
        push @all_categories, $category->term();
    }
    print "All Categories: ",join(', ',@all_categories),"\n";
    
    # The abstract is in the <summary> element
    print "Abstract: ",$entry->summary();
    
    
    
    print "\n";
}
