diff --git a/config/default.cjs b/config/default.cjs index 09a9561..7ed41d0 100755 --- a/config/default.cjs +++ b/config/default.cjs @@ -179,7 +179,7 @@ module.exports = { stashes: { nameLength: [2, 24], namePattern: /^[a-zA-Z0-9!?$&\s_-]+$/, - viewRefreshCron: '* * * * *', // every minute + viewRefreshCrontab: '* * * * *', // every minute viewRefreshCooldowns: { actors: 60, // minutes stashes: 1, @@ -192,4 +192,8 @@ module.exports = { s3Path: 'https://s3.wasabisys.com', videoRestrictions: [], // entity slugs, _ prefix for networks, hides trailer and teaser videos }, + sync: { + enabled: true, + crontab: '*/10 * * * *', // every 10 minutes + }, }; diff --git a/src/stashes.js b/src/stashes.js index 6a93f88..41b0023 100755 --- a/src/stashes.js +++ b/src/stashes.js @@ -592,7 +592,7 @@ export async function unstashMovie(movieId, stashId, sessionUser) { } CronJob.from({ - cronTime: config.stashes.viewRefreshCron, + cronTime: config.stashes.viewRefreshCrontab, async onTick() { logger.verbose('Updating stash views'); diff --git a/src/sync.js b/src/sync.js index 8ca5e03..d184fd7 100644 --- a/src/sync.js +++ b/src/sync.js @@ -1,4 +1,6 @@ +import config from 'config'; import { format } from 'date-fns'; +import { CronJob } from 'cron'; import initLogger from './logger.js'; import { knexOwner as knex } from './knex.js'; @@ -438,3 +440,36 @@ export async function syncActors(actorIds) { await syncManticoreActors(actorIds); } + +function getQueueItemIds(tasks, domain) { + return Array.from(new Set(tasks.filter((task) => task.domain === domain).flatMap((task) => task.item_ids))); +} + +export async function syncQueue() { + const tasks = await knex('sync'); + + const sceneIds = getQueueItemIds(tasks, 'scene'); + const movieIds = getQueueItemIds(tasks, 'movie'); + const actorIds = getQueueItemIds(tasks, 'actor'); + + await Promise.all([ + syncScenes(sceneIds), + syncMovies(movieIds), + syncActors(actorIds), + ]); + + await knex('sync') + .whereIn('id', tasks.map((task) => task.id)) + .delete(); + + logger[process.tasks > 0 ? 'info' : 'verbose'](`Processed ${tasks.length} sync items`); +} + +CronJob.from({ + cronTime: config.sync.crontab, + async onTick() { + syncQueue(); + }, + start: config.sync.enabled, + runOnInit: true, +}); diff --git a/src/web/sync.js b/src/web/sync.js index b406794..075556f 100644 --- a/src/web/sync.js +++ b/src/web/sync.js @@ -5,6 +5,7 @@ import { syncMovies, syncActors, syncStashes, + syncQueue, } from '../sync.js'; import verifyAbility from '../../utils/verify-ability.js'; @@ -43,7 +44,16 @@ async function syncStashesApi(req, res) { res.status(204).send(); } +async function syncQueueApi(req, res) { + verifyAbility(req.user, 'sync', null, { throwError: true }); + + await syncQueue(); + + res.status(204).send(); +} + syncRouter.post('/api/sync/scenes', syncScenesApi); syncRouter.post('/api/sync/movies', syncMoviesApi); syncRouter.post('/api/sync/actors', syncActorsApi); syncRouter.post('/api/sync/stashes', syncStashesApi); +syncRouter.post('/api/sync', syncQueueApi);