102 lines
4.1 KiB
Python
Executable File
102 lines
4.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
TikTok Database Adapter for Unified Database
|
|
Provides compatibility layer between TikTok module and unified database
|
|
"""
|
|
|
|
from typing import Optional, Dict
|
|
from datetime import datetime
|
|
import json
|
|
|
|
class TikTokDatabaseAdapter:
|
|
"""Adapter to make unified database work with TikTok module"""
|
|
|
|
def __init__(self, unified_db):
|
|
"""Initialize adapter with unified database instance"""
|
|
self.unified_db = unified_db
|
|
self.platform = 'tiktok'
|
|
|
|
def get_file_hash(self, file_path: str) -> Optional[str]:
|
|
"""Calculate SHA256 hash of a file (delegates to UnifiedDatabase)"""
|
|
return self.unified_db.get_file_hash(file_path)
|
|
|
|
def get_download_by_file_hash(self, file_hash: str) -> Optional[Dict]:
|
|
"""Get download record by file hash (delegates to UnifiedDatabase)"""
|
|
return self.unified_db.get_download_by_file_hash(file_hash)
|
|
|
|
def record_download(self, video_id: str, username: str, filename: str,
|
|
post_date: Optional[datetime] = None, metadata: Dict = None,
|
|
file_path: str = None):
|
|
"""Record a TikTok download in the unified database"""
|
|
# Convert TikTok's video_id to a URL format for unified database
|
|
# For carousel photos, append filename to make URL unique (otherwise url_hash collision)
|
|
url = f"https://www.tiktok.com/@{username}/video/{video_id}#{filename}"
|
|
|
|
# Calculate file hash if file_path provided
|
|
file_hash = None
|
|
if file_path:
|
|
try:
|
|
from pathlib import Path
|
|
if Path(file_path).exists():
|
|
file_hash = self.unified_db.get_file_hash(file_path)
|
|
except Exception:
|
|
pass # If hash fails, continue without it
|
|
|
|
# Detect content type from file extension
|
|
from pathlib import Path
|
|
ext = Path(filename).suffix.lower()
|
|
image_exts = {'.jpg', '.jpeg', '.png', '.gif', '.heic', '.heif', '.webp', '.bmp', '.tiff'}
|
|
content_type = 'image' if ext in image_exts else 'video'
|
|
|
|
return self.unified_db.record_download(
|
|
url=url,
|
|
platform=self.platform,
|
|
source=username,
|
|
content_type=content_type,
|
|
filename=filename,
|
|
post_date=post_date,
|
|
metadata=metadata,
|
|
file_hash=file_hash,
|
|
file_path=file_path
|
|
)
|
|
|
|
def is_downloaded(self, video_id: str, username: str = None) -> bool:
|
|
"""Check if a video has been downloaded"""
|
|
# Check if ANY file from this video_id has been downloaded
|
|
# (For carousels, URLs include #filename so we need to search by video_id pattern)
|
|
try:
|
|
import sqlite3
|
|
with self.unified_db.get_connection() as conn:
|
|
cursor = conn.cursor()
|
|
# Search for URLs containing this video_id
|
|
if username:
|
|
url_pattern = f"https://www.tiktok.com/@{username}/video/{video_id}%"
|
|
else:
|
|
url_pattern = f"%/video/{video_id}%"
|
|
|
|
cursor.execute(
|
|
"SELECT 1 FROM downloads WHERE url LIKE ? AND platform = ? LIMIT 1",
|
|
(url_pattern, self.platform)
|
|
)
|
|
return cursor.fetchone() is not None
|
|
except Exception:
|
|
return False
|
|
|
|
def is_already_downloaded(self, video_id: str) -> bool:
|
|
"""Check if a video has already been downloaded (alias for compatibility)"""
|
|
return self.is_downloaded(video_id)
|
|
|
|
def get_download_info(self, video_id: str) -> Optional[Dict]:
|
|
"""Get download information for a video"""
|
|
# This is a simplified lookup - may need to search by video_id in URL
|
|
results = self.unified_db.get_downloads(platform=self.platform, limit=1000)
|
|
|
|
for download in results:
|
|
if video_id in download.get('url', ''):
|
|
return download
|
|
|
|
return None
|
|
|
|
def cleanup_old_downloads(self, days: int = 180):
|
|
"""Clean up old download records"""
|
|
return self.unified_db.cleanup_old_downloads(days=days, platform=self.platform) |