eprints code - adammoore/corda GitHub Wiki

/usr/share/eprints3/archives/cordahack/cgi/users/orcid_api

######################################################################
#
#  EPrints Repository Info Exporter
#
######################################################################
#
#  __COPYRIGHT__
#
# Copyright 2000-2010 University of Southampton. All Rights Reserved.
# 
#  __LICENSE__
#
######################################################################

use EPrints;
use EPrints::Const qw( :http );

use Digest::MD5;
use EPrints::Sword::Utils;

use Apache2::RequestRec ();
use Apache2::RequestIO ();

use strict;
my $repository = EPrints->new->current_repository;
exit( 0 ) unless( defined $repository );
# $repository->get_database->set_debug( 1 );

my $path_info = $repository->get_request->path_info;

#/creators/
#/users/

my @path = split( '/', $path_info );
shift @path; # lose leading /

#if( $path[0] =~ m/^\d+$/ && scalar @path == 1 )
#{
#       show_eprint_export_options( $repository, $path[0] );
#       exit;
#}

#my $prettyname = pop @path;
#my $format = pop @path;
#
#unless( defined $format )
#{
#       print STDERR "no format\n";
#       $repository->not_found;
#       exit;
#}

my $plugin = $repository->plugin( "Export::Report::ORCID_JSON" );

if( !$plugin )
{
        $repository->not_found;
        exit;
}

if( $plugin->param( "visible" ) eq "staff" )
{
        my $user = $repository->current_user;
        if( !defined $user )
        {
                my $rc = EPrints::Apache::Auth::authen( $repository->get_request );
                if( $rc != OK )
                {
                        $repository->get_request->status( $rc );
                        exit;
                }
                $user = $repository->current_user;
        }
        if( $user->get_type ne "editor" && $user->get_type ne "admin" )
        {
                $repository->get_request->status( HTTP_FORBIDDEN );
                exit;
        }
}

my %arguments = %{$plugin->param( "arguments" )};
# fetch the plugin arguments, if any
foreach my $argname (keys %arguments)
{
        if( defined $repository->param( $argname ) )
        {
                $arguments{$argname} = $repository->param( $argname );
        }
}
if( $path[0] =~ m/^creators$/ && $path[1] =~ m/^users$/ && scalar @path == 2 )
{
        print STDERR "BY USERS\n";
        export_creators_by_userid( $repository, $plugin, \%arguments, "eprint", $path[0] );
}
elsif( $path[0] =~ m/^creators$/ && $path[1] =~ m/^orcids$/ && scalar @path == 2 )
{
        print STDERR "BY ORCIDS\n";
        export_creators_by_orcid( $repository, $plugin, \%arguments, "eprint", $path[0] );
}
else
{
        $repository->not_found;
}

exit;

# Export all eprints.creators and associated orcid stuff
sub export_creators_by_userid
{
        my( $repository, $plugin, $args ) = @_;

        my $list = $repository->dataset( "eprint" )->search;
        my $users = {};
        $list->map( sub{
                my( $session, $dataset, $eprint ) = @_;

                my $creators_orcids = $eprint->value("creators_orcid");
                my $user;
                for my $orcid(@{$creators_orcids}){
                        next if(!EPrints::Utils::is_set($orcid));
                        $user = $repository->dataset( "user" )->search(filters => [ { meta_fields => [ 'orcid' ], value => $orcid, describe=>0 } ])->item(0,1);
                        next if(!EPrints::Utils::is_set($user));
                        $users->{$user->id}->{user} = $user if(!EPrints::Utils::is_set($users->{$user->id}->{user}));
                        push @{$users->{$user->id}->{eprints}}, $eprint;
                }

        } );

        $plugin->initialise_fh( \*STDOUT );

        $repository->send_http_header( "content_type"=>$plugin->param("mimetype") );

        $plugin->output_list( fh=>\*STDOUT, list=>$users, exportfields=>[qw/eprintid title/], dataset=>$repository->dataset("eprint"), key_type => "user" );

}

