### Single File/Album Download Examples Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/configuration.md Demonstrates various command-line options for downloading single files or entire albums from Bunkr. Includes examples for default usage, ignoring/including specific files, custom download paths, and disabling features. ```bash python3 downloader.py https://bunkr.si/a/PUK068QE ``` ```bash python3 downloader.py https://bunkr.si/a/PUK068QE --ignore .zip .txt ``` ```bash python3 downloader.py https://bunkr.si/a/PUK068QE --include FullSizeRender ``` ```bash python3 downloader.py https://bunkr.si/f/xyz123 --custom-path /mnt/external ``` -------------------------------- ### Install Dependencies Source: https://github.com/lysagxra/bunkrdownloader/blob/main/README.md Install all required Python packages listed in the requirements.txt file. ```bash pip install -r requirements.txt ``` -------------------------------- ### Single File Download Example Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Demonstrates how to download a single file from Bunkr using its direct URL. ```bash python3 downloader.py https://bunkr.si/f/xyz123 ``` -------------------------------- ### Session Log Examples Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/configuration.md Provides examples of log entries recorded in session.log, detailing download outcomes and errors. Entries include messages for service unavailability, successful downloads, and skipped files with reasons. ```python {'message': 'Service unavailable for https://bunkr.si/a/xyz'} ``` ```python {'task': 0, 'filename': 'image.jpg', 'download_link': '...', 'item_url': '...', 'outcome': 'Downloaded'} ``` ```python {'task': 1, 'filename': 'archive.zip', ..., 'reason': 'IGNORE_LIST', 'outcome': 'Skipped'} ``` -------------------------------- ### LiveManager Usage Example Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-managers.md Demonstrates how to use the LiveManager to manage download progress and logging within a context manager. Ensure LiveManager is initialized before use. ```python with live_manager.live: # ... do downloads ... live_manager.stop() ``` -------------------------------- ### URLs.txt Example Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/configuration.md Shows the format for a text file used to specify multiple Bunkr URLs for batch downloads. Each URL should be on a new line. ```plaintext https://bunkr.si/a/PUK068QE https://bunkr.fi/f/gBrv5f8tAGlGW https://bunkr.fi/a/kVYLh49Q ``` -------------------------------- ### Example Commit Message Source: https://github.com/lysagxra/bunkrdownloader/blob/main/CONTRIBUTING.md An example of a clear and concise commit message with a detailed description. ```text Add new utility function for matrix inversion This function handles small matrices with optimized performance and includes comprehensive tests. ``` -------------------------------- ### Batch Download Examples Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/configuration.md Illustrates command-line usage for batch downloading from a list of URLs. Shows options for specifying a custom download path, reducing retry attempts, and disabling the progress UI for environments like Jupyter notebooks. ```bash python3 main.py --custom-path /home/user/media ``` ```bash python3 main.py --max-retries 3 ``` ```bash python3 main.py --disable-ui ``` -------------------------------- ### Example Log Entry for ALREADY_DOWNLOADED Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/errors.md This JSON object shows a log entry for a task that was skipped because the file already exists at the final destination. It includes task details, outcome, and the reason for skipping. ```json { "task": 2, "filename": "image.jpg", "download_link": "https://cdn.bunkr.su/...". "item_url": "https://bunkr.si/f/xyz123", "outcome": "Skipped", "reason": "ALREADY_DOWNLOADED" } ``` -------------------------------- ### Example DOMAIN_OFFLINE Log Entry Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/errors.md Illustrates the structure of a log entry when a download is skipped due to the subdomain being offline. This occurs when the server is down or the download fails with no response. ```python { 'task': 5, 'filename': 'video.mp4', 'download_link': 'https://cdn-offline.bunkr.su/ப்புகளை', 'item_url': 'https://bunkr.si/f/xyz123', 'outcome': 'Skipped', 'reason': 'DOMAIN_OFFLINE' } ``` -------------------------------- ### Execute Media Download Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-media-downloader.md Call the download method on a MediaDownloader instance to start the download process. Handles skips and retries internally. Returns None on success or skip, otherwise returns details for retry. ```python downloader = MediaDownloader( session_info=session_info, download_info=download_info, live_manager=live_manager ) # Returns None on success or internal skip result = downloader.download() if result: # File needs retry later print(f"Retry needed for {result['filename']}") else: # File downloaded or skipped print("Download complete") ``` -------------------------------- ### Example Log Entry for INCLUDE_LIST Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/errors.md This JSON object represents a log entry for a task skipped because the filename did not match any patterns in the include list. It shows task details, outcome, and the INCLUDE_LIST reason. ```json { "task": 3, "filename": "thumbnail.jpg", "download_link": "...", "item_url": "...", "outcome": "Skipped", "reason": "INCLUDE_LIST" } ``` -------------------------------- ### Example Log Entry for IGNORE_LIST Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/errors.md This JSON object illustrates a log entry for a task skipped because its filename matched a pattern in the ignore list. It details the task, outcome, and the IGNORE_LIST reason. ```json { "task": 1, "filename": "archive.zip", "download_link": "...", "item_url": "...", "outcome": "Skipped", "reason": "IGNORE_LIST" } ``` -------------------------------- ### Example SERVICE_UNAVAILABLE Log Entry Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/errors.md Shows a log entry when the Bunkr album or file page cannot be fetched, resulting in a SERVICE_UNAVAILABLE skip reason. This typically happens due to network timeouts or specific HTTP error codes. ```python { 'message': 'Service unavailable for https://bunkr.si/a/xyz123' } ``` -------------------------------- ### Get Offline Bunkr Servers Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Returns a dictionary of non-operational Bunkr servers. It can optionally use a pre-fetched status dictionary; otherwise, it fetches the status itself. The returned dictionary contains servers where the status is not 'Operational'. ```python from src.bunkr_utils import get_offline_servers offline = get_offline_servers() if offline: print(f"Offline servers: {list(offline.keys())}") ``` -------------------------------- ### Get Download Info for an Item Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-crawlers.md Gathers the download link and filename for a specific item. This is useful when you have the item's page URL and its parsed HTML, and you need to obtain the direct download URL and the formatted filename. ```python async def get_download_info( item_url: str, item_soup: BeautifulSoup ) -> tuple ``` ```python import asyncio from bs4 import BeautifulSoup from src.crawlers.crawler_utils import get_download_info from src.general_utils import fetch_page async def get_item_info(): item_url = "https://bunkr.si/f/xyz123" soup = await fetch_page(item_url) download_link, filename = await get_download_info(item_url, soup) print(f"File: {filename}") print(f"Link: {download_link}") asyncio.run(get_item_info()) ``` -------------------------------- ### Get Bunkr API Signed Download URL Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-crawlers.md Fetches an encryption token from the Bunkr API to generate a signed download URL. Use this when you need to obtain a direct download link for an item on Bunkr. ```python import asyncio import aiohttp from bs4 import BeautifulSoup from src.crawlers.api_utils import get_api_response from src.general_utils import fetch_page async def get_signed_url(): item_url = "https://bunkr.si/f/xyz123" soup = await fetch_page(item_url) async with aiohttp.ClientSession() as session: download_url = await get_api_response(session, item_url, soup) print(f"Download URL: {download_url}") asyncio.run(get_signed_url()) ``` -------------------------------- ### Example Log Entry for MAX_RETRIES_REACHED Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/errors.md This JSON object represents a log entry when a download task fails due to exceeding the maximum number of retries. It indicates the task, filename, download link, item URL, outcome, and the specific reason for failure. ```json { "task": 0, "filename": "large_file.zip", "download_link": "https://cdn.bunkr.su/...". "item_url": "https://bunkr.si/f/xyz123", "outcome": "Failed", "reason": "MAX_RETRIES_REACHED" } ``` -------------------------------- ### Get Bunkr Server Status Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Fetches the operational status of all Bunkr servers. It parses the HTML from the status page and returns a dictionary mapping server names to their status strings. Returns an empty dictionary if fetching or parsing fails. ```python from src.bunkr_utils import get_bunkr_status status = get_bunkr_status() # {'cdn1': 'Operational', 'cdn2': 'Non-operational', ...} for server, state in status.items(): print(f"{server}: {state}") ``` -------------------------------- ### Initialize AlbumDownloader Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-album-downloader.md Instantiate the AlbumDownloader with session, album, and live manager configurations. Ensure all required objects are properly initialized before creating the downloader instance. ```python from src.config import SessionInfo, AlbumInfo from src.downloaders.album_downloader import AlbumDownloader from src.managers.live_manager import initialize_managers live_manager = initialize_managers(disable_ui=False) session_info = SessionInfo( args=args, bunkr_status=bunkr_status, download_path="/path/to/downloads" ) album_info = AlbumInfo( album_id="PUK068QE", item_pages=[ "https://bunkr.si/f/item1", "https://bunkr.si/f/item2", "https://bunkr.si/f/item3" ] ) downloader = AlbumDownloader( session_info=session_info, album_info=album_info, live_manager=live_manager ) ``` -------------------------------- ### Get Album ID from URL Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Extracts the album ID, which is the last path segment of a Bunkr album URL. ```python from src.url_utils import get_album_id album_id = get_album_id("https://bunkr.si/a/PUK068QE") # Returns: "PUK068QE" ``` -------------------------------- ### Navigate to Project Directory Source: https://github.com/lysagxra/bunkrdownloader/blob/main/README.md Change the current directory to the cloned BunkrDownloader project folder. ```bash cd BunkrDownloader ``` -------------------------------- ### get_host_page Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Extracts the base host URL from a given URL string. For example, it would return 'https://bunkr.si' from 'https://bunkr.si/a/xyz'. ```APIDOC ## get_host_page ### Description Extracts base host URL from a given URL. ### Parameters #### Path Parameters - **url** (str) - Required - Full URL ### Return Type str: Base URL (e.g., "https://bunkr.si" from "https://bunkr.si/a/xyz") ### Example ```python from src.url_utils import get_host_page host = get_host_page("https://bunkr.si/f/xyz123") # Returns: "https://bunkr.si" ``` ``` -------------------------------- ### Extract Host URL Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Extracts the base host URL from a given URL. For example, it transforms 'https://bunkr.si/a/xyz' into 'https://bunkr.si'. ```python from src.url_utils import get_host_page host = get_host_page("https://bunkr.si/f/xyz123") # Returns: "https://bunkr.si" ``` -------------------------------- ### Initialize MediaDownloader Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-media-downloader.md Instantiate the MediaDownloader class with session, download, and live manager information. Configure the number of retries for download attempts. ```python from src.config import SessionInfo, DownloadInfo, MAX_RETRIES from src.downloaders.media_downloader import MediaDownloader from src.managers.live_manager import initialize_managers live_manager = initialize_managers(disable_ui=False) session_info = SessionInfo( args=args, bunkr_status=bunkr_status, download_path="/path/to/downloads" ) download_info = DownloadInfo( item_url="https://bunkr.si/f/xyz123", download_link="https://cdn.bunkr.su/file/xyz123?token=...", filename="image.jpg", task=0 ) downloader = MediaDownloader( session_info=session_info, download_info=download_info, live_manager=live_manager, retries=5 ) ``` -------------------------------- ### main (Batch Download Module) Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Orchestrates the complete batch download flow using a list of URLs from URLs.txt. This is the main entry point for batch downloads. ```APIDOC ## main (async) ### Description Orchestrates the complete batch download flow. This function is the main entry point for batch downloads, reading URLs from a file and processing them. ### Method Asynchronous Function ### Signature `async def main() -> None` ### Behavior 1. Clears terminal screen 2. Checks Python version >= 3.10 3. Parses command-line arguments (common only, no URL) 4. Creates backup of URLs.txt with timestamp 5. Reads URLs from URLs.txt file 6. Filters out empty lines 7. Calls `process_urls()` with URL list 8. Clears/empties URLs.txt file after successful completion ### File Operations **Reads:** URLs.txt (one URL per line) **Creates:** Backups/URLs_[timestamp].bak with contents of URLs.txt **Writes:** session.log (cleared at start), URLs.txt (emptied at end) ### Error Handling - Exits on KeyboardInterrupt (Ctrl+C) - Python version error exits process - Disk space error exits process ### Startup Flow ``` Clear terminal ↓ Check Python >= 3.10 ↓ Parse arguments (--custom-path, --disable-ui, etc.) ↓ Create backup of URLs.txt ↓ Read URLs from URLs.txt ↓ Process each URL ↓ Clear URLs.txt ``` ### Command-Line Usage ```bash # Basic batch download python3 main.py # With custom path python3 main.py --custom-path /mnt/external/media # With reduced retries python3 main.py --max-retries 3 # Without UI (for background/Jupyter) python3 main.py --disable-ui # Combine options python3 main.py --custom-path /storage --disable-ui --max-retries 2 ``` ### Source `main.py:35-53` ``` -------------------------------- ### main (Single File/Album Module) Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Initializes and orchestrates single download of a Bunkr album or file with advanced options. This is the main entry point for single downloads. ```APIDOC ## main (async) ### Description Initializes and orchestrates single download. This function is the main entry point for downloading a single Bunkr album or file. ### Method Asynchronous Function ### Signature `async def main() -> None` ### Behavior 1. Clears terminal screen 2. Checks Python version >= 3.10 3. Fetches Bunkr server status 4. Parses command-line arguments (including URL, filters) 5. Initializes managers for live display 6. Enters live display context 7. Calls `validate_and_download()` with provided URL 8. Stops live display and logs summary 9. Exits live display context on KeyboardInterrupt ### Argument Parsing Includes all arguments: - URL (required) - --ignore (optional) - --include (optional) - --custom-path (optional) - --no-download-folder (optional) - --disable-ui (optional) - --disable-disk-check (optional) - --max-retries (optional, default 5) ### File Operations **Writes:** session.log with download results **Creates:** Downloads directory structure **May create:** .temp partial files during download ### Error Handling - Exits on KeyboardInterrupt (Ctrl+C) - Python version check exits on failure - Network errors caught in `validate_and_download()` ### Example Flows **Single file download:** ```bash python3 downloader.py https://bunkr.si/f/xyz123 ``` **Album with ignore list:** ```bash python3 downloader.py https://bunkr.si/a/PUK068QE --ignore .zip .txt ``` **Album with include list:** ```bash python3 downloader.py https://bunkr.si/a/PUK068QE --include FullSizeRender ``` **Custom path, no retries on failure:** ```bash python3 downloader.py https://bunkr.si/f/xyz --custom-path /media --max-retries 0 ``` ### Source `downloader.py` ``` -------------------------------- ### Get URL Identifier Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Extracts the unique identifier (album ID or media slug) from a Bunkr URL. It can optionally use pre-parsed HTML to extract a media slug. ```python from src.url_utils import get_identifier album_id = get_identifier("https://bunkr.si/a/PUK068QE") # Returns: "PUK068QE" slug = get_identifier("https://bunkr.si/f/xyz123", soup) # Returns: "xyz123" or extracted from page ``` -------------------------------- ### MediaDownloader Constructor Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-media-downloader.md Initializes a new MediaDownloader instance. It sets up the downloader with session information, download details, a live manager for UI updates, and configurable retry attempts. ```APIDOC ## MediaDownloader Constructor ### Description Initializes a new MediaDownloader instance. It sets up the downloader with session information, download details, a live manager for UI updates, and configurable retry attempts. ### Parameters - **session_info** (SessionInfo) - Required - Session configuration with args, status, and download path - **download_info** (DownloadInfo) - Required - Download details: URL, link, filename, and task ID - **live_manager** (LiveManager) - Required - Manager for UI updates and progress tracking - **retries** (int) - Optional - Maximum number of download attempts (default: MAX_RETRIES (5)) ### Instance Attributes - `session_info`: SessionInfo - Current session configuration - `download_info`: DownloadInfo - Download target details - `live_manager`: LiveManager - Progress/log manager - `retries`: int - Remaining retry count ### Example ```python from src.config import SessionInfo, DownloadInfo, MAX_RETRIES from src.downloaders.media_downloader import MediaDownloader from src.managers.live_manager import initialize_managers live_manager = initialize_managers(disable_ui=False) session_info = SessionInfo( args=args, bunkr_status=bunkr_status, download_path="/path/to/downloads" ) download_info = DownloadInfo( item_url="https://bunkr.si/f/xyz123", download_link="https://cdn.bunkr.su/file/xyz123?token=...", filename="image.jpg", task=0 ) downloader = MediaDownloader( session_info=session_info, download_info=download_info, live_manager=live_manager, retries=5 ) ``` ``` -------------------------------- ### AlbumDownloader Constructor Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-album-downloader.md Initializes the AlbumDownloader with session, album, and live manager information. It sets up the necessary components for managing album downloads, including tracking failed downloads for retries. ```APIDOC ## AlbumDownloader Constructor ### Description Initializes the AlbumDownloader with session, album, and live manager information. It sets up the necessary components for managing album downloads, including tracking failed downloads for retries. ### Parameters - **session_info** (SessionInfo) - Required - Session configuration with args, status, and download path - **album_info** (AlbumInfo) - Required - Album metadata including ID and list of item page URLs - **live_manager** (LiveManager) - Required - Manager for UI updates and progress tracking ### Instance Attributes - `session_info`: SessionInfo - Current session configuration - `album_info`: AlbumInfo - Album details (ID and item pages) - `live_manager`: LiveManager - Progress/log manager - `failed_downloads`: list - Queue of failed downloads for retry ### Example ```python from src.config import SessionInfo, AlbumInfo from src.downloaders.album_downloader import AlbumDownloader from src.managers.live_manager import initialize_managers live_manager = initialize_managers(disable_ui=False) session_info = SessionInfo( args=args, bunkr_status=bunkr_status, download_path="/path/to/downloads" ) album_info = AlbumInfo( album_id="PUK068QE", item_pages=[ "https://bunkr.si/f/item1", "https://bunkr.si/f/item2", "https://bunkr.si/f/item3" ] ) downloader = AlbumDownloader( session_info=session_info, album_info=album_info, live_manager=live_manager ) ``` ``` -------------------------------- ### Basic Batch Download Command Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Executes the batch download process using default settings. ```bash python3 main.py ``` -------------------------------- ### Get Album Name from HTML Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Retrieves the album name by parsing the HTML of an album page. It specifically looks for an h1 tag with certain classes and handles potential character encoding issues. ```python from src.url_utils import get_album_name from src.general_utils import fetch_page soup = await fetch_page("https://bunkr.si/a/xyz") name = get_album_name(soup) print(f"Album: {name}") ``` -------------------------------- ### SummaryManager Get Result Count Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-managers.md Retrieves the count of tasks based on their result status (COMPLETED, FAILED, SKIPPED) and an optional specific reason. Use `TaskReason.REASON_ALL` to count all reasons for a given status. ```python completed = summary.get_result_count(TaskResult.COMPLETED) skipped_already = summary.get_result_count( TaskResult.SKIPPED, SkippedReason.ALREADY_DOWNLOADED ) ``` -------------------------------- ### LiveManager Constructor Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-managers.md Initializes the LiveManager with necessary components for real-time display management. ```APIDOC ## LiveManager Constructor ### Description Initializes the LiveManager with necessary components for real-time display management. ### Method __init__ ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - **progress_manager** (ProgressManager) - Required - Tracks download progress - **logger_table** (LoggerTable) - Required - Logs events and details - **summary_manager** (SummaryManager) - Required - Aggregates task results - **disable_ui** (bool) - Optional - If True, disables Rich live display (Default: False) ``` -------------------------------- ### Download Single Media or Album Source: https://github.com/lysagxra/bunkrdownloader/blob/main/README.md Use the downloader.py script to download either a single media file or an entire album from a Bunkr URL. ```bash python3 downloader.py https://bunkr.si/a/PUK068QE # Download album ``` ```bash python3 downloader.py https://bunkr.fi/f/gBrv5f8tAGlGW # Download single media ``` -------------------------------- ### Handle Bunkr Download Process Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-downloader.md Internal function to route downloads to either album or single-item handlers based on the URL and parsed HTML. It determines the download type and initializes the corresponding downloader. Requires pre-parsed HTML content. ```python async def handle_download_process( session_info: SessionInfo, url: str, initial_soup: BeautifulSoup, live_manager: LiveManager, max_retries: int, ) -> None ``` -------------------------------- ### Single Download with Custom Path and No Retries Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Downloads a single item to a custom path and configures zero retries on download failure. ```bash python3 downloader.py https://bunkr.si/f/xyz --custom-path /media --max-retries 0 ``` -------------------------------- ### Batch Download from URLs.txt Source: https://github.com/lysagxra/bunkrdownloader/blob/main/README.md To perform a batch download, create a URLs.txt file with each URL on a new line and run the main.py script. Ensure each URL is on its own line without extra spaces. ```text https://bunkr.si/a/PUK068QE https://bunkr.fi/f/gBrv5f8tAGlGW https://bunkr.fi/a/kVYLh49Q ``` ```bash python3 main.py ``` -------------------------------- ### Batch Download with Combined Options Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Combines multiple command-line options for batch downloading, including custom path, disabled UI, and specific retry count. ```bash python3 main.py --custom-path /storage --disable-ui --max-retries 2 ``` -------------------------------- ### Batch Download with Custom Path Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Performs a batch download, specifying a custom directory for downloaded files. ```bash python3 main.py --custom-path /mnt/external/media ``` -------------------------------- ### BunkrDownloader Component Architecture Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/INDEX.md Overview of the BunkrDownloader's modular structure, detailing the roles of entry points, core orchestration, download managers, crawlers, UI components, and utilities. ```text ENTRY POINTS ├── downloader.py (single URL mode) └── main.py (batch mode from URLs.txt) CORE ORCHESTRATION ├── downloader.validate_and_download() — Main download router └── downloader.handle_download_process() — Album/file dispatcher DOWNLOAD MANAGERS ├── downloaders/album_downloader.py │ └── AlbumDownloader — Manages concurrent album downloads └── downloaders/media_downloader.py └── MediaDownloader — Individual file download with retries CRAWLERS & EXTRACTORS ├── crawlers/crawler_utils.py — Album pages, item links, filenames ├── crawlers/api_utils.py — Signed download URLs └── downloaders/download_utils.py — File streaming with progress UI & PROGRESS ├── managers/live_manager.py — Orchestrates all displays ├── managers/progress_manager.py — Progress bars ├── managers/log_manager.py — Event logging └── managers/summary_manager.py — Result statistics UTILITIES ├── bunkr_utils.py — Server status ├── url_utils.py — URL parsing ├── file_utils.py — File operations ├── general_utils.py — System checks, page fetching └── config.py — Configuration, constants, data classes VERSION └── version.py — Version metadata ``` -------------------------------- ### Create New Branch Source: https://github.com/lysagxra/bunkrdownloader/blob/main/CONTRIBUTING.md Create a new branch for your work using descriptive names. ```bash git checkout -b feature/my-new-feature ``` ```bash git checkout -b bugfix/fix-issue-123 ``` -------------------------------- ### Create Download Directory Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Creates a directory for downloads, optionally within a custom base path and with or without a 'Downloads' subfolder. The directory name is sanitized to remove invalid characters. ```python from src.file_utils import create_download_directory path = create_download_directory( "Album Name (ABC123)", custom_path="/mnt/media", no_download_folder=False ) # Returns: "/mnt/media/Downloads/Album Name (ABC123)" ``` -------------------------------- ### Single File/Album Download CLI Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Use this command to download a specific album or file from Bunkr. Supports filtering files by pattern and custom download paths. ```bash python3 downloader.py [OPTIONS] ``` ```bash python3 downloader.py https://bunkr.si/a/PUK068QE ``` ```bash python3 downloader.py https://bunkr.si/f/xyz --max-retries 10 ``` ```bash python3 downloader.py https://bunkr.si/a/album --ignore .zip ``` ```bash python3 downloader.py https://bunkr.si/a/album --include large ``` -------------------------------- ### Initialize LiveManager Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-managers.md Factory function to create a configured LiveManager. Use `disable_ui=True` to suppress progress UI. ```python from src.managers.live_manager import initialize_managers live_manager = initialize_managers(disable_ui=False) with live_manager.live: # Use live_manager for all progress/logging live_manager.add_overall_task("album-id", 10) task = live_manager.add_task() live_manager.update_task(task, completed=50) live_manager.stop() ``` -------------------------------- ### Handle Directory Creation Error Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/errors.md Logs an OSError when the download directory cannot be created and exits the program. ```python try: os.makedirs(self.download_dir) except OSError as e: logging.exception(f"Failed to create download directory: {self.download_dir}") sys.exit(1) ``` -------------------------------- ### Test Direct Function Call for Download Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/INDEX.md This Python script demonstrates how to directly call the `validate_and_download` function asynchronously. It initializes necessary managers, sets up mock arguments, and executes the download process. ```python import asyncio from downloader import validate_and_download from src.managers.live_manager import initialize_managers from src.bunkr_utils import get_bunkr_status async def test(): bunkr_status = get_bunkr_status() live_manager = initialize_managers(disable_ui=False) url = "https://bunkr.si/a/xyz" # Create mock args from argparse import Namespace args = Namespace( custom_path=None, no_download_folder=False, disable_ui=False, disable_disk_check=False, max_retries=5 ) with live_manager.live: await validate_and_download(bunkr_status, url, live_manager, args=args) live_manager.stop() asyncio.run(test()) ``` -------------------------------- ### Validate and Download Bunkr URL Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-downloader.md Initiates the download process for a Bunkr URL after validation. It handles disk space checks, URL prefixing, HTML parsing, and routing to appropriate download handlers. Use this as the primary entry point for downloads. ```python async def validate_and_download( bunkr_status: dict[str, str], url: str, live_manager: LiveManager, args: Namespace | None = None, ) -> None ``` ```python import asyncio from src.managers.live_manager import initialize_managers from src.bunkr_utils import get_bunkr_status from downloader import validate_and_download from argparse import Namespace async def main(): bunkr_status = get_bunkr_status() live_manager = initialize_managers(disable_ui=False) args = Namespace( custom_path=None, no_download_folder=False, disable_ui=False, disable_disk_check=False, max_retries=5 ) url = "https://bunkr.si/a/PUK068QE" with live_manager.live: await validate_and_download(bunkr_status, url, live_manager, args=args) live_manager.stop() asyncio.run(main()) ``` -------------------------------- ### validate_and_download Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-downloader.md Validates the provided URL and initiates the download process. This is the main entry point for downloading from a Bunkr URL. ```APIDOC ## validate_and_download ### Description Validates the provided URL and initiates the download process. This is the main entry point for downloading from a Bunkr URL. ### Parameters #### Path Parameters - **bunkr_status** (dict[str, str]) - Required - Dictionary mapping server names to their operational status - **url** (str) - Required - Bunkr URL to download (album or single file) - **live_manager** (LiveManager) - Required - Manager instance for UI updates and progress tracking - **args** (Namespace | None) - Optional - Command-line arguments containing download options ### Return Type None ### Behavior - Checks available disk space if `args.disable_disk_check` is False - Adds https:// prefix to the URL if missing - Fetches the page and parses HTML - Extracts album name and ID if applicable - Creates appropriate download directory structure - Routes to either album or single file download handler - Catches network errors and logs them ### Exceptions - **RuntimeError**: Network error during download (RequestConnectionError, Timeout, RequestException) ### Example ```python import asyncio from src.managers.live_manager import initialize_managers from src.bunkr_utils import get_bunkr_status from downloader import validate_and_download from argparse import Namespace async def main(): bunkr_status = get_bunkr_status() live_manager = initialize_managers(disable_ui=False) args = Namespace( custom_path=None, no_download_folder=False, disable_ui=False, disable_disk_check=False, max_retries=5 ) url = "https://bunkr.si/a/PUK068QE" with live_manager.live: await validate_and_download(bunkr_status, url, live_manager, args=args) live_manager.stop() asyncio.run(main()) ``` ``` -------------------------------- ### Download Thresholds Configuration Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/types.md A list of tuples defining chunk sizes based on file size thresholds. Also includes a constant for large file chunk size. Used to optimize download performance. ```python THRESHOLDS = [ (1 * MB, 32 * KB), # < 1 MB: 32 KB chunks (10 * MB, 128 * KB), # 1-10 MB: 128 KB chunks (50 * MB, 512 * KB), # 10-50 MB: 512 KB chunks (100 * MB, 1 * MB), # 50-100 MB: 1 MB chunks (250 * MB, 2 * MB), # 100-250 MB: 2 MB chunks (500 * MB, 4 * MB), # 250-500 MB: 4 MB chunks (1 * GB, 8 * MB), # 500 MB-1 GB: 8 MB chunks ] LARGE_FILE_CHUNK_SIZE = 16 * MB # > 1 GB: 16 MB chunks ``` -------------------------------- ### Process URLs for Batch Download Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Validates and downloads items from a list of Bunkr URLs with live progress display. Requires parsed command-line arguments. ```python async def process_urls(urls: list[str], args: Namespace) -> None ``` ```python import asyncio from argparse import Namespace from main import process_urls async def batch_download(): urls = [ "https://bunkr.si/a/album1", "https://bunkr.si/f/file1", "https://bunkr.si/a/album2" ] args = Namespace( disable_ui=False, custom_path="/media/downloads", no_download_folder=False, disable_disk_check=False, max_retries=5 ) await process_urls(urls, args) asyncio.run(batch_download()) ``` -------------------------------- ### Clone Repository Source: https://github.com/lysagxra/bunkrdownloader/blob/main/README.md Clone the BunkrDownloader repository from GitHub. ```bash git clone https://github.com/Lysagxra/BunkrDownloader.git ``` -------------------------------- ### Batch Download via CLI Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/INDEX.md Perform a batch download by providing a list of URLs in a file. This command supports custom retry attempts and disabling the UI. ```bash echo "https://bunkr.si/a/album1" > URLs.txt python3 main.py --disable-ui --max-retries 2 ``` -------------------------------- ### Orchestrate Complete Batch Download Flow Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md The main asynchronous function for `main.py` that orchestrates the complete batch download flow, including argument parsing, file reading, and calling `process_urls`. ```python async def main() -> None ``` -------------------------------- ### Clone Repository Source: https://github.com/lysagxra/bunkrdownloader/blob/main/CONTRIBUTING.md Clone the repository to your local machine after forking it. ```bash git clone https://github.com/your-username/your-repo.git ``` -------------------------------- ### Batch Download CLI Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Use this command to download multiple URLs listed in URLs.txt. Supports custom paths and disabling the UI. ```bash python3 main.py [OPTIONS] ``` ```bash python3 main.py ``` ```bash python3 main.py --custom-path /mnt/external ``` ```bash python3 main.py --disable-ui --max-retries 3 ``` -------------------------------- ### Download Album with Custom Concurrency and Retries Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-album-downloader.md Execute the album download process using custom values for maximum concurrent workers and retry attempts. This allows fine-tuning performance and resilience based on network conditions and server limits. ```python import asyncio async def main(): downloader = AlbumDownloader(session_info, album_info, live_manager) # Download with default settings (3 workers, 5 retries) await downloader.download_album() # Or with custom settings await downloader.download_album(max_workers=5, max_retries=3) asyncio.run(main()) ``` -------------------------------- ### Download Album with Ignore Pattern via CLI Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/INDEX.md Download an entire album from a URL, ignoring files matching a specific pattern. The --disable-ui option hides the progress display. ```bash python3 downloader.py https://bunkr.si/a/album123 --ignore .zip --disable-ui ``` -------------------------------- ### Download Album with Include List Source: https://github.com/lysagxra/bunkrdownloader/blob/main/README.md Download only specific files from an album that contain certain strings in their filenames. This allows for targeted downloads. ```bash python3 downloader.py https://bunkr.si/a/PUK068QE --include FullSizeRender ``` -------------------------------- ### Album Download with Ignore List Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Downloads an album from Bunkr, excluding specified file types or patterns. ```bash python3 downloader.py https://bunkr.si/a/PUK068QE --ignore .zip .txt ``` -------------------------------- ### create_download_directory Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Creates a directory for downloads, optionally within a custom path and with or without a 'Downloads' subfolder. The directory name is sanitized for invalid characters. ```APIDOC ## create_download_directory ### Description Creates a directory for downloads, optionally within a custom path and with or without a 'Downloads' subfolder. The directory name is sanitized for invalid characters. ### Parameters #### Path Parameters - **directory_name** (str) - Required - Album name or ID - **custom_path** (str | None) - Optional - Custom base path (default: current directory) - **no_download_folder** (bool) - Optional - If True, skip "Downloads" subfolder ### Return Type str: Full path to created directory ### Behavior - Base path: custom_path or current directory - Adds "Downloads" subfolder unless no_download_folder=True - Sanitizes directory name for invalid characters - Creates directory if it doesn't exist - Exits with error on OSError ### Example ```python from src.file_utils import create_download_directory path = create_download_directory( "Album Name (ABC123)", custom_path="/mnt/media", no_download_folder=False ) # Returns: "/mnt/media/Downloads/Album Name (ABC123)" ``` ``` -------------------------------- ### Check URL Type (Album or File) Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Determines if a given Bunkr URL points to an album or a single file. Returns True for an album and False for a single file. ```python # Example usage for check_url_type would go here, but is not provided in the source. ``` -------------------------------- ### Format Item Filename Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-crawlers.md Combines two filenames while preserving the file extension. Use this when you have a filename from the page title and another derived from the download link, and you need a single, consistent filename. ```python def format_item_filename( original_filename: str, url_based_filename: str ) -> str ``` -------------------------------- ### Initialize LiveManager Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-managers.md Instantiates the LiveManager class, which orchestrates real-time display of progress bars and log messages. It integrates ProgressManager, LoggerTable, and SummaryManager. The disable_ui parameter can be used to turn off the Rich live display. ```python def __init__( self, progress_manager: ProgressManager, logger_table: LoggerTable, summary_manager: SummaryManager, *, disable_ui: bool = False, ) -> None ``` -------------------------------- ### check_url_type Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Determines whether a given Bunkr URL points to an album or a single file. ```APIDOC ## check_url_type ### Description Determines if URL is an album or single file. ### Parameters #### Path Parameters - **url** (str) - Required - Bunkr URL ### Return Type bool: True for album, False for single file ``` -------------------------------- ### ProgressManager Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-managers.md Manages progress bars for overall and per-item download progress. ```APIDOC ## ProgressManager Class ### Description Manages progress bars for overall and per-item download progress. ### Constructor ```python def __init__( self, task_name: str, item_description: str, ) -> None ``` ### Parameters - **task_name** (str) - Required - Name for overall progress (e.g., "Album") - **item_description** (str) - Required - Name for individual items (e.g., "File") ### Methods #### get_panel_width ##### Description Returns the width of the progress panel. ##### Return Type int: Panel width in characters #### create_progress_table ##### Description Creates a Rich Table for display with both progress bars. ##### Return Type Rich Table with two panels (overall and per-item progress) ##### Parameters - **min_panel_width** (int) - Optional - Default: 30 - Minimum width for the progress panel. ``` -------------------------------- ### initialize_managers Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-managers.md Factory function to create a configured LiveManager. It initializes ProgressManager, LoggerTable, and SummaryManager, then wraps them in a LiveManager. ```APIDOC ## initialize_managers ### Description Factory function to create a configured LiveManager. It initializes ProgressManager, LoggerTable, and SummaryManager, then wraps them in a LiveManager. ### Method Factory Function ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **disable_ui** (bool) - Optional - Default: False - If True, disables progress UI ### Return Type LiveManager: Fully initialized manager ### Behavior - Creates ProgressManager with "Album" and "File" labels - Creates LoggerTable with default settings - Creates SummaryManager - Wraps all three in LiveManager - Logs "Script started" event ### Example ```python from src.managers.live_manager import initialize_managers live_manager = initialize_managers(disable_ui=False) with live_manager.live: # Use live_manager for all progress/logging live_manager.add_overall_task("album-id", 10) task = live_manager.add_task() live_manager.update_task(task, completed=50) live_manager.stop() ``` ``` -------------------------------- ### get_download_info Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-crawlers.md Gathers the download link and filename for a given item. It retrieves the signed download URL and extracts the item's filename, then formats the filename. ```APIDOC ## get_download_info ### Description Gathers the download link and filename for a given item. It retrieves the signed download URL and extracts the item's filename, then formats the filename. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **item_url** (str) - Yes - URL of the item page - **item_soup** (BeautifulSoup) - Yes - Parsed HTML of the item page ### Return Type tuple[str | None, str]: (download_link, formatted_filename) ### Example ```python import asyncio from bs4 import BeautifulSoup from src.crawlers.crawler_utils import get_download_info from src.general_utils import fetch_page async def get_item_info(): item_url = "https://bunkr.si/f/xyz123" soup = await fetch_page(item_url) download_link, filename = await get_download_info(item_url, soup) print(f"File: {filename}") print(f"Link: {download_link}") asyncio.run(get_item_info()) ``` ``` -------------------------------- ### execute_item_download Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-album-downloader.md Downloads a single item from an album, handling page fetching, concurrency control, and retries. It acquires a semaphore, fetches the item page, extracts download details, and initiates the download. ```APIDOC ## execute_item_download ### Description Downloads a single item from an album, handling page fetching, concurrency control, and retries. It acquires a semaphore, fetches the item page, extracts download details, and initiates the download. ### Parameters - **item_page** (str) - Required - URL of the item page to download - **current_task** (int) - Required - Index of this item in the album (0-based) - **semaphore** (Semaphore) - Required - Asyncio semaphore controlling concurrency - **max_retries** (int) - Required - Maximum retry attempts for this item ### Return Type None ### Behavior 1. Acquires semaphore permit (waits if at worker limit) 2. Fetches item page with retries using _fetch_page_with_retries 3. Extracts download link and filename from page 4. Creates MediaDownloader instance 5. Runs download in thread pool to avoid blocking async 6. Queues failed downloads for later retry 7. Releases semaphore permit ``` -------------------------------- ### Save File with Progress Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-utilities.md Saves a file from a response stream while tracking and updating the download progress using a provided progress manager. ```python def save_file_with_progress( response: Response, download_path: str, task: int, progress_manager: ProgressManager, ) -> bool: pass ``` -------------------------------- ### get_api_response Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-crawlers.md Fetches encryption token from Bunkr API to generate signed download URL. It extracts necessary information from the HTML, makes an API call, and returns a signed URL or a fallback URL. ```APIDOC ## get_api_response ### Description Fetches encryption token from Bunkr API to generate signed download URL. It extracts necessary information from the HTML, makes an API call, and returns a signed URL or a fallback URL. ### Method Asynchronous Function ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **session** (aiohttp.ClientSession) - Required - Active aiohttp session - **item_url** (str) - Required - URL of the item page - **soup** (BeautifulSoup | None) - Optional - Pre-parsed HTML (fetches if None) ### Return Type str | None: Signed download URL with token and expiry, or fallback URL ### Behavior 1. Extracts JavaScript variables from HTML via extract_js_vars 2. Gets jsCDN URL and item slug 3. Makes API call to BUNKR_API with path parameter 4. If token and expiry present, appends them to URL 5. If not, returns jsCDN fallback 6. Returns None on error ### Example ```python import asyncio import aiohttp from bs4 import BeautifulSoup from src.crawlers.api_utils import get_api_response from src.general_utils import fetch_page async def get_signed_url(): item_url = "https://bunkr.si/f/xyz123" soup = await fetch_page(item_url) async with aiohttp.ClientSession() as session: download_url = await get_api_response(session, item_url, soup) print(f"Download URL: {download_url}") asyncio.run(get_signed_url()) ``` ``` -------------------------------- ### Batch Download Without UI Source: https://github.com/lysagxra/bunkrdownloader/blob/main/_autodocs/api-reference-entry-points.md Runs the batch download process without displaying the progress UI, suitable for background tasks or environments like Jupyter notebooks. ```bash python3 main.py --disable-ui ```