Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: OAI-Interface #479

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions controller.xql
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,14 @@ else if (matches($exist:path, '^/cmif_v2.xml$')) then
</forward>
</dispatch>

(: OAI-PMH-Interface :)
else if (matches($exist:path, '/(en|de)?/?' || config:get-option('generalIdPattern') || '(.*)/oai.xml')) then
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<forward url="{concat($exist:controller, '/modules/oai.xql')}">
<set-attribute name="docID" value="{functx:substring-after-last(functx:substring-before-last($exist:path,'/'),'/')}"/>
</forward>
</dispatch>

(: Sitemap :)
else if (matches($exist:path, '^/sitemap(/?|/index.xml)?$') or matches($exist:path, '^/sitemap/sitemap_(en|de).xml.(gz|zip)$')) then
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
Expand Down
136 changes: 136 additions & 0 deletions modules/oai.xql
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
xquery version "3.1" encoding "UTF-8";

(:~
: Module for exporting data as oai/xml
: see https://www.openarchives.org/OAI/openarchivesprotocol.html
:)

declare namespace tei="http://www.tei-c.org/ns/1.0";
declare namespace mei="http://www.music-encoding.org/ns/mei";
declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace response="http://exist-db.org/xquery/response";
declare namespace util="http://exist-db.org/xquery/util";
declare namespace oai="http://www.openarchives.org/OAI/2.0/";

import module namespace functx="http://www.functx.com";
import module namespace crud="http://xquery.weber-gesamtausgabe.de/modules/crud" at "crud.xqm";
import module namespace config="http://xquery.weber-gesamtausgabe.de/modules/config" at "config.xqm";
import module namespace wega-util="http://xquery.weber-gesamtausgabe.de/modules/wega-util" at "wega-util.xqm";
import module namespace date="http://xquery.weber-gesamtausgabe.de/modules/date" at "xmldb:exist:///db/apps/WeGA-WebApp-lib/xquery/date.xqm";
import module namespace str="http://xquery.weber-gesamtausgabe.de/modules/str" at "xmldb:exist:///db/apps/WeGA-WebApp-lib/xquery/str.xqm";
import module namespace mycache="http://xquery.weber-gesamtausgabe.de/modules/cache" at "xmldb:exist:///db/apps/WeGA-WebApp-lib/xquery/cache.xqm";
import module namespace lod="http://xquery.weber-gesamtausgabe.de/modules/lod" at "lod.xqm";
import module namespace lang="http://xquery.weber-gesamtausgabe.de/modules/lang" at "lang.xqm";
import module namespace query="http://xquery.weber-gesamtausgabe.de/modules/query" at "query.xqm";
import module namespace wdt="http://xquery.weber-gesamtausgabe.de/modules/wdt" at "wdt.xqm";

declare option output:method "xml";
declare option output:media-type "application/xml";
declare option output:indent "yes";

(:~
: Get the last date of modification from dataHistory.xml. Fallback: VersionDate from options.xml
: @author Dennis Ried
:
: @param $docID The ID of the document
: return The date ad xs:dateTime or empty
:)
declare %private function oai:last-modified($docID) as xs:dateTime {
let $props := config:get-data-props($docID)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function is called config:get-svn-props. A quick fix would be to adjust it here, the more elaborate way would be to duplicate such a function in the config module as e.g. config:get-version-control-props, link the old one to the new function and deprecate the old one, like:

(:~
 : Deprecated, please use config:get-version-control-props#1
 : This function is to be removed in the near future
:)

declare function config:get-svn-props($docID as xs:string) as map(*) {
    config:get-version-control-props($docID),
    wega-util:log-to-file('info', 'call to deprecated function `config:get-svn-props`!')
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, in my code it will be overwritten and the different name was to avoid myself to get confused. I'll fix that!

return
if($props?dateTime castable as xs:dateTime)
then ($props?dateTime => xs:dateTime())
else (fn:current-dateTime())
};

(:~
: Create a header response
:
: @author Dennis Ried
:)
declare %private function oai:response-headers($docID) as empty-sequence() {
response:set-header('Access-Control-Allow-Origin', '*'),
response:set-header('Last-Modified', date:rfc822(oai:last-modified($docID))),
response:set-header('Cache-Control', 'max-age=300,public')
};

(:~
: Creating the response for the interface (header, calling record by oai:record)
:
: @author Dennis Ried
:)
declare function oai:oai($model as map(*)) as node() {
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
<responseDate>{fn:current-dateTime()}</responseDate>
<request verb="GetRecord" identifier="{$lod-metadata?DC.identifier}" metadataPrefix="oai_dc">http://www.openarchives.org/OAI/2.0/oai_dc/</request>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable $lod-metadata is not available in this function. It's probably best to fetch lod:metadata first and append this to the main $model (see below)?!

Suggested change
<request verb="GetRecord" identifier="{$lod-metadata?DC.identifier}" metadataPrefix="oai_dc">http://www.openarchives.org/OAI/2.0/oai_dc/</request>
<request verb="GetRecord" identifier="{$model?lod?DC.identifier}" metadataPrefix="oai_dc">http://www.openarchives.org/OAI/2.0/oai_dc/</request>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, but why does it work on my machine?

<GetRecord>
{oai:record($model)}
</GetRecord>
</OAI-PMH>
};

(:~
: Creating the record for the called file (body of response)
:
: @author Dennis Ried
:)
declare function oai:record($model as map(*)) as node() {
let $docID := $model('docID')
let $lang := $model('lang')
let $dc-date := oai:last-modified($docID) => substring(1,10)
let $lod-metadata := lod:metadata(<node/>, $model, $lang)
return
<record xmlns="http://www.openarchives.org/OAI/2.0/">
<header>
<identifier>{$lod-metadata?DC.identifier}</identifier>
<datestamp>{fn:current-dateTime()}</datestamp>
<setSpec>{$model('docType')}</setSpec>
</header>
<metadata>
<oai_dc:dc
xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
<dc:title>{$lod-metadata?meta-page-title}</dc:title>
<dc:creator>{$lod-metadata?DC.creator}</dc:creator>
<dc:subject>{$lod-metadata?DC.subject}</dc:subject>
<dc:description>{$lod-metadata?DC.description}</dc:description>
<dc:date>{$dc-date}</dc:date>
<dc:identifier>{$docID}</dc:identifier>
</oai_dc:dc>
</metadata>
<about>
<provenance
xmlns="http://www.openarchives.org/OAI/2.0/provenance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/provenance http://www.openarchives.org/OAI/2.0/provenance.xsd">
<originDescription harvestDate="{fn:current-dateTime()}" altered="true">
<baseURL>{config:get-option('permaLinkPrefix')}</baseURL>
<identifier>{$docID}</identifier>
<datestamp>{$dc-date}</datestamp>
<metadataNamespace>http://www.openarchives.org/OAI/2.0/oai_dc/</metadataNamespace>
</originDescription>
</provenance>
</about>
</record>
};

let $lang := config:guess-language(())
let $docID := request:get-attribute('docID')
let $doc := crud:doc($docID)
let $model :=
map {
'lang': $lang,
'docID': $docID,
'doc': $doc,
'docType': config:get-doctype-by-id($docID),
'lod': lod:metadata(<node/>, $model, $lang)
}
return
(
oai:response-headers($docID),
response:set-status-code(202),
oai:oai($model)
)