Commit 373a5c3b authored by Quentin David's avatar Quentin David
Browse files

Adding client & server in the same repo

parent 094ce996
echo $1 "http://localhost:8081"$2
curl -X $1 "http://localhost:8081"$2
echo ""
# CheneTAL
## Install dependencies
`npm install`
## Start server
`npm start`
If you are developping this repository, you can use the following command so that it automatically reloads when you modify a file.
`npm run devstart`
\ No newline at end of file
openapi: 3.0.0
#swagger: "2.0"
info:
title: CheneTAL API
description: All the tools needed to process a corpus.
version: 0.1
servers:
- url: http://api.example.com/v1
description: Optional server description, e.g. Main (production) server
- url: http://staging-api.example.com
description: Optional server description, e.g. Internal staging server for testing
paths:
/users:
get:
tags: [users]
summary: Returns all users.
responses:
'200': # status code
description: A JSON array of all users
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
/users/{userId}:
get:
tags: [users]
summary: Find user by ID
description: Returns a single user
operationId: getUserById
produces: application/json
parameters:
- name: userId
in: path
description: ID of user to return
required: true
type: integer
responses:
200:
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/User'
400:
description: invalid ID supplied
404:
description: User not found
put:
tags: [users]
summary: Updates a user
consumes: application/json
produces: application/json
parameters:
- name:
/pipelines/{pipelineId}:
get:
tags: [corpora]
summary: Returns a pipeline
responses:
'200':
description: A JSON of the pipeline
content:
application/json:
schema:
$ref: '#/components/schemas/Pipeline'
components:
schemas:
User:
type: object
description: User is beautiful.
properties:
name:
type: string
description: Name of the user
mail:
type: string
description: Mail address of the user
password:
type: string
description: Password of the user
Process:
type: object
description: Instructions for a module to execute given a list of parameters
properties:
moduleName:
type: String
description: Name of the module that execute the process
moduleParameter:
type: array
description: A parameter for the module that execute the process
items:
type: object
properties:
name:
type: String
description: Name of the parameter
value:
type: String
description: Value of the parameter
Pipeline:
type: object
description: A list of process to execute on a corpus
properties:
corpusId:
type: String
description: Id of the corpus attached to that process
currentProcessingModule:
type: String
description: Name of the module that is being executed currently by the pipeline. Is null if the pipeline has not started, failed, or finished.
status:
type: String
enum:
- Not started yet
- Started
- Finished
- Failed
description: Status of the pipeline
processes:
type: array
items:
$ref: '#/components/schemas/Process'
\ No newline at end of file
// ***
// Corpus Controller file
// ***
const CorpusModel = require('../models/Corpus.js');
const responseHelper = require('./lib/responseHelper');
const errorHandler = responseHelper.errorHandler;
const successHandler = responseHelper.successHandler;
const failHandler = responseHelper.failHandler; // For eg. "User not found" is a fail, not an error
// DEBUG: find all corpora
exports.debug_corpus_list = function(req, res) {
CorpusModel.find({},(error, corpora) => {
if (error) { errorHandler(res, error); }
else {
successHandler(res, { corpora: corpora } );
}
})
}
// Add a new corpus
exports.corpus_create = function(req,res) {
const newCorpus = CorpusModel({
corpus_name: req.body.corpus_name,
content: req.body.content,
created_by: req.body.created_by
});
newCorpus.save((error, corpus) => {
if (error) { errorHandler(res, error); }
else {
successHandler(res, { corpus: corpus}, 201);
}
})
}
// Get an existing corpus
exports.corpus_get = function(req,res) {
const corpusId = req.params.corpusId;
CorpusModel.findById(corpusId, (error, corpus) => {
if (error) { errorHandler(res, error); }
if (!corpus) {
failHandler(res, { corpus: `No corpus was found with id: ${corpusId}`}, 404);
}
else {
successHandler(res, { corpus: corpus});
}
})
}
// Modify an existing corpus
exports.corpus_modify = function(req,res) {
const corpusId = req.params.corpusId;
CorpusModel.findByIdAndUpdate(corpusId, req.body, (error, corpus) => {
if (error) { errorHandler(res, error); }
if (!corpus) {
failHandler(res, { corpus: `No corpus was found with id: ${corpusId}`}, 404);
}
else {
successHandler(res, { corpus: corpus});
}
})
}
// Delete an existing corpus
exports.corpus_delete = function(req,res) {
const corpusId = req.params.corpusId;
CorpusModel.findByIdAndDelete(corpusId, (error, corpus) => {
if (error) { errorHandler(res, error); }
if (!corpus) {
failHandler(res, { corpus: `No corpus was found with id: ${corpusId}`}, 404);
}
else {
successHandler(res, { corpus: null})
}
});
}
// Get a summary of an existing corpus
exports.corpus_summary = function(req,res) {
const corpusId = req.params.corpusId;
CorpusModel.findById(corpusId, (error, corpus) => {
if (error) { errorHandler(res, error); }
if (!corpus) {
failHandler(res, { corpus: `No corpus was found with id: ${corpusId}`}, 404)
}
else {
successHandler(res, { corpus_summary: 'TBD' });
}
})
}
// Get a specific document in a corpus
exports.corpus_document_get = function(req, res) {
const corpusId = req.params.corpusId;
CorpusModel.findById(corpusId, (error, corpus) => {
if (error) { errorHandler(res, error); }
if (!corpus) {
failHandler(res, { corpus: `No corpus was found with id: ${corpusId}`}, 404);
}
else {
const documentNumber = req.params.documentNumber;
const document = corpus.documents[documentNumber];
if (!document) {
failHandler(res, { corpus: { document: `No document found at this index: ${documentNumber}`}}, 404);
}
else {
successHandler(res, { corpus: { document: document}});
}
}
})
}
// Change a document in a corpus
exports.corpus_document_modify = function(req, res) {
const corpusId = req.params.corpusId;
CorpusModel.findById(corpusId, (error, corpus) => {
if (error) { errorHandler(res, error); }
if (!corpus) {
failHandler(res, { corpus: `No corpus was found with id: ${corpusId}`}, 404);
}
else {
const documentNumber = req.params.documentNumber;
const document = corpus.documents[documentNumber];
if (!document) {
failHandler(res, { corpus: { document: `No document found at this index: ${documentNumber}`}}, 404);
}
else {
// Document is updated here
//const newDocument = { content: 'New content'};
// corpus.save((error, _) ....)
successHandler(res, { corpus: { document: document}});
}
}
})
}
// Get a specific report from a document in a corpus
exports.corpus_document_report_get = function(req, res) {
const corpusId = req.params.corpusId;
CorpusModel.findById(corpusId, (error, corpus) => {
if (error) { errorHandler(res, error); }
if (!corpus) {
failHandler(res, { corpus: `No corpus was found with id: ${corpusId}`}, 404);
}
else {
const documentNumber = req.params.documentNumber;
const document = corpus.documents[documentNumber];
if (!document) {
failHandler(res, { corpus: { document: `No document found at this index: ${documentNumber}`}}, 404);
}
else {
// Get the report here
// const report = document.report[...];
successHandler(res, { corpus: { document: document}});
}
}
})
}
\ No newline at end of file
exports.moduleList = [
{
moduleName: "Néoveille",
moduleParameters: [
{
parameterName: "...",
parameterValue: '...'
}
]
}
]
exports.startModuleProcess = function(processToStart, cb) {
// Should make a call for the module with its parameters.
return cb(null);
}
\ No newline at end of file
const moduleHelper = require('./moduleHelper');
// A process is a module plus its corresponding parameters
// Advance the pipeline to the next process and update it
exports.advanceToNextProcess = function(pipeline, cb) {
var nextProcess;
var error;
// The process has not started yet.
if (!pipeline.currentProcessingModule && pipeline.status == 'To be started') {
nextProcess = pipeline.process[0];
}
// Already started, find index of that process and take the next one
else {
currentProcessIndex = pipeline.process.findIndex( function(element) {
return element.moduleName == pipeline.currentProcessingModule;
});
// The pipeline has finished, no more processing left.
if (pipeline.process.length == currentProcessIndex+1) {
pipeline.currentProcessingModule = null;
pipeline.status = 'Finished';
return cb(null, pipeline);
}
else if (currentProcessIndex > -1) {
nextProcess = pipeline.process[currentProcessIndex+1];
}
else {
error = new Error(`Could not find the module named ${pipeline.currentProcessingModule} in the pipeline`);
return cb(error, null);
}
}
// We got nextProcess that contains the name of the module
// And its parameters. We can now call the next module.
moduleHelper.startModuleProcess(nextProcess, (error) => {
if (error) { return cb(error, null); }
// Success: updates pipeline and send it back.
else {
pipeline.currentProcessingModule = nextProcess.moduleName;
pipeline.status = 'In progress';
return cb(null, pipeline);
}
})
}
\ No newline at end of file
exports.errorHandler = function(res, error) {
// I'm not sure howExpress deals with http code and error, does it always send200 OK ?
res.json({
status: "error",
message: error
});
console.error(error);
}
exports.successHandler = function(res, data, httpCode = 200) {
res.status(httpCode);
res.json({
status: "success",
data: data
});
}
// For eg. "User not found" is a fail, not an error
exports.failHandler = function(res, data, httpCode) {
res.status(httpCode);
res.json({
status: "fail",
data: data
});
}
\ No newline at end of file
// ***
// Module Controller file
// ***
const moduleHelper = require('./lib/moduleHelper');
const responseHelper = require('./lib/responseHelper');
const errorHandler = responseHelper.errorHandler;
const successHandler = responseHelper.successHandler;
const failHandler = responseHelper.failHandler; // For eg. "User not found" is a fail, not an error
// Get all available modules and their specification
exports.module_list = function(req,res) {
// Js / Json file or in a collection ?....
successHandler(res, { moduleList: moduleHelper.moduleList });
}
// Create a new treatment for a module given some parameters
exports.module_treatment_create = function(req,res) {
res.send(`NOT IMPLEMENTED! POST - Create a new treatment for ${req.params.moduleName} with params ${req.params}`)
}
// Get the status of a module given a pipeline Id
exports.module_treatment_summary = function(req,res) {
res.send(`NOT IMPLEMENTED! GET - Get the status of the treatment for ${req.params.moduleName} for pipeline Id: ${req.params.pipelineId}`)
}
\ No newline at end of file
// ***
// Pipeline Controller file
// ***
const PipelineModel = require('../models/Pipeline.js');
const responseHelper = require('./lib/responseHelper');
const errorHandler = responseHelper.errorHandler;
const successHandler = responseHelper.successHandler;
const failHandler = responseHelper.failHandler; // For eg. "User not found" is a fail, not an error
const pipelineHelper = require('./lib/pipelineHelper');
// Add a new pipeline and start it
exports.pipeline_create = function(req,res) {
const newPipeline = PipelineModel({
currentProcess: null,
status: 'To be started',
corpusId: req.body.corpusId,
process: req.body.pipelineProcess
});
pipelineHelper.startPipeline( newPipeline, (error, startedPipeline) => {
if (error) { errorHandler(res, error) }
else {
// Successfully started the pipeline
// Now save it.
startedPipeline.save((error, pipeline) => {
if (error) { errorHandler(res, error); }
else {
successHandler(res, { pipeline: pipeline }, 201);
}
})
}
})
}
// Get info on an existing pipeline
exports.pipeline_get = function(req, res) {
const pipelineId = req.params.pipelineId;
PipelineModel.findById(pipelineId, (error, pipeline) => {
if (error) { errorHandler(res, error); }
else if (!pipeline) {
failHandler(res, { pipeline: `No pipeline was found with id: ${pipelineId}`}, 404);
}
else {
successHandler(res, { pipeline: pipeline });
}
})
}
// Delete an existing pipeline
exports.pipeline_delete = function(req, res) {
const pipelineId = req.params.pipelineId;
PipelineModel.findByIdAndDelete(pipelineId, (error, pipeline) => {
if (error) { errorHandler(res, error); }
else if (!pipeline) {
failHandler(res, { pipeline: `No pipeline was found with id: ${pipelineId}`}, 404);
}
else {
successHandler(res, { pipeline: null });
}
})
}
// Get the status of an existing pipeline
exports.pipeline_status = function(req,res) {
const pipelineId = req.params.pipelineId;
PipelineModel.findById(pipelineId, (error, pipeline) => {
if (error) { errorHandler(res, error); }
else if (!pipeline) {
failHandler(res, { pipeline: `No pipeline was found with id: ${pipelineId}`}, 404);
}
else {
successHandler(res, { pipeline: { status: pipeline.status } });
}
})
}
\ No newline at end of file
// ***
// User Controller file
// ***
const UserModel = require('../models/User.js');
const responseHelper = require('./lib/responseHelper');
const errorHandler = responseHelper.errorHandler;
const successHandler = responseHelper.successHandler;
const failHandler = responseHelper.failHandler; // For eg. "User not found" is a fail, not an error
/* User personal information management functions */
// DEBUG: User list
exports.debug_user_list = function(req, res) {
UserModel.find({}, (error, users) => {
if (error) { errorHandler(res, error); }
else {
successHandler(res, { users: users } );
}
})
}
// Create a new user
exports.user_create = function(req,res) {
const newUser = UserModel({
name: req.body.name,
mail: req.body.mail
});
newUser.save((error, user) => {
if (error) { errorHandler(res, error); }
else {
successHandler(res, { user: user}, 201);
}
})
}
// Fetch user informations about an existing user
exports.user_get = function(req,res) {
const userId = req.params.userId;
UserModel.findById(userId, (error, user) => {
if (error) { errorHandler(res, error); }
else if (!user) {
failHandler(res, { user: `No user was found with id: ${userId}`}, 404);
}
else {
successHandler(res, { user: user});
}
})
}
// Change informations on an existing user
exports.user_modify = function(req,res) {
const userId = req.params.userId;
// {new: true} lets you have the updated document as user.
UserModel.findByIdAndUpdate(userId, req.body, {new: true}, (error, user) => {
if (error) { errorHandler(res, error); }
else if (!user) {
failHandler(res, { user: `No user was found with id: ${userId}`}, 404);
}
else {
successHandler(res, { user: user});
}
})
}
// Delete an existing user
exports.user_delete = function(req,res) {
const userId = req.params.userId;
UserModel.findByIdAndDelete(userId, (error, user) => {
if (error) { errorHandler(res, error); }
else if (!user) {
failHandler(res, { user: `No user was found with id: ${userId}`}, 404);
}
else {
successHandler(res, { user: null});
}
})
}
/* User profile corpora management functions */
// Fetch all the corpora from an existing user
exports.user_corpus_list = function(req,res) {
// TODO: Fetch the corpora from the corpus DB
const userId = req.params.userId;
UserModel.findById(userId, (error, user) => {
if (error) { errorHandler(res, error); }
else if (!user) {
failHandler(res, { user: `No user was found with id: ${userId}`}, 404);
}
else {
// Should fetch /corpus to get the summary ?
successHandler(res, { profileCorpora: user.profileCorpora});
}
})
}
// Add a new corpus to an existing user
exports.user_corpus_create = function(req,res) {
const userId = req.params.userId;
UserModel.findById(userId, (error, user) => {
if (error) { errorHandler(res, error); }
else if (!user) {
failHandler(res, { user: `No user was found with id: ${userId}`}, 404);
}
else {
const corpusId = req.body.corpusId;
const newCorpus = { corpusId: corpusId};