import redis from 'redis'; import models from '../../models'; import { formatFile } from '../../lib/format'; import Uploader from '../../lib/uploader'; const redisUrl = process.env.REDIS_URL; export async function post(ctx, next) { if (!ctx.request.is('multipart/*')) { await next(); return; } const uploader = new Uploader(ctx); await uploader.checkLimit(); await uploader.accept(); await uploader.processImage(); await uploader.finalise(); ctx.status = 201; ctx.body = formatFile(uploader.file); uploader.completeEvent(); uploader.malwareScan(); } export async function list(ctx) { let limit = 20; if (ctx.request.query.perpage === '0') { limit = 1000; } else if (ctx.request.query.perpage > 0) { limit = parseInt(ctx.request.query.perpage / 1, 10); } let offset = 0; if (ctx.request.query.page) { offset = parseInt(ctx.request.query.page - 1, 10) * limit; } const files = await models.file.findAll({ where: { userId: ctx.user.id, processed: true, }, order: [ ['createdAt', 'DESC'], ], offset, limit, }); ctx.statsd.incr('file.list', 1); ctx.body = files.map(formatFile); } export async function get(ctx) { const file = await models.file.findOne({ where: { id: ctx.params.id, }, }); ctx.assert(file, 404, '{"error": {"message": "File not found", "code": 604}}'); const user = await file.getUser(); ctx.assert(user && !user.banned, 404, '{"error": {"message": "File not found", "code": 604}}'); ctx.statsd.incr('file.get', 1); ctx.body = formatFile(file); } export async function del(ctx) { const file = await models.file.findOne({ where: { id: ctx.params.id, userId: ctx.user.id, }, }); ctx.assert(file, 401, '{"error": {"message": "File not found", "code": 604}}'); await file.destroy(); const event = { type: 'file-deleted', data: { id: ctx.params.id } }; await ctx.redis.publish(`/file/${ctx.params.id}`, JSON.stringify(event)); await ctx.redis.publish(`/user/${ctx.user.id}`, JSON.stringify(event)); ctx.statsd.incr('file.delete', 1); ctx.status = 204; ctx.body = ''; } export async function events(ctx) { const pubsub = redis.createClient(redisUrl); pubsub.on('ready', () => { pubsub.subscribe(ctx.path); }); pubsub.on('message', (channel, message) => { ctx.websocket.send(message); }); ctx.websocket.on('close', () => { pubsub.quit(); }); }