- add file.controller.ts and File.ts for downloading files from server
- allow Get and Post form Oia/Index method
This commit is contained in:
parent
44688ac806
commit
83685b68ed
|
@ -5,6 +5,7 @@ import HomeRoutes from "./routes/home.routes.js";
|
||||||
import { initDB } from "./config/db.config";
|
import { initDB } from "./config/db.config";
|
||||||
import { DatasetController } from "./controllers/dataset.controller";
|
import { DatasetController } from "./controllers/dataset.controller";
|
||||||
import { OaiController } from "./controllers/oai.controller";
|
import { OaiController } from "./controllers/oai.controller";
|
||||||
|
import { FileController } from "./controllers/file.controller";
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
export class App extends Server {
|
export class App extends Server {
|
||||||
|
@ -54,7 +55,7 @@ export class App extends Server {
|
||||||
|
|
||||||
// addroutes
|
// addroutes
|
||||||
// this.app.use('/api/dataset', DatasetRoutes);
|
// this.app.use('/api/dataset', DatasetRoutes);
|
||||||
super.addControllers([new DatasetController(), new OaiController()]);
|
super.addControllers([new DatasetController(), new OaiController(), new FileController()]);
|
||||||
|
|
||||||
this.app.use("/api/", HomeRoutes);
|
this.app.use("/api/", HomeRoutes);
|
||||||
this.app.get("/", (request, response) => {
|
this.app.get("/", (request, response) => {
|
||||||
|
|
54
src/controllers/file.controller.ts
Normal file
54
src/controllers/file.controller.ts
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import { Controller, Get } from "@overnightjs/core";
|
||||||
|
import { File } from "../models/init-models.js";
|
||||||
|
import { StatusCodes } from "http-status-codes";
|
||||||
|
import { Request, Response } from "express";
|
||||||
|
import * as path from "path";
|
||||||
|
import * as fs from "fs";
|
||||||
|
|
||||||
|
@Controller("file")
|
||||||
|
export class FileController {
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
@Get("download/:id")
|
||||||
|
public async findOne(req: Request, res: Response) {
|
||||||
|
const id = req.params.id;
|
||||||
|
const file = await File.findOne({
|
||||||
|
where: { id: id },
|
||||||
|
});
|
||||||
|
if (file) {
|
||||||
|
let filePath = "/storage/app/public/" + file.path_name;
|
||||||
|
const ext = path.extname(filePath);
|
||||||
|
let fileName = file.label + ext;
|
||||||
|
try {
|
||||||
|
fs.accessSync(filePath, fs.constants.R_OK | fs.constants.W_OK);
|
||||||
|
// console.log("can read/write:", path);
|
||||||
|
res.set({
|
||||||
|
"Cache-Control": "no-cache private",
|
||||||
|
"Content-Description": "File Transfer",
|
||||||
|
"Content-Type": file.mime_type,
|
||||||
|
"Content-Disposition": "inline; filename=" + fileName,
|
||||||
|
"Content-Transfer-Encoding": "binary",
|
||||||
|
});
|
||||||
|
res.status(StatusCodes.OK).sendFile(filePath);
|
||||||
|
} catch (err) {
|
||||||
|
// console.log("no access:", path);
|
||||||
|
res.status(StatusCodes.NOT_FOUND).send({
|
||||||
|
message: `File with id ${id} doesn't exist on file server`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// res.status(StatusCodes.OK).sendFile(filePath, (err) => {
|
||||||
|
// // res.setHeader("Content-Type", "application/json");
|
||||||
|
// // res.removeHeader("Content-Disposition");
|
||||||
|
// res.status(StatusCodes.NOT_FOUND).send({
|
||||||
|
// message: `File with id ${id} doesn't exist on file server`,
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
} else {
|
||||||
|
res.status(StatusCodes.NOT_FOUND).send({
|
||||||
|
message: `Cannot find File with id=${id}.`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { Controller, Get } from "@overnightjs/core";
|
import { Controller, Get, Post } from "@overnightjs/core";
|
||||||
import Sequelize from "sequelize";
|
import Sequelize from "sequelize";
|
||||||
import { NextFunction, Request, Response } from "express";
|
import { NextFunction, Request, Response } from "express";
|
||||||
import { StatusCodes } from "http-status-codes";
|
import { StatusCodes } from "http-status-codes";
|
||||||
|
@ -55,6 +55,7 @@ export class OaiController {
|
||||||
this.configuration = new Configuration();
|
this.configuration = new Configuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post("")
|
||||||
@Get("")
|
@Get("")
|
||||||
public async index(request: Request, response: Response, next: NextFunction) {
|
public async index(request: Request, response: Response, next: NextFunction) {
|
||||||
this.xml = create(
|
this.xml = create(
|
||||||
|
@ -87,7 +88,6 @@ export class OaiController {
|
||||||
try {
|
try {
|
||||||
await this.handleRequest(oaiRequest, request);
|
await this.handleRequest(oaiRequest, request);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// return next(error);
|
|
||||||
if (error instanceof OaiModelException) {
|
if (error instanceof OaiModelException) {
|
||||||
this.xsltParameter["oai_error_code"] = error.oaiCode;
|
this.xsltParameter["oai_error_code"] = error.oaiCode;
|
||||||
this.xsltParameter["oai_error_message"] = error.message;
|
this.xsltParameter["oai_error_message"] = error.message;
|
||||||
|
@ -151,7 +151,7 @@ export class OaiController {
|
||||||
// $this->loadStyleSheet('datasetxml2oai-pmh.xslt');
|
// $this->loadStyleSheet('datasetxml2oai-pmh.xslt');
|
||||||
|
|
||||||
// Set response time
|
// Set response time
|
||||||
const now: dayjs.Dayjs = dayjs();
|
const now: Dayjs = dayjs();
|
||||||
this.xsltParameter["responseDate"] = now.format("YYYY-MM-DDThh:mm:ss[Z]");
|
this.xsltParameter["responseDate"] = now.format("YYYY-MM-DDThh:mm:ss[Z]");
|
||||||
this.xsltParameter["unixTimestamp"] = now.unix();
|
this.xsltParameter["unixTimestamp"] = now.unix();
|
||||||
|
|
||||||
|
@ -182,12 +182,8 @@ export class OaiController {
|
||||||
this.handleIllegalVerb();
|
this.handleIllegalVerb();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// const err = new HttpException(404, 'Not Found')
|
|
||||||
// next(err);
|
|
||||||
|
|
||||||
// try {
|
// try {
|
||||||
// console.log("Async code example.")
|
// console.log("Async code example.")
|
||||||
// const err = new HttpException(404, 'Not Found');
|
|
||||||
const err = new PageNotFoundException("verb not found");
|
const err = new PageNotFoundException("verb not found");
|
||||||
throw err;
|
throw err;
|
||||||
// } catch (error) { // manually catching
|
// } catch (error) { // manually catching
|
||||||
|
@ -363,21 +359,8 @@ export class OaiController {
|
||||||
let totalIds = 0;
|
let totalIds = 0;
|
||||||
let start = maxRecords + 1;
|
let start = maxRecords + 1;
|
||||||
let reldocIds: (number | null)[] = [];
|
let reldocIds: (number | null)[] = [];
|
||||||
|
|
||||||
let metadataPrefix = null;
|
let metadataPrefix = null;
|
||||||
|
|
||||||
// const tokenWorker = new TokenWorker(86400);
|
|
||||||
// await tokenWorker.connect();
|
|
||||||
// $tokenWorker->setResumptionPath($tokenTempPath);
|
|
||||||
// const url = process.env.REDIS_URL || "redis://redis:6379";
|
|
||||||
// const redisClient = createClient({
|
|
||||||
// url
|
|
||||||
// });
|
|
||||||
// redisClient.on('error', (error) => {
|
|
||||||
// const err = new InternalServerErrorException("Error occured while connecting or accessing redis server'");
|
|
||||||
// throw err;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// resumptionToken is defined
|
// resumptionToken is defined
|
||||||
if ("resumptionToken" in oaiRequest) {
|
if ("resumptionToken" in oaiRequest) {
|
||||||
const resParam = oaiRequest["resumptionToken"]; //e.g. "158886496600000"
|
const resParam = oaiRequest["resumptionToken"]; //e.g. "158886496600000"
|
||||||
|
|
71
src/models/File.ts
Normal file
71
src/models/File.ts
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import { Model, DataTypes, InferAttributes, InferCreationAttributes, CreationOptional } from "sequelize";
|
||||||
|
import sequelizeConnection from "../config/db.config";
|
||||||
|
|
||||||
|
class File extends Model<InferAttributes<File>, InferCreationAttributes<File>> {
|
||||||
|
// id can be undefined during creation when using `autoIncrement`
|
||||||
|
declare id: CreationOptional<number>;
|
||||||
|
declare path_name: string; // not nullable fields
|
||||||
|
declare label: string | null;
|
||||||
|
declare comment: string | null;
|
||||||
|
declare mime_type: string;
|
||||||
|
declare language: string | null;
|
||||||
|
declare file_size: bigint;
|
||||||
|
declare visible_in_frontdoor: boolean;
|
||||||
|
declare visible_in_oai: boolean;
|
||||||
|
declare sort_order: number;
|
||||||
|
|
||||||
|
// createdAt can be undefined during creation
|
||||||
|
declare created_at: CreationOptional<Date>;
|
||||||
|
// updatedAt can be undefined during creation
|
||||||
|
declare updated_at: CreationOptional<Date>;
|
||||||
|
}
|
||||||
|
|
||||||
|
File.init(
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
path_name: {
|
||||||
|
type: DataTypes.STRING(100),
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
label: DataTypes.STRING(100),
|
||||||
|
comment: DataTypes.STRING(255),
|
||||||
|
mime_type: {
|
||||||
|
type: DataTypes.STRING(255),
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
language: DataTypes.STRING(3),
|
||||||
|
file_size: {
|
||||||
|
type: DataTypes.BIGINT,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
visible_in_frontdoor: {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: true,
|
||||||
|
},
|
||||||
|
visible_in_oai: {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: true,
|
||||||
|
},
|
||||||
|
sort_order: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
created_at: DataTypes.DATE,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
createdAt: "created_at",
|
||||||
|
updatedAt: "updated_at",
|
||||||
|
tableName: "document_files",
|
||||||
|
sequelize: sequelizeConnection,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export default File;
|
|
@ -11,13 +11,14 @@ import Person from "./Person";
|
||||||
import { Sequelize } from "sequelize";
|
import { Sequelize } from "sequelize";
|
||||||
import Subject from "./subject.model.js";
|
import Subject from "./subject.model.js";
|
||||||
import Project from "./Project";
|
import Project from "./Project";
|
||||||
import File from "./file.model.js";
|
// import File from "./file.model.js";
|
||||||
|
import File from "./File";
|
||||||
import Identifier from "./Identifier";
|
import Identifier from "./Identifier";
|
||||||
import DocumentXmlCache from "./DocumentXmlCache";
|
import DocumentXmlCache from "./DocumentXmlCache";
|
||||||
|
|
||||||
const dbContext = initModels();
|
const dbContext = initModels();
|
||||||
|
|
||||||
export { Dataset, Title, Abstract, User, Person, Subject, Coverage, License, Project, Identifier, DocumentXmlCache };
|
export { Dataset, Title, Abstract, User, Person, Subject, Coverage, License, Project, Identifier, DocumentXmlCache, File };
|
||||||
export default dbContext;
|
export default dbContext;
|
||||||
|
|
||||||
export function initModels() {
|
export function initModels() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user