Difference between revisions of "Create Export Plugins"

From EPrints Documentation
Jump to: navigation, search
m
(Reverting spam.)
Line 1: Line 1:
[http://xxxenichkaa.ifrance.com/la-bicicletta.html la bicicletta] [http://snakeystil.ifrance.com/jade/index.html jade] [http://thecrownless.ifrance.com/i-don-t-want-to/index.html i don t want to be] [http://katzella.ifrance.com/i-n-p-s-it/index.html i n p s it] [http://katzella.ifrance.com/hai/index.html hai] [http://starcross33.ifrance.com/ljepi-dani/index.html ljepi dani] [http://child-ofadot.ifrance.com/inquinmento.html inquinmento] [http://plyuh-vios.ifrance.com/i-want-internet.html i want internet in english] [http://thecrownless.ifrance.com/iheb-tawfik/index.html iheb tawfik] [http://starcross33.ifrance.com/l-amore-piu-grande/index.html l amore piu grande] [http://carbonphoenix.ifrance.com/jem-boy.html jem boy] [http://cuivenarius.ifrance.com/hot-party-2002.html hot party 2002] [http://risdimpuka.ifrance.com/la-vita-loca/index.html la vita loca] [http://busjavka.ifrance.com/hotel-capo-noli/index.html hotel capo noli] [http://angeljazz711.ifrance.com/incontri-a-letto.html incontri a letto] [http://snakeystil.ifrance.com/jennifer-sky/index.html jennifer sky] [http://taylors-acolyte.ifrance.com/inizio-scuole-superiori.html inizio scuole superiori montebelluna] [http://plyuh-vios.ifrance.com/isn-t-it-beautiful.html isn t it beautiful suteki da ne] [http://thecrownless.ifrance.com/il-futurismo-in/index.html il futurismo in arte] [http://oddonpurpose.ifrance.com/lil-jon-and.html lil jon and the eastside boyz] [http://taylors-acolyte.ifrance.com/imbarco-olbia.html imbarco olbia] [http://eliasn5gh.ifrance.com/los-machucambos.html los machucambos pepito] [http://angeljazz711.ifrance.com/ipostenia.html ipostenia] [http://listmishyk.ifrance.com/katy-playground/index.html katy playground] [http://pupsik1993.ifrance.com/l-aumour-toujours.html l aumour toujours] [http://carbonphoenix.ifrance.com/judy-weiss.html judy weiss] [http://taylors-acolyte.ifrance.com/innamorarsi-in-riviera.html innamorarsi in riviera] [http://risdimpuka.ifrance.com/la-serenella/index.html la serenella] [http://carbonphoenix.ifrance.com/jericho-di-rosetta.html jericho di rosetta tharpe] [http://oddonpurpose.ifrance.com/laudato-sii-mio.html laudato sii mio dolcissimo signore] [http://xxxenichkaa.ifrance.com/last-minute-offerte.html last minute offerte viaggi] [http://carbonphoenix.ifrance.com/jingle-bell-rock-joe.html jingle bell rock joe beal e jim boothe] [http://snakeystil.ifrance.com/julieta-veniegas/index.html julieta veniegas] [http://risdimpuka.ifrance.com/lenceria-sexi/index.html lenceria sexi] [http://cuivenarius.ifrance.com/harry-potter-com.html harry potter com] [http://oddonpurpose.ifrance.com/lineadeigolfi.html lineadeigolfi] [http://eliasn5gh.ifrance.com/la-cesta.html la cesta] [http://xxxenichkaa.ifrance.com/libertango.html libertango] [http://pupsik1993.ifrance.com/ludmilla-radchenko.html ludmilla radchenko letterina] [http://busjavka.ifrance.com/hamman-della-rosa/index.html hamman della rosa] [http://taylors-acolyte.ifrance.com/igrale-se-delije.html igrale se delije] [http://angeljazz711.ifrance.com/intimissimo.html intimissimo] [http://plyuh-vios.ifrance.com/inno-rifondazione-comunista.html inno rifondazione comunista] [http://fluffy-mind.ifrance.com/kim-sunill.html kim sunill] [http://busjavka.ifrance.com/http-www-bdsm-sex/index.html http www bdsm sex ru] [http://carbonphoenix.ifrance.com/jaclyn-smith.html jaclyn smith] [http://fluffy-mind.ifrance.com/kury.html kury] [http://katzella.ifrance.com/haiduchi-dragostea/index.html haiduchi dragostea din tei mai ai hii] [http://pupsik1993.ifrance.com/low-rider.html low rider] [http://taylors-acolyte.ifrance.com/il-mondo-insieme-a-te.html il mondo insieme a te mp3] [http://alexandraa80.ifrance.com/la-citta-de-pullecenella/index.html la citta de pullecenella] [http://alexandraa80.ifrance.com/lady-be-beatles/index.html lady be beatles] [http://alexandraa80.ifrance.com/lecabloc/index.html lecabloc] [http://child-ofadot.ifrance.com/il-secondo-tragico.html il secondo tragico fantozzi] [http://thecrownless.ifrance.com/italia-d-oro/index.html italia d oro] [http://child-ofadot.ifrance.com/il-film-un-principo.html il film un principo tutto mio] [http://cuivenarius.ifrance.com/hotel-canazei.html hotel canazei] [http://starcross33.ifrance.com/la-festa-dei-folli/index.html la festa dei folli] [http://cuivenarius.ifrance.com/hello-evanescene.html hello evanescene] [http://child-ofadot.ifrance.com/i-ll-drown-in-my.html i ll drown in my own tears] [http://plyuh-vios.ifrance.com/in-the-shadows.html in the shadows] [http://child-ofadot.ifrance.com/inno-brigata.html inno brigata sassari] [http://chasingspaces.ifrance.com/hotel-5-stelle-roma/index.html hotel 5 stelle roma hotel] [http://thecrownless.ifrance.com/italo-janne/index.html italo janne] [http://plyuh-vios.ifrance.com/i-vatussi-mp3.html i vatussi mp3] [http://busjavka.ifrance.com/hit-mania-dnce-2004/index.html hit mania dnce 2004] [http://eliasn5gh.ifrance.com/lisa-gerrad.html lisa gerrad] [http://alexandraa80.ifrance.com/laura-andresan-e-mutu/index.html laura andresan e mutu] [http://taylors-acolyte.ifrance.com/irvin-goffman.html irvin goffman] [http://plyuh-vios.ifrance.com/illeone.html illeone] [http://snakeystil.ifrance.com/juegos-olimpicos/index.html juegos olimpicos atenas 2004] [http://busjavka.ifrance.com/hymne-a-l-amour/index.html hymne a l amour] [http://cuivenarius.ifrance.com/hector-y-tito-gata.html hector y tito gata salvage] [http://oddonpurpose.ifrance.com/lucybell.html lucybell] [http://child-ofadot.ifrance.com/isola-dei-famosi.html isola dei famosi 2003] [http://pupsik1993.ifrance.com/let-s-go-trick-dady.html let s go trick dady] [http://cuivenarius.ifrance.com/hey-ho-lets-go.html hey ho lets go] [http://angeljazz711.ifrance.com/iwan-i-delfin.html iwan i delfin czarne oczy mp3] [http://alexandraa80.ifrance.com/la-vie-rose-testo/index.html la vie rose testo canzone] [http://oddonpurpose.ifrance.com/love-my-live.html love my live] [http://taylors-acolyte.ifrance.com/inbet.html inbet] [http://xxxenichkaa.ifrance.com/le-vent-nous-portera.html le vent nous portera noir desire] [http://plyuh-vios.ifrance.com/il-ballo-di-simoni.html il ballo di simoni] [http://cuivenarius.ifrance.com/haiuch.html haiuch] [http://angeljazz711.ifrance.com/imprenditoria.html imprenditoria] [http://xxxenichkaa.ifrance.com/la-danse-de-zorba.html la danse de zorba] [http://cuivenarius.ifrance.com/himno-nacional-colombiano.html himno nacional colombiano] [http://chasingspaces.ifrance.com/garante-della-privacy/index.html garante della privacy] [http://eliasn5gh.ifrance.com/luoghi-sadomaso.html luoghi sadomaso] [http://child-ofadot.ifrance.com/i-delfino-pesci.html i delfino pesci] [http://child-ofadot.ifrance.com/il-gladiatore-di-russel.html il gladiatore di russel crowe] [http://plyuh-vios.ifrance.com/i-life.html i life] [http://taylors-acolyte.ifrance.com/il-dopo-guerra.html il dopo guerra] [http://katzella.ifrance.com/icarito-cl/index.html icarito cl] [http://xxxenichkaa.ifrance.com/lubrificanti-oli.html lubrificanti oli e grassi] [http://snakeystil.ifrance.com/jessyca-rizzo/index.html jessyca rizzo] [http://alexandraa80.ifrance.com/lupo-animale/index.html lupo animale] [http://child-ofadot.ifrance.com/il-mondo-che-non.html il mondo che non c e] [http://listmishyk.ifrance.com/karama/index.html karama] [http://starcross33.ifrance.com/le-donne-di-baggio/index.html le donne di baggio] [http://pupsik1993.ifrance.com/los-vanvan.html los vanvan] [http://pupsik1993.ifrance.com/lei-cerca-gigolo.html lei cerca gigolo] [http://chasingspaces.ifrance.com/giorgio-vanni/index.html giorgio vanni dragon ball gt] [http://chasingspaces.ifrance.com/hex-tv-cabo/index.html hex tv cabo] [http://chasingspaces.ifrance.com/henya/index.html henya] [http://starcross33.ifrance.com/luana-piovanni/index.html luana piovanni] [http://cuivenarius.ifrance.com/heavy-on-my-heart.html heavy on my heart anastacia] [http://xxxenichkaa.ifrance.com/lettere-giapponesi.html lettere giapponesi] [http://busjavka.ifrance.com/hombres-y-mujeres/index.html hombres y mujeres desnudas] [http://carbonphoenix.ifrance.com/j-five.html j five] [http://angeljazz711.ifrance.com/immobiliare.html immobiliare argentario] [http://plyuh-vios.ifrance.com/illusion-benassi-bros.html illusion benassi bros f sandy] [http://busjavka.ifrance.com/http-www-rosasalvatore/index.html http www rosasalvatore com] [http://xxxenichkaa.ifrance.com/la-funzione-del.html la funzione del riscaldamento nello spor] [http://chasingspaces.ifrance.com/greco-esame-maturita/index.html greco esame maturita 2004] [http://listmishyk.ifrance.com/katal/index.html katal] [http://taylors-acolyte.ifrance.com/if-i-could.html if i could] [http://eliasn5gh.ifrance.com/la-chanson-des.html la chanson des vieux amants] [http://thecrownless.ifrance.com/io-cisaro/index.html io cisaro] [http://snakeystil.ifrance.com/juliana-bbb/index.html juliana bbb] [http://eliasn5gh.ifrance.com/loreena-mackennitt.html loreena mackennitt] [http://katzella.ifrance.com/hoang-oanh/index.html hoang oanh] [http://pupsik1993.ifrance.com/leone-alato.html leone alato] [http://pupsik1993.ifrance.com/lancio-del-pinguino.html lancio del pinguino] [http://risdimpuka.ifrance.com/lsass-exe/index.html lsass exe] [http://angeljazz711.ifrance.com/iraq-baldoni-foto.html iraq baldoni foto] [http://alexandraa80.ifrance.com/l-italiano-karaoke/index.html l italiano karaoke] [http://plyuh-vios.ifrance.com/io-della-vita-non.html io della vita non ha capito un cazzo] [http://fluffy-mind.ifrance.com/katrin-grande-fratello.html katrin grande fratello europeo] [http://eliasn5gh.ifrance.com/lunove-price.html lunove price] [http://pupsik1993.ifrance.com/la-conga.html la conga] [http://risdimpuka.ifrance.com/laetitia-casta/index.html laetitia casta nuda] [http://snakeystil.ifrance.com/j-veux-d-la-tendresse/index.html j veux d la tendresse] [http://eliasn5gh.ifrance.com/let-outside-alona.html let outside alona] [http://alexandraa80.ifrance.com/lyrics-y-m-c-a/index.html lyrics y m c a] [http://busjavka.ifrance.com/hotel-on-line/index.html hotel on line] [http://alexandraa80.ifrance.com/locman/index.html locman] [http://snakeystil.ifrance.com/jinatera/index.html jinatera] [http://carbonphoenix.ifrance.com/just-for-jou.html just for jou] [http://alexandraa80.ifrance.com/le-vent-nour/index.html le vent nour portera] [http://fluffy-mind.ifrance.com/k-mari.html k mari] [http://eliasn5gh.ifrance.com/lumydee.html lumydee] [http://taylors-acolyte.ifrance.com/in-the-disco.html in the disco] [http://pupsik1993.ifrance.com/lo-strano-percorso-pezzali.html lo strano percorso pezzali max] [http://snakeystil.ifrance.com/i-piu-gattonati/index.html i piu gattonati] [http://eliasn5gh.ifrance.com/legge-20-maggio-1970.html legge 20 maggio 1970 n 300] [http://eliasn5gh.ifrance.com/locali-prive.html locali prive] [http://angeljazz711.ifrance.com/in-alto-mare-di.html in alto mare di 2black] [http://snakeystil.ifrance.com/jelena-brocic/index.html jelena brocic] [http://risdimpuka.ifrance.com/lyon-sorties/index.html lyon sorties] [http://listmishyk.ifrance.com/kal-ho/index.html kal ho] [http://eliasn5gh.ifrance.com/les-deux-alpes.html les deux alpes] [http://oddonpurpose.ifrance.com/la-sorpresa-un.html la sorpresa un raggio di sole] [http://starcross33.ifrance.com/la-fattoria-danza-del/index.html la fattoria danza del ventre] [http://katzella.ifrance.com/helene-sviden/index.html helene sviden] [http://chasingspaces.ifrance.com/htomail/index.html htomail] [http://fluffy-mind.ifrance.com/kanye-west-jesus.html kanye west jesus walks] [http://xxxenichkaa.ifrance.com/las-mejores-tetas.html las mejores tetas del mundo] [http://fluffy-mind.ifrance.com/k-amaro-femme.html k amaro femme like u] [http://snakeystil.ifrance.com/jennifer-lopez/index.html jennifer lopez sex images] [http://alexandraa80.ifrance.com/lucchesi-ad-atene/index.html lucchesi ad atene] [http://carbonphoenix.ifrance.com/jennifer-saunders.html jennifer saunders holding out for a hero] [http://listmishyk.ifrance.com/karl/index.html karl] [http://chasingspaces.ifrance.com/howell/index.html howell] [http://plyuh-vios.ifrance.com/i-don-t-wona-know.html i don t wona know] [http://child-ofadot.ifrance.com/il-gran-sole-di-hiroshima.html il gran sole di hiroshima] [http://pupsik1993.ifrance.com/let-s-dance.html let s dance] [http://eliasn5gh.ifrance.com/linear-assicurazioni.html linear assicurazioni] [http://busjavka.ifrance.com/hombres-en-calzoncillos/index.html hombres en calzoncillos] [http://angeljazz711.ifrance.com/it-s-al-right.html it s al right] [http://angeljazz711.ifrance.com/immagini-di-persone.html immagini di persone] [http://pupsik1993.ifrance.com/lauro-prenna.html lauro prenna] [http://taylors-acolyte.ifrance.com/indicatore-della.html indicatore della situazione economica eq] [http://thecrownless.ifrance.com/isac-hugo/index.html isac hugo] [http://snakeystil.ifrance.com/jordan-james/index.html jordan james] [http://snakeystil.ifrance.com/jasmin-muharemovic-nocima/index.html jasmin muharemovic nocima i danima] [http://listmishyk.ifrance.com/kiosque-code/index.html kiosque code] [http://eliasn5gh.ifrance.com/lupus-in-fabula.html lupus in fabula] [http://alexandraa80.ifrance.com/la-vita-e-bella-nicola/index.html la vita e bella nicola piovani] [http://risdimpuka.ifrance.com/linee-erotiche/index.html linee erotiche] [http://busjavka.ifrance.com/hallospank/index.html hallospank] [http://oddonpurpose.ifrance.com/liviu-gut-mp3.html liviu gut mp3] [http://angeljazz711.ifrance.com/ingres-il-bagno.html ingres il bagno turco] [http://angeljazz711.ifrance.com/inchiappettare.html inchiappettare] [http://cuivenarius.ifrance.com/hundai.html hundai] [http://fluffy-mind.ifrance.com/koftos.html koftos] [http://plyuh-vios.ifrance.com/island-of-ustica.html island of ustica] [http://eliasn5gh.ifrance.com/latin.html latin] [http://starcross33.ifrance.com/le-ghiaie/index.html le ghiaie] [http://pupsik1993.ifrance.com/laps-dance.html laps dance] [http://starcross33.ifrance.com/legge-sulla-praivasi/index.html legge sulla praivasi] [http://alexandraa80.ifrance.com/lg-5410/index.html lg 5410] [http://pupsik1993.ifrance.com/lungotevere-dorme.html lungotevere dorme] [http://eliasn5gh.ifrance.com/loyd.html loyd] [http://cuivenarius.ifrance.com/hilltop-hoods-the-nosebleed.html hilltop hoods the nosebleed section] [http://listmishyk.ifrance.com/khoa-than/index.html khoa than] [http://oddonpurpose.ifrance.com/l-elefante-e.html l elefante e la formica] [http://chasingspaces.ifrance.com/gioditonnofansclub/index.html gioditonnofansclub] [http://alexandraa80.ifrance.com/les-demoiselles/index.html les demoiselles d avignon] [http://risdimpuka.ifrance.com/la-bella-pastorella/index.html la bella pastorella] {{development}}
+
{{development}}
  
 
Export plugins increase the value of your repository by allowing users to get data out in the format they want.  
 
Export plugins increase the value of your repository by allowing users to get data out in the format they want.  
Line 403: Line 403:
 
                 if (defined $r{$username})                                        #if it's defined, increment and compare timestamps
 
                 if (defined $r{$username})                                        #if it's defined, increment and compare timestamps
 
                 {
 
                 {
                         $r{$username}->{count}   ;
+
                         $r{$username}->{count} ++;
 
                         if ($r{$username}->{most_recent} lt $datestamp)
 
                         if ($r{$username}->{most_recent} lt $datestamp)
 
                         {
 
                         {

Revision as of 18:26, 2 September 2007

Warning This page is under development as part of the EPrints 3.0 manual. It may still contain content specific to earlier versions. Manuals for previous versions of EPrints are also available.

Export plugins increase the value of your repository by allowing users to get data out in the format they want.

Export plugins also help Integrate your repository with other systems by allowing the systems to exchange data via an interchange format.

EPrints 3 is packaged with a number of export plugins, and export plugins are also developed and shared by other EPrints users.

The purpose of this guide is to describe how to create new export plugins for your repository.

Before getting started, check that the output/interchange format that you want to add to your repository has not already been made available in the EPrints Files repository: http://files.eprints.org/view/type/plugin.html

Plugins are written in Perl, so some coding experience is required, as is a familiarity with the EPrints API.

Export plugin overview

An EPrints export plugin is typically a standalone Perl module. There are 2 key functions that an export plugin must carry out:

  1. Register with EPrints
  2. Define how to convert EPrint records to the output/interchange format

Registration

Export plugins register the following properties:

  • name - the name of the plugin
  • visible - who can use it
  • accept - what the plugin can convert
    • lists of records or single records (or both)
    • type of record (eprints, users, subjects.. see EPrints data objects)
  • suffix and mimetype - file extension and MIME type of format it converts to

Example: BibTeX export plugin (extract from registration section)

       $self->{name} = "BibTeX";
       $self->{accept} = [ 'list/eprint', 'dataobj/eprint' ];
       $self->{visible} = "all";
       $self->{suffix} = ".bib";
       $self->{mimetype} = "text/plain";

This BibTeX export plugin can convert lists of eprints or single eprints, is available to all users, and produces a plain text file with a .bib extension.

Example: XML (with embedded files) export plugin

       $self->{name} = "EP3 XML with Files Embeded";
       $self->{accept} = [ 'list/eprint', 'dataobj/eprint' ];
       $self->{visible} = "staff";
       $self->{suffix} = ".xml";
       $self->{mimetype} = "text/xml";

This XML export plugin is available to repository staff only.

Example: DIDL export plugin

       $self->{name} = "DIDL";
       $self->{accept} = [ 'dataobj/eprint' ];
       $self->{visible} = "all";
       $self->{suffix} = ".xml";
       $self->{mimetype} = "text/xml";

This DIDL export plugin can handle only a single eprint record at a time.

Example: FOAF export plugin

       $self->{name} = "FOAF Export";
       $self->{accept} = [ 'dataobj/user' ];
       $self->{visible} = "all";
       $self->{suffix} = ".rdf";
       $self->{mimetype} = "text/xml";

This FOAF export plugin converts a single user record.

Example: XML export plugin

       $self->{name} = "EP3 XML";
       $self->{accept} = [ 'list/*', 'dataobj/*' ];
       $self->{visible} = "all";
       $self->{suffix} = ".xml";
       $self->{mimetype} = "text/xml";

This XML export plugin can handle lists or individual records of any type.

Conversion

This might include mapping EPrints fields to output/interchange format fields and serialising the output/interchange format.

Example: EndNote export plugin (extract from conversion section)

       # K Keywords
       $data->{K} = $dataobj->get_value( "keywords" ) if $dataobj->exists_and_set( "keywords" );
       # T Title
       $data->{T} = $dataobj->get_value( "title" ) if $dataobj->exists_and_set( "title" );
       # U URL
       $data->{U} = $dataobj->get_url;
       # X Abstract
       $data->{X} = $dataobj->get_value( "abstract" ) if $dataobj->exists_and_set( "abstract" );
       # Z Notes
       $data->{Z} = $dataobj->get_value( "note" ) if $dataobj->exists_and_set( "note" );

This extract shows how the values of the EndNote fields %K, %T, %U, %X and %Z are mapped from the EPrint_Object.

Example: Text export plugin (extract from conversion section)

       my $cite = $dataobj->render_citation;
       return EPrints::Utils::tree_to_utf8( $cite )."\n\n";

To serialise an EPrint_Object, the Text export plugin simply outputs the citation.

Hello World export plugin

http://en.wikipedia.org/wiki/Hello_world_program

Export plugins are stored in:

/opt/eprints3/perl_lib/EPrints/Plugin/Export/

Create a new file in this directory called HelloWorld.pm, and paste the following code into it (this is a useful template for writing export plugins!):

package EPrints::Plugin::Export::HelloWorld;

use EPrints::Plugin::Export;
@ISA = ( "EPrints::Plugin::Export" );

use strict;

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

sub output_dataobj
{
        my( $plugin, $dataobj ) = @_;
}

1;


The new subroutine creates the plugin - this is where you register the plugin with EPrints. The output_dataobj subroutine is where you convert EPrints data to the output format.

Perl notes:

  1. package ... - the plugin (Perl module) namespace, which should always be EPrints::Plugin::Export::PluginID (note that the file should be called PluginID.pm)
  2. use EPrints::Plugin::Export, @ISA=... - inherit all the internal wiring needed for EPrints to use your plugin

Register Hello World plugin

Add the following to the new subroutine to register the plugin with EPrints:

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

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

        $self->{name} = "Hello, World!";
        $self->{accept} = [ 'dataobj/eprint', 'list/eprint' ];
        $self->{visible} = "all";
        $self->{suffix} = ".txt";
        $self->{mimetype} = "text/plain; charset=utf-8";

        return $self;
}

Convert EPrints data to Hello World data

Add the following to the output_dataobj subroutine:

sub output_dataobj
{
        my( $plugin, $dataobj ) = @_;

        my $title = $dataobj->get_value( "title" );

        return "Hello, World! $title\n\n";
} 

This subroutine "converts" an eprint object by getting its title and using it in a Hello, World! message.

Testing the Hello World plugin

Save the HelloWorld.pm file and then restart the Web server, eg.:

service httpd restart

Why do I need to restart the Web server? EPrints uses mod_perl which loads all Perl modules at start up; therefore whenever these modules change they need to be reloaded.

The Hello World export plugin handles lists of eprints and single eprints. Therefore, EPrints displays it in the list of export plugins on the search results page:

Selecting the Hello World export plugin from the search results page

When the Hello World export plugin is activated, the convert_dataobj subroutine is applied to every item in the list to produce the result:

The output of the Hello World export plugin

Walkthough: Using existing plugins to build new plugins

Walkthrough: Deposit activity plugin

Imagine we want to create an export plugin that will take a group of eprints (or a single eprint) and output a csv file containing a list of who deposited the eprints, and the dates on which they were deposited.

Registration

The top of the plugin should look like this:

 package EPrints::Plugin::Export::DepositorActivity;
 
 use Unicode::String qw( utf8 );
 use EPrints::Plugin::Export;
 use EPrints::DataObj::User;
 @ISA = ( "EPrints::Plugin::Export" );
 use strict;
 
 sub new
 {
        my( $class, %params ) = @_;
 
        my $self = $class->SUPER::new( %params );
 
        $self->{name} = "Depositor Activity";
        $self->{accept} = [ 'list/eprint', 'dataobj/eprint' ];
        $self->{visible} = "all";
        $self->{suffix} = ".csv";
        $self->{mimetype} = "text/csv";
 
        return $self;
 }

This will create a filter object, and set a number of configuration constants:

  • name - The name of the filter
  • accept - A list detailing what the filter will take as inputs. In this case, a list of eprints or a single eprint. It is possible to write filters for dataobj types 'eprint', 'user', 'subject', 'history', 'access' and '*' (all).
  • visible - Who can see this filter. It's set to 'all' above so that anyone can use it. It could be set to 'staff' to only allow repository staff to use it. If set to 'API' then the filter is not available through the web interface.
  • suffix - Appended to the url to create a filename extension.
  • mimetype - Should be set to the correct mime type for the output of the filter.

Note that 'name' and 'accept' are essential. These allow the filter to register itself with EPrints.

We will be extracting the username of the depositor, so we need to use 'EPrints::DataObj::User'.

Conversion

The 'output_dataobj' function takes a dataobj (in our case an eprint object) and returns a perl scalar which will be the output. We are going to extract some data from the dataobj using EPrints API calls.

Note that by convention, '$plugin' is used instead of '$self'.

 sub output_dataobj
 {
       my( $plugin, $dataobj ) = @_;
 
       my $r = "";
       if ($dataobj->exists_and_set("userid"))                                       #userid may not be set if the deposit was done by a script.
       {
               my $session = $plugin->{"session"}; 
               my $userid = $dataobj->get_value( "userid" );
               my $depositor_obj = new EPrints::DataObj::User($session, $userid);    #create a user object
               my $depositor = $depositor_obj->get_value( "username" );              #get the user ID
               if ($depositor =~ m/[\n" ,]/)                                         #Check for illegal CSV characters
               {
                       $depositor =~ s/"/""/g;                                       #escape quotes
                       $depositor = '"' . $depositor . '"';                          #delimit text
               }
               $r .= $depositor;
       }
       else
       {
               $r .= '"Depositor Unknown"';
       }
       $r .= ',"' . $dataobj->get_value( "datestamp" ) . '"' ."\n";                   #datestamp is always set, and contains a space so needs delimiting
 
       return $r;
 }

Notes:

  • Retreiving the username takes a little fancy footwork because the EPrints object contains depositor userids. We need to create a user object and get the username from that.
  • We use '$dataobj->get_value' to retrieve metadata from the eprint (or user) objects.
  • As we're outputting in CSV, we need to do a little normalisation.

Put it in a Module

Put all this into a file called 'DepositorActivity.pm' and save the file into the 'eprints3/perl_lib/EPrints/Plugin/Export/' directory. Don't forget to add this to the bottom of the file:

 1;

Before you can use the plugin, you must restart the webserver. This will cause EPrints to load it.

Adding Column Headings

The 'output_dataobj' runs on a single EPrint. If the plugin runs over a list of eprints (we've given it that capability), the default behaviour is to run 'output_dataobj' on every eprint in the list and concatenate the results.

The output_list function is what handles the lists. This takes itself ($plugin) and a hash (%opts) as arguments. The %opt hash contains the list. It could also contain a filehandle. When writing 'output_list', you need to check for the filehandle and if present, print to it. If it's not present, return the results as a scalar.

Here is an output_list function that will add column headings to our CSV file.

 sub output_list
 {
        my( $plugin, %opts ) = @_;
        my $r = [];                                                      #array for results accumulation
        my $part;
 
        $part = '"User ID","Date Stamp"' . "\n";                         #column headings
        if( defined $opts{fh} )                                          #write to file or accumulate headings
        {
                print {$opts{fh}} $part;
        }
        else
        {
                push @{$r}, $part;
        }
 
        foreach my $dataobj ( $opts{list}->get_records )                 #Iterate over list
        {
                $part = $plugin->output_dataobj( $dataobj, %opts );      #call output_dataobj
                if( defined $opts{fh} )                                  #write to file or accumulate results
                {
                         print {$opts{fh}} $part;
                }
                else
                {
                        push @{$r}, $part;
                }
        }
 
        if( defined $opts{fh} )                                          #Don't return results if writing to file.
        {
                return;
        }
        return join( '', @{$r} );
 }

The conditionals for printing to a file make the function look overly complex. Here it is if you ignore file handles (which you certainly shouldn't do):

 sub output_list
 {
        my( $plugin, %opts ) = @_;
        my $r = [];                                                      #array for results accumulation
        my $part;
 
        $part = '"User ID","Date Stamp"' . "\n";                         #column headings
        push @{$r}, $part;
        foreach my $dataobj ( $opts{list}->get_records )                 #Iterate over list
        {
                $part = $plugin->output_dataobj( $dataobj, %opts );      #call output_dataobj
                push @{$r}, $part;
        }
        return join( '', @{$r} );
 }

More Complex List Processing

output_list can be used to do more than simple concatenating results from output_dataobj. For example, the plugin above will output a table containing one entry for every eprint showing the depositor and the deposit date. Perhaps this could be made more useful by changing the table so that it contains a row for each user that deposited an eprint. Perhaps three columns (userid, number of deposits, datestamp of latest deposit) could be useful.

For readability, output_list is shown without filehandle handling. If this were a real filter, IT WOULD BE NECESSARY!

Firstly, an auxhillary function that will return a CSV normalised username. It's similar to the output_data function above, so should be easy to understand.

 sub get_username
 {
       my( $plugin, $dataobj ) = @_;
 
       my $username;
       if ($dataobj->exists_and_set("userid"))                                     #userid may not be set if the deposit was done by a script.
       {
               my $session = $plugin->{"session"};
               my $userid = $dataobj->get_value( "userid" );

               my $depositor_obj = new EPrints::DataObj::User($session, $userid);  #create a user object
               my $depositor = $depositor_obj->get_value( "username" );            #get the user ID
               if ($depositor =~ m/[\n" ,]/)         #Check for illegal CSV characters
               {
                       $depositor =~ s/"/""/g; #escape quotes
                       $depositor = '"' . $depositor . '"'; #delimit text
               }
               $username = $depositor;
       }
       else
       {
               $username = '"Depositor Unknown"';
       }
       return $username;
 }

The new output_list function uses a hash to accumlate the results:

 sub output_list
 {
        my( $plugin, %opts ) = @_;
        my %r = ();
 
        #Iterate over the list
        foreach my $dataobj ( $opts{list}->get_records )
        {
                my $username = $plugin->get_username( $dataobj );
                my $datestamp = '"' . $dataobj->get_value( "datestamp" ) . '"';
                if (defined $r{$username})                                        #if it's defined, increment and compare timestamps
                {
                        $r{$username}->{count} ++;
                        if ($r{$username}->{most_recent} lt $datestamp)
                        {
                                $r{$username}->{most_recent} = $datestamp;
                        }
                }
                else                                                              #if it's not defined, create a hash for this user's results
                {
                        $r{$username} = {count => 1, most_recent => $datestamp};
                }
        }
 
        # Construct the CSV and return it.
        my $csv = '"User Name","Number of Deposits","Most Recent Deposit"' . "\n";
        foreach my $username (sort keys %r)
        {
                $csv .= $username . "," . $r{$username}->{count} . "," . $r{$username}->{most_recent} . "\n";
        }
        return $csv;
 }

Note that because this plugin can take a single eprint as well as a list of eprints, you must have a output_dataobj function that will do something sensible. However, bear in mind that search results are always a list, even if there's only one result.