11 Commits

Author SHA1 Message Date
DebaucheryLibrarian
32a3f876e3 Added abilities seed file to repo. 2026-06-17 00:58:21 +02:00
DebaucheryLibrarian
ccf815b71f 1.253.6 2026-06-17 00:57:48 +02:00
DebaucheryLibrarian
da6b54079f Hashing media in transform in an attempt to improve reliability. Added seed file for user abilities. 2026-06-17 00:57:45 +02:00
DebaucheryLibrarian
43d58ff093 1.253.5 2026-06-09 05:54:11 +02:00
DebaucheryLibrarian
677f72df33 Utilizing allow global match into scene actor association. 2026-06-09 05:54:09 +02:00
DebaucheryLibrarian
18d6832f95 1.253.4 2026-06-09 04:23:16 +02:00
DebaucheryLibrarian
170c42c282 Updated common. 2026-06-09 04:23:11 +02:00
DebaucheryLibrarian
51eafc9a07 1.253.3 2026-06-09 03:19:10 +02:00
DebaucheryLibrarian
01213afd8b Updated common. 2026-06-09 03:19:08 +02:00
DebaucheryLibrarian
2ef1ef80e4 1.253.2 2026-06-09 01:06:46 +02:00
DebaucheryLibrarian
5ed7c611e9 Syncing new actors to web. 2026-06-09 01:06:45 +02:00
7 changed files with 68 additions and 36 deletions

2
common

Submodule common updated: 1374f90397...ec0812ad9d

4
package-lock.json generated
View File

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

View File

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

28
seeds/08_abilities.js Normal file
View File

@@ -0,0 +1,28 @@
exports.seed = async (knex) => {
await knex('users_roles')
.update('abilities', JSON.stringify([
{ subject: 'scene', action: 'create' },
{ subject: 'scene', action: 'update' },
{ subject: 'scene', action: 'delete' },
{ subject: 'actor', action: 'create' },
{ subject: 'actor', action: 'update' },
{ subject: 'actor', action: 'delete' },
{ subject: 'actor', action: 'merge' },
{ subject: 'sync' },
{ subject: 'plainUrls' },
]))
.where('role', 'admin');
await knex('users_roles')
.update('abilities', JSON.stringify([
{ subject: 'scene', action: 'create' },
{ subject: 'scene', action: 'update' },
{ subject: 'scene', action: 'delete' },
{ subject: 'actor', action: 'create' },
{ subject: 'actor', action: 'update' },
{ subject: 'actor', action: 'delete' },
{ subject: 'actor', action: 'merge' },
{ subject: 'plainUrls' },
]))
.where('role', 'editor');
};

View File

@@ -30,6 +30,7 @@ const { toBaseReleases } = require('./deep');
const { associateAvatars, flushOrphanedMedia } = require('./media');
const { fetchEntitiesBySlug } = require('./entities');
const { deleteScenes } = require('./releases');
const { updateActorSearch } = require('./update-search');
const actorsCommon = import('../common/actors.mjs'); // eslint-disable-line import/extensions, import/no-relative-packages
const geoCommon = import('../common/geo.mjs'); // eslint-disable-line import/extensions, import/no-relative-packages
@@ -912,7 +913,7 @@ async function getOrCreateActors(baseActors, batchId) {
.whereRaw(`
actors.slug = base_actors.slug
AND actors.entity_id IS NULL
AND NOT base_actors.collision_likely
AND (NOT base_actors.collision_likely OR actors.allow_global_match)
`)
.orWhereRaw(`
actors.slug = base_actors.slug
@@ -980,7 +981,8 @@ async function getOrCreateActors(baseActors, batchId) {
await storeProfiles(newActorProfiles);
if (Array.isArray(newActors)) {
if (Array.isArray(newActors) && newActors.length > 0) {
await updateActorSearch(newActors.map((actor) => actor.id));
return newActors.concat(existingActors);
}

View File

@@ -28,7 +28,6 @@ const chunk = require('./utils/chunk');
const { get } = require('./utils/qu');
const { fetchEntityReleaseIds } = require('./entity-releases');
// const pipeline = util.promisify(stream.pipeline);
const streamQueue = taskQueue();
const s3 = new S3Client({
@@ -516,16 +515,6 @@ async function storeImageFile(media, hashDir, hashSubDir, filename, filedir, fil
writeLazy(image, lazypath, info),
]);
/*
if (isProcessed) {
// file already stored, remove temporary file
await fsPromises.unlink(media.file.path);
} else {
// image not processed, simply move temporary file to final location
await fsPromises.rename(media.file.path, path.join(config.media.path, filepath));
}
*/
await fsPromises.unlink(media.file.path);
if (config.s3.enabled) {
@@ -731,31 +720,31 @@ async function fetchSource(source, baseMedia) {
}
async function attempt(attempts = 1) {
const hasher = new blake2.Hash('blake2b', { digestLength: 24 });
let hasherReady = true;
hasher.setEncoding('hex');
const tempFilePath = path.join(config.media.path, 'temp', `${baseMedia.id}`);
let tempFileTarget;
const hasher = blake2.createHash('blake2b', { digestLength: 24 });
let size = 0;
const hashStream = new stream.Transform({
transform(streamChunk, _encoding, callback) {
size += streamChunk.length;
hasher.update(streamChunk);
this.push(streamChunk);
callback();
},
});
try {
const tempFilePath = path.join(config.media.path, 'temp', `${baseMedia.id}`);
const tempFileTarget = fs.createWriteStream(tempFilePath);
const hashStream = new stream.PassThrough();
let size = 0;
hashStream.on('data', (streamChunk) => {
size += streamChunk.length;
if (hasherReady) {
hasher.write(streamChunk);
}
});
tempFileTarget = fs.createWriteStream(tempFilePath);
const { mimetype } = source.stream
? await streamQueue.push('fetchStreamSource', { source, tempFileTarget, hashStream })
: await fetchHttpSource(source, tempFileTarget, hashStream);
hasher.end();
const hash = hasher.digest('hex');
const hash = hasher.read();
const [type, subtype] = mimetype.split('/');
const extension = mime.getExtension(mimetype);
@@ -778,8 +767,10 @@ async function fetchSource(source, baseMedia) {
},
};
} catch (error) {
hasherReady = false;
hasher.end();
// hasherReady = false;
// hasher.end();
hashStream.destroy();
tempFileTarget?.destroy();
if (error.code !== 'VERIFY_TYPE') {
logger.warn(`Failed attempt ${attempts}/${maxAttempts} to fetch ${source.src}: ${error.message}`);

View File

@@ -6,6 +6,10 @@ const unprint = require('unprint');
const knex = require('./knex');
async function syncWeb(domain, ids) {
if (!ids || ids.length === 0) {
return;
}
await knex('sync').insert({ domain, item_ids: ids });
if (config.webApi.enabled) {
@@ -31,7 +35,14 @@ async function updateMovieSearch(releaseIds) {
await syncWeb('movie', releaseIds);
}
async function updateActorSearch(actorIds) {
await knex.raw('REFRESH MATERIALIZED VIEW actors_meta;');
await syncWeb('actor', actorIds);
}
module.exports = {
updateSceneSearch,
updateMovieSearch,
updateActorSearch,
};