Origin/hoster filter w /scenes + Filter modal
Dotąd nie dało się docelować sceny konkretnego hostera — search faworyzuje xnxx/xvideos (dominują bazę), brak filtra po źródle. Diagnostyka per-hoster (test cookie-fix, luluvid, porntrex) wymagała trafienia sceny danego tube'a. - /scenes?origin=<substr> — exists() na PlaybackSource.origin ilike, np. 'hqporner' łapie tube:hqpornercom - ScenesFilterModal: sekcja "Source / hoster" (TextInput) w FilterState.origin - ScenesScreen: filter.origin → listScenes; liczone do activeCount Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
28273eda02
commit
b6e3b1cbb5
5 changed files with 38 additions and 1 deletions
|
|
@ -83,6 +83,13 @@ def list_scenes(
|
|||
"po PlaybackSource.quality (string typu '720p' / '1080p Full HD')."
|
||||
),
|
||||
),
|
||||
origin: str | None = Query(
|
||||
default=None,
|
||||
description=(
|
||||
"Filtruj po playback origin (np. 'tube:hqpornercom'). Substring match — "
|
||||
"'hqporner' złapie tube:hqpornercom. Diagnostyka per-hoster."
|
||||
),
|
||||
),
|
||||
include_stubs: bool = Query(
|
||||
default=False,
|
||||
description=(
|
||||
|
|
@ -164,6 +171,18 @@ def list_scenes(
|
|||
)
|
||||
)
|
||||
|
||||
if origin:
|
||||
# Substring match na origin — 'hqporner' złapie 'tube:hqpornercom'.
|
||||
base = base.where(
|
||||
exists(
|
||||
select(1).where(
|
||||
PlaybackSource.scene_id == Scene.id,
|
||||
PlaybackSource.dead_at.is_(None),
|
||||
PlaybackSource.origin.ilike(f"%{origin}%"),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# Blacklisty — globalne wykluczenia. Jeśli scena ma JAKIEGOKOLWIEK blacklisted
|
||||
# performera, jest na blacklisted studio, lub ma JAKIKOLWIEK blacklisted tag → out.
|
||||
from app.models.blacklist import (
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ export class GoonClient {
|
|||
qs.set('released_within_days', String(params.released_within_days));
|
||||
if (params.min_quality_p !== undefined) qs.set('min_quality_p', String(params.min_quality_p));
|
||||
if (params.include_stubs !== undefined) qs.set('include_stubs', String(params.include_stubs));
|
||||
if (params.origin) qs.set('origin', params.origin);
|
||||
if (params.sort) qs.set('sort', params.sort);
|
||||
qs.set('page', String(params.page ?? 1));
|
||||
qs.set('per_page', String(params.per_page ?? 50));
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export interface FilterState {
|
|||
sort: ScenesSort;
|
||||
hasPlayback: boolean;
|
||||
includeStubs: boolean;
|
||||
origin: string;
|
||||
}
|
||||
|
||||
export const DEFAULT_FILTER: FilterState = {
|
||||
|
|
@ -33,6 +34,7 @@ export const DEFAULT_FILTER: FilterState = {
|
|||
sort: 'created_at',
|
||||
hasPlayback: true, // default: ukryj sceny bez playback linka (kompletność > świeżość)
|
||||
includeStubs: false, // default: ukryj 5-10min hqporner trailery bez release_date
|
||||
origin: '', // pusty = wszystkie źródła; substring match np. 'hqporner'
|
||||
};
|
||||
|
||||
const SORT_OPTIONS: { value: ScenesSort; label: string }[] = [
|
||||
|
|
@ -161,6 +163,18 @@ export function ScenesFilterModal({
|
|||
</View>
|
||||
</Section>
|
||||
|
||||
<Section title="Source / hoster">
|
||||
<TextInput
|
||||
style={styles.search}
|
||||
value={draft.origin}
|
||||
onChangeText={(v) => setDraft({ ...draft, origin: v })}
|
||||
placeholder="np. hqporner, porntrex, xnxx — puste = wszystkie"
|
||||
placeholderTextColor={theme.muted}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
/>
|
||||
</Section>
|
||||
|
||||
<Section title={`Tags (${draft.tagSlugs.length} selected)`}>
|
||||
<TextInput
|
||||
style={styles.search}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ export function ScenesScreen() {
|
|||
has_playback: filter.hasPlayback || undefined,
|
||||
sort: filter.sort,
|
||||
include_stubs: filter.includeStubs || undefined,
|
||||
origin: filter.origin.trim() || undefined,
|
||||
page: pageParam,
|
||||
per_page: PER_PAGE,
|
||||
}),
|
||||
|
|
@ -71,7 +72,8 @@ export function ScenesScreen() {
|
|||
filter.tagSlugs.length +
|
||||
filter.studioSlugs.length +
|
||||
filter.performerIds.length +
|
||||
(filter.hasPlayback ? 1 : 0);
|
||||
(filter.hasPlayback ? 1 : 0) +
|
||||
(filter.origin.trim() ? 1 : 0);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ export interface ScenesListParams {
|
|||
released_within_days?: number;
|
||||
min_quality_p?: number;
|
||||
include_stubs?: boolean;
|
||||
origin?: string;
|
||||
sort?: ScenesSort;
|
||||
page?: number;
|
||||
per_page?: number;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue