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 6 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
:)
declare variable $oai:last-modified as xs:dateTime? :=
riedde marked this conversation as resolved.
Show resolved Hide resolved
if($config:svn-change-history-file/dictionary/@dateTime castable as xs:dateTime)
then $config:svn-change-history-file/dictionary/xs:dateTime(@dateTime)
else (
let $versionDateSeq := tokenize(config:get-option('versionDate'),'-')
let $year := subsequence($versionDateSeq,1,1)
let $month := subsequence($versionDateSeq,2,1)
let $day := subsequence($versionDateSeq,3,1)
return
functx:dateTime($year,$month,$day,0,0,0)
);

(:~
: Create a header response
:
: @author Dennis Ried
:)
declare %private function oai:response-headers() as empty-sequence() {
response:set-header('Access-Control-Allow-Origin', '*'),
response:set-header('Last-Modified', date:rfc822($oai:last-modified)),
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:DC.identifier($model)}" metadataPrefix="oai_dc">http://www.openarchives.org/OAI/2.0/oai_dc/</request>
riedde marked this conversation as resolved.
Show resolved Hide resolved
<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 $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>{substring($oai:last-modified,1,10)}</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>{substring($oai:last-modified,1,10)}</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)
riedde marked this conversation as resolved.
Show resolved Hide resolved
}
return
(
oai:response-headers(),
response:set-status-code(202),
oai:oai($model)
)