python: Select all
#!/usr/bin/env python3
"""
FileBot Wrapper - Interactive CLI for simplified FileBot operations
Simplifies the process of renaming media files and downloading subtitles.
"""
import subprocess
import sys
import glob
from pathlib import Path
class FileType:
"""Media file extensions supported by FileBot"""
VIDEO = ['.mkv', '.mp4', '.avi', '.m4v', '.mov', '.wmv', '.flv', '.mpg', '.mpeg']
SUBTITLE = ['.srt', '.sub', '.idx', '.ass', '.ssa']
def get_media_files(directory='.', file_types=None):
"""Find all media files in the current directory"""
if file_types is None:
file_types = FileType.VIDEO
files = []
for ext in file_types:
files.extend(glob.glob(f'{directory}/*{ext}'))
return files
def prompt_choice(question, choices):
"""Display a question with numbered choices and return the selected value"""
print(f"\n{question}")
for i, choice in enumerate(choices, 1):
print(f" {i}. {choice}")
while True:
try:
selection = input(f"Enter your choice (1-{len(choices)}): ").strip()
index = int(selection) - 1
if 0 <= index < len(choices):
return choices[index]
else:
print(f"Please enter a number between 1 and {len(choices)}")
except (ValueError, KeyboardInterrupt):
print("\nInvalid input. Please enter a number.")
def prompt_text(question, default=None):
"""Prompt for text input with optional default"""
if default:
prompt = f"{question} [{default}]: "
else:
prompt = f"{question}: "
response = input(prompt).strip()
return response if response else default
def build_filebot_command(operation, media_type, show_name, files_pattern='*'):
"""Build the appropriate FileBot command based on user inputs"""
command = ['filebot']
if operation == 'Get Subtitles':
command.extend(['-get-subtitles'])
db = 'TheMovieDB' if media_type == 'Movie' else 'TheTVDB'
command.extend([
'--db', db,
'--lang', 'en',
'--output', 'srt',
'--encoding', 'utf8'
])
else: # Rename
command.extend(['-rename'])
db = 'TheMovieDB' if media_type == 'Movie' else 'TheTVDB'
command.extend([
'--db', db,
'--lang', 'en'
])
# Add query parameter
command.extend(['--q', show_name])
# Expand glob pattern and add actual files
# This is needed because subprocess doesn't do shell globbing
expanded_files = glob.glob(files_pattern)
if not expanded_files:
# If no match, pass the pattern itself as fallback
command.append(files_pattern)
else:
# Add all matching files
command.extend(expanded_files)
return command
def detect_file_pattern():
"""Auto-detect the most common video file extension in current directory"""
video_files = get_media_files()
if not video_files:
return '*.mkv' # Default fallback
# Count extensions
extensions = {}
for file in video_files:
ext = Path(file).suffix
extensions[ext] = extensions.get(ext, 0) + 1
# Return most common extension pattern
most_common = max(extensions.items(), key=lambda x: x[1])
return f'*{most_common[0]}'
def main():
"""Main interactive workflow"""
print("=" * 60)
print("FileBot Wrapper - Simplified Media Management")
print("=" * 60)
# Check if FileBot is available
try:
result = subprocess.run(['filebot', '-version'],
capture_output=True,
text=True,
timeout=5)
if result.returncode != 0:
print("Warning: FileBot may not be installed or configured correctly")
except FileNotFoundError:
print("Error: FileBot is not installed or not in PATH")
print("Please install FileBot from https://www.filebot.net/")
sys.exit(1)
except subprocess.TimeoutExpired:
print("Warning: FileBot check timed out")
# Question 1: Operation type
operation = prompt_choice(
"What would you like to do?",
['Get Subtitles', 'Rename']
)
# Question 2: Media type
media_type = prompt_choice(
"What type of media?",
['TV Show', 'Movie']
)
# Question 3: Show/Movie name
show_name = prompt_text("Enter the show/movie name")
if not show_name:
print("Error: Show/movie name is required")
sys.exit(1)
# Auto-detect or confirm file pattern
detected_pattern = detect_file_pattern()
video_files = get_media_files()
if video_files:
print(f"\nFound {len(video_files)} video file(s) matching pattern: {detected_pattern}")
for f in video_files[:5]: # Show first 5
print(f" - {Path(f).name}")
if len(video_files) > 5:
print(f" ... and {len(video_files) - 5} more")
# Allow user to override pattern
file_pattern = prompt_text(
"\nFile pattern to process",
default=detected_pattern
)
# Build and display command
command = build_filebot_command(operation, media_type, show_name, file_pattern)
print("\n" + "=" * 60)
print("Generated FileBot Command:")
print("=" * 60)
print(' '.join(command))
print("=" * 60)
# Confirm execution
confirm = input("\nExecute this command? [Y/n]: ").strip().lower()
if confirm and confirm not in ['y', 'yes']:
print("Cancelled.")
sys.exit(0)
# Execute FileBot command
print("\nExecuting FileBot...\n")
try:
result = subprocess.run(command, text=True)
sys.exit(result.returncode)
except KeyboardInterrupt:
print("\n\nOperation cancelled by user")
sys.exit(130)
except Exception as e:
print(f"\nError executing FileBot: {e}")
sys.exit(1)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print("\n\nOperation cancelled by user")
sys.exit(130)