sub export_creators_by_orcid
{
        my( $repository, $plugin, $args ) = @_;

        my $list = $repository->dataset( "eprint" )->search;
        my $users = {};
        $list->map( sub{
                my( $session, $dataset, $eprint ) = @_;

                my $creators_orcids = $eprint->value("creators_orcid");
                my $user;
                for my $orcid(@{$creators_orcids}){
                        next if(!EPrints::Utils::is_set($orcid));
                        $user = $repository->dataset( "user" )->search(filters => [ { meta_fields => [ 'orcid' ], value => $orcid, describe=>0 } ])->item(0,1);
                        if(!EPrints::Utils::is_set($user)){

                        }else{
                                $users->{$orcid}->{user} = $user if(!EPrints::Utils::is_set($users->{$orcid}->{user}));
                        }
                        push @{$users->{$orcid}->{eprints}}, $eprint;
                }

        } );

        $plugin->initialise_fh( \*STDOUT );

        $repository->send_http_header( "content_type"=>$plugin->param("mimetype") );

        $plugin->output_list( fh=>\*STDOUT, list=>$users, exportfields=>[qw/eprintid title/], dataset=>$repository->dataset("eprint"), key_type => "orcid" );

}

/archives/cordahack/cfg/plugins/EPrints/Plugin/Export/Report/ORCID_JSON.pm

package EPrints::Plugin::Export::Report::ORCID_JSON;

use Data::Dumper;
use JSON;
use EPrints::Plugin::Export::Report;
@ISA = ( "EPrints::Plugin::Export::Report" );

use strict;

sub new
{
        my( $class, %params ) = @_;

        my $self = $class->SUPER::new( %params );

        $self->{name} = "ORCID JSON";
        $self->{suffix} = ".js";
        $self->{mimetype} = "application/json; charset=utf-8";
        $self->{accept} = [ 'report/generic' ];
        $self->{advertise} = 1;

        return $self;
}

sub _header
{
        my( $self, %opts ) = @_;

        my $jsonp = $opts{json} || $opts{jsonp} || $opts{callback};
        if( EPrints::Utils::is_set( $jsonp ) )
        {
                $jsonp =~ s/[^=A-Za-z0-9_]//g;
                return "$jsonp(";
        }

        return "";
}

sub _footer
{
        my( $self, %opts ) = @_;

        my $jsonp = $opts{json} || $opts{jsonp} || $opts{callback};
        if( EPrints::Utils::is_set( $jsonp ) )
        {
                return ");\n";
        }
        return "";
}

sub output_list
{
        my( $plugin, %opts ) = @_;

        $plugin->get_export_fields( %opts ); #get export fields based on user requirements or plugin defaults

        my $ds = $opts{dataset};
        $plugin->{dataset} = $ds;

        my $r = [];
        my $part;
        $part = $plugin->_header(%opts)."[\n";
        if( defined $opts{fh} )
        {
                print {$opts{fh}} $part;
        }
        else
        {
                push @{$r}, $part;
        }

        my $key_type = $opts{key_type}; # either userid or orcid...possibly other crap

        $opts{json_indent} = 1;
        my $first = 1;
        my $user_eprints = $opts{list};
        foreach my $key ( keys %{$user_eprints} )
        {
                my $list = $user_eprints->{$key}->{eprints};
                my $json_data = {};
                
                if(EPrints::Utils::is_set($user_eprints->{$key}->{user})){
                        my $user = $user_eprints->{$key}->{user};
                        $json_data->{userid} = $user->id;
                        $json_data->{orcid} = $user->get_value( "orcid" );
                }elsif($key_type eq "orcid"){
                        #user not available... we may have orcid
                        $json_data->{orcid} = $key;
                }
                $json_data->{eprints} = []; 
    
                print STDERR "list....$list\n";

                #eprint data....
                foreach my $e ( @{$user_eprints->{$key}->{eprints}} )
                {
                        #my( $session, $dataset, $dataobj ) = @_;                       
                        if( $first ) { $first = 0; } else { $part = ",\n"; }
                        push @{$json_data->{eprints}}, $plugin->_epdata_to_json( $e, %opts );               
                }

                print STDERR "json_data.....$json_data\n";
                my $json_string = encode_json( $json_data );
                #my $json_string = EPrints::Utils::js_string( $json_data );
                #print STDERR "json_string....$json_string\n";
                if( defined $opts{fh} )
                {
                        print {$opts{fh}} $json_string;
                }
                else
                {
                        push @{$r}, $json_string;
                }
        }

        $part= "\n]\n\n".$plugin->_footer(%opts);
        if( defined $opts{fh} )
        {
                print {$opts{fh}} $part;
        }
        else
        {
                push @{$r}, $part;
        }


        if( defined $opts{fh} )
        {
                return;
        }

        return join( '', @{$r} );
}

