#!/usr/bin/env python3 """ Start chat downloader standalone for testing without recording video. Usage: python run_chat_only.py --username vinesauce [--output path] [--max-messages N] [--timeout S] [--verbose] This script uses the project's `ConfigManager` and `FileManager` to create appropriate directories and then starts the chat downloader in a background thread. Press Ctrl+C to stop. """ import argparse import time from datetime import datetime import os from colorama import Fore, Style from modules.config import ConfigManager from modules.file_manager import FileManager from modules.utils import get_ffmpeg_executable, get_twitch_downloader_executable, detect_operating_system from modules.downloader import ContentDownloader def main(): parser = argparse.ArgumentParser(description='Run chat downloader standalone for testing') parser.add_argument('--username', '-u', required=True, help='Twitch username/channel name') parser.add_argument('--output', '-o', help='Output JSON path (optional)') parser.add_argument('--max-messages', type=int, default=None, help='Max messages to capture') parser.add_argument('--timeout', type=float, default=None, help='Timeout in seconds') parser.add_argument('--verbose', action='store_true', help='Show verbose/chat previews') parser.add_argument('--foreground', action='store_true', help='Run downloader in foreground (blocking)') parser.add_argument('--use-chat-downloader-primary', action='store_true', help='Use chat_downloader as primary method') parser.add_argument('--use-chat-downloader-fallback', dest='use_chat_downloader_fallback', action='store_true', help='Allow chat_downloader as fallback (default)') parser.add_argument('--no-chat-downloader-fallback', dest='use_chat_downloader_fallback', action='store_false', help='Disable chat_downloader fallback') args = parser.parse_args() cfg = ConfigManager() config = cfg.load_streamer_config(args.username) # Apply overrides from CLI if args.use_chat_downloader_primary: config['useChatDownloaderPrimary'] = True if args.use_chat_downloader_fallback is not None: config['useChatDownloaderFallback'] = bool(args.use_chat_downloader_fallback) # Ensure directories exist (use configured archive root path) fm = FileManager(root_path=config.get('root_path', 'archive'), username=args.username, config=config) fm.initialize_directories() # Build default output path if not provided if args.output: json_path = args.output else: ts = datetime.now().strftime('%Y%m%d_%Hh%Mm%Ss') json_path = str(fm.chat_json_path / f"CHAT_TEST_{args.username}_{ts}.json") # Initialize downloader os_type = detect_operating_system() twitch_downloader_path = get_twitch_downloader_executable(os_type) ffmpeg_path = get_ffmpeg_executable(os_type) downloader = ContentDownloader(twitch_downloader_path=twitch_downloader_path, ffmpeg_path=ffmpeg_path, config=config) print(f"{Fore.CYAN}Starting standalone chat downloader for {args.username}{Style.RESET_ALL}") print(f"Output path: {json_path}") stop_requested = {'stop': False} def shutdown_check(): return stop_requested['stop'] # Start thread thread = downloader.start_chat_downloader_thread( args.username, json_path, shutdown_check=shutdown_check, stream_monitor=None, verbose=args.verbose ) try: if args.foreground: # Run download directly in foreground print('Running in foreground; this will block until download completes or interrupted') success = downloader.download_live_chat_with_chat_downloader( args.username, json_path, max_messages=args.max_messages, timeout=args.timeout, shutdown_check=shutdown_check, stream_monitor=None, verbose=args.verbose ) print('Done, success=' + str(success)) else: # Wait for thread to finish or until interrupted while thread.is_alive(): time.sleep(0.5) except KeyboardInterrupt: print('\nKeyboard interrupt received; stopping downloader...') stop_requested['stop'] = True thread.join(timeout=5) if __name__ == '__main__': main()