code workflow - panuozzo77/StreamingCommunity GitHub Wiki

Code Workflow

This document explains the workflow of the StreamingCommunity application, focusing on what happens when a user starts the program and how the different components interact.

Program Entry Point

The main entry point for the StreamingCommunity application is the main() function in the run.py file. This function orchestrates the entire workflow of the application, from initialization to content selection and downloading.

Workflow Overview

When a user starts the StreamingCommunity application, the following sequence of events occurs:

  1. Initialization: The application initializes, displays welcome messages, and checks system information
  2. Configuration Loading: Configuration settings are loaded from the config.json file
  3. Module Loading: Available site modules are dynamically loaded
  4. Command Line Parsing: Command line arguments are parsed to override configuration settings
  5. Site Selection: The user selects a streaming site or chooses global search
  6. Content Search: The user searches for content on the selected site(s)
  7. Content Selection: The user selects specific content to download
  8. Download Process: The selected content is downloaded using the appropriate method
  9. Post-Processing: Downloaded content is processed according to configuration settings

Detailed Workflow

1. Initialization

The initialization process is handled by the initialize() function, which:

  • Displays the welcome message via start_message()
  • Retrieves system information via os_summary.get_system_summary()
  • Adjusts terminal size for Windows 7 systems
  • Checks Python version compatibility
  • Displays trending content from TMDB if enabled
  • Attempts to update the application from GitHub
def initialize():
    # Get start message
    start_message()
    
    # Get system info
    os_summary.get_system_summary()
    
    # Set terminal size for win 7
    if platform.system() == "Windows" and "7" in platform.version():
        os.system('mode 120, 40')
    
    # Check python version
    if sys.version_info < (3, 7):
        console.log("[red]Install python version > 3.7.16")
        sys.exit(0)
    
    # Trending tmbd
    if SHOW_TRENDING:
        print()
        tmdb.display_trending_films()
        tmdb.display_trending_tv_shows()
    
    # Attempting GitHub update
    try:
        git_update()
    except:
        console.log("[red]Error with loading github.")

2. Module Loading

The application dynamically loads all available site modules using the load_search_functions() function:

  1. It identifies all site modules in the StreamingCommunity/Api/Site directory
  2. It imports each module and retrieves its search function
  3. It organizes modules by their index value and categorizes them by type (anime, film, series, etc.)
  4. It excludes deprecated modules and those incompatible with Telegram bot mode if enabled
def load_search_functions():
    modules = []
    loaded_functions = {}
    
    # List of sites to exclude if TELEGRAM_BOT is active
    excluded_sites = {"cb01new", "ddlstreamitaly", "guardaserie", "ilcorsaronero", "mostraguarda"} if TELEGRAM_BOT else set()
    
    # Find api home directory
    if getattr(sys, 'frozen', False):  # PyInstaller mode
        base_path = os.path.join(sys._MEIPASS, "StreamingCommunity")
    else:
        base_path = os.path.dirname(__file__)
    
    api_dir = os.path.join(base_path, 'Api', 'Site')
    init_files = glob.glob(os.path.join(api_dir, '*', '__init__.py'))
    
    # Retrieve modules and their indices
    for init_file in init_files:
        # Get folder name as module name
        module_name = os.path.basename(os.path.dirname(init_file))
        
        # Skip if module is in the exclusion list
        if module_name in excluded_sites:
            continue
            
        # ... (module loading logic)
        
    # Sort modules by 'indice'
    modules.sort(key=lambda x: x[1])
    
    # Load search functions in the sorted order
    for module_name, _, use_for in modules:
        # ... (function loading logic)
        
    return loaded_functions

3. Command Line Parsing

The application uses argparse to parse command line arguments, which can override configuration settings:

  1. It creates an argument parser with descriptions for each option
  2. It adds arguments for configuration parameters, site selection, and search terms
  3. It parses the provided arguments
  4. It applies any configuration updates based on the arguments
# Create argument parser
parser = argparse.ArgumentParser(
    description='Script to download movies and series from the internet. Use these commands to configure the script and control its behavior.'
)

# Add arguments for the main configuration parameters
parser.add_argument(
    '--add_siteName', type=bool, help='Enable or disable adding the site name to the file name (e.g., true/false).'
)
# ... (more arguments)

# Parse command-line arguments
args = parser.parse_args()

# Map command-line arguments to the config values
config_updates = {}
if args.add_siteName is not None:
    config_updates['DEFAULT.add_siteName'] = args.add_siteName
# ... (more config updates)

