#!/usr/bin/env python3 """ Helper script to add manual videos to the manual videos collection. """ import json import re from pathlib import Path from typing import Dict, List, Optional def extract_video_id(url: str) -> Optional[str]: """Extract video ID from YouTube URL.""" patterns = [ r'(?:youtube\.com/watch\?v=|youtu\.be/|youtube\.com/embed/)([a-zA-Z0-9_-]{11})', r'youtube\.com/watch\?.*v=([a-zA-Z0-9_-]{11})' ] for pattern in patterns: match = re.search(pattern, url) if match: return match.group(1) return None def add_manual_video(title: str, url: str, manual_file: str = "data/manual_videos.json"): """ Add a manual video to the collection. Args: title: Video title (e.g., "Artist - Song (Karaoke Version)") url: YouTube URL manual_file: Path to manual videos JSON file """ manual_path = Path(manual_file) # Load existing data or create new if manual_path.exists(): with open(manual_path, 'r', encoding='utf-8') as f: data = json.load(f) else: data = { "channel_name": "@ManualVideos", "channel_url": "manual://static", "description": "Manual collection of individual karaoke videos", "videos": [], "parsing_rules": { "format": "artist_title_separator", "separator": " - ", "artist_first": true, "title_cleanup": { "remove_suffix": { "suffixes": ["(Karaoke)", "(Karaoke Version)", "(Karaoke Version) Lyrics"] } } } } # Extract video ID video_id = extract_video_id(url) if not video_id: print(f"❌ Could not extract video ID from URL: {url}") return False # Check if video already exists existing_ids = [video.get("id") for video in data["videos"]] if video_id in existing_ids: print(f"⚠️ Video already exists: {title}") return False # Add new video new_video = { "title": title, "url": url, "id": video_id, "upload_date": "2024-01-01", # Default date "duration": 180, # Default duration "view_count": 1000 # Default view count } data["videos"].append(new_video) # Save updated data manual_path.parent.mkdir(parents=True, exist_ok=True) with open(manual_path, 'w', encoding='utf-8') as f: json.dump(data, f, indent=2, ensure_ascii=False) print(f"✅ Added video: {title}") print(f" URL: {url}") print(f" ID: {video_id}") return True def list_manual_videos(manual_file: str = "data/manual_videos.json"): """List all manual videos.""" manual_path = Path(manual_file) if not manual_path.exists(): print("❌ No manual videos file found") return with open(manual_path, 'r', encoding='utf-8') as f: data = json.load(f) print(f"📋 Manual Videos ({len(data['videos'])} videos):") print("=" * 60) for i, video in enumerate(data['videos'], 1): print(f"{i:2d}. {video['title']}") print(f" URL: {video['url']}") print(f" ID: {video['id']}") print() def remove_manual_video(video_id: str, manual_file: str = "data/manual_videos.json"): """Remove a manual video by ID.""" manual_path = Path(manual_file) if not manual_path.exists(): print("❌ No manual videos file found") return False with open(manual_path, 'r', encoding='utf-8') as f: data = json.load(f) # Find and remove video for i, video in enumerate(data['videos']): if video['id'] == video_id: removed_video = data['videos'].pop(i) with open(manual_path, 'w', encoding='utf-8') as f: json.dump(data, f, indent=2, ensure_ascii=False) print(f"✅ Removed video: {removed_video['title']}") return True print(f"❌ Video with ID '{video_id}' not found") return False def main(): """Interactive mode for adding manual videos.""" print("🎤 Manual Video Manager") print("=" * 30) print("1. Add video") print("2. List videos") print("3. Remove video") print("4. Exit") while True: choice = input("\nSelect option (1-4): ").strip() if choice == "1": title = input("Enter video title (e.g., 'Artist - Song (Karaoke Version)'): ").strip() url = input("Enter YouTube URL: ").strip() if title and url: add_manual_video(title, url) else: print("❌ Title and URL are required") elif choice == "2": list_manual_videos() elif choice == "3": video_id = input("Enter video ID to remove: ").strip() if video_id: remove_manual_video(video_id) else: print("❌ Video ID is required") elif choice == "4": print("👋 Goodbye!") break else: print("❌ Invalid option") if __name__ == "__main__": import sys if len(sys.argv) > 1: # Command line mode if sys.argv[1] == "add" and len(sys.argv) >= 4: add_manual_video(sys.argv[2], sys.argv[3]) elif sys.argv[1] == "list": list_manual_videos() elif sys.argv[1] == "remove" and len(sys.argv) >= 3: remove_manual_video(sys.argv[2]) else: print("Usage:") print(" python add_manual_video.py add 'Title' 'URL'") print(" python add_manual_video.py list") print(" python add_manual_video.py remove VIDEO_ID") else: # Interactive mode main()