XciD's picture
XciD HF staff
initial commit
8969f81
require('./lib/Extensions').install();
import * as express from 'express';
import * as bodyParser from 'body-parser';
import __rootDir from './lib/RootDirFinder';
import { c } from './lib/Log';
import db from './models/Database';
import Doc, { ALL_MODELS, ModelId } from './models/Doc';
import { config } from './lib/config';
import { hbs } from './lib/Hbs';
const app = express();
const PORT = process.env.PORT || config.appPort;
const __frontDir = __rootDir+`/front`;
// Express setup
app.set('trust proxy', 'loopback');
app.disable('x-powered-by');
app.use(bodyParser.json());
app.set('views', `${__frontDir}/views`);
app.set('view engine', 'hbs');
app.engine('hbs', hbs.__express);
const staticHandler = express.static(__frontDir);
const staticHandlerNoHtml: express.RequestHandler = function(req, res, next) {
if (req.path === '/' || req.path.endsWith('.html') || req.path.endsWith('.hbs')) {
return next();
} else {
return staticHandler(req, res, next);
}
};
app.get('/favicon.ico', (req, res) => res.sendFile(`${__frontDir}/favicon.ico`));
app.get('/robots.txt', (req, res) => res.sendFile(`${__frontDir}/robots.txt`));
app.use('/front', staticHandlerNoHtml);
/// ^^ in production, those aren't used b/c we serve static files from nginx.
/**
* Routes(html)
*/
app.get('/', async function(req, res) {
const docs = await db.docs
.find<Doc>({ featured: true })
.sort({ _id: -1 })
.limit(10)
.project({ shortId: true, title: true })
.toArray()
;
/// ^^ cache this query at some point for performance.
res.render('landing', {
body_classes: `landing`,
docs
});
});
app.get('/model/:model', function(req, res) {
const model = req.params.model;
if (! ['arxiv-nlp', 'distil-gpt2', 'ctrl', 'pplm'].includes(model)) {
return res.sendStatus(404);
}
res.render('model', {
body_classes: `model`,
model,
meta: {
/// ^^ do NOT call this key `layout`.
title: (model === 'distil-gpt2') ? `🐎 DistilGPT-2 model checkpoint`
: (model === 'ctrl') ? `☁️ Salesforce Research CTRL`
: (model === 'pplm') ? `πŸš• Uber AI Plug and Play Language Model`
: `πŸ€“ ArXiv NLP model checkpoint`,
thumbnail: (model === 'distil-gpt2') ? 'thumbnail-large-distilgpt2'
: (model === 'pplm') ? `thumbnail-large-pplm`
: undefined,
path: req.path,
},
});
});
app.get('/doc/:model', function(req, res) {
const model = req.params.model;
if (! ALL_MODELS.includes(model)) {
return res.sendStatus(404);
}
const doc = Doc.seed(model as ModelId);
/// ^^ new document. It doesn't exist in the db yet,
/// will only be stored if user presses save.
res.render('index', {
body_classes: `app`,
editable: true,
doc,
});
});
app.get('/doc/:model/:id/edit', async function(req, res) {
const model = req.params.model;
if (! ALL_MODELS.includes(model)) {
return res.sendStatus(404);
}
const doc = await Doc.findOne<Doc>({
longId: req.params.id,
});
if (!doc) {
return res.sendStatus(404);
}
/// Existing document, accessed through its private edit url.
res.render('index', {
body_classes: `app`,
editable: true,
doc,
});
});
app.get('/share/:shortId', async function(req, res) {
const doc = await Doc.findOne<Doc>(req.params.shortId);
if (!doc) {
return res.sendStatus(404);
}
/// Existing document, accessed through its public share url.
/// CAUTION: Make sure we don't expose the edit url!
delete doc.longId;
res.render('index', {
body_classes: `app`,
editable: false,
doc,
});
});
/**
* Routes(ajax)
*/
app.post('/edit/:model/:longId/:shortId', async function(req, res) {
const query = {
shortId: req.params.shortId,
longId: req.params.longId,
model: req.params.model,
};
c.debug(`––`);
c.log(`Attempting to save doc`, query);
const result = await db.docs.updateOne(
query,
{ $set: req.body },
{ upsert: true }
);
c.log(result.result);
res.sendStatus(200);
});
app.post('/duplicate/:shortId', async function(req, res) {
const doc = await Doc.findOne<Doc>(req.params.shortId);
if (!doc) {
return res.sendStatus(404);
}
c.debug(`––`);
c.log(`Duplicating doc`, doc.shortId);
const newdoc = await doc.duplicate();
res.send(newdoc.editUrl);
});
// Start engine.
(async () => {
await db.connect();
app.listen(PORT, () => {
c.debug(`Running on http://localhost:${PORT}`);
});
})();