Compare commits

...

2 Commits

Author SHA1 Message Date
DebaucheryLibrarian
9f37f54634 1.250.0 2026-02-24 06:17:41 +01:00
DebaucheryLibrarian
dc7f325d13 Added scene media detach. 2026-02-24 06:17:38 +01:00
6 changed files with 70 additions and 8 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "traxxx",
"version": "1.249.15",
"version": "1.250.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "traxxx",
"version": "1.249.15",
"version": "1.250.0",
"license": "ISC",
"dependencies": {
"@aws-sdk/client-s3": "^3.458.0",

View File

@@ -1,6 +1,6 @@
{
"name": "traxxx",
"version": "1.249.15",
"version": "1.250.0",
"description": "All the latest porn releases in one place",
"main": "src/app.js",
"scripts": {

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,
};