rdio-scanner/server/imports/api/upload.ts

103 lines
3.2 KiB
TypeScript

import { IncomingMessage, ServerResponse } from 'http';
import { Meteor } from 'meteor/meteor';
import { WebApp } from 'meteor/webapp';
import { Form } from 'multiparty';
import { Calls } from '../../../imports/collections/calls';
import { Call } from '../../../imports/models/call';
if (Meteor.isServer) {
WebApp.connectHandlers.use('/upload', (req: IncomingMessage, res: ServerResponse) => {
if (req.method === 'POST') {
const form = new Form();
let audio = '';
let json = '';
let key = '';
let system = '';
form.on('part', (part) => {
part.on('data', (data) => {
switch (part.name.toLowerCase()) {
case 'audio':
audio += data.toString('binary');
break;
case 'json':
json += data.toString('utf8');
break;
case 'key':
key += data.toString('utf8');
break;
case 'system':
system += data.toString('utf8');
break;
}
});
part.resume();
});
form.on('close', Meteor.bindEnvironment(() => {
const apiKeys = Meteor.settings.apiKeys;
if (key && Array.isArray(apiKeys) && apiKeys.find((apiKey) => apiKey === key)) {
try {
const call = new Call(Object.assign({}, JSON.parse(json), {
audio: urlEncode('audio/mpeg', audio),
system,
}));
Calls.collection.insert(call, (error: Meteor.Error) => {
res.writeHead(error ? 500 : 200);
res.end();
});
} catch (error) {
res.writeHead(500);
res.end(error.message);
}
} else {
res.writeHead(403);
res.end('wrong or no api key provided');
}
}));
form.parse(req);
pruneCalls();
} else {
res.writeHead(404);
res.end();
}
});
}
function base64Encode(value: any): string {
return Buffer.from(value, 'binary').toString('base64');
}
function urlEncode(mimeType: string, value: any): string {
return `data:${mimeType};base64,${base64Encode(value)}`;
}
function getPruneDays(): number | null {
const pruneDays = Meteor.settings.pruneDays;
return typeof pruneDays === 'number' ? pruneDays : null;
}
function pruneCalls(): void {
const pruneDays = getPruneDays();
if (pruneDays !== null) {
const currentDate = new Date();
const dateLimit = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() - pruneDays);
Calls.collection.remove({
createdAt: {
$lt: dateLimit,
},
});
}
}