# Apply the updates to the config file
for key, value in config_updates.items():
    section, option = key.split('.')
    config_manager.set_key(section, option, value)

config_manager.save_config()

4. Site Selection and Content Search

The application presents the user with a list of available streaming sites:

  1. It displays a menu of available sites, color-coded by category
  2. The user selects a site by number
  3. The corresponding search function is called
  4. If global search is selected, the global_search() function is called instead
# Mapping user input to functions
input_to_function = {str(i): func for i, (alias, (func, _)) in enumerate(search_functions.items())}

# Create dynamic prompt message and choices
choice_labels = {str(i): (alias.split("_")[0].capitalize(), use_for) for i, (alias, (_, use_for)) in enumerate(search_functions.items())}

# Display the category legend in a single line
legend_text = " | ".join([f"[{color}]{category.capitalize()}[/{color}]" for category, color in color_map.items()])
console.print(f"\n[bold green]Category Legend:[/bold green] {legend_text}")

# Construct the prompt message with color-coded site names
prompt_message = "[green]Insert category [white](" + ", ".join(
    [f"{key}: [{color_map.get(label[1], 'white')}]{label[0]}[/{color_map.get(label[1], 'white')}]" for key, label in choice_labels.items()]
) + "[white])"

# Get user selection
category = msg.ask(prompt_message, choices=list(choice_labels.keys()), default="0", show_choices=False, show_default=False)

# Run the corresponding function based on user input
if category in input_to_function:
    run_function(input_to_function[category], search_terms=search_terms)

5. Search Function Execution

Each site module implements a search() function that:

  1. Prompts the user for search terms (if not provided via command line)
  2. Queries the streaming site for matching content
  3. Displays the search results
  4. Allows the user to select content for viewing or downloading

The specific implementation varies by site, but the general pattern is:

def search(search_terms=None):
    # Get search terms from user if not provided
    if not search_terms:
        search_terms = get_search_input()
    
    # Query the site API or scrape the site for results
    results = query_site(search_terms)
    
    # Display results to user
    display_results(results)
    
    # Get user selection
    selection = get_user_selection(results)
    
    # Process the selected content
    process_selection(selection)

6. Content Processing and Download

Once content is selected, it is processed according to its type:

  1. Movies: Typically downloaded directly
  2. TV Series: The user selects season and episode(s) to download
  3. Anime: Similar to TV series, with season and episode selection

The download process depends on the content type and source:

  1. HLS (M3U8) Content: Processed by the HLS_Downloader class
  2. Direct MP4 Files: Processed by the MP4_downloader class
  3. Torrent Content: Processed by the TOR_downloader class

7. Post-Processing

After download, content is processed according to configuration settings:

  1. Audio tracks are merged if enabled
  2. Subtitles are merged if enabled
  3. Temporary files are cleaned up if enabled
  4. The final file is moved to the configured output directory

8. Program Termination

The program terminates based on the not_close configuration:

  1. If not_close is true, the program loops back to the site selection step
  2. If not_close is false, the program exits
def run_function(func: Callable[..., None], close_console: bool = False, search_terms: str = None) -> None:
    if close_console:
        while 1:
            func(search_terms)
    else:
        func(search_terms)

Global Search Workflow

The global search feature follows a slightly different workflow:

  1. The user selects global search mode
  2. The user is presented with search options:
    • Search all sites
    • Search by category
    • Select specific sites
  3. The user enters search terms
  4. The application searches across the selected sites
  5. Results are consolidated and displayed
  6. The user selects content to download
  7. The appropriate site-specific function handles the download

Telegram Bot Integration

When Telegram bot integration is enabled, the workflow changes:

  1. The bot receives commands from the user via Telegram
  2. Commands are processed and mapped to application functions
  3. Results and prompts are sent back to the user via Telegram
  4. Downloads run in separate screen sessions for parallel operation

Error Handling

The application includes several error handling mechanisms:

  1. Graceful Termination: The force_exit() function ensures clean shutdown
  2. Restart Capability: The restart_script() function allows restarting the application
  3. Exception Handling: Try-except blocks catch and handle errors throughout the code

Conclusion

The StreamingCommunity application follows a modular, user-driven workflow that:

  1. Initializes the environment
  2. Loads available site modules
  3. Presents options to the user
  4. Processes user selections
  5. Downloads and processes content
  6. Terminates or loops based on configuration

This design allows for flexibility in adding new sites and features while maintaining a consistent user experience.

⚠️ **GitHub.com Fallback** ⚠️