Filter out male performers across Stash matching, AI prompts, candidate buttons and Intellisense

This commit is contained in:
david
2026-08-17 09:42:59 -04:00
parent 94872f5ae8
commit d51cfe12d8
2 changed files with 55 additions and 40 deletions
+20 -18
View File
@@ -2658,17 +2658,17 @@
fileNames = torrent.innerFiles.map(f => f.name).slice(0, 15); fileNames = torrent.innerFiles.map(f => f.name).slice(0, 15);
} }
const prompt = `Analyze the following adult video torrent title and internal files to identify ALL performers / actors. const prompt = `Analyze the following adult video torrent title and internal files to identify ALL FEMALE performers / actresses.
Torrent Name: "${torrent.name}" Torrent Name: "${torrent.name}"
Internal Files: ${JSON.stringify(fileNames)} Internal Files: ${JSON.stringify(fileNames)}
CRITICAL INSTRUCTIONS: CRITICAL INSTRUCTIONS:
1. Extract EVERY distinct performer / actor mentioned. 1. Extract ONLY distinct FEMALE performers / actresses mentioned. Completely OMIT and ignore all male performers, male actors, and directors.
2. If multiple performers appear (e.g. "Alison Rey Reagan Foxx" or "Kendra Lust and Lisa Ann"), you MUST return EACH individual person as a separate entry in the "all_performers" array: ["Alison Rey", "Reagan Foxx"]. 2. If multiple female performers appear (e.g. "Alison Rey Reagan Foxx" or "Kendra Lust and Lisa Ann"), you MUST return EACH individual female as a separate entry in "all_performers": ["Alison Rey", "Reagan Foxx"].
3. NEVER combine multiple performers into one 4-word name (e.g. NEVER output "Alison Rey Reagan Foxx" as a single name). 3. NEVER combine multiple performers into one 4-word name (e.g. NEVER output "Alison Rey Reagan Foxx" as a single name).
4. Ignore studio names (Brazzers, NaughtyAmerica, Blacked, Vixen, Tushy, PureTaboo, RealityKings, BangBros, TeamSkeet, EvilAngel, MissaX, etc.), resolutions, release groups, and codecs. 4. Ignore studio names (Brazzers, NaughtyAmerica, Blacked, Vixen, Tushy, PureTaboo, RealityKings, BangBros, TeamSkeet, EvilAngel, MissaX, etc.), resolutions, release groups, and codecs.
5. List all detected performers in "all_performers", pick the primary performer in "primary_performer", assign confidence ('high'|'medium'|'low'), and short reasoning. 5. List all detected female performers in "all_performers", pick the primary performer in "primary_performer", assign confidence ('high'|'medium'|'low'), and short reasoning.
Return ONLY valid JSON matching this schema: Return ONLY valid JSON matching this schema:
{ {
@@ -2719,15 +2719,16 @@ Return ONLY valid JSON matching this schema:
return `[Item ${idx + 1}] ID: "${t.hash}"\nName: "${t.name}"\nFiles: ${JSON.stringify(fileNames)}`; return `[Item ${idx + 1}] ID: "${t.hash}"\nName: "${t.name}"\nFiles: ${JSON.stringify(fileNames)}`;
}).join('\n\n'); }).join('\n\n');
const prompt = `Analyze the following ${batchTorrents.length} adult video torrents and identify ALL performers / actors for EACH item. const prompt = `Analyze the following ${batchTorrents.length} adult video torrents and identify ALL FEMALE performers / actresses for EACH item.
${itemsListStr} ${itemsListStr}
CRITICAL INSTRUCTIONS: CRITICAL INSTRUCTIONS:
1. For each item, extract EVERY distinct performer / actor name. If multiple performers appear (e.g. "Alison Rey Reagan Foxx", "Kendra Lust and Lisa Ann"), list EACH person separately in "all_performers": ["Alison Rey", "Reagan Foxx"]. 1. For each item, extract ONLY distinct FEMALE performers / actresses. Completely OMIT and ignore all male performers, male actors, and directors.
2. NEVER combine two performers into a single 4-word string (e.g. NEVER output "Alison Rey Reagan Foxx"). 2. If multiple female performers appear (e.g. "Alison Rey Reagan Foxx", "Kendra Lust and Lisa Ann"), list EACH female person separately in "all_performers": ["Alison Rey", "Reagan Foxx"].
3. Ignore studio names (Brazzers, NaughtyAmerica, Blacked, Vixen, Tushy, PureTaboo, RealityKings, BangBros, TeamSkeet, EvilAngel, MissaX, etc.), scene numbers, resolutions, and codecs. 3. NEVER combine two performers into a single 4-word string (e.g. NEVER output "Alison Rey Reagan Foxx").
4. List all detected performers in "all_performers", pick the primary performer in "primary_performer", assign confidence ('high'|'medium'|'low'), and short reasoning. 4. Ignore studio names (Brazzers, NaughtyAmerica, Blacked, Vixen, Tushy, PureTaboo, RealityKings, BangBros, TeamSkeet, EvilAngel, MissaX, etc.), scene numbers, resolutions, and codecs.
5. List all detected female performers in "all_performers", pick the primary performer in "primary_performer", assign confidence ('high'|'medium'|'low'), and short reasoning.
Return ONLY valid JSON matching: Return ONLY valid JSON matching:
{ {
@@ -3346,16 +3347,16 @@ Return ONLY valid JSON matching:
async function analyzeSmbFileWithAI(fileItem) { async function analyzeSmbFileWithAI(fileItem) {
const destRoot = (smbDestRootInput ? smbDestRootInput.value.trim() : '/mnt/isolation/videos').replace(/\/+$/, '') || '/mnt/isolation/videos'; const destRoot = (smbDestRootInput ? smbDestRootInput.value.trim() : '/mnt/isolation/videos').replace(/\/+$/, '') || '/mnt/isolation/videos';
const prompt = `Analyze the following adult video filename to identify ALL performers / actors. const prompt = `Analyze the following adult video filename to identify ALL FEMALE performers / actresses.
Filename: "${fileItem.name}" Filename: "${fileItem.name}"
CRITICAL INSTRUCTIONS: CRITICAL INSTRUCTIONS:
1. Extract EVERY distinct video performer / actor mentioned. 1. Extract ONLY distinct FEMALE video performers / actresses mentioned. Completely OMIT and ignore all male performers, male actors, and directors.
2. If multiple performers appear (e.g. "Alison Rey Reagan Foxx" or "Kendra Lust and Lisa Ann"), you MUST return EACH individual person as a separate entry in the "all_performers" array: ["Alison Rey", "Reagan Foxx"]. 2. If multiple female performers appear (e.g. "Alison Rey Reagan Foxx" or "Kendra Lust and Lisa Ann"), you MUST return EACH individual female as a separate entry in "all_performers": ["Alison Rey", "Reagan Foxx"].
3. NEVER combine multiple performers into one 4-word name (e.g. NEVER output "Alison Rey Reagan Foxx" as a single name). 3. NEVER combine multiple performers into one 4-word name (e.g. NEVER output "Alison Rey Reagan Foxx" as a single name).
4. Ignore studio names (Brazzers, NaughtyAmerica, Blacked, Vixen, Tushy, PureTaboo, RealityKings, BangBros, TeamSkeet, EvilAngel, MissaX, Family Roleplay, Spy Fam, etc.), resolutions, release groups, and codecs. 4. Ignore studio names (Brazzers, NaughtyAmerica, Blacked, Vixen, Tushy, PureTaboo, RealityKings, BangBros, TeamSkeet, EvilAngel, MissaX, Family Roleplay, Spy Fam, etc.), resolutions, release groups, and codecs.
5. List all detected performers in "all_performers", pick the primary performer in "primary_performer", assign confidence ('high'|'medium'|'low'), and short reasoning. 5. List all detected female performers in "all_performers", pick the primary performer in "primary_performer", assign confidence ('high'|'medium'|'low'), and short reasoning.
Return ONLY valid JSON matching this schema: Return ONLY valid JSON matching this schema:
{ {
@@ -3400,15 +3401,16 @@ Return ONLY valid JSON matching this schema:
return `[Item ${idx + 1}] ID: "${f.path}"\nFilename: "${f.name}"`; return `[Item ${idx + 1}] ID: "${f.path}"\nFilename: "${f.name}"`;
}).join('\n\n'); }).join('\n\n');
const prompt = `Analyze the following ${batchFiles.length} adult video filenames and identify ALL performers / actors for EACH item. const prompt = `Analyze the following ${batchFiles.length} adult video filenames and identify ALL FEMALE performers / actresses for EACH item.
${itemsListStr} ${itemsListStr}
CRITICAL INSTRUCTIONS: CRITICAL INSTRUCTIONS:
1. For each item, extract EVERY distinct performer / actor name. If multiple performers appear (e.g. "Alison Rey Reagan Foxx", "Kendra Lust and Lisa Ann"), list EACH person separately in "all_performers": ["Alison Rey", "Reagan Foxx"]. 1. For each item, extract ONLY distinct FEMALE performers / actresses. Completely OMIT and ignore all male performers, male actors, and directors.
2. NEVER combine two performers into a single 4-word string (e.g. NEVER output "Alison Rey Reagan Foxx"). 2. If multiple female performers appear (e.g. "Alison Rey Reagan Foxx", "Kendra Lust and Lisa Ann"), list EACH female person separately in "all_performers": ["Alison Rey", "Reagan Foxx"].
3. Ignore studio names (Brazzers, NaughtyAmerica, Blacked, Vixen, Tushy, PureTaboo, RealityKings, BangBros, TeamSkeet, EvilAngel, MissaX, Family Roleplay, Spy Fam, etc.), scene numbers, resolutions, and codecs. 3. NEVER combine two performers into a single 4-word string (e.g. NEVER output "Alison Rey Reagan Foxx").
4. List all detected performers in "all_performers", pick the primary performer in "primary_performer", assign confidence ('high'|'medium'|'low'), and short reasoning. 4. Ignore studio names (Brazzers, NaughtyAmerica, Blacked, Vixen, Tushy, PureTaboo, RealityKings, BangBros, TeamSkeet, EvilAngel, MissaX, Family Roleplay, Spy Fam, etc.), scene numbers, resolutions, and codecs.
5. List all detected female performers in "all_performers", pick the primary performer in "primary_performer", assign confidence ('high'|'medium'|'low'), and short reasoning.
Return ONLY a valid JSON object with an array named "results": Return ONLY a valid JSON object with an array named "results":
{ {
+35 -22
View File
@@ -180,22 +180,26 @@ def parse_stash_scene_data(scene, match_strategy='exact_path'):
if not performers: if not performers:
return None return None
females = [p['name'] for p in performers if p.get('gender') == 'FEMALE'] females = [p for p in performers if p.get('gender') == 'FEMALE']
males = [p['name'] for p in performers if p.get('gender') == 'MALE'] non_males = [p for p in performers if p.get('gender') not in ('FEMALE', 'MALE')]
others = [p['name'] for p in performers if p.get('gender') not in ('FEMALE', 'MALE')]
# Priority: Females first as primary, then others, then males # Priority: NEVER include male performers if any female or non-male performers are present
ordered_names = females + others + males eligible_performers = females if females else (non_males if non_males else performers)
if not ordered_names:
ordered_names = [p['name'] for p in performers]
formatted_candidates = [] formatted_candidates = []
seen = set() seen = set()
for name in ordered_names: for p in eligible_performers:
name = p.get('name', '')
fmt = format_performer_slug(name) fmt = format_performer_slug(name)
if fmt and fmt not in seen: if fmt and fmt not in seen:
seen.add(fmt) seen.add(fmt)
formatted_candidates.append({'raw': name, 'formatted': fmt}) formatted_candidates.append({
'raw': name,
'formatted': fmt,
'id': p.get('id'),
'gender': p.get('gender'),
'image': p.get('image_path')
})
if not formatted_candidates: if not formatted_candidates:
return None return None
@@ -217,8 +221,8 @@ def parse_stash_scene_data(scene, match_strategy='exact_path'):
'studio': studio_name, 'studio': studio_name,
'primaryPerformer': primary_formatted, 'primaryPerformer': primary_formatted,
'allPerformers': formatted_candidates, 'allPerformers': formatted_candidates,
'femalePerformers': [format_performer_slug(n) for n in females], 'femalePerformers': [p['formatted'] for p in formatted_candidates if p.get('gender') == 'FEMALE'],
'malePerformers': [format_performer_slug(n) for n in males], 'malePerformers': [],
'confidence': 'verified', 'confidence': 'verified',
'reasoning': reasoning, 'reasoning': reasoning,
'matchStrategy': match_strategy 'matchStrategy': match_strategy
@@ -781,11 +785,11 @@ class RobustProxyHandler(http.server.SimpleHTTPRequestHandler):
except Exception as e: except Exception as e:
print(f"Error merging performers from DB: {e}") print(f"Error merging performers from DB: {e}")
# Also merge performers from Stash database if online # Also merge female performers from Stash database if online
try: try:
stash_q = '{ allPerformers { name } }' stash_q = '{ findPerformers(performer_filter: { gender: { value: FEMALE, modifier: EQUALS } }, filter: { per_page: -1 }) { performers { name } } }'
res = execute_stash_graphql(stash_q, timeout=2) res = execute_stash_graphql(stash_q, timeout=3)
for p in res.get('data', {}).get('allPerformers', []): for p in res.get('data', {}).get('findPerformers', {}).get('performers', []):
slug = format_performer_slug(p.get('name')) slug = format_performer_slug(p.get('name'))
if slug: if slug:
performers_set.add(slug) performers_set.add(slug)
@@ -807,13 +811,22 @@ class RobustProxyHandler(http.server.SimpleHTTPRequestHandler):
p_id = params.get('id', [''])[0] p_id = params.get('id', [''])[0]
stash_url = params.get('url', [''])[0] stash_url = params.get('url', [''])[0]
content_type, img_bytes = fetch_performer_image_data(name, p_id, stash_url) try:
self.send_response(200) content_type, img_bytes = fetch_performer_image_data(name, p_id, stash_url)
self.send_header('Content-Type', content_type) self.send_response(200)
self.send_header('Cache-Control', 'public, max-age=86400') self.send_header('Content-Type', content_type)
self.send_cors_headers() self.send_header('Cache-Control', 'public, max-age=86400')
self.end_headers() self.send_cors_headers()
self.wfile.write(img_bytes) self.end_headers()
self.wfile.write(img_bytes)
except (BrokenPipeError, ConnectionResetError):
pass
except Exception as e:
try:
self.send_response(500)
self.end_headers()
except Exception:
pass
# ==================== Stash Server API Handlers ==================== # ==================== Stash Server API Handlers ====================
def handle_stash_status(self): def handle_stash_status(self):