tethys.backend/app/Controllers/Http/Oai/OaiController.ts

190 lines
7.8 KiB
TypeScript
Raw Normal View History

import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
import { RequestContract } from '@ioc:Adonis/Core/Request';
import { XMLBuilder } from 'xmlbuilder2/lib/interfaces';
import { create } from 'xmlbuilder2';
import dayjs, { Dayjs } from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import { readFileSync } from 'fs';
import { StatusCodes } from 'http-status-codes';
import { transform } from 'saxon-js';
// import { Xslt, xmlParse } from 'xslt-processor'
import { OaiErrorCodes, OaiModelError } from 'App/Exceptions/OaiErrorCodes';
import { OaiModelException } from 'App/Exceptions/OaiModelException';
interface XslTParameter {
[key: string]: any;
}
interface Dictionary {
[index: string]: string;
}
export default class OaiController {
// private deliveringDocumentStates = ["published", "deleted"];
// private sampleRegEx = /^[A-Za-zäüÄÜß0-9\-_.!~]+$/;
private xsltParameter: XslTParameter;
/**
* Holds xml representation of document information to be processed.
*
* @var xmlbuilder.XMLDocument | null Defaults to null.
*/
private xml: XMLBuilder;
private proc;
constructor() {
// Load the XSLT file
this.proc = readFileSync('public/assets2/datasetxml2oai.sef.json');
// tests
// const xslPath = 'assets/datasetxml2oai-pmh.xslt'; // Replace with the actual path to your XSLT file
// this.proc = readFileSync(xslPath, 'utf-8');
// this.configuration = new Configuration();
dayjs.extend(utc);
dayjs.extend(timezone);
}
public async index({ response, request }: HttpContextContract): Promise<void> {
this.xml = create({ version: '1.0', encoding: 'UTF-8', standalone: true }, '<root></root>');
// this.proc = new XSLTProcessor();
// const stylesheet = readFileSync(__dirname + "/datasetxml2oai.sef.json");
const xsltParameter = (this.xsltParameter = {});
let oaiRequest: Dictionary = {};
if (request.method() === 'POST') {
oaiRequest = request.body();
} else if (request.method() === 'GET') {
oaiRequest = request.qs();
} else {
xsltParameter['oai_error_code'] = 'unknown';
xsltParameter['oai_error_message'] = 'Only POST and GET methods are allowed for OAI-PMH.';
}
// const oaiRequest: OaiParameter = request.body;
try {
this.handleRequest(oaiRequest, request);
} catch (error) {
if (error instanceof OaiModelException) {
const code = error.oaiCode;
let oaiErrorCode: string | undefined = 'Unknown oai error code ' + code;
if (OaiModelError.has(error.oaiCode) && OaiModelError.get(code) !== undefined) {
oaiErrorCode = OaiModelError.get(error.oaiCode);
}
this.xsltParameter['oai_error_code'] = oaiErrorCode;
this.xsltParameter['oai_error_message'] = error.message;
} else {
// // return next(error); // passing to default express middleware error handler
this.xsltParameter['oai_error_code'] = 'unknown';
this.xsltParameter['oai_error_message'] = 'An internal error occured.';
}
}
const xmlString = this.xml.end({ prettyPrint: true });
let xmlOutput;
try {
const result = await transform({
// stylesheetFileName: `${config.TMP_BASE_DIR}/data-quality/rules/iati.sef.json`,
stylesheetText: this.proc,
destination: 'serialized',
// sourceFileName: sourceFile,
sourceText: xmlString,
stylesheetParams: xsltParameter,
// logLevel: 10,
});
xmlOutput = result.principalResult;
} catch (error) {
return response.status(500).json({
message: 'An error occurred while creating the user',
error: error.message,
});
}
response
.header('Content-Type', 'application/xml; charset=utf-8')
.header('Access-Control-Allow-Origin', '*')
.header('Access-Control-Allow-Methods', 'GET,POST');
response.status(StatusCodes.OK).send(xmlOutput);
}
protected handleRequest(oaiRequest: Dictionary, request: RequestContract) {
// Setup stylesheet
// $this->loadStyleSheet('datasetxml2oai-pmh.xslt');
// Set response time
const now: Dayjs = dayjs();
this.xsltParameter['responseDate'] = now.format('YYYY-MM-DDTHH:mm:ss[Z]');
this.xsltParameter['unixTimestamp'] = now.unix();
// set OAI base url
const baseDomain = process.env.BASE_DOMAIN || 'localhost';
this.xsltParameter['baseURL'] = baseDomain + '/oai';
this.xsltParameter['repURL'] = request.protocol() + '://' + request.hostname();
this.xsltParameter['downloadLink'] = request.protocol() + '://' + request.hostname() + '/file/download/';
this.xsltParameter['doiLink'] = 'https://doi.org/';
this.xsltParameter['doiPrefix'] = 'info:eu-repo/semantics/altIdentifier/doi/';
if (oaiRequest['verb']) {
const verb = oaiRequest['verb'];
this.xsltParameter['oai_verb'] = verb;
if (verb === 'Identify') {
this.handleIdentify();
} else if (verb === 'ListMetadataFormats') {
this.handleListMetadataFormats();
}
// else if (verb == "GetRecord") {
// await this.handleGetRecord(oaiRequest);
// } else if (verb == "ListRecords") {
// await this.handleListRecords(oaiRequest);
// } else if (verb == "ListIdentifiers") {
// await this.handleListIdentifiers(oaiRequest);
// } else if (verb == "ListSets") {
// await this.handleListSets();
// }
else {
this.handleIllegalVerb();
}
} else {
// // try {
// // console.log("Async code example.")
// const err = new PageNotFoundException("verb not found");
// throw err;
// // } catch (error) { // manually catching
// // next(error); // passing to default middleware error handler
// // }
throw new OaiModelException(
StatusCodes.INTERNAL_SERVER_ERROR,
'The verb provided in the request is illegal.',
OaiErrorCodes.BADVERB,
);
}
}
protected handleIdentify() {
const email = process.env.OAI_EMAIL || 'repository@geosphere.at';
const repositoryName = 'Tethys RDR';
const repIdentifier = 'tethys.at';
const sampleIdentifier = 'oai:' + repIdentifier + ':1'; //$this->_configuration->getSampleIdentifier();
// Dataset::earliestPublicationDate()->server_date_published->format('Y-m-d\TH:i:s\Z') : null;
// earliestDateFromDb!= null && (this.xsltParameter['earliestDatestamp'] = earliestDateFromDb?.server_date_published);
// set parameters for oai-pmh.xslt
this.xsltParameter['email'] = email;
this.xsltParameter['repositoryName'] = repositoryName;
this.xsltParameter['repIdentifier'] = repIdentifier;
this.xsltParameter['sampleIdentifier'] = sampleIdentifier;
// $this->proc->setParameter('', 'earliestDatestamp', $earliestDateFromDb);
this.xml.root().ele('Datasets');
}
protected handleListMetadataFormats() {
this.xml.root().ele('Datasets');
}
private handleIllegalVerb() {
this.xsltParameter['oai_error_code'] = 'badVerb';
this.xsltParameter['oai_error_message'] = 'The verb provided in the request is illegal.';
}
}