diff --git a/Public API v1.yaml b/Public API v1.yaml index 55d4b3d..22b57da 100644 --- a/Public API v1.yaml +++ b/Public API v1.yaml @@ -1673,6 +1673,16 @@ components: required: - task_key - new_data + UpdateTaskOptionsRequest: + type: object + properties: + task_key: + type: string + new_options: + type: object + required: + - task_key + - new_options GetTaskResponse: type: object properties: @@ -2549,6 +2559,8 @@ components: type: string schedule: type: object + options: + type: object Schedule: required: - type diff --git a/backend/app.js b/backend/app.js index 560f13a..7ada2d6 100644 --- a/backend/app.js +++ b/backend/app.js @@ -1814,6 +1814,15 @@ app.post('/api/updateTaskData', optionalJwt, async (req, res) => { res.send({success: success}); }); +app.post('/api/updateTaskOptions', optionalJwt, async (req, res) => { + const task_key = req.body.task_key; + const new_options = req.body.new_options; + + const success = await db_api.updateRecord('tasks', {key: task_key}, {options: new_options}); + + res.send({success: success}); +}); + app.post('/api/getDBBackups', optionalJwt, async (req, res) => { const backup_dir = path.join('appdata', 'db_backup'); fs.ensureDirSync(backup_dir); diff --git a/backend/db.js b/backend/db.js index f9400eb..f3c1948 100644 --- a/backend/db.js +++ b/backend/db.js @@ -1095,6 +1095,14 @@ exports.applyFilterLocalDB = (db_path, filter_obj, operation) => { filtered &= (record[filter_prop].search(new RegExp(filter_prop_value['$regex'], filter_prop_value['$options'])) !== -1); } else if ('$ne' in filter_prop_value) { filtered &= filter_prop in record && record[filter_prop] !== filter_prop_value['$ne']; + } else if ('$lt' in filter_prop_value) { + filtered &= filter_prop in record && record[filter_prop] < filter_prop_value['$lt']; + } else if ('$gt' in filter_prop_value) { + filtered &= filter_prop in record && record[filter_prop] > filter_prop_value['$gt']; + } else if ('$lte' in filter_prop_value) { + filtered &= filter_prop in record && record[filter_prop] <= filter_prop_value['$lt']; + } else if ('$gte' in filter_prop_value) { + filtered &= filter_prop in record && record[filter_prop] >= filter_prop_value['$gt']; } } else { // handle case of nested property check diff --git a/backend/tasks.js b/backend/tasks.js index dc91053..427cdfd 100644 --- a/backend/tasks.js +++ b/backend/tasks.js @@ -34,6 +34,12 @@ const TASKS = { confirm: youtubedl_api.updateYoutubeDL, title: 'Update youtube-dl', job: null + }, + delete_old_files: { + run: checkForAutoDeleteFiles, + confirm: autoDeleteFiles, + title: 'Delete old files', + job: null } } @@ -124,6 +130,7 @@ exports.executeTask = async (task_key) => { exports.executeRun = async (task_key) => { logger.verbose(`Running task ${task_key}`); + await db_api.updateRecord('tasks', {key: task_key}, {error: null}) // don't set running to true when backup up DB as it will be stick "running" if restored if (task_key !== 'backup_local_db') await db_api.updateRecord('tasks', {key: task_key}, {running: true}); const data = await TASKS[task_key].run(); @@ -131,10 +138,15 @@ exports.executeRun = async (task_key) => { logger.verbose(`Finished running task ${task_key}`); const task_obj = await db_api.getRecord('tasks', {key: task_key}); await notifications_api.sendTaskNotification(task_obj, false); + + if (task_obj['options'] && task_obj['options']['auto_confirm']) { + exports.executeConfirm(task_key); + } } exports.executeConfirm = async (task_key) => { logger.verbose(`Confirming task ${task_key}`); + await db_api.updateRecord('tasks', {key: task_key}, {error: null}) if (!TASKS[task_key]['confirm']) { return null; } @@ -197,4 +209,29 @@ async function removeDuplicates(data) { } } +// auto delete files + +async function checkForAutoDeleteFiles() { + const task_obj = await db_api.getRecord('tasks', {key: 'delete_old_files'}); + if (!task_obj['options'] || !task_obj['options']['threshold_days']) { + const error_message = 'Failed to do delete check because no limit was set!'; + logger.error(error_message); + await db_api.updateRecord('tasks', {key: 'delete_old_files'}, {error: error_message}) + return null; + } + const delete_older_than_timestamp = Date.now() - task_obj['options']['threshold_days']*86400*1000; + const uids = (await db_api.getRecords('files', {registered: {$lt: delete_older_than_timestamp}})).map(file => file.uid); + return {uids: uids}; +} + +async function autoDeleteFiles(data) { + if (data['uids']) { + logger.info(`Removing ${data['uids'].length} old files!`); + for (let i = 0; i < data['uids'].length; i++) { + const file_to_remove = data['uids'][i]; + await db_api.deleteFile(file_to_remove); + } + } +} + exports.TASKS = TASKS; \ No newline at end of file diff --git a/src/api-types/index.ts b/src/api-types/index.ts index 5819a8c..0fa0c93 100644 --- a/src/api-types/index.ts +++ b/src/api-types/index.ts @@ -114,6 +114,7 @@ export type { UpdatePlaylistRequest } from './models/UpdatePlaylistRequest'; export type { UpdaterStatus } from './models/UpdaterStatus'; export type { UpdateServerRequest } from './models/UpdateServerRequest'; export type { UpdateTaskDataRequest } from './models/UpdateTaskDataRequest'; +export type { UpdateTaskOptionsRequest } from './models/UpdateTaskOptionsRequest'; export type { UpdateTaskScheduleRequest } from './models/UpdateTaskScheduleRequest'; export type { UpdateUserRequest } from './models/UpdateUserRequest'; export type { User } from './models/User'; diff --git a/src/api-types/models/Task.ts b/src/api-types/models/Task.ts index e6f68be..4b85095 100644 --- a/src/api-types/models/Task.ts +++ b/src/api-types/models/Task.ts @@ -12,4 +12,5 @@ export type Task = { data: any; error: string; schedule: any; + options?: any; }; \ No newline at end of file diff --git a/src/api-types/models/UpdateTaskOptionsRequest.ts b/src/api-types/models/UpdateTaskOptionsRequest.ts new file mode 100644 index 0000000..47cde2d --- /dev/null +++ b/src/api-types/models/UpdateTaskOptionsRequest.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type UpdateTaskOptionsRequest = { + task_key: string; + new_options: any; +}; \ No newline at end of file diff --git a/src/app/app.module.ts b/src/app/app.module.ts index d0b205e..36bad89 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -90,6 +90,7 @@ import { UpdateTaskScheduleDialogComponent } from './dialogs/update-task-schedul import { RestoreDbDialogComponent } from './dialogs/restore-db-dialog/restore-db-dialog.component'; import { NotificationsComponent } from './components/notifications/notifications.component'; import { NotificationsListComponent } from './components/notifications-list/notifications-list.component'; +import { TaskSettingsComponent } from './components/task-settings/task-settings.component'; registerLocaleData(es, 'es'); @@ -137,7 +138,8 @@ registerLocaleData(es, 'es'); UpdateTaskScheduleDialogComponent, RestoreDbDialogComponent, NotificationsComponent, - NotificationsListComponent + NotificationsListComponent, + TaskSettingsComponent ], imports: [ CommonModule, diff --git a/src/app/components/task-settings/task-settings.component.html b/src/app/components/task-settings/task-settings.component.html new file mode 100644 index 0000000..6639bbf --- /dev/null +++ b/src/app/components/task-settings/task-settings.component.html @@ -0,0 +1,23 @@ +