Added scene media detach.

This commit is contained in:
DebaucheryLibrarian
2026-02-24 06:17:38 +01:00
parent 35c941488e
commit dc7f325d13
4 changed files with 67 additions and 5 deletions

View File

@@ -24,7 +24,7 @@ const { updateSceneSearch, updateMovieSearch } = require('./update-search');
const { scrapeActors, deleteActors, flushActors, flushProfiles, interpolateProfiles } = require('./actors');
const { flushEntities } = require('./entities');
const { deleteScenes, deleteMovies, flushScenes, flushMovies, flushBatches } = require('./releases');
const { flushOrphanedMedia } = require('./media');
const { flushOrphanedMedia, detachReleaseMedia, detachEntityReleaseMedia } = require('./media');
const { reassociateEntityReleaseTags, reassociateReleaseTags, reassociateOriginalTags } = require('./tags');
const getFileEntries = require('./utils/file-entries');
@@ -160,7 +160,8 @@ async function init() {
}
if (argv.flushNetworks || argv.flushChannels) {
await flushEntities(argv.flushNetworks, argv.flushChannels);
// inject flushOrphanedMedia to prevent circular dependency with entity media flush
await flushEntities(argv.flushNetworks, argv.flushChannels, flushOrphanedMedia);
}
if (argv.flushBatches) {
@@ -203,6 +204,14 @@ async function init() {
await flushOrphanedMedia();
}
if (argv.detachReleaseMedia) {
await detachReleaseMedia(argv.detachReleaseMedia);
}
if (argv.detachNetworkMedia || argv.detachChannelMedia) {
await detachEntityReleaseMedia(argv.detachNetworkMedia, argv.detachChannelMedia);
}
if (argv.request) {
const res = await http[argv.requestMethod](argv.request);

View File

@@ -349,7 +349,32 @@ const { argv } = yargs
describe: 'Remove files from storage when flushing media.',
type: 'boolean',
alias: 'flush-files',
default: true,
})
.option('detach-channel-media', {
describe: 'Remove media files from channel scenes.',
type: 'array',
})
.option('detach-network-media', {
describe: 'Remove media files from network scenes.',
type: 'array',
})
.option('detach-release-media', {
describe: 'Remove media files from network scenes.',
type: 'array',
alias: ['detach-scene-media'],
})
.option('detach-media-domains', {
describe: 'Only detach these types of media.',
type: 'array',
default: [
'posters',
'photos',
'caps',
'trailers',
'teasers',
'covers',
],
alias: ['detach-media'],
})
.option('flush-channels', {
describe: 'Delete all scenes and movies from channels.',

View File

@@ -7,7 +7,6 @@ const logger = require('./logger')(__filename);
const argv = require('./argv');
const knex = require('./knex');
const { deleteScenes, deleteMovies, deleteSeries } = require('./releases');
const { flushOrphanedMedia } = require('./media');
const { resolveScraper, resolveLayoutScraper } = require('./scrapers/resolve');
const getRecursiveParameters = require('./utils/get-recursive-parameters');
@@ -454,7 +453,7 @@ async function fetchEntityReleaseIds(networkSlugs = [], channelSlugs = []) {
};
}
async function flushEntities(networkSlugs = [], channelSlugs = []) {
async function flushEntities(networkSlugs = [], channelSlugs = [], flushOrphanedMedia) {
const { sceneIds, movieIds, serieIds } = await fetchEntityReleaseIds(networkSlugs, channelSlugs);
const entitySlugs = networkSlugs.concat(channelSlugs).join(', ');

View File

@@ -26,6 +26,7 @@ const http = require('./utils/http');
const bulkInsert = require('./utils/bulk-insert');
const chunk = require('./utils/chunk');
const { get } = require('./utils/qu');
const { fetchEntityReleaseIds } = require('./entities');
// const pipeline = util.promisify(stream.pipeline);
const streamQueue = taskQueue();
@@ -1159,8 +1160,36 @@ async function flushOrphanedMedia(stage = 1) {
}
}
async function detachReleaseMedia(rawSceneIds) {
const sceneIds = rawSceneIds.map((sceneId) => Number(sceneId)).filter(Boolean);
await argv.detachMediaDomains.reduce(async (chain, domain) => {
await chain;
const mediaEntries = await knex(`releases_${domain}`).whereIn('release_id', sceneIds);
await knex(`releases_${domain}`)
.whereIn('release_id', sceneIds)
.delete();
logger.info(`Removed ${mediaEntries.length} ${domain} from ${new Set(mediaEntries.map((mediaEntry) => mediaEntry.release_id)).size} scenes`);
}, Promise.resolve());
if (argv.flushOrphanedMedia !== false) {
await flushOrphanedMedia();
}
}
async function detachEntityReleaseMedia(networkSlugs = [], channelSlugs = []) {
const { sceneIds } = await fetchEntityReleaseIds(networkSlugs, channelSlugs);
await detachReleaseMedia(sceneIds);
}
module.exports = {
associateAvatars,
associateReleaseMedia,
flushOrphanedMedia,
detachReleaseMedia,
detachEntityReleaseMedia,
};