in-the-database-2/src/upload.ts

75 lines
2.2 KiB
TypeScript

import { tmpdir } from 'os';
import * as fs from 'fs';
import * as AdmZip from 'adm-zip';
import { parseSM } from './lib/smparse';
import { File, User } from './schema';
export function run(app) {
const logger = app.get('logger');
app.post('/api/upload', async (req, res) => { // only for testing, very abusable
if (!req.files) return res.status(400).send('No files were given');
if (!req.session.uuid) return res.status(401).send('Not authorized, use /discordauth');
const user = (await User.find({uuid: req.session.uuid}))[0];
if (!user) return res.status(401).send('User doesn\'t exist, try re-logging in');
if (!user.get('approvedUpload')) return res.status(403).send('Your account is not allowed to upload files! Contact a moderator to verify your account');
const file = req.files.file;
if (file.mimetype !== 'application/zip' && file.mimetype !== 'application/x-zip-compressed') return res.status(400).send('Invalid filetype');
const dir = tmpdir() + '/' + file.md5;
fs.writeFile(dir, file.data, async (err) => {
if (err) throw err;
try {
const zip = new AdmZip(dir);
const zipEntries = zip.getEntries();
const smFile: any = Object.values(zipEntries).find((f: any) =>
!f.isDirectory && (f.entryName.endsWith('.sm'))
);
if (!smFile) {
res.status(400).send('No .sm found');
} else {
const data = smFile.getData().toString('utf8');
const chart = parseSM(data.toString());
logger.info(`${chart.artist} - ${chart.title} was just uploaded`);
let id = 0;
for (const f of await File.find({})) {
id = Math.max(Number(f.id), id);
}
chart.id = id + 1;
chart.uploader = req.session.uuid;
chart.createdAt = new Date();
fs.writeFile('./storage/files/' + (id + 1) + '.zip', file.data, (err) => {
if (err) throw err;
const file = new File(chart);
file.save();
// TODO: filter out _id and __v? possibly more
res.send(chart);
});
}
fs.unlink(dir, (err) => {
if (err) throw err;
});
} catch(err) {
logger.error(err.toString());
console.error(err);
res.status(400);
res.send(err.toString());
}
});
});
}