mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-02-14 19:32:45 +00:00
feat: Add conference manager (#71)
This commit is contained in:
113
src/Conference.ts
Normal file
113
src/Conference.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import AnonymizedRepositoryModel from "./database/anonymizedRepositories/anonymizedRepositories.model";
|
||||
import { IConferenceDocument } from "./database/conference/conferences.types";
|
||||
import Repository from "./Repository";
|
||||
import { ConferenceStatus } from "./types";
|
||||
|
||||
export default class Conference {
|
||||
private _data: IConferenceDocument;
|
||||
private _repositories: Repository[] = null;
|
||||
|
||||
constructor(data: IConferenceDocument) {
|
||||
this._data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the status of the conference
|
||||
* @param status the new status
|
||||
* @param errorMessage a potential error message to display
|
||||
*/
|
||||
async updateStatus(status: ConferenceStatus, errorMessage?: string) {
|
||||
this._data.status = status;
|
||||
return this._data.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the conference is expired
|
||||
*/
|
||||
isExpired() {
|
||||
return this._data.endDate < new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expire the conference
|
||||
*/
|
||||
async expire() {
|
||||
await this.updateStatus("expired");
|
||||
await Promise.all(
|
||||
(await this.repositories()).map(async (conf) => await conf.expire())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the conference
|
||||
*/
|
||||
async remove() {
|
||||
await this.updateStatus("removed");
|
||||
await Promise.all(
|
||||
(await this.repositories()).map(async (conf) => await conf.remove())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of repositories of this conference
|
||||
*
|
||||
* @returns the list of repositories of this conference
|
||||
*/
|
||||
async repositories(): Promise<Repository[]> {
|
||||
if (this._repositories) return this._repositories;
|
||||
const repoIds = this._data.repositories
|
||||
.filter((r) => !r.removeDate)
|
||||
.map((r) => r.id)
|
||||
.filter((f) => f);
|
||||
this._repositories = (
|
||||
await AnonymizedRepositoryModel.find({
|
||||
_id: { $in: repoIds },
|
||||
})
|
||||
).map((r) => new Repository(r));
|
||||
return this._repositories;
|
||||
}
|
||||
|
||||
get ownerIDs() {
|
||||
return this._data?.owners;
|
||||
}
|
||||
|
||||
get quota() {
|
||||
return this._data.plan.quota;
|
||||
}
|
||||
|
||||
get status() {
|
||||
return this._data.status;
|
||||
}
|
||||
|
||||
toJSON(opt?: { billing: boolean }): any {
|
||||
const pricePerHourPerRepo = this._data.plan.pricePerRepository / 30;
|
||||
let price = 0;
|
||||
const today =
|
||||
new Date() > this._data.endDate ? this._data.endDate : new Date();
|
||||
this._data.repositories.forEach((r) => {
|
||||
const removeDate =
|
||||
r.removeDate && r.removeDate < today ? r.removeDate : today;
|
||||
price +=
|
||||
(Math.max(removeDate.getTime() - r.addDate.getTime(), 0) /
|
||||
1000 /
|
||||
60 /
|
||||
60 /
|
||||
24) *
|
||||
pricePerHourPerRepo;
|
||||
});
|
||||
return {
|
||||
conferenceID: this._data.conferenceID,
|
||||
name: this._data.name,
|
||||
url: this._data.url,
|
||||
startDate: this._data.startDate,
|
||||
endDate: this._data.endDate,
|
||||
status: this._data.status,
|
||||
billing: this._data.billing,
|
||||
options: this._data.options,
|
||||
plan: this._data.plan,
|
||||
price,
|
||||
nbRepositories: this._data.repositories.filter((r) => !r.removeDate)
|
||||
.length,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ import UserModel from "./database/users/users.model";
|
||||
import { IAnonymizedRepositoryDocument } from "./database/anonymizedRepositories/anonymizedRepositories.types";
|
||||
import { anonymizeStream } from "./anonymize-utils";
|
||||
import GitHubBase from "./source/GitHubBase";
|
||||
import Conference from "./Conference";
|
||||
import ConferenceModel from "./database/conference/conferences.model";
|
||||
|
||||
export default class Repository {
|
||||
private _model: IAnonymizedRepositoryDocument;
|
||||
@@ -247,6 +249,21 @@ export default class Repository {
|
||||
return this._model.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the conference of the repository
|
||||
*
|
||||
* @returns conference of the repository
|
||||
*/
|
||||
async conference(): Promise<Conference | null> {
|
||||
if (!this._model.conference) {
|
||||
return null;
|
||||
}
|
||||
const conference = await ConferenceModel.findOne({
|
||||
conferenceID: this._model.conference,
|
||||
});
|
||||
return new Conference(conference);
|
||||
}
|
||||
|
||||
/***** Getters ********/
|
||||
|
||||
get repoId() {
|
||||
|
||||
12
src/database/conference/conferences.model.ts
Normal file
12
src/database/conference/conferences.model.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import * as mongoose from "mongoose";
|
||||
const { model } = mongoose;
|
||||
|
||||
import { IConferenceDocument, IConferenceModel } from "./conferences.types";
|
||||
import ConferenceSchema from "./conferences.schema";
|
||||
|
||||
const ConferenceModel = model<IConferenceDocument>(
|
||||
"Conference",
|
||||
ConferenceSchema
|
||||
) as IConferenceModel;
|
||||
|
||||
export default ConferenceModel;
|
||||
59
src/database/conference/conferences.schema.ts
Normal file
59
src/database/conference/conferences.schema.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import * as mongoose from "mongoose";
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const RepositorySchema = new Schema({
|
||||
name: String,
|
||||
conferenceID: {
|
||||
type: String,
|
||||
index: { unique: true },
|
||||
},
|
||||
url: String,
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
status: String,
|
||||
owners: { type: [mongoose.Schema.Types.ObjectId] },
|
||||
repositories: {
|
||||
type: [
|
||||
{
|
||||
id: { type: mongoose.Schema.Types.ObjectId },
|
||||
addDate: { type: Date },
|
||||
removeDate: { type: Date },
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
expirationMode: String,
|
||||
expirationDate: Date,
|
||||
update: Boolean,
|
||||
image: Boolean,
|
||||
pdf: Boolean,
|
||||
notebook: Boolean,
|
||||
link: Boolean,
|
||||
page: Boolean,
|
||||
},
|
||||
dateOfEntry: {
|
||||
type: Date,
|
||||
default: new Date(),
|
||||
},
|
||||
plan: {
|
||||
planID: String,
|
||||
pricePerRepository: Number,
|
||||
quota: {
|
||||
repository: Number,
|
||||
size: Number,
|
||||
file: Number,
|
||||
},
|
||||
},
|
||||
billing: {
|
||||
name: String,
|
||||
email: String,
|
||||
address: String,
|
||||
address2: String,
|
||||
city: String,
|
||||
zip: String,
|
||||
country: String,
|
||||
vat: String,
|
||||
},
|
||||
});
|
||||
|
||||
export default RepositorySchema;
|
||||
49
src/database/conference/conferences.types.ts
Normal file
49
src/database/conference/conferences.types.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import * as mongoose from "mongoose";
|
||||
import { ConferenceStatus } from "../../types";
|
||||
|
||||
export interface IConference {
|
||||
name: string;
|
||||
conferenceID: string;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
url: string;
|
||||
status: ConferenceStatus;
|
||||
owners: string[];
|
||||
repositories: {
|
||||
id: string;
|
||||
addDate: Date;
|
||||
removeDate?: Date;
|
||||
}[];
|
||||
options: {
|
||||
expirationMode: "never" | "redirect" | "remove";
|
||||
expirationDate?: Date;
|
||||
update: boolean;
|
||||
image: boolean;
|
||||
pdf: boolean;
|
||||
notebook: boolean;
|
||||
link: boolean;
|
||||
page: boolean;
|
||||
};
|
||||
plan: {
|
||||
planID: string;
|
||||
pricePerRepository: number;
|
||||
quota: {
|
||||
repository: number;
|
||||
size: number;
|
||||
file: number;
|
||||
};
|
||||
};
|
||||
billing?: {
|
||||
name: string;
|
||||
email: string;
|
||||
address: string;
|
||||
address2?: string;
|
||||
city: string;
|
||||
zip: string;
|
||||
country: string;
|
||||
vat?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IConferenceDocument extends IConference, mongoose.Document {}
|
||||
export interface IConferenceModel extends mongoose.Model<IConferenceDocument> {}
|
||||
199
src/routes/conference.ts
Normal file
199
src/routes/conference.ts
Normal file
@@ -0,0 +1,199 @@
|
||||
import * as express from "express";
|
||||
import config from "../../config";
|
||||
import Conference from "../Conference";
|
||||
import AnonymizedRepositoryModel from "../database/anonymizedRepositories/anonymizedRepositories.model";
|
||||
import ConferenceModel from "../database/conference/conferences.model";
|
||||
import Repository from "../Repository";
|
||||
import { ensureAuthenticated } from "./connection";
|
||||
import { handleError, getUser } from "./route-utils";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// user needs to be connected for all user API
|
||||
router.use(ensureAuthenticated);
|
||||
|
||||
const plans = [
|
||||
{
|
||||
id: "free_conference",
|
||||
name: "Free",
|
||||
pricePerRepo: 0,
|
||||
storagePerRepo: -1,
|
||||
description: `<li><strong>Quota is deducted from user account</strong></li>
|
||||
<li>No-download</li>
|
||||
<li>Conference dashboard</li>`,
|
||||
},
|
||||
{
|
||||
id: "premium_conference",
|
||||
name: "Premium",
|
||||
pricePerRepo: 0.5,
|
||||
storagePerRepo: 500 * 8 * 1024,
|
||||
description: `<li>500Mo / repository</li>
|
||||
<li>Repository download</li>
|
||||
<li>Conference dashboard</li>`,
|
||||
},
|
||||
{
|
||||
id: "unlimited_conference",
|
||||
name: "Unlimited",
|
||||
pricePerRepo: 3,
|
||||
storagePerRepo: 0,
|
||||
description: `<li><strong>Unlimited</strong> repository size</li>
|
||||
<li>Repository download</li>
|
||||
<li>Conference dashboard</li>`,
|
||||
},
|
||||
];
|
||||
|
||||
router.get("/plans", async (req: express.Request, res: express.Response) => {
|
||||
res.json(plans);
|
||||
});
|
||||
|
||||
router.get("/", async (req: express.Request, res: express.Response) => {
|
||||
try {
|
||||
const user = await getUser(req);
|
||||
const conferences = await Promise.all(
|
||||
(
|
||||
await ConferenceModel.find({
|
||||
owners: { $in: user.model.id },
|
||||
})
|
||||
).map(async (data) => {
|
||||
const conf = new Conference(data);
|
||||
if (data.endDate < new Date() && data.status == "ready") {
|
||||
await conf.updateStatus("expired");
|
||||
}
|
||||
return conf;
|
||||
})
|
||||
);
|
||||
res.json(conferences.map((conf) => conf.toJSON()));
|
||||
} catch (error) {
|
||||
handleError(error, res);
|
||||
}
|
||||
});
|
||||
|
||||
function validateConferenceForm(conf) {
|
||||
if (!conf.name) throw new Error("conf_name_missing");
|
||||
if (!conf.conferenceID) throw new Error("conf_id_missing");
|
||||
if (!conf.startDate) throw new Error("conf_start_date_missing");
|
||||
if (!conf.endDate) throw new Error("conf_end_date_missing");
|
||||
if (new Date(conf.startDate) > new Date(conf.endDate))
|
||||
throw new Error("conf_start_date_invalid");
|
||||
if (new Date() > new Date(conf.endDate))
|
||||
throw new Error("conf_end_date_invalid");
|
||||
if (plans.filter((p) => p.id == conf.plan.planID).length != 1)
|
||||
throw new Error("invalid_plan");
|
||||
const plan = plans.filter((p) => p.id == conf.plan.planID)[0];
|
||||
if (plan.pricePerRepo > 0) {
|
||||
const billing = conf.billing;
|
||||
if (!billing) throw new Error("billing_missing");
|
||||
if (!billing.name) throw new Error("billing_name_missing");
|
||||
if (!billing.email) throw new Error("billing_email_missing");
|
||||
if (!billing.address) throw new Error("billing_address_missing");
|
||||
if (!billing.city) throw new Error("billing_city_missing");
|
||||
if (!billing.zip) throw new Error("billing_zip_missing");
|
||||
if (!billing.country) throw new Error("billing_country_missing");
|
||||
}
|
||||
}
|
||||
|
||||
router.post(
|
||||
"/:conferenceID?",
|
||||
async (req: express.Request, res: express.Response) => {
|
||||
try {
|
||||
const user = await getUser(req);
|
||||
let model = new ConferenceModel();
|
||||
if (req.params.conferenceID) {
|
||||
model = await ConferenceModel.findOne({
|
||||
conferenceID: req.params.conferenceID,
|
||||
});
|
||||
if (model.owners.indexOf(user.model.id) == -1)
|
||||
throw new Error("not_authorized");
|
||||
}
|
||||
validateConferenceForm(req.body);
|
||||
model.name = req.body.name;
|
||||
model.startDate = new Date(req.body.startDate);
|
||||
model.endDate = new Date(req.body.endDate);
|
||||
model.status = "ready";
|
||||
model.url = req.body.url;
|
||||
model.repositories = [];
|
||||
model.options = req.body.options;
|
||||
|
||||
if (!req.params.conferenceID) {
|
||||
model.owners.push(user.model.id);
|
||||
model.conferenceID = req.body.conferenceID;
|
||||
|
||||
model.plan = {
|
||||
planID: req.body.plan.planID,
|
||||
pricePerRepository: plans.filter(
|
||||
(p) => p.id == req.body.plan.planID
|
||||
)[0].pricePerRepo,
|
||||
quota: {
|
||||
size: plans.filter((p) => p.id == req.body.plan.planID)[0]
|
||||
.storagePerRepo,
|
||||
file: 0,
|
||||
repository: 0,
|
||||
},
|
||||
};
|
||||
|
||||
if (req.body.billing)
|
||||
model.billing = {
|
||||
name: req.body.billing.name,
|
||||
email: req.body.billing.email,
|
||||
address: req.body.billing.address,
|
||||
address2: req.body.billing.address2,
|
||||
city: req.body.billing.city,
|
||||
zip: req.body.billing.zip,
|
||||
country: req.body.billing.country,
|
||||
vat: req.body.billing.vat,
|
||||
};
|
||||
}
|
||||
await model.save();
|
||||
|
||||
res.send("ok");
|
||||
} catch (error) {
|
||||
if (error.message?.indexOf(" duplicate key") > -1) {
|
||||
return handleError(new Error("conf_id_used"), res);
|
||||
}
|
||||
handleError(error, res);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/:conferenceID",
|
||||
async (req: express.Request, res: express.Response) => {
|
||||
try {
|
||||
const user = await getUser(req);
|
||||
const data = await ConferenceModel.findOne({
|
||||
conferenceID: req.params.conferenceID,
|
||||
});
|
||||
if (!data) throw new Error("conf_not_found");
|
||||
const conference = new Conference(data);
|
||||
if (conference.ownerIDs.indexOf(user.model.id) == -1)
|
||||
throw new Error("not_authorized");
|
||||
const o: any = conference.toJSON();
|
||||
o.repositories = (await conference.repositories()).map((r) => r.toJSON());
|
||||
res.json(o);
|
||||
} catch (error) {
|
||||
handleError(error, res);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/:conferenceID",
|
||||
async (req: express.Request, res: express.Response) => {
|
||||
try {
|
||||
const user = await getUser(req);
|
||||
const data = await ConferenceModel.findOne({
|
||||
conferenceID: req.params.conferenceID,
|
||||
});
|
||||
if (!data) throw new Error("conf_not_found");
|
||||
const conference = new Conference(data);
|
||||
if (conference.ownerIDs.indexOf(user.model.id) == -1)
|
||||
throw new Error("not_authorized");
|
||||
await conference.remove();
|
||||
res.send("ok");
|
||||
} catch (error) {
|
||||
handleError(error, res);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default router;
|
||||
@@ -1,5 +1,6 @@
|
||||
import repositoryPrivate from "./repository-private";
|
||||
import repositoryPublic from "./repository-public";
|
||||
import conference from "./conference";
|
||||
import file from "./file";
|
||||
import webview from "./webview";
|
||||
import user from "./user";
|
||||
@@ -12,4 +13,5 @@ export default {
|
||||
webview,
|
||||
user,
|
||||
option,
|
||||
conference
|
||||
};
|
||||
|
||||
@@ -10,6 +10,7 @@ import AnonymizedRepositoryModel from "../database/anonymizedRepositories/anonym
|
||||
import config from "../../config";
|
||||
import { IAnonymizedRepositoryDocument } from "../database/anonymizedRepositories/anonymizedRepositories.types";
|
||||
import Repository from "../Repository";
|
||||
import ConferenceModel from "../database/conference/conferences.model";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
@@ -61,7 +62,7 @@ router.post(
|
||||
async (req: express.Request, res: express.Response) => {
|
||||
try {
|
||||
const repo = await getRepo(req, res, { nocheck: true });
|
||||
if (!repo) throw new Error("repo_not_found");
|
||||
if (!repo) return;
|
||||
|
||||
const user = await getUser(req);
|
||||
if (repo.owner.username != user.username) {
|
||||
@@ -163,7 +164,7 @@ router.get(
|
||||
router.get("/:repoId/", async (req: express.Request, res: express.Response) => {
|
||||
try {
|
||||
const repo = await getRepo(req, res, { nocheck: true });
|
||||
if (!repo) throw new Error("repo_not_found");
|
||||
if (!repo) return;
|
||||
|
||||
const user = await getUser(req);
|
||||
if (user.username != repo.model.owner) {
|
||||
@@ -215,7 +216,6 @@ function updateRepoModel(
|
||||
}
|
||||
model.source.commit = repoUpdate.source.commit;
|
||||
model.source.branch = repoUpdate.source.branch;
|
||||
model.conference = repoUpdate.conference;
|
||||
model.options = {
|
||||
terms: repoUpdate.terms,
|
||||
expirationMode: repoUpdate.options.expirationMode,
|
||||
@@ -238,7 +238,7 @@ router.post(
|
||||
async (req: express.Request, res: express.Response) => {
|
||||
try {
|
||||
const repo = await getRepo(req, res, { nocheck: true });
|
||||
if (!repo) throw new Error("repo_not_found");
|
||||
if (!repo) return;
|
||||
const user = await getUser(req);
|
||||
|
||||
if (repo.owner.username != user.username) {
|
||||
@@ -257,6 +257,48 @@ router.post(
|
||||
|
||||
updateRepoModel(repo.model, repoUpdate);
|
||||
|
||||
async function removeRepoFromConference(conferenceID) {
|
||||
const conf = await ConferenceModel.findOne({
|
||||
conferenceID,
|
||||
});
|
||||
if (conf) {
|
||||
const r = conf.repositories.filter((r) => r.id == repo.model.id);
|
||||
if (r.length == 1) r[0].removeDate = new Date();
|
||||
await conf.save();
|
||||
}
|
||||
}
|
||||
if (!repoUpdate.conference) {
|
||||
// remove conference
|
||||
if (repo.model.conference) {
|
||||
await removeRepoFromConference(repo.model.conference);
|
||||
}
|
||||
} else if (repoUpdate.conference != repo.model.conference) {
|
||||
// update/add conference
|
||||
const conf = await ConferenceModel.findOne({
|
||||
conferenceID: repoUpdate.conference,
|
||||
});
|
||||
if (conf) {
|
||||
if (new Date() < conf.startDate || new Date() > conf.endDate || conf.status !== "ready") {
|
||||
throw new Error("conf_not_activated");
|
||||
}
|
||||
const f = conf.repositories.filter((r) => r.id == repo.model.id);
|
||||
if (f.length) {
|
||||
// the repository already referenced the conference
|
||||
f[0].addDate = new Date();
|
||||
f[0].removeDate = null;
|
||||
} else {
|
||||
conf.repositories.push({
|
||||
id: repo.model.id,
|
||||
addDate: new Date(),
|
||||
});
|
||||
}
|
||||
if (repo.model.conference) {
|
||||
await removeRepoFromConference(repo.model.conference);
|
||||
}
|
||||
await conf.save();
|
||||
}
|
||||
}
|
||||
repo.model.conference = repoUpdate.conference;
|
||||
await repo.updateStatus("preparing");
|
||||
res.send("ok");
|
||||
new Repository(repo.model).anonymize();
|
||||
@@ -285,7 +327,7 @@ router.post("/", async (req: express.Request, res: express.Response) => {
|
||||
repo.repoId = repoUpdate.repoId;
|
||||
repo.anonymizeDate = new Date();
|
||||
repo.owner = user.username;
|
||||
|
||||
|
||||
updateRepoModel(repo, repoUpdate);
|
||||
repo.source.accessToken = user.accessToken;
|
||||
repo.source.repositoryId = repository.model.id;
|
||||
@@ -297,8 +339,27 @@ router.post("/", async (req: express.Request, res: express.Response) => {
|
||||
return res.status(500).send({ error: "invalid_mode" });
|
||||
}
|
||||
}
|
||||
repo.conference = repoUpdate.conference;
|
||||
|
||||
await repo.save();
|
||||
|
||||
if (repoUpdate.conference) {
|
||||
const conf = await ConferenceModel.findOne({
|
||||
conferenceID: repoUpdate.conference,
|
||||
});
|
||||
if (conf) {
|
||||
if (new Date() < conf.startDate || new Date() > conf.endDate || conf.status !== "ready") {
|
||||
await repo.remove()
|
||||
throw new Error("conf_not_activated");
|
||||
}
|
||||
conf.repositories.push({
|
||||
id: repo.id,
|
||||
addDate: new Date(),
|
||||
});
|
||||
await conf.save();
|
||||
}
|
||||
}
|
||||
|
||||
res.send("ok");
|
||||
new Repository(repo).anonymize();
|
||||
} catch (error) {
|
||||
|
||||
@@ -48,7 +48,7 @@ router.get(
|
||||
async (req: express.Request, res: express.Response) => {
|
||||
try {
|
||||
const repo = await getRepo(req, res, { nocheck: true });
|
||||
if (!repo) throw new Error("repo_not_found");
|
||||
if (!repo) return;
|
||||
let redirectURL = null;
|
||||
if (
|
||||
repo.status == "expired" &&
|
||||
@@ -62,10 +62,19 @@ router.get(
|
||||
|
||||
await repo.updateIfNeeded();
|
||||
|
||||
let download = false;
|
||||
const conference = await repo.conference();
|
||||
if (conference) {
|
||||
console.log(conference.quota)
|
||||
download =
|
||||
conference.quota.size > -1 &&
|
||||
!!config.ENABLE_DOWNLOAD &&
|
||||
repo.source.type == "GitHubDownload";
|
||||
}
|
||||
|
||||
res.json({
|
||||
url: redirectURL,
|
||||
download:
|
||||
!!config.ENABLE_DOWNLOAD && repo.source.type == "GitHubDownload",
|
||||
download,
|
||||
});
|
||||
} catch (error) {
|
||||
handleError(error, res);
|
||||
|
||||
17
src/schedule.ts
Normal file
17
src/schedule.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import * as schedule from "node-schedule";
|
||||
import Conference from "./Conference";
|
||||
import ConferenceModel from "./database/conference/conferences.model";
|
||||
|
||||
export function conferenceStatusCheck() {
|
||||
// check every 6 hours the status of the conference
|
||||
const job = schedule.scheduleJob("0 */6 * * *", async () => {
|
||||
(await ConferenceModel.find({ status: { $eq: "ready" } })).forEach(
|
||||
async (data) => {
|
||||
const conference = new Conference(data);
|
||||
if (conference.isExpired() && conference.status == "ready") {
|
||||
await conference.expire();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import * as passport from "passport";
|
||||
import * as connection from "./routes/connection";
|
||||
import router from "./routes";
|
||||
import AnonymizedRepositoryModel from "./database/anonymizedRepositories/anonymizedRepositories.model";
|
||||
import { conferenceStatusCheck } from "./schedule";
|
||||
|
||||
function indexResponse(req: express.Request, res: express.Response) {
|
||||
if (
|
||||
@@ -58,6 +59,7 @@ export default async function start() {
|
||||
|
||||
// api routes
|
||||
app.use("/api/options", rate, router.option);
|
||||
app.use("/api/conferences", rate, router.conference);
|
||||
app.use("/api/user", rate, router.user);
|
||||
app.use("/api/repo", rate, router.repositoryPublic);
|
||||
app.use("/api/repo", rate, router.file);
|
||||
@@ -96,6 +98,9 @@ export default async function start() {
|
||||
|
||||
app.get("*", indexResponse);
|
||||
|
||||
// start schedules
|
||||
conferenceStatusCheck();
|
||||
|
||||
await db.connect();
|
||||
app.listen(config.PORT);
|
||||
console.log("Database connected and Server started on port: " + config.PORT);
|
||||
|
||||
@@ -117,6 +117,8 @@ export type RepositoryStatus =
|
||||
| "expired"
|
||||
| "removed";
|
||||
|
||||
export type ConferenceStatus = "ready" | "expired" | "removed";
|
||||
|
||||
export type SourceStatus = "available" | "unavailable";
|
||||
|
||||
export type TreeElement = Tree | TreeFile;
|
||||
|
||||
Reference in New Issue
Block a user