185 lines
5.9 KiB
Python
185 lines
5.9 KiB
Python
"""
|
|
Data path management utilities for the karaoke downloader.
|
|
Provides centralized data directory path management and file path resolution.
|
|
"""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
from .config_manager import get_config_manager
|
|
|
|
|
|
class DataPathManager:
|
|
"""
|
|
Manages data directory paths and provides utilities for resolving file paths
|
|
relative to the configured data directory.
|
|
"""
|
|
|
|
def __init__(self, data_dir: Optional[str] = None):
|
|
"""
|
|
Initialize the data path manager.
|
|
|
|
Args:
|
|
data_dir: Optional custom data directory path. If None, uses config.
|
|
"""
|
|
self._data_dir = data_dir
|
|
|
|
# If a custom data directory is provided, look for config.json in that directory
|
|
if data_dir:
|
|
config_file = Path(data_dir) / "config.json"
|
|
self._config_manager = get_config_manager(str(config_file))
|
|
else:
|
|
# Otherwise, use the default config.json in the root directory
|
|
self._config_manager = get_config_manager()
|
|
|
|
@property
|
|
def data_dir(self) -> Path:
|
|
"""
|
|
Get the configured data directory path.
|
|
|
|
Returns:
|
|
Path to the data directory
|
|
"""
|
|
if self._data_dir:
|
|
return Path(self._data_dir)
|
|
|
|
# Get from config
|
|
config = self._config_manager.get_config()
|
|
data_dir = getattr(config.folder_structure, 'data_dir', 'data')
|
|
return Path(data_dir)
|
|
|
|
def get_path(self, filename: str) -> Path:
|
|
"""
|
|
Get the full path to a file in the data directory.
|
|
|
|
Args:
|
|
filename: Name of the file (e.g., 'config.json', 'channels.json')
|
|
|
|
Returns:
|
|
Full path to the file
|
|
"""
|
|
return self.data_dir / filename
|
|
|
|
def get_channels_json_path(self) -> Path:
|
|
"""Get path to channels.json file."""
|
|
return self.get_path('channels.json')
|
|
|
|
def get_channels_txt_path(self) -> Path:
|
|
"""Get path to channels.txt file."""
|
|
return self.get_path('channels.txt')
|
|
|
|
def get_songlist_path(self) -> Path:
|
|
"""Get path to songList.json file."""
|
|
return self.get_path('songList.json')
|
|
|
|
def get_songlist_tracking_path(self) -> Path:
|
|
"""Get path to songlist_tracking.json file."""
|
|
return self.get_path('songlist_tracking.json')
|
|
|
|
def get_karaoke_tracking_path(self) -> Path:
|
|
"""Get path to karaoke_tracking.json file."""
|
|
return self.get_path('karaoke_tracking.json')
|
|
|
|
def get_server_duplicates_tracking_path(self) -> Path:
|
|
"""Get path to server_duplicates_tracking.json file."""
|
|
return self.get_path('server_duplicates_tracking.json')
|
|
|
|
def get_manual_videos_path(self) -> Path:
|
|
"""Get path to manual_videos.json file."""
|
|
return self.get_path('manual_videos.json')
|
|
|
|
def get_songs_path(self) -> Path:
|
|
"""Get path to songs.json file."""
|
|
return self.get_path('songs.json')
|
|
|
|
def get_channel_cache_dir(self) -> Path:
|
|
"""Get path to channel_cache directory."""
|
|
return self.get_path('channel_cache')
|
|
|
|
def get_channel_cache_path(self, channel_id: str) -> Path:
|
|
"""Get path to a specific channel cache file."""
|
|
return self.get_channel_cache_dir() / f"{channel_id}.json"
|
|
|
|
def get_download_plan_cache_path(self, plan_name: str, **kwargs) -> Path:
|
|
"""Get path to download plan cache file."""
|
|
# Create a hash from kwargs for unique cache files
|
|
import hashlib
|
|
if kwargs:
|
|
kwargs_str = str(sorted(kwargs.items()))
|
|
hash_suffix = hashlib.md5(kwargs_str.encode()).hexdigest()[:8]
|
|
plan_name = f"{plan_name}_{hash_suffix}"
|
|
return self.get_path(f"plan_latest_per_channel_{plan_name}.json")
|
|
|
|
def get_unmatched_report_path(self, timestamp: Optional[str] = None) -> Path:
|
|
"""Get path to unmatched songs report file."""
|
|
if timestamp:
|
|
return self.get_path(f"unmatched_songs_report_{timestamp}.json")
|
|
return self.get_path("unmatched_songs_report.json")
|
|
|
|
def ensure_data_dir_exists(self) -> None:
|
|
"""Ensure the data directory exists."""
|
|
self.data_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
def list_data_files(self) -> list:
|
|
"""List all files in the data directory."""
|
|
if not self.data_dir.exists():
|
|
return []
|
|
|
|
files = []
|
|
for file_path in self.data_dir.iterdir():
|
|
if file_path.is_file():
|
|
files.append(file_path.name)
|
|
return sorted(files)
|
|
|
|
def file_exists(self, filename: str) -> bool:
|
|
"""Check if a file exists in the data directory."""
|
|
return self.get_path(filename).exists()
|
|
|
|
|
|
# Global data path manager instance
|
|
_data_path_manager: Optional[DataPathManager] = None
|
|
|
|
|
|
def get_data_path_manager(data_dir: Optional[str] = None) -> DataPathManager:
|
|
"""
|
|
Get the global data path manager instance.
|
|
|
|
Args:
|
|
data_dir: Optional custom data directory path
|
|
|
|
Returns:
|
|
DataPathManager instance
|
|
"""
|
|
global _data_path_manager
|
|
if _data_path_manager is None or data_dir is not None:
|
|
_data_path_manager = DataPathManager(data_dir)
|
|
return _data_path_manager
|
|
|
|
|
|
def get_data_path(filename: str, data_dir: Optional[str] = None) -> Path:
|
|
"""
|
|
Get the full path to a file in the data directory.
|
|
|
|
Args:
|
|
filename: Name of the file
|
|
data_dir: Optional custom data directory path
|
|
|
|
Returns:
|
|
Full path to the file
|
|
"""
|
|
return get_data_path_manager(data_dir).get_path(filename)
|
|
|
|
|
|
def get_data_dir(data_dir: Optional[str] = None) -> Path:
|
|
"""
|
|
Get the configured data directory path.
|
|
|
|
Args:
|
|
data_dir: Optional custom data directory path
|
|
|
|
Returns:
|
|
Path to the data directory
|
|
"""
|
|
return get_data_path_manager(data_dir).data_dir
|