mirror of
https://github.com/chuot/rdio-scanner.git
synced 2026-08-13 16:33:01 -06:00
105 lines
3.3 KiB
TypeScript
105 lines
3.3 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 mimeType = '';
|
|
let system = '';
|
|
|
|
form.on('part', (part) => {
|
|
part.on('data', (data) => {
|
|
switch (part.name.toLowerCase()) {
|
|
case 'audio':
|
|
audio += data.toString('binary');
|
|
mimeType = part.headers['content-type'];
|
|
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(mimeType, 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,
|
|
},
|
|
});
|
|
}
|
|
}
|