Recv/lib/repository/upload.js

301 lines
5.6 KiB
JavaScript

const map = require('lodash/map');
const filter = require('lodash/filter');
const resolvePath = require('resolve-path');
const fs = require('mz/fs');
const async = require('async');
class Upload
{
constructor(values)
{
var self = this;
self.id = values.id || values._id || null;
self.userId = values.userId || null;
self.codeId = values.codeId || null;
self.created = values.created || new Date();
self.expirationDate = values.expirationDate || null;
self.files = values.files || [];
}
}
class UploadRepository
{
constructor(store)
{
var self = this;
self.store = store;
}
init()
{
var self = this;
return new Promise((resolve, reject) =>
{
// Initialize database if empty
self.store.count({}, (err, count) =>
{
if (err)
{
reject(err);
return;
}
if (count == 0)
self.addUser('admin', null, 'test', null);
resolve();
});
});
}
insert(upload)
{
var self = this;
return new Promise((resolve, reject) =>
{
let insertUpload = {
created: upload.created || new Date(),
userId: upload.userId,
codeId: upload.codeId,
expirationDate: upload.expirationDate,
files: map(filter(upload.files,
(file) => file.hasOwnProperty('id') && file.hasOwnProperty('name')),
(file) => { return { id: file.id, name: file.name, size: file.size } })
};
if (insertUpload.files.length)
{
self.store.insert(insertUpload, (err, dbUpload) =>
{
if (err)
{
reject(err);
return;
}
resolve(dbUpload._id);
});
}
else
{
reject();
}
});
}
list(userId)
{
var self = this;
return new Promise((resolve, reject) =>
{
self.store.find(userId != null ? { userId: userId } : {}, (err, docs) =>
{
if (err)
{
reject(err);
return;
}
resolve(docs.map((dbUpload) =>
{
return new Upload(dbUpload);
}));
});
});
}
listForCode(codeId)
{
var self = this;
return new Promise((resolve, reject) =>
{
self.store.find({ codeId: codeId }, (err, docs) =>
{
if (err)
{
reject(err);
return;
}
resolve(docs.map((dbUpload) =>
{
return new Upload(dbUpload);
}));
});
});
}
get(uploadId)
{
var self = this;
return new Promise((resolve, reject) =>
{
self.store.findOne({ _id: uploadId }, (err, doc) =>
{
if (err)
{
reject(err);
return;
}
resolve(doc !== null ? new Upload(doc) : null);
});
});
}
move(codeId, userId)
{
var self = this;
return new Promise((resolve, reject) =>
{
self.store.update({ codeId: codeId }, {
$set: {
userId: userId
}
},
(err, numAffected) =>
{
if (err)
{
reject(err);
return;
}
if (numAffected == 0)
{
reject();
}
resolve();
});
});
}
delete(uploadId)
{
var self = this;
return new Promise((resolve, reject) =>
{
self.store.findOne({ _id: uploadId }, (err, doc) =>
{
if (err)
{
reject(err);
return;
}
if (doc === null)
{
resolve();
return;
}
let upload = new Upload(doc);
self.store.remove({ _id: uploadId }, async (err, numRemoved) =>
{
if (err)
{
reject(err);
return;
}
await Promise.all(upload.files.map(async (file) =>
{
if (!file.id) return;
if (!(await self.fileExists(file.id)))
{
var fullpath = resolvePath(config.fileUpload.path, file.id);
try
{
await fs.unlink(fullpath);
}
catch (err)
{
console.log('Failed to delete ' + fullpath);
}
}
}));
resolve();
});
});
});
}
fileExists(fileId)
{
var self = this;
return new Promise((resolve, reject) =>
{
self.store.findOne({ 'files.id': fileId }, (err, doc) =>
{
if (err)
{
reject(err);
return;
}
resolve(doc !== null);
});
});
}
deleteExpired()
{
var self = this;
return new Promise((resolve, reject) =>
{
let now = new Date();
self.store.find({ $where: function() { return this.expirationDate !== null && this.expirationDate < now }}, (err, docs) =>
{
if (err)
{
reject(err);
return;
}
async.eachOfSeries(docs,
async (doc) =>
{
console.log('Expired upload: ' + doc._id);
await self.delete(doc._id);
},
(err) =>
{
if (err)
reject(err);
else
resolve();
});
});
});
}
}
module.exports = {
UploadRepository
}