Files
NodeBB/src/posts/uploads.js

85 lines
2.7 KiB
JavaScript
Raw Normal View History

2018-04-13 16:12:11 -04:00
'use strict';
var async = require('async');
var crypto = require('crypto');
2018-04-13 16:12:11 -04:00
var db = require('../database');
module.exports = function (Posts) {
Posts.uploads = {};
const md5 = filename => crypto.createHash('md5').update(filename).digest('hex');
2018-04-13 16:12:11 -04:00
Posts.uploads.sync = function (pid, callback) {
// Scans a post and updates sorted set of uploads
2018-04-16 15:36:59 -04:00
const searchRegex = /\/assets\/uploads\/files\/([^\s")]+\.?[\w]*)/g;
2018-04-13 16:12:11 -04:00
async.parallel({
content: async.apply(Posts.getPostField, pid, 'content'),
uploads: async.apply(Posts.uploads.list, pid),
}, function (err, data) {
if (err) {
return callback(err);
}
// Extract upload file paths from post content
let match = searchRegex.exec(data.content);
const uploads = [];
while (match) {
uploads.push(match[1]);
match = searchRegex.exec(data.content);
}
// Create add/remove sets
const add = uploads.filter(path => !data.uploads.includes(path));
const remove = data.uploads.filter(path => !uploads.includes(path));
async.parallel([
async.apply(Posts.uploads.associate, pid, add),
async.apply(Posts.uploads.dissociate, pid, remove),
], function (err) {
// Strictly return only err
callback(err);
});
2018-04-13 16:12:11 -04:00
});
};
Posts.uploads.list = function (pid, callback) {
// Returns array of this post's uploads
db.getSortedSetRange('post:' + pid + ':uploads', 0, -1, callback);
};
2018-04-16 16:44:17 -04:00
Posts.uploads.isOrphan = function (filePath, callback) {
// Returns bool indicating whether a file is still CURRENTLY included in any posts
db.sortedSetCard('upload:' + md5(filePath) + ':pids', function (err, length) {
callback(err, length === 0);
});
};
2018-04-13 16:12:11 -04:00
Posts.uploads.associate = function (pid, filePaths, callback) {
// Adds an upload to a post's sorted set of uploads
const now = Date.now();
filePaths = !Array.isArray(filePaths) ? [filePaths] : filePaths;
2018-04-16 12:46:20 -04:00
const scores = filePaths.map(() => now);
let methods = [async.apply(db.sortedSetAdd.bind(db), 'post:' + pid + ':uploads', scores, filePaths)];
methods = methods.concat(filePaths.map(path => async.apply(db.sortedSetAdd.bind(db), 'upload:' + md5(path) + ':pids', now, pid)));
2018-04-13 16:12:11 -04:00
async.parallel(methods, function (err) {
// Strictly return only err
callback(err);
});
2018-04-13 16:12:11 -04:00
};
Posts.uploads.dissociate = function (pid, filePaths, callback) {
// Removes an upload from a post's sorted set of uploads
filePaths = !Array.isArray(filePaths) ? [filePaths] : filePaths;
let methods = [async.apply(db.sortedSetRemove.bind(db), 'post:' + pid + ':uploads', filePaths)];
methods = methods.concat(filePaths.map(path => async.apply(db.sortedSetRemove.bind(db), 'upload:' + md5(path) + ':pids', pid)));
2018-04-13 16:12:11 -04:00
async.parallel(methods, function (err) {
// Strictly return only err
callback(err);
});
2018-04-13 16:12:11 -04:00
};
};