sub _epdata_to_json
{
        my( $self, $eprint, %opts ) = @_;

        my $repo = $self->repository;


        my $filtered_eprint_data = {};
        foreach my $fieldname ( @{$self->{exportfields}} )
        {
                print STDERR "fieldname.....$fieldname\n";
                my @fnames = split( /\./, $fieldname );
                if( scalar( @fnames > 1 ) ) #a field of another dataset, e.g. documents.content
                {
=comment
                        my $field = $self->{dataset}->get_field( $fnames[0] ); #first get the field
                        if( $field->is_type( "subobject", "itemref" ) ) #if thee field belongs to another dataset
                        {
                                my $subsubdata = $subdata->{$fnames[0]} || []; #create an array for the sub ojects
                                my $dataobjs= $eprint->value( $fnames[0] ); #get the dataobjects this field represents
                                for (my $i=0; $i < scalar( @{$dataobjs} ); $i++)
                                {
                                        my $obj = @{$dataobjs}[$i]; #get the value from the dataobject                  
                                        my $value = $obj->value( $fnames[1] );
                                        next if !EPrints::Utils::is_set( $value );

                                        my $subsubsubdata = $subdata->{$fnames[0]}[$i] || {};
                                        $subsubsubdata->{$fnames[1]} = $value;          

                                        $subdata->{$fnames[0]}[$i] = $subsubsubdata;                                    
                                }                                   
                       }
=cut
                }
                else
                {
                        my $field = $self->{dataset}->get_field( $fieldname );
                        next if !$field->get_property( "export_as_xml" );
                        next if defined $field->{sub_name};
                        my $value = $field->get_value( $eprint );
                        if( exists $self->{report}->{export_conf} && exists $repo->config( $self->{report}->{export_conf}, "custom_export" )->{$field->get_name} )
                        {
                                $value = $repo->config( $self->{report}->{export_conf}, "custom_export" )->{$field->get_name}->( $eprint, $self->{report} );
                        }
                        if( defined $field->{virtual} )
                        {
                                $value = EPrints::Utils::tree_to_utf8( $eprint->render_value( $field->get_name ) );
                        }
                        next if !EPrints::Utils::is_set( $value );
                        $filtered_eprint_data->{$field->get_name} = $value;
                }
        }

        return $filtered_eprint_data;
}
=comment
sub _epdata_to_json
{
        my( $self, $epdata, $depth, $in_hash, %opts ) = @_;

        my $repo = $self->repository;

        my $pad = "  " x $depth;
        my $pre_pad = $in_hash ? "" : $pad;


        if( !ref( $epdata ) )
        {

                if( !defined $epdata )
                {
                        return "null"; # part of a compound field
                }

                if( $epdata =~ /^-?[0-9]*\.?[0-9]+(?:e[-+]?[0-9]+)?$/i )
                {
                        return $pre_pad . ($epdata + 0);
                }
                else
                {
                        return $pre_pad . EPrints::Utils::js_string( $epdata );
                }
        }
        elsif( ref( $epdata ) eq "ARRAY" )
        {
                return "$pre_pad\[\n" . join(",\n", grep { length $_ } map {
                        $self->_epdata_to_json( $_, $depth + 1, 0, %opts )
                } @$epdata ) . "\n$pad\]";
        }
        elsif( ref( $epdata ) eq "ARRAY" )
        {
                return "$pre_pad\[\n" . join(",\n", grep { length $_ } map {
                        $self->_epdata_to_json( $_, $depth + 1, 0, %opts )
                } @$epdata ) . "\n$pad\]";
        }
        elsif( ref( $epdata ) eq "HASH" )
        {
                return "$pre_pad\{\n" . join(",\n", map {
                        $pad . "  \"" . $_ . "\": " . $self->_epdata_to_json( $epdata->{$_}, $depth + 1, 1, %opts )
                } keys %$epdata) . "\n$pad\}";
        }
        elsif( $epdata->isa( "EPrints::DataObj" ) )
        {
                my $subdata = {};

                return "" if(
                        $opts{hide_volatile} &&
                        $epdata->isa( "EPrints::DataObj::Document" ) &&
                        $epdata->has_relation( undef, "isVolatileVersionOf" )
                  );

                foreach my $fieldname ( @{$self->{exportfields}} )
                {
                        print STDERR "fieldname.....$fieldname\n";
                        my @fnames = split( /\./, $fieldname );
                        if( scalar( @fnames > 1 ) ) #a field of another dataset, e.g. documents.content
                        {
                                my $field = $self->{dataset}->get_field( $fnames[0] ); #first get the field
                                if( $field->is_type( "subobject", "itemref" ) ) #if thee field belongs to another dataset
                                {
                                        my $subsubdata = $subdata->{$fnames[0]} || []; #create an array for the sub ojects
                                        my $dataobjs= $epdata->value( $fnames[0] ); #get the dataobjects this field represents
                                        for (my $i=0; $i < scalar( @{$dataobjs} ); $i++)
                                        {
                                                my $obj = @{$dataobjs}[$i]; #get the value from the dataobject                  
                                                my $value = $obj->value( $fnames[1] );
                                                next if !EPrints::Utils::is_set( $value );

                                                my $subsubsubdata = $subdata->{$fnames[0]}[$i] || {};
                                                $subsubsubdata->{$fnames[1]} = $value;          

                                                $subdata->{$fnames[0]}[$i] = $subsubsubdata;                                    
                                        }                                   
                               }
                        }
                        else
                        {
                                my $field = $self->{dataset}->get_field( $fieldname );
                                next if !$field->get_property( "export_as_xml" );
                                next if defined $field->{sub_name};
                                my $value = $field->get_value( $epdata );                               
                                if( exists $self->{report}->{export_conf} && exists $repo->config( $self->{report}->{export_conf}, "custom_export" )->{$field->get_name} )
                                {
                                        $value = $repo->config( $self->{report}->{export_conf}, "custom_export" )->{$field->get_name}->( $epdata, $self->{report} );
                                }
                                if( defined $field->{virtual} )
                                {
                                        $value = EPrints::Utils::tree_to_utf8( $epdata->render_value( $field->get_name ) );
                                }
                                next if !EPrints::Utils::is_set( $value );
                                $subdata->{$field->get_name} = $value;
                        }
                }
                $subdata->{uri} = $epdata->uri;

                return $self->_epdata_to_json( $subdata, $depth + 1, 0, %opts );
        }
}
=cut

sub escape_value
{
        my( $plugin, $value ) = @_;

        return '""' unless( defined EPrints::Utils::is_set( $value ) );

        # strips any kind of double-quotes:
        $value =~ s/\x93|\x94|"/'/g;
        # and control-characters
        $value =~ s/\n|\r|\t//g;

        # if value is a pure number, then add ="$value" so that Excel stops the auto-formatting (it'd turn 123456 into 1.23e+6)
        if( $value =~ /^[0-9\-]+$/ )
        {
                return "=\"$value\"";
        }

        # only escapes row with spaces and commas
        if( $value =~ /,| / )
        {
                return "\"$value\"";
        }

        return $value;
}

1;