Files
personal_development/ServerManagerWebApp/backend/app/stash_service.py
T
2026-01-09 19:24:41 +00:00

89 lines
3.2 KiB
Python

import sqlite3
import os
import logging
from .config import Settings
logger = logging.getLogger(__name__)
class StashService:
def __init__(self, settings: Settings):
self.settings = settings
self.db_path = settings.stash_db_path
def get_db_connection(self):
if not os.path.exists(self.db_path):
logger.warning(f"Stash database not found at {self.db_path}")
return None
return sqlite3.connect(self.db_path)
def translate_to_stash_path(self, local_path):
"""
Translates a local/SMB path to Stash internal container path.
Example: /media/videos/Girl/Scene.mp4 -> /data/Girl/Scene.mp4
"""
remote_base = self.settings.stash_remote_base.rstrip('/')
container_base = self.settings.stash_container_base.rstrip('/')
if local_path.startswith(remote_base):
return local_path.replace(remote_base, container_base, 1)
# If it doesn't start with remote_base, maybe it's already relative or formatted differently?
# Stash also uses basenames in 'files' table.
return local_path
def get_file_metadata(self, local_path):
"""
Returns (phash, oshash, scene_id, duration) from Stash DB for a given file.
"""
stash_path = self.translate_to_stash_path(local_path)
conn = self.get_db_connection()
if not conn:
return None, None, None, None
try:
cursor = conn.cursor()
cursor.execute("SELECT id FROM files WHERE path = ?", (stash_path,))
row = cursor.fetchone()
if not row:
return None, None, None, None
file_id = row[0]
# Get fingerprints
cursor.execute("SELECT type, fingerprint FROM files_fingerprints WHERE file_id = ?", (file_id,))
fingerprints = cursor.fetchall()
phash = None
oshash = None
for f_type, f_val in fingerprints:
if f_type == 'phash':
phash = hex(int(f_val) & 0xffffffffffffffff)[2:].zfill(16)
elif f_type == 'oshash':
oshash = f_val
# Get scene_id
cursor.execute("SELECT scene_id FROM scenes_files WHERE file_id = ?", (file_id,))
scene_row = cursor.fetchone()
scene_id = scene_row[0] if scene_row else None
# Get duration
cursor.execute("SELECT duration FROM video_files WHERE file_id = ?", (file_id,))
dur_row = cursor.fetchone()
duration = dur_row[0] if dur_row else None
return phash, oshash, scene_id, duration
except Exception as e:
logger.error(f"Failed to query Stash metadata for {local_path}: {e}")
return None, None, None, None
finally:
conn.close()
def get_sprite_path(self, oshash):
"""
Returns the remote SMB path for the sprite.
Example: /media/stashapp/generated/vtt/{oshash}_sprite.jpg
"""
if not oshash: return None
return f"{self.settings.stash_generated_path}/vtt/{oshash}_sprite.jpg"