89 lines
3.2 KiB
Python
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"
|