Showing non-showcased batches in latest and upcoming, only meant to be excluded from new.

This commit is contained in:
2026-11-13 22:56:51 +01:00
parent 121d31d325
commit 3645c2a0e6
9 changed files with 37 additions and 10 deletions
+4 -1
View File
@@ -4,6 +4,7 @@ import { curateScenesQuery } from '#/src/web/scenes.js';
export async function onBeforeRender(pageContext) { export async function onBeforeRender(pageContext) {
const withQuery = Object.hasOwn(pageContext.urlParsed.search, 'q'); const withQuery = Object.hasOwn(pageContext.urlParsed.search, 'q');
const scope = pageContext.routeParams.scope || 'latest';
const [ const [
sceneResults, sceneResults,
@@ -11,8 +12,10 @@ export async function onBeforeRender(pageContext) {
] = await Promise.all([ ] = await Promise.all([
fetchScenes(await curateScenesQuery({ fetchScenes(await curateScenesQuery({
...pageContext.urlQuery, ...pageContext.urlQuery,
scope: pageContext.routeParams.scope || 'latest', scope,
isShowcased: withQuery ? null : true, isShowcased: withQuery ? null : true,
// New sorts by scrape date, so large scrape batches would drown it out, they still show up in Latest and Upcoming
isBatchShowcased: !withQuery && scope === 'new' ? true : null,
tagFilter: pageContext.tagFilter, tagFilter: pageContext.tagFilter,
}), { }), {
page: Number(pageContext.routeParams.page) || 1, page: Number(pageContext.routeParams.page) || 1,
+4
View File
@@ -639,6 +639,10 @@ async function queryManticoreSql(filters, options, _reqUser) {
builder.where('scenes.is_showcased', filters.isShowcased); builder.where('scenes.is_showcased', filters.isShowcased);
} }
if (typeof filters.isBatchShowcased === 'boolean') {
builder.where('scenes.is_batch_showcased', filters.isBatchShowcased);
}
if (options.dedupe) { if (options.dedupe) {
builder.where('scenes.dupe_index', '<', 2); builder.where('scenes.dupe_index', '<', 2);
} }
+3 -1
View File
@@ -128,8 +128,9 @@ export async function syncManticoreScenes(sceneIds) {
studios.showcased IS NOT false studios.showcased IS NOT false
AND (entities.showcased IS NOT false OR COALESCE(studios.showcased, false) = true) AND (entities.showcased IS NOT false OR COALESCE(studios.showcased, false) = true)
AND (parents.showcased IS NOT false OR COALESCE(entities.showcased, false) = true OR COALESCE(studios.showcased, false) = true) AND (parents.showcased IS NOT false OR COALESCE(entities.showcased, false) = true OR COALESCE(studios.showcased, false) = true)
AND (releases_summaries.batch_showcased IS NOT false)
AS showcased, AS showcased,
-- kept separate from the channel showcasing, a batch only hides large scrapes from New, not from Latest and Upcoming
releases_summaries.batch_showcased IS NOT false AS batch_showcased,
row_number() OVER (PARTITION BY releases.entry_id, parents.id ORDER BY releases.effective_date DESC) as dupe_index row_number() OVER (PARTITION BY releases.entry_id, parents.id ORDER BY releases.effective_date DESC) as dupe_index
FROM releases FROM releases
LEFT JOIN releases_summaries ON releases_summaries.release_id = releases.id LEFT JOIN releases_summaries ON releases_summaries.release_id = releases.id
@@ -232,6 +233,7 @@ export async function syncManticoreScenes(sceneIds) {
created_at: Math.round(scene.created_at.getTime() / 1000), created_at: Math.round(scene.created_at.getTime() / 1000),
effective_date: Math.round((scene.date || scene.created_at).getTime() / 1000), effective_date: Math.round((scene.date || scene.created_at).getTime() / 1000),
is_showcased: scene.showcased, is_showcased: scene.showcased,
is_batch_showcased: scene.batch_showcased,
shoot_id: scene.shoot_id || undefined, shoot_id: scene.shoot_id || undefined,
channel_id: scene.channel_id, channel_id: scene.channel_id,
channel_slug: scene.channel_slug, channel_slug: scene.channel_slug,
+1
View File
@@ -57,6 +57,7 @@ export async function curateScenesQuery(query) {
serieId: Number(query.serieId) || null, serieId: Number(query.serieId) || null,
stashId: Number(query.stashId) || null, stashId: Number(query.stashId) || null,
isShowcased: typeof query.isShowcased === 'boolean' ? query.isShowcased : null, isShowcased: typeof query.isShowcased === 'boolean' ? query.isShowcased : null,
isBatchShowcased: typeof query.isBatchShowcased === 'boolean' ? query.isBatchShowcased : null,
}; };
} }
+2 -2
View File
@@ -2,7 +2,7 @@ import argv from '../src/argv.js';
import { utilsApi } from '../src/manticore.js'; import { utilsApi } from '../src/manticore.js';
import { syncManticoreActors } from '../src/sync.js'; import { syncManticoreActors } from '../src/sync.js';
import runTool from './run-tool.js'; import runTool, { isMain } from './run-tool.js';
export async function rebuildActors() { export async function rebuildActors() {
await utilsApi.sql('drop table if exists actors'); await utilsApi.sql('drop table if exists actors');
@@ -33,7 +33,7 @@ export async function rebuildActors() {
await syncManticoreActors(); await syncManticoreActors();
} }
if (import.meta.main) { if (isMain(import.meta.url)) {
runTool(async () => { runTool(async () => {
if (argv.update) { if (argv.update) {
await rebuildActors(); await rebuildActors();
+2 -2
View File
@@ -1,7 +1,7 @@
import argv from '../src/argv.js'; import argv from '../src/argv.js';
import { utilsApi } from '../src/manticore.js'; import { utilsApi } from '../src/manticore.js';
import { syncManticoreMovies } from '../src/sync.js'; import { syncManticoreMovies } from '../src/sync.js';
import runTool from './run-tool.js'; import runTool, { isMain } from './run-tool.js';
export async function rebuildMovies() { export async function rebuildMovies() {
await utilsApi.sql('drop table if exists movies'); await utilsApi.sql('drop table if exists movies');
@@ -37,7 +37,7 @@ export async function rebuildMovies() {
await syncManticoreMovies(); await syncManticoreMovies();
} }
if (import.meta.main) { if (isMain(import.meta.url)) {
runTool(async () => { runTool(async () => {
if (argv.update) { if (argv.update) {
await rebuildMovies(); await rebuildMovies();
+3 -2
View File
@@ -1,7 +1,7 @@
import argv from '../src/argv.js'; import argv from '../src/argv.js';
import { utilsApi } from '../src/manticore.js'; import { utilsApi } from '../src/manticore.js';
import { syncManticoreScenes } from '../src/sync.js'; import { syncManticoreScenes } from '../src/sync.js';
import runTool from './run-tool.js'; import runTool, { isMain } from './run-tool.js';
export async function rebuildScenes() { export async function rebuildScenes() {
await utilsApi.sql('drop table if exists scenes'); await utilsApi.sql('drop table if exists scenes');
@@ -40,6 +40,7 @@ export async function rebuildScenes() {
date bigint, date bigint,
fingerprints text, fingerprints text,
is_showcased bool, is_showcased bool,
is_batch_showcased bool,
created_at bigint, created_at bigint,
effective_date bigint, effective_date bigint,
stashed int, stashed int,
@@ -62,7 +63,7 @@ export async function rebuildScenes() {
await syncManticoreScenes(); await syncManticoreScenes();
} }
if (import.meta.main) { if (isMain(import.meta.url)) {
runTool(async () => { runTool(async () => {
if (argv.update) { if (argv.update) {
await rebuildScenes(); await rebuildScenes();
+2 -2
View File
@@ -1,6 +1,6 @@
import { utilsApi } from '../src/manticore.js'; import { utilsApi } from '../src/manticore.js';
import { syncStashes } from '../src/sync.js'; import { syncStashes } from '../src/sync.js';
import runTool from './run-tool.js'; import runTool, { isMain } from './run-tool.js';
export async function rebuildStashes() { export async function rebuildStashes() {
await utilsApi.sql('drop table if exists scenes_stashed'); await utilsApi.sql('drop table if exists scenes_stashed');
@@ -37,6 +37,6 @@ export async function rebuildStashes() {
await syncStashes('movie'); await syncStashes('movie');
} }
if (import.meta.main) { if (isMain(import.meta.url)) {
runTool(rebuildStashes); runTool(rebuildStashes);
} }
+16
View File
@@ -1,8 +1,24 @@
import { realpathSync } from 'node:fs';
import process from 'node:process'; import process from 'node:process';
import { fileURLToPath } from 'node:url';
import { knexOwner as knex } from '../src/knex.js'; import { knexOwner as knex } from '../src/knex.js';
import redis from '../src/redis.js'; import redis from '../src/redis.js';
// whether the module was run directly rather than imported, a stand-in for import.meta.main, which needs node 24.2 or 22.18
export function isMain(moduleUrl) {
if (!process.argv[1]) {
return false;
}
try {
return realpathSync(process.argv[1]) === realpathSync(fileURLToPath(moduleUrl));
}
catch (_error) {
return false;
}
}
// runs a command line tool and closes the connections afterwards, the knex pool and redis would otherwise keep the process alive // runs a command line tool and closes the connections afterwards, the knex pool and redis would otherwise keep the process alive
export default async function runTool(tool) { export default async function runTool(tool) {
try { try {