This commit is contained in:
Jason 2021-11-03 19:31:49 +01:00 committed by GitHub
commit 439e98b6c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 19140 additions and 19109 deletions

38206
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,9 @@ class configGET extends Route {
metaDescription: Util.config.metaDescription,
metaKeywords: Util.config.metaKeywords,
metaTwitterHandle: Util.metaTwitterHandle,
domain: process.env.DOMAIN
domain: process.env.DOMAIN,
deleteExpiredFilesEnabled: Util.config.deleteExpiredFilesEnabled,
deleteExpiredFilesAfter: Util.config.deleteExpiredFilesAfter
}
});
}

View File

@ -97,6 +97,7 @@ class Server {
createJobs() {
// TODO: move into the database config. (we can just show the crontab line for start, later on we can add dropdowns and stuff)
this.jobs.stats = new CronJob('0 0 * * * *', Util.saveStatsToDb, null, true);
this.jobs.fileExpiry = new CronJob('*/5 * * * * *', Util.deleteExpiredFiles, null, true);
}
start() {

View File

@ -86,6 +86,16 @@ const schema = Joi.object({
.label('Blocked extensions')
.description('List of extensions which will be rejected by the server'),
deleteExpiredFilesEnabled: Joi.boolean().default(false)
.meta({ section: Sections.FILE })
.label('Automatic File Deletion')
.description('Enables automatic file deletion after the specified amount of days'),
deleteExpiredFilesAfter: Joi.number().integer().default(30)
.meta({ section: Sections.FILE })
.label('Automatic File Deletion After')
.description('The amount of days to delete files after, if Automatic File Deletion is enabled'),
// User settings
publicMode: Joi.boolean().default(true)
.meta({

View File

@ -196,6 +196,21 @@ class Util {
}
}
static async deleteAllFilesFromFileArray(files) {
try {
const fileIds = files.map(file => file.id);
await db.table('albumsFiles').whereIn('fileId', fileIds).delete(); // Delete album mappings
await db.table('fileTags').whereIn('id', fileIds).delete(); // Delete tag mappings
await db.table('files').whereIn('id', fileIds).delete(); // Delete file references
for (const file of files) {
// Delete file from storage
await this.deleteFile(file.name, false);
}
} catch (error) {
log.error(error);
}
}
static async deleteAllFilesFromUser(id) {
try {
const files = await db.table('files').where({ userId: id });
@ -375,6 +390,19 @@ class Util {
return extname + multi;
}
static async deleteExpiredFiles() {
if (!Util.config.deleteExpiredFilesEnabled) return;
const expiryBefore = moment.utc().subtract(Util.config.deleteExpiredFilesAfter ?? 30, 'days');
const dbExpiredFiles = await db.table('files').where('createdAt', '<', expiryBefore.toDate());
if (!dbExpiredFiles.length) return;
await Util.deleteAllFilesFromFileArray(dbExpiredFiles);
log.info(`Deleted ${dbExpiredFiles.length} expired files`);
}
// TODO: Allow choosing what to save to db and what stats we care about in general
// TODO: if a stat is not saved to db but selected to be shows on the dashboard, it will be generated during the request
static async saveStatsToDb(force) {