bbdrop

BBDrop Features Documentation

Platform: Windows 10+ Linux (Ubuntu 20.04+)

Table of Contents

  1. Gallery Management
  2. Multi-Host Upload System
  3. Archive & Compression
  4. BBCode Generation & Templates
  5. File Host Integration
  6. Template System
  7. Automation & Hooks
  8. Configuration & Settings
  9. User Interface
  10. Advanced Features
  11. Database & Storage
  12. Network & Performance

Drag & Drop Interface

Description: Intuitive drag-and-drop functionality for adding galleries to the upload queue.

Features:

Supported Image Formats:


Queue Management

Description: Comprehensive queue system for managing multiple gallery uploads.

Queue States (11 Total):

Batch Operations:

Features:

Database Schema:

CREATE TABLE galleries (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL,
  path TEXT NOT NULL UNIQUE,
  status TEXT NOT NULL,
  tab TEXT DEFAULT 'Main',
  template TEXT DEFAULT 'Default Template',
  custom1-4 TEXT,  -- User-defined fields
  ext1-4 TEXT,     -- External app outputs
  created_at INTEGER NOT NULL,
  completed_at INTEGER,
  gallery_id TEXT,
  bbcode_path TEXT,
  artifact_path TEXT,
  retry_count INTEGER DEFAULT 0,
  error_message TEXT
);

Tab-Based Organization

Description: Organize galleries across multiple tabs for better workflow management.

Features:

Default Tabs:


Description: Flexible gallery naming with conflict detection.

Features:

Unrenamed Gallery Dialog:


Multi-Host Upload System

Description: Upload galleries to 7 file hosting services simultaneously.

Supported File Hosts (7 Total)

1. Fileboom (fboom.me)

Configuration:

{
  "name": "Fileboom",
  "auth_type": "bearer",
  "upload_init_url": "https://fboom.me/api/upload/getinfo?api_key={token}",
  "response_type": "json",
  "link_prefix": "https://fboom.me/file/"
}

2. Filedot (filedot.to)

CAPTCHA Solving Example:

<!-- Visual CAPTCHA with CSS positioning -->
<span style="padding-left:26px">2</span>
<span style="padding-left:45px">8</span>
<span style="padding-left:67px">1</span>

<!-- Parsed as: [(26, '2'), (45, '8'), (67, '1')] -->
<!-- Sorted by position: "281" -->

Workflow:

  1. Visit login page (GET request)
  2. Extract CSRF tokens from hidden fields
  3. Parse CAPTCHA via CSS padding-left positions
  4. Submit login form (POST request)
  5. Store session cookies for future requests

3. Filespace (filespace.com)


4. Keep2Share (k2s.cc)


5. Rapidgator (rapidgator.net)

Token Management:

# Token cached in .bbdrop/token_cache.db
{
  "host": "rapidgator",
  "token": "abc123xyz789",
  "expiry": 1700000000,  # Unix timestamp
  "ttl": 86400,  # 24 hours in seconds
  "created_at": 1699913600
}

6. Tezfiles (tezfiles.com)


7. Katfile (katfile.com)


Authentication Methods

Method 1: API Key (Permanent Token)

Hosts: Fileboom, Keep2Share, Tezfiles, Katfile

Advantages:

Setup:

  1. Log into file host account
  2. Navigate to Account -> API Settings
  3. Generate or copy your API key
  4. Paste into BBDrop Settings -> File Hosts -> Configure
  5. Click Test Connection to verify

Security:


Method 2: Token Login (Username/Password -> Temporary Token)

Hosts: Rapidgator

Workflow:

  1. User provides credentials in format: username:password
  2. BBDrop performs login request to obtain token
  3. Extracts authentication token from JSON response
  4. Caches token with TTL (24 hours for Rapidgator)
  5. Automatically refreshes token on expiration or 401/403 errors

Token Cache:

Auto-Refresh Logic:


Method 3: Session-Based (Username/Password -> Cookies)

Hosts: Filedot, Filespace

Features:

Login Flow:

  1. GET request to login page
  2. Extract hidden fields (CSRF tokens, session IDs)
  3. Parse CAPTCHA (if present) via CSS positioning
  4. POST login form with credentials + CAPTCHA
  5. Store session cookies (Set-Cookie headers)
  6. Validate login success (check for error messages)
  7. Extract upload session tokens from page HTML

Connection Management

Features:

Configuration:

CONNECTION_LIMITS = {
  "global_max": 3,        # Total across all hosts
  "per_host_max": 2,      # Per individual host
  "timeout": 30,          # Request timeout (seconds)
  "retry_attempts": 3,    # Auto-retry count
  "retry_delay": 5        # Delay between retries (seconds)
}

Semaphore Implementation:

# Global semaphore limits total concurrent uploads
global_semaphore = threading.Semaphore(3)

# Per-host semaphores limit per-host concurrency
host_semaphores = {
  "rapidgator": threading.Semaphore(2),
  "fileboom": threading.Semaphore(2),
  # ...
}

Bandwidth Tracking

Features:

Display:

Status Bar: Upload 2.5 MB/s | Total: 127.3 MB / 245.8 MB | ETA: 3m 24s

Placeholder: #hostLinks#

Description: Automatically generate BBCode download links for all enabled file hosts.

Example Output:

[b]Download:[/b]
[url=https://fboom.me/file/abc123]Fileboom[/url] | [url=https://rapidgator.net/file/xyz789]Rapidgator[/url] | [url=https://k2s.cc/file/def456]Keep2Share[/url]

Template Usage:

[if hostLinks]
[b]Download Links:[/b]
#hostLinks#
[else]
[i]No file host uploads configured[/i]
[/if]

Archive & Compression

Description: Advanced ZIP archive handling for gallery compression and extraction.

ZIP Creation

Features:

Usage Example:

# External app parameter: %z
# Automatically creates temporary ZIP, uploads, then deletes
python hooks/muh.py rapidgator "%z"

ZIP Extraction

Features:

Archive Folder Selector Dialog:

+-- Select Folders to Upload ---------------+
| Archive: vacation_photos.zip              |
| Extracted to: /tmp/bbdrop_extract          |
|                                           |
| Found 3 image folders:                    |
| [x] Day1_Beach (127 images)               |
| [x] Day2_City (84 images)                 |
| [x] Day3_Mountain (95 images)             |
|                                           |
|      [Select All] [Upload] [Cancel]       |
+-------------------------------------------+

Archive Coordinator

Component: src/processing/archive_coordinator.py

Features:

Worker Architecture:

 ArchiveCoordinator
 +-- ArchiveWorker #1 (compression thread)
 +-- ArchiveWorker #2 (extraction thread)
 +-- ArchiveWorker #3 (validation thread)

BBCode Generation & Templates

Description: Powerful template system for generating formatted forum posts.

Placeholder Description Example Output
#folderName# Gallery name Summer Vacation 2024
#pictureCount# Number of images 127
#width# Average width (px) 4000
#height# Average height (px) 3000
#longest# Longest dimension (px) 4000
#extension# File format (uppercase) JPG
#folderSize# Total size 245.8 MB
#galleryLink# imx.to gallery URL https://imx.to/g/abc123
#allImages# BBCode for all images [img]...[/img]
Placeholder Description Example Output
#hostLinks# Download links [url=...]Fileboom[/url] \| [url=...]Rapidgator[/url]

Custom Fields (8 placeholders)

Placeholder Description Use Case
#custom1# - #custom4# User-defined fields Photographer, camera, location, license
#ext1# - #ext4# External app outputs Upload links, processing results, ratings

Example Usage:

[center][b]#folderName#[/b][/center]

[b]Gallery Stats:[/b]
- Images: #pictureCount# (#extension# format)
- Resolution: #width#x#height# (longest: #longest#px)
- Size: #folderSize#

[if galleryLink]
[b]Gallery:[/b] [url=#galleryLink#]View on imx.to[/url]
[/if]

[if hostLinks]
[b]Download:[/b]
#hostLinks#
[/if]

#allImages#

Conditional Logic

Syntax:

[if placeholder]Content[/if]
[if placeholder=value]Content[/if]
[if placeholder]True[else]False[/if]

Examples:

Simple Conditional:

[if galleryLink]
[b]Source:[/b] [url=#galleryLink#]View Original Gallery[/url]
[/if]

Value Comparison:

[if extension=PNG]
  [i]Lossless PNG format - high quality![/i]
[else]
  [i]Standard JPG format[/i]
[/if]

Nested Conditionals:

[if pictureCount]
  [b]Gallery contains #pictureCount# images[/b]
  [if pictureCount>100]
    [i]Large gallery - may take time to load![/i]
  [/if]
[else]
  [b]Empty gallery[/b]
[/if]

File Host Links:

[if hostLinks]
[b]Alternative Downloads:[/b]
#hostLinks#
[else]
[i]Direct download only (no file hosts configured)[/i]
[/if]

Custom Fields:

[if custom1]
[b]Photographer:[/b] #custom1#
[/if]

[if ext1]
[b]External Link:[/b] [url=#ext1#]Download ZIP[/url]
[/if]

Template Manager

Component: src/gui/dialogs/template_manager.py Access: Settings -> BBCode -> Manage Templates

Features:

Template Storage:

~/.bbdrop/templates/
+-- Default Template.template.txt
+-- Detailed Example.template.txt
+-- Compact Template.template.txt
+-- My Custom Template.template.txt

Built-in Templates:

Keyboard Shortcuts:


BBCode Viewer

Component: src/gui/dialogs/bbcode_viewer.py Access: Right-click gallery -> View BBCode

Features:

Theme Support:


File Host Integration

Description: Comprehensive integration with 7 file hosting services.

Credential Management

Component: src/gui/dialogs/credential_setup.py

Features:

Storage Methods:

# Method 1: System Keyring (preferred)
import keyring
keyring.set_password("bbdrop", "rapidgator", "username:password")

# Method 2: Encrypted config file (fallback)
# ~/.bbdrop/credentials.enc
from cryptography.fernet import Fernet
cipher = Fernet(key)
encrypted = cipher.encrypt(b"username:password")

File Host Configuration Dialog

Component: src/gui/dialogs/file_host_config_dialog.py

Per-Host Settings:

Authentication Setup:

Test Connection:

UI Example:

+-- File Host Configuration ----------------+
| Host: Rapidgator [dropdown]               |
| [x] Enable this host                      |
|                                           |
| Credentials:                              |
| +---------------------------------------+ |
| | username:password                     | |
| +---------------------------------------+ |
| [Test Connection]                         |
|                                           |
| Settings:                                 |
| Max Connections: [2] [dropdown]           |
| Retry Attempts:  [3] [dropdown]           |
| Timeout:         [30] seconds             |
|                                           |
| Account Info:                             |
| Premium until: 2025-12-31                 |
| Storage: 245.8 GB / 1000 GB               |
| Email: user@example.com                   |
|                                           |
|          [Save]  [Cancel]                 |
+-------------------------------------------+

Token Cache System

Component: src/network/token_cache.py Database: ~/.bbdrop/token_cache.db (SQLite)

Features:

Schema:

CREATE TABLE tokens (
  host TEXT PRIMARY KEY,
  token TEXT NOT NULL,
  expiry INTEGER NOT NULL,  -- Unix timestamp
  ttl INTEGER NOT NULL,     -- Time To Live in seconds
  created_at INTEGER NOT NULL
);

TTL Values:

TOKEN_TTL = {
  "rapidgator": 86400,   # 24 hours
  "fileboom": 0,         # Permanent (API key)
  "keep2share": 0,       # Permanent (API key)
  "filedot": 3600,       # 1 hour (session)
  "filespace": 3600,     # 1 hour (session)
  "tezfiles": 0,         # Permanent (API key)
  "katfile": 0           # Permanent (API key)
}

API:

class TokenCache:
    def get_token(self, host: str) -> Optional[str]
    def set_token(self, host: str, token: str, ttl: int)
    def is_expired(self, host: str) -> bool
    def refresh_token(self, host: str) -> bool
    def clear_token(self, host: str)
    def cleanup_expired()

File Host Clients

Component: src/network/file_host_client.py

Architecture:

FileHostClient is a single concrete class that handles all 7 file hosts via configuration. Each host’s behavior (authentication method, upload protocol, endpoint URLs) is driven by per-host config dictionaries rather than separate subclasses.

Key Methods:

class FileHostClient:
    def authenticate(self) -> bool
    def upload_file(self, filepath: Path) -> str
    def get_account_info(self) -> dict
    def test_connection(self) -> bool
    def refresh_token(self) -> bool
    def is_authenticated(self) -> bool

Upload Flow:

# 1. Authenticate (if needed)
if not client.is_authenticated():
    success = client.authenticate()
    if not success:
        raise AuthenticationError("Login failed")

# 2. Initialize upload (multi-step hosts)
upload_info = client.init_upload(
    filename="vacation.zip",
    filesize=245823412
)

# 3. Upload file
upload_url = upload_info.get("url")
response = client.upload_file(filepath, upload_url)

# 4. Poll for completion (if required)
if client.requires_polling():
    upload_id = upload_info.get("upload_id")
    status = client.poll_upload(upload_id, max_retries=10)

# 5. Extract download link
download_link = client.extract_link(response)
return download_link

Template System

Template Storage Format

Location: ~/.bbdrop/templates/*.template.txt Encoding: UTF-8 Format: Plain text with BBCode and placeholder syntax

Example Template:

[center][b]Gallery: #folderName#[/b][/center]

[b]Statistics:[/b]
- Images: #pictureCount# (#extension# format)
- Resolution: #width#x#height# (longest side: #longest#px)
- Total Size: #folderSize#

[if galleryLink]
[b]Gallery Link:[/b] [url=#galleryLink#]View on imx.to[/url]
[/if]

[if hostLinks]
[b]Download:[/b]
#hostLinks#
[/if]

[if custom1]
[b]Photographer:[/b] #custom1#
[/if]

[if custom2]
[b]Location:[/b] #custom2#
[/if]

[b]Images:[/b]
#allImages#

Template Syntax Highlighting

Features:

Theme Support:

# Dark theme colors
DARK_THEME = {
  "placeholder": "#ffff00",
  "conditional": "#3399ff",
  "bbcode": "#00cc00",
  "url": "#cc99ff",
  "text": "#d4d4d4"
}

# Light theme colors
LIGHT_THEME = {
  "placeholder": "#ffcc00",
  "conditional": "#0066cc",
  "bbcode": "#008000",
  "url": "#9900ff",
  "text": "#333333"
}

Template Validation

Validation Rules:

  1. Placeholder Check: All placeholders must be from the 18 recognized placeholders
  2. Conditional Syntax: Matching [if]...[/if] pairs
  3. Nested Conditionals: Proper nesting (max 2 levels)
  4. Else Placement: [else] only within [if]...[/if]
  5. BBCode Tags: Matching opening/closing tags
  6. URL Syntax: Valid URL structure in [url] tags

Error Messages:

Error Line 5: Unknown placeholder: #invalidPlaceholder#
   Valid placeholders: #folderName#, #pictureCount#, ...

Error Line 12: Unclosed conditional tag
   Found: [if pictureCount]
   Missing: [/if]

Error Line 18: Orphaned [else] tag without matching [if]

Error Line 23: Unmatched BBCode tag
   Found: [b]Bold text
   Missing: [/b]

Error Line 30: Invalid URL syntax
   Found: [url]Invalid[/url]
   Expected: [url=http://...]Text[/url]

Automation & Hooks

Description: External script integration for custom workflows and automation.

Hook System

Component: src/processing/hooks_executor.py

Hook Types:

Features:


External Apps Configuration

Access: Settings -> External Apps

Configuration Fields:

Example Configuration:

{
  "name": "Upload to Rapidgator",
  "command": "python",
  "args": ["hooks/muh.py", "rapidgator", "%z"],
  "working_directory": "/home/user/bbdrop",
  "capture_output": true,
  "execute_on": "completed",
  "timeout": 300,
  "output_mapping": {
    "ext1": "$.download_link",
    "ext2": "$.file_id",
    "ext3": "$.file_size",
    "ext4": "$.upload_time"
  }
}

Parameter Substitution

Available Parameters:

Parameter Description Example Value
%N Gallery name Summer Vacation
%T Tab name Main
%p Gallery folder path /home/user/images/vacation
%C Image count 127
%s Size in bytes 245823412
%t Template name Detailed Example
%g Gallery ID (completed only) abc123xyz
%j JSON artifact path ~/.bbdrop/artifacts/abc123.json
%b BBCode file path ~/.bbdrop/bbcode/abc123.txt
%z ZIP path (auto-created) /tmp/bbdrop_abc123_vacation.zip
%c1-%c4 Custom field values User-defined
%e1-%e4 Extension field values External app outputs

Usage Example:

# Upload ZIP to external host after gallery completes
python hooks/muh.py rapidgator "%z"

# Process images with metadata
python hooks/process.py --name "%N" --count %C --path "%p"

# Send notification with gallery details
curl -X POST https://api.example.com/notify \
  -H "Content-Type: application/json" \
  -d '{"gallery":"%N","count":%C,"link":"%g"}'

Multi-Host Uploader (muh.py)

Component: hooks/muh.py Description: Standalone multi-host file uploader inspired by PolyUploader.

Supported Hosts:

Features:

Usage:

# Upload file to Rapidgator
python muh.py rapidgator /path/to/file.zip

# Upload with credentials
python muh.py rapidgator /path/to/file.zip username:password

# Upload from BBDrop hook (auto-created ZIP)
python muh.py rapidgator "%z"

Example Output:

{
  "success": true,
  "host": "rapidgator",
  "download_link": "https://rapidgator.net/file/abc123",
  "file_id": "abc123",
  "file_name": "vacation.zip",
  "file_size": 245823412,
  "upload_time": 12.34,
  "expires": null
}

Field Mapping in BBDrop:

{
  "ext1": "$.download_link",  // https://rapidgator.net/file/abc123
  "ext2": "$.file_id",        // abc123
  "ext3": "$.file_size",      // 245823412
  "ext4": "$.upload_time"     // 12.34
}

Auto-ZIP Creation

Feature: Automatic temporary ZIP creation for external hooks Parameter: %z

Behavior:

  1. User configures external app with %z parameter
  2. Gallery upload completes
  3. BBDrop creates temporary ZIP:
    • Location: System temp directory
    • Name: bbdrop_<gallery_id>_<gallery_name>.zip
    • Compression: STORE mode (no compression, fastest)
    • Contents: All images from gallery
  4. External app executes with ZIP path
  5. ZIP automatically deleted after execution (success or failure)

Benefits:


Configuration & Settings

Description: Comprehensive settings system with persistent storage.

Settings Dialog

Component: src/gui/settings_dialog.py Access: Ctrl+, or File -> Settings

Sections (sidebar navigation):


Adaptive Settings Panel

Component: src/gui/widgets/adaptive_settings_panel.py

Features:

Adaptive Behavior Example:

# File host settings only visible when host enabled
if fileboom_enabled:
    show(fileboom_api_key_field)
    show(fileboom_max_connections)
    show(fileboom_test_button)
else:
    hide(fileboom_api_key_field)
    hide(fileboom_max_connections)
    hide(fileboom_test_button)

Settings Storage

Locations:

Windows:

Registry: HKEY_CURRENT_USER\Software\BBDropUploader\BBDropGUI
Files: %APPDATA%\BBDropUploader\
  +-- settings.ini
  +-- bbdrop.db
  +-- token_cache.db
  +-- templates/

Linux:

Config: ~/.config/BBDropUploader/BBDropGUI.conf
Files: ~/.bbdrop/
  +-- bbdrop.ini
  +-- bbdrop.db
  +-- token_cache.db
  +-- templates/
  +-- artifacts/
  +-- bbcode/

Stored Settings:

SETTINGS = {
  # Window
  "window/width": 1200,
  "window/height": 800,
  "window/x": 100,
  "window/y": 100,
  "window/maximized": False,
  "window/theme": "auto",  # auto, dark, light

  # Upload
  "upload/max_retries": 3,
  "upload/retry_delay": 5,
  "upload/parallel_workers": 4,
  "upload/thumbnail_size": 3,  # 250x250
  "upload/thumbnail_format": 2,  # JPEG 90%
  "upload/public_gallery": True,

  # BBCode
  "bbcode/template": "Default Template",
  "bbcode/auto_copy": True,
  "bbcode/include_host_links": True,

  # File Hosts
  "filehosts/global_max": 3,
  "filehosts/fileboom/enabled": False,
  "filehosts/fileboom/max_connections": 2,
  "filehosts/rapidgator/enabled": False,
  "filehosts/rapidgator/max_connections": 2,

  # UI
  "ui/show_tray_icon": True,
  "ui/minimize_to_tray": True,
  "ui/confirm_delete": True,
  "ui/show_splash": True,

  # Logging
  "logging/level": "INFO",
  "logging/max_lines": 1000,
  "logging/auto_scroll": True,
  "logging/show_prefix": True
}

User Interface

Platform: PyQt6 Description: Modern, responsive GUI with dark/light theme support.

Main Window

Component: src/gui/main_window.py

Layout:

+-- BBDrop ----------------------------------------+
| File  Edit  View  Tools  Help                |
+----------------------------------------------+
| +-- Tabs ----------------------------------+ |
| | Main(3) | Archive(0) | File Hosts(1) | + | |
| +------------------------------------------+ |
| | Gallery Queue                            | |
| | +--------------------------------------+ | |
| | | Name          | Status    | Progress | | |
| | +---------------+-----------+----------+ | |
| | | Vacation      | Done      | [#####]  | | |
| | | Birthday      | Paused    | [###..]  | | |
| | | Event Photos  | Upload    | [##...]  | | |
| | +--------------------------------------+ | |
| +------------------------------------------+ |
| +-- Quick Settings ------------------------+ |
| | Template: [Detailed Example v]           | |
| | Public: [x]  Retries: [3v]  Size: [250v] | |
| +------------------------------------------+ |
| +-- Controls ------------------------------+ |
| | [Start All] [Pause All] [Clear Done]     | |
| | [Settings]  [View BBCode] [Help]         | |
| +------------------------------------------+ |
| Status: Upload 2.5 MB/s | 127.3/245.8 MB    |
+----------------------------------------------+

Features:


Keyboard Shortcuts

Tab Management:

Gallery Management:

Application:

Context Menu (Right-click gallery):


Themes

Supported Themes:

Stylesheets: Modular QSS system (assets/qss/base.qss + assets/qss/components/*.qss + assets/qss/themes/*.qss)

Dark Theme:

QMainWindow {
  background-color: #1e1e1e;
  color: #d4d4d4;
}

QPushButton {
  background-color: #2d2d30;
  color: #ffffff;
  border: 1px solid #3e3e42;
  padding: 5px 15px;
  border-radius: 3px;
}

QPushButton:hover {
  background-color: #3e3e42;
}

QTableWidget {
  background-color: #252526;
  alternate-background-color: #2d2d30;
  gridline-color: #3e3e42;
  color: #d4d4d4;
}

QTextEdit {
  background-color: #222222;  /* Code background */
  color: #d4d4d4;
  selection-background-color: #264f78;
  border: 1px solid #3e3e42;
}

Icon Manager

Component: src/gui/icon_manager.py

Features:

Icon Categories:

Icon Locations:

Since v0.7.4 icons use unified names (no -dark/-light suffix). The icon manager handles theme adaptation at runtime.

assets/
+-- status_queued.png
+-- status_uploading-001.png
+-- status_uploading-002.png
+-- status_uploading-003.png
+-- status_uploading-004.png
+-- status_completed.png
+-- status_failed.png
+-- hosts/
|   +-- logo/
|       +-- fileboom-icon.png
|       +-- rapidgator-icon.png
|       +-- keep2share-icon.png
|       +-- tezfiles-icon.png
|       +-- filedot-icon.png
|       +-- filespace-icon.png
|       +-- katfile-icon.png
+-- qss/
    +-- base.qss
    +-- components/
    +-- themes/

API:

from src.gui.icon_manager import get_icon_manager

icon_manager = get_icon_manager()

# Get themed icon
icon = icon_manager.get_icon("status_uploading", theme="dark")

# Get file host icon
icon = icon_manager.get_host_icon("rapidgator")

# Check if icon exists
exists = icon_manager.has_icon("custom_icon")

Progress Tracking

Component: src/gui/widgets/gallery_table.py

Features:

Progress Display:

+-- Gallery: Summer Vacation ------------------+
| Status: Uploading                            |
| Progress: [########........] 42%             |
| Images: 54 / 127                             |
| Speed: 2.5 MB/s                              |
| ETA: 3m 24s                                  |
| Uploaded: 127.3 MB / 245.8 MB                |
+----------------------------------------------+

Status Bar:

Upload 2.5 MB/s | Total: 127.3 MB / 245.8 MB | ETA: 3m 24s | Active: 2 | Queued: 3

Log Viewer

Component: src/gui/dialogs/log_viewer.py Access: Ctrl+L or Help -> View Logs

Features:

Log Levels:

LOG_LEVELS = {
  "DEBUG": logging.DEBUG,      # Detailed diagnostic info
  "INFO": logging.INFO,        # General information
  "WARNING": logging.WARNING,  # Warning messages
  "ERROR": logging.ERROR,      # Error messages
  "CRITICAL": logging.CRITICAL # Critical failures
}

Color Scheme:


Advanced Features

Duplicate Detection

Component: src/gui/dialogs/duplicate_detection_dialogs.py

Detection Methods:

User Options:

Configuration:

DUPLICATE_DETECTION = {
  "enabled": True,
  "check_path": True,      # Check folder path
  "check_name": True,      # Check gallery name
  "check_hash": False,     # MD5 hash (slow)
  "prompt_user": True      # Ask before action
}

Component: src/gui/dialogs/gallery_file_manager.py

Features:

UI:

+-- Gallery File Manager ----------------------+
| Gallery: Summer Vacation                     |
| Path: /home/user/images/vacation             |
| Total: 127 images | Size: 245.8 MB           |
|                                              |
| Filter: [Extension v] [Size v] [Dims v]      |
|                                              |
| +-- Files --------------------------------+  |
| | [x] IMG_0001.jpg  3.2 MB  4000x3000    |  |
| | [x] IMG_0002.jpg  3.1 MB  4000x3000    |  |
| | [ ] IMG_0003.jpg  3.3 MB  4000x3000    |  |
| | [x] IMG_0004.jpg  3.0 MB  4000x3000    |  |
| +----------------------------------------+  |
|                                              |
| Selected: 3 / 127 (9.6 MB)                   |
| [Select All] [Deselect All] [Delete]         |
|                      [Upload] [Cancel]       |
+----------------------------------------------+

Help Dialog

Component: src/gui/dialogs/help_dialog.py

Help Tabs:

  1. Overview: Application introduction and quick start
  2. Keyboard Shortcuts: All keyboard shortcuts reference
  3. BBCode Templates: Template syntax and placeholder guide
  4. Multi-Host Upload: File host setup and configuration
  5. Archive Support: ZIP extraction and compression
  6. Troubleshooting: Common issues and solutions

Features:

Emoji Font Stack:

font = QFont()
font.setFamilies([
  "Segoe UI",           # Base font (Windows)
  "Segoe UI Emoji",     # Emoji font (Windows)
  "Noto Color Emoji",   # Emoji font (Linux)
  "Apple Color Emoji"   # Emoji font (macOS)
])

Database & Storage

Queue Database

Location: ~/.bbdrop/bbdrop.db Engine: SQLite 3 Component: src/storage/database.py

Schema:

CREATE TABLE galleries (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL,
  path TEXT NOT NULL UNIQUE,
  status TEXT NOT NULL,
  tab TEXT DEFAULT 'Main',
  template TEXT DEFAULT 'Default Template',
  custom1 TEXT,
  custom2 TEXT,
  custom3 TEXT,
  custom4 TEXT,
  ext1 TEXT,
  ext2 TEXT,
  ext3 TEXT,
  ext4 TEXT,
  created_at INTEGER NOT NULL,
  completed_at INTEGER,
  gallery_id TEXT,
  bbcode_path TEXT,
  artifact_path TEXT,
  retry_count INTEGER DEFAULT 0,
  error_message TEXT
);

CREATE INDEX idx_status ON galleries(status);
CREATE INDEX idx_tab ON galleries(tab);
CREATE INDEX idx_created_at ON galleries(created_at);
CREATE INDEX idx_gallery_id ON galleries(gallery_id);

Features:


Queue Manager

Component: src/storage/queue_manager.py

API:

class QueueManager:
    def add_gallery(self, name: str, path: str, tab: str = "Main") -> int
    def get_gallery(self, gallery_id: int) -> dict
    def update_status(self, gallery_id: int, status: str)
    def update_custom_field(self, gallery_id: int, field: str, value: str)
    def get_galleries_by_status(self, status: str) -> List[dict]
    def get_galleries_by_tab(self, tab: str) -> List[dict]
    def remove_gallery(self, gallery_id: int)
    def clear_completed(self)
    def count_by_status(self) -> dict
    def get_all_galleries(self) -> List[dict]

Thread Safety:


Database Maintenance

Features:

Backup Location:

~/.db-backups/
+-- bbdrop-2025-11-17-001.db
+-- bbdrop-2025-11-16-001.db
+-- bbdrop-2025-11-15-001.db

Vacuum Schedule:

# Auto-vacuum on startup if:
# - Last vacuum > 7 days ago
# - Database size > 100 MB
# - Fragmentation > 20%

Artifact Storage

Location: ~/.bbdrop/artifacts/ Format: JSON Purpose: Store upload metadata and results

Artifact Structure:

{
  "gallery_id": "abc123xyz",
  "name": "Summer Vacation",
  "path": "/home/user/images/vacation",
  "uploaded_at": 1700000000,
  "image_count": 127,
  "total_size": 245823412,
  "gallery_url": "https://imx.to/g/abc123xyz",
  "images": [
    {
      "filename": "IMG_0001.jpg",
      "url": "https://imx.to/i/abc001",
      "size": 3200000,
      "width": 4000,
      "height": 3000
    }
  ],
  "file_host_links": {
    "rapidgator": "https://rapidgator.net/file/xyz789",
    "fileboom": "https://fboom.me/file/abc123",
    "keep2share": "https://k2s.cc/file/def456"
  },
  "custom_fields": {
    "custom1": "Photographer: John Doe",
    "custom2": "Location: Hawaii"
  },
  "ext_fields": {
    "ext1": "https://pixeldrain.com/u/abc123",
    "ext2": "file_id_12345",
    "ext3": "245823412",
    "ext4": "12.34"
  }
}

Network & Performance

HTTP Client

Component: src/network/client.py

Features:

Configuration:

SESSION_CONFIG = {
  "pool_connections": 10,
  "pool_maxsize": 100,
  "max_retries": 3,
  "timeout": 30,
  "keep_alive": True
}

pycurl Integration

Component: src/network/client.py (pycurl backend)

Features:

Windows DLL Bundling:

DLLs Required:

libcurl-*.dll
libssh2-*.dll
zlib-*.dll
openssl-*.dll (libssl, libcrypto)
nghttp2-*.dll

Parallel Upload Workers

Component: src/processing/upload_workers.py

Architecture:

UploadCoordinator
+-- UploadWorker #1 (thread)
+-- UploadWorker #2 (thread)
+-- UploadWorker #3 (thread)
+-- UploadWorker #4 (thread)

Features:

Configuration:

WORKER_CONFIG = {
  "max_workers": 4,
  "queue_size": 100,
  "thread_timeout": 300,
  "restart_on_error": True
}

Performance Optimizations

Startup Optimization:

Upload Optimization:

Memory Optimization: