103 lines
3.2 KiB
Python
103 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Regenerate all thumbnails for Fansly attachments."""
|
|
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
import io
|
|
from pathlib import Path
|
|
from PIL import Image
|
|
|
|
# Bootstrap PostgreSQL adapter before any sqlite3 imports
|
|
sys.path.insert(0, '/opt/media-downloader')
|
|
from modules.db_bootstrap import bootstrap_database
|
|
bootstrap_database()
|
|
import sqlite3
|
|
|
|
# Database path (routed to PostgreSQL via pgadapter)
|
|
DB_PATH = '/opt/media-downloader/database/media_downloader.db'
|
|
THUMB_CACHE = Path('/opt/media-downloader/cache/thumbnails/large')
|
|
MAX_SIZE = (800, 800)
|
|
|
|
|
|
def generate_thumbnail(file_path, file_type):
|
|
"""Generate thumbnail for image or video."""
|
|
try:
|
|
if file_type == 'image':
|
|
with Image.open(file_path) as img:
|
|
img.thumbnail(MAX_SIZE, Image.LANCZOS)
|
|
if img.mode in ('RGBA', 'P'):
|
|
img = img.convert('RGB')
|
|
buffer = io.BytesIO()
|
|
img.save(buffer, format='JPEG', quality=85)
|
|
return buffer.getvalue()
|
|
|
|
elif file_type == 'video':
|
|
cmd = [
|
|
'ffmpeg', '-y', '-ss', '1', '-i', str(file_path),
|
|
'-vframes', '1', '-f', 'image2pipe', '-vcodec', 'mjpeg', '-'
|
|
]
|
|
result = subprocess.run(cmd, capture_output=True, timeout=30)
|
|
if result.returncode == 0 and result.stdout:
|
|
with Image.open(io.BytesIO(result.stdout)) as img:
|
|
img.thumbnail(MAX_SIZE, Image.LANCZOS)
|
|
if img.mode in ('RGBA', 'P'):
|
|
img = img.convert('RGB')
|
|
buffer = io.BytesIO()
|
|
img.save(buffer, format='JPEG', quality=85)
|
|
return buffer.getvalue()
|
|
except Exception as e:
|
|
print(f" Error: {e}")
|
|
return None
|
|
|
|
|
|
def main():
|
|
THUMB_CACHE.mkdir(parents=True, exist_ok=True)
|
|
|
|
conn = sqlite3.connect(DB_PATH)
|
|
cursor = conn.execute("""
|
|
SELECT a.id, a.local_path, a.file_type
|
|
FROM paid_content_attachments a
|
|
JOIN paid_content_posts p ON a.post_id = p.id
|
|
JOIN paid_content_creators c ON p.creator_id = c.id
|
|
WHERE c.service_id = 'fansly_direct'
|
|
AND a.status = 'completed'
|
|
AND a.local_path IS NOT NULL
|
|
ORDER BY a.id
|
|
""")
|
|
attachments = cursor.fetchall()
|
|
conn.close()
|
|
|
|
print(f"Regenerating thumbnails for {len(attachments)} files...")
|
|
|
|
generated = 0
|
|
failed = 0
|
|
missing = 0
|
|
|
|
for i, (att_id, local_path, file_type) in enumerate(attachments):
|
|
if i % 100 == 0:
|
|
print(f"Progress: {i}/{len(attachments)} (generated: {generated}, failed: {failed})")
|
|
|
|
file_path = Path(local_path)
|
|
if not file_path.exists():
|
|
missing += 1
|
|
continue
|
|
|
|
thumb_data = generate_thumbnail(file_path, file_type)
|
|
if thumb_data:
|
|
thumb_file = THUMB_CACHE / f"{att_id}.jpg"
|
|
thumb_file.write_bytes(thumb_data)
|
|
generated += 1
|
|
else:
|
|
failed += 1
|
|
print(f" Failed: {att_id} - {local_path}")
|
|
|
|
print(f"\nDone!")
|
|
print(f" Generated: {generated}")
|
|
print(f" Failed: {failed}")
|
|
print(f" Missing files: {missing}")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|