major server manager overhaul
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
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"
|
||||
Reference in New Issue
Block a user