SotM_Playfield/src/server.js

125 lines
4.2 KiB
JavaScript
Raw Normal View History

2018-12-28 10:46:01 -05:00
// jshint node:true
// jshint esversion:6
"use strict";
const express = require('express'),
Bundler = require('parcel-bundler'),
fs = require('fs'),
path = require('path'),
phantom = require('phantom'),
Datastore = require('nedb-promises'),
port = process.env.PORT || 1234;
2018-12-28 10:46:01 -05:00
const db = Datastore.create('decks.db');
2018-12-28 10:46:01 -05:00
const app = express();
app.use(express.json({limit: '50mb'}));
2018-12-28 10:46:01 -05:00
app.use('/template', express.static('template'));
app.get('/decks/:deckID.tts.json', getTTSJSON);
app.get('/decks/:deckID.json', getInputJSON);
app.get('/decks/:deckID.png', getDeckImage);
app.get('/decks.json', getDecksList);
2018-12-28 10:46:01 -05:00
app.post('/upload', handleUpload);
let bundler = new Bundler(path.join(__dirname, 'index.html'));
app.use(bundler.middleware());
app.listen(port, () => console.log(`App listening on port ${port}!`));
function getDecksList(req, res) {
db.find({}, {'deck.meta': 1})
.then(docs => res.json(docs))
.catch(err => res.status(404).end());
}
function getInputJSON(req, res) {
db.findOne({_id: req.params.deckID}, {image: 0})
.then(doc => res.json(doc))
.catch(err => res.status(404).end());
}
function getDeckImage(req, res) {
db.findOne({_id: req.params.deckID})
.then(doc => res.send(new Buffer.from(doc.image, 'base64')))
.catch(err => res.status(404).end());
}
function getTTSJSON(req, res) {
// TODO: fix
db.findOne({_id: req.params.deckID})
.then(doc => {
let deckIn = doc.deck;
const cardTemplate = fs.readFileSync(__dirname + '/template/card.json');
const template = JSON.parse(fs.readFileSync(__dirname + `/template/${deckIn.type}/input.json`));
const cardCount = Object.entries(template.cardTypes)
.map(ct => deckIn[ct[0]].length * (ct[1].back ? 2 : 1))
.reduce((sum, current) => sum + current, 0);
let deckOut = JSON.parse(fs.readFileSync(__dirname + '/template/deck.json'));
deckOut.ObjectStates[0].Nickname = deckIn.meta.name;
Object.assign(deckOut.ObjectStates[0].CustomDeck['1'],
{NumWidth: Math.ceil(Math.sqrt(cardCount)),
NumHeight: Math.ceil(cardCount/Math.ceil(Math.sqrt(cardCount))),
FaceURL: `http://${req.headers.host}/decks/${doc.meta.name}.png`,
BackURL: "http://cloud-3.steamusercontent.com/ugc/156906385556221451/CE2C3AFE1759790CB0B532FFD636D05A99EC91F4/"});
let index = 100;
deckOut.ObjectStates[0].ContainedObjects = Object
.keys(deckIn)
.filter(cardType => cardType !== 'meta')
.map(cardType => deckIn[cardType].map((card, index) => {
let cardOut = {...JSON.parse(cardTemplate),
Nickname: card.name,
Description: card.keywords,
CardID: index};
deckOut.ObjectStates[0].DeckIDs.push(...Array(card.count || 1).fill(index));
2018-12-28 10:46:01 -05:00
index++;
if(card.back) {
cardOut.States = {"2": {...JSON.parse(cardTemplate),
Nickname: card.back.name,
Description: card.back.keywords,
CardID: index}};
index++;
2018-12-28 10:46:01 -05:00
}
return cardOut;
}))
.reduce((sum, cur) => sum.concat(cur), []); // flatten
res.json(deckOut);
});
2018-12-28 10:46:01 -05:00
}
async function handleUpload(req, res) {
const json = req.body;
console.log("Making deck image");
const ph = await phantom.create();
const page = await ph.createPage();
page.on('onLoadFinished', status => {
if (status === 'success') {
page.renderBase64(`PNG`)
.then(image => db.update(
{_id: json.id},
{deck: json.deck, image: image},
{upsert: true, returnUpdatedDocs: true}))
.then(doc => res.status(201).json({id: doc._id}))
.then(() => page.close().then(() => ph.exit()));
}
else {
console.log('Failed to load page');
ph.exit(1);
}
});
page.property('zoomFactor', 2); // pretty arbitrary
page.property('content',
'<head><link rel="stylesheet" href="' + json.css + '"></head>' +
'<body style="margin:0;">' + json.dom + '</body>');
2018-12-28 10:46:01 -05:00
}