# smeshidojoe/snatchr architecture

> Architecture diagram of the GitHub repository smeshidojoe/snatchr, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/smeshidojoe/snatchr
- Repository: https://github.com/smeshidojoe/snatchr

## Overview

1. **What this repo is**
   - Snatchr is a **Windows-only GUI downloader** packaged to live in the **system tray/menu bar** rather than as a traditional desktop window.
   - The architecture is centered around a lightweight Python app shell, a background download engine, and a small set of UI pages.

2. **Entry points and app bootstrap**
   - `main.py`, `app.py`, and `tray.py` are the top-level orchestration layer.
   - This layer likely initializes the application, creates the tray presence, and wires the UI to the core services.
   - The tray-first design is important: the app’s primary lifecycle is driven from the system tray rather than a full-screen or always-open window.

3. **UI layer**
   - The `ui/` directory contains the visible application surfaces:
     - `main_page.py` for the main download workflow
     - `settings_page.py` for preferences
     - `about_page.py` for app info/themes
     - `bottom_bar.py`, `widgets.py`, and `anim.py` for shared controls and motion effects
   - This layer is responsible for user input, presenting download progress, and reflecting app state, but not for the download logic itself.

4. **Core application services**
   - The `core/` package holds the non-UI logic that the interface depends on.
   - This includes:
     - `downloader.py` for acquiring media
     - `convert.py` for media post-processing
     - `workers.py` for background execution
     - `updater.py` for app/backend updating
     - `tools.py` for utility behavior shared across the app

5. **Download pipeline**
   - The main data flow is: **user pastes URL(s) in the UI → background worker starts → downloader fetches media → convert/post-processing runs if needed → UI updates with progress/result**.
   - `core/downloader.py` is the main boundary to the external media world, likely wrapping `yt-dlp` behavior as described in the README.
   - `core/convert.py` handles transformations such as embedding metadata, thumbnails, subtitles, or format conversion.

6. **Background execution and responsiveness**
   - `core/workers.py` is the key concurrency boundary.
   - Downloading and conversion are kept off the UI thread so the tray app stays responsive while handling single links or batches.
   - The README’s batch download behavior suggests this worker layer also manages queueing/collapsing UI state during long-running jobs.

7. **Configuration, state, and persistence**
   - `core/config.py` and `core/cache.py` define the app’s persisted state.
   - The README says configuration is stored under `C:\Users\[username]\AppData\Roaming\Snatchr`, so this repo has a clear separation between ephemeral UI state and user settings.
   - Likely persisted items include download preferences, theme selection, pinned/auto-hide behavior, and recent state.

8. **Theme, fonts, icons, and presentation assets**
   - `core/themes.py`, `core/fonts.py`, and `core/icons.py` bridge the UI to resources in `assets/`.
   - `assets/Themes/` and `assets/fonts/` indicate the app has a branded, themeable interface with bundled typography and visual styling.
   - These are presentation resources, not business logic, but they materially affect how the UI is composed.

9. **Internationalization and logging**
   - `core/i18n.py` suggests the UI text is abstracted for localization or language switching.
   - `core/logbook.py` suggests structured logging or operational diagnostics, likely useful for download failures and updater issues.
   - These subsystems are supportive but important for reliability and supportability.

10. **System/tray integration**
   - `tray.py` is a distinct boundary for Windows shell interaction.
   - Given the product positioning, tray integration likely handles open/close actions, pinning, auto-hide behavior, and launching the main page without a persistent dock/taskbar presence.

11. **External dependency boundary**
   - The README explicitly calls out `yt-dlp` as the backend engine.
   - From an architecture perspective, Snatchr is a GUI orchestrator around a local downloader backend rather than a network service or server app.
   - That means the critical external boundary is not a remote API owned by Snatchr, but the websites/media sources being accessed through the downloader engine.

12. **Operational model**
   - This is a **single-user, local-first desktop application** with no obvious server component in the repo.
   - Its main runtime responsibilities are: tray lifecycle, local configuration, background downloads, conversion, and UI state updates.
   - The architecture is therefore best diagrammed as a client app with internal service modules, not as a distributed system.

13. **Suggested high-level diagram boundaries**
   - One boundary for **UI/tray shell**
   - One boundary for **core services**: downloader, workers, conversion, updater
   - One boundary for **local persistence/resources**: config, cache, themes, fonts, icons
   - One external boundary for **media websites / yt-dlp backend**

Main entry points: [`app.py`](https://github.com/smeshidojoe/snatchr/blob/main/app.py) (app.py), [`core/workers.py`](https://github.com/smeshidojoe/snatchr/blob/main/core/workers.py) (Workers), [`ui/main_page.py`](https://github.com/smeshidojoe/snatchr/blob/main/ui/main_page.py) (Main page), [`core/themes.py`](https://github.com/smeshidojoe/snatchr/blob/main/core/themes.py) (Themes)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_shell["UI shell"]
  node_main["main.py<br/>entrypoint<br/>[main.py]"]
  node_app["app.py<br/>app shell<br/>[app.py]"]
  node_tray(("tray.py<br/>tray integration<br/>[tray.py]"))
  node_main_page["Main page<br/>ui page<br/>[main_page.py]"]
  node_settings_page["Settings<br/>ui page<br/>[settings_page.py]"]
  node_about_page["About<br/>ui page<br/>[about_page.py]"]
  node_widgets["Widgets<br/>ui components<br/>[widgets.py]"]
  node_anim["Animation<br/>ui motion<br/>[anim.py]"]
end

subgraph group_core["Core services"]
  node_workers["Workers<br/>background jobs<br/>[workers.py]"]
  node_downloader["Downloader<br/>media fetch<br/>[downloader.py]"]
  node_convert["Convert<br/>post-process<br/>[convert.py]"]
  node_updater["Updater<br/>update service<br/>[updater.py]"]
end

subgraph group_state["State and resources"]
  node_config[("Config<br/>settings store<br/>[config.py]")]
  node_cache[("Cache<br/>local state<br/>[cache.py]")]
  node_themes["Themes<br/>presentation resources<br/>[themes.py]"]
  node_fonts["Fonts<br/>resource loader<br/>[fonts.py]"]
  node_icons["Icons<br/>resource loader<br/>[icons.py]"]
  node_i18n["i18n<br/>localization<br/>[i18n.py]"]
  node_logbook["Logs<br/>logging<br/>[logbook.py]"]
end

subgraph group_external["External boundary"]
  node_yt_dlp{{"yt-dlp<br/>external backend"}}
  node_media_sites{{"Media sites<br/>external sources"}}
end

node_main -->|"starts"| node_app
node_app -->|"creates"| node_tray
node_app -->|"shows"| node_main_page
node_app -->|"shows"| node_settings_page
node_app -->|"shows"| node_about_page
node_main_page -->|"starts jobs"| node_workers
node_main_page -->|"composes"| node_widgets
node_main_page -->|"animates"| node_anim
node_settings_page -->|"edits"| node_config
node_about_page -->|"uses"| node_themes
node_app -->|"localizes"| node_i18n
node_app -->|"logs"| node_logbook
node_workers -->|"fetches"| node_downloader
node_workers -->|"post-processes"| node_convert
node_workers -->|"updates"| node_updater
node_workers -->|"reads/writes"| node_config
node_workers -->|"stores"| node_cache
node_downloader -->|"wraps"| node_yt_dlp
node_yt_dlp -.->|"accesses"| node_media_sites
node_themes -->|"loads"| node_fonts
node_themes -->|"loads"| node_icons
node_app -->|"applies"| node_themes
node_app -->|"loads"| node_config

click node_main "https://github.com/smeshidojoe/snatchr/blob/main/main.py"
click node_app "https://github.com/smeshidojoe/snatchr/blob/main/app.py"
click node_tray "https://github.com/smeshidojoe/snatchr/blob/main/tray.py"
click node_main_page "https://github.com/smeshidojoe/snatchr/blob/main/ui/main_page.py"
click node_settings_page "https://github.com/smeshidojoe/snatchr/blob/main/ui/settings_page.py"
click node_about_page "https://github.com/smeshidojoe/snatchr/blob/main/ui/about_page.py"
click node_widgets "https://github.com/smeshidojoe/snatchr/blob/main/ui/widgets.py"
click node_anim "https://github.com/smeshidojoe/snatchr/blob/main/ui/anim.py"
click node_workers "https://github.com/smeshidojoe/snatchr/blob/main/core/workers.py"
click node_downloader "https://github.com/smeshidojoe/snatchr/blob/main/core/downloader.py"
click node_convert "https://github.com/smeshidojoe/snatchr/blob/main/core/convert.py"
click node_updater "https://github.com/smeshidojoe/snatchr/blob/main/core/updater.py"
click node_config "https://github.com/smeshidojoe/snatchr/blob/main/core/config.py"
click node_cache "https://github.com/smeshidojoe/snatchr/blob/main/core/cache.py"
click node_themes "https://github.com/smeshidojoe/snatchr/blob/main/core/themes.py"
click node_fonts "https://github.com/smeshidojoe/snatchr/blob/main/core/fonts.py"
click node_icons "https://github.com/smeshidojoe/snatchr/blob/main/core/icons.py"
click node_i18n "https://github.com/smeshidojoe/snatchr/blob/main/core/i18n.py"
click node_logbook "https://github.com/smeshidojoe/snatchr/blob/main/core/logbook.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main,node_app,node_tray,node_main_page,node_settings_page,node_about_page,node_widgets,node_anim toneBlue
class node_workers,node_downloader,node_convert,node_updater toneAmber
class node_config,node_cache,node_themes,node_fonts,node_icons,node_i18n,node_logbook toneMint
class node_yt_dlp,node_media_sites toneRose
```

## Components

### UI shell

Tray-driven app bootstrap and visible pages.

- [main.py](https://github.com/smeshidojoe/snatchr/blob/main/main.py): entrypoint · Application start and bootstrap. · `main.py`
- [app.py](https://github.com/smeshidojoe/snatchr/blob/main/app.py): app shell · Top-level application wiring. · `app.py`
- [tray.py](https://github.com/smeshidojoe/snatchr/blob/main/tray.py): tray integration · System tray lifecycle and shell actions. · `tray.py`
- [Main page](https://github.com/smeshidojoe/snatchr/blob/main/ui/main_page.py): ui page · Primary download workflow. · `ui/main_page.py`
- [Settings](https://github.com/smeshidojoe/snatchr/blob/main/ui/settings_page.py): ui page · User preferences and app behavior. · `ui/settings_page.py`
- [About](https://github.com/smeshidojoe/snatchr/blob/main/ui/about_page.py): ui page · App info and theme presentation. · `ui/about_page.py`
- [Widgets](https://github.com/smeshidojoe/snatchr/blob/main/ui/widgets.py): ui components · Shared controls and reusable UI pieces. · `ui/widgets.py`
- [Animation](https://github.com/smeshidojoe/snatchr/blob/main/ui/anim.py): ui motion · Motion and transition effects. · `ui/anim.py`

### Core services

Download pipeline, background execution, and app logic.

- [Workers](https://github.com/smeshidojoe/snatchr/blob/main/core/workers.py): background jobs · Runs downloads and conversion off the UI thread. · `core/workers.py`
- [Downloader](https://github.com/smeshidojoe/snatchr/blob/main/core/downloader.py): media fetch · Acquires media through the backend downloader. · `core/downloader.py`
- [Convert](https://github.com/smeshidojoe/snatchr/blob/main/core/convert.py): post-process · Transforms media after download. · `core/convert.py`
- [Updater](https://github.com/smeshidojoe/snatchr/blob/main/core/updater.py): update service · Handles app or backend updating. · `core/updater.py`

### State and resources

Local persistence and bundled presentation assets.

- [Config](https://github.com/smeshidojoe/snatchr/blob/main/core/config.py): settings store · Persisted user preferences and app settings. · `core/config.py`
- [Cache](https://github.com/smeshidojoe/snatchr/blob/main/core/cache.py): local state · Ephemeral runtime or recent-state storage. · `core/cache.py`
- [Themes](https://github.com/smeshidojoe/snatchr/blob/main/core/themes.py): presentation resources · Theme loading and styling resources. · `core/themes.py`
- [Fonts](https://github.com/smeshidojoe/snatchr/blob/main/core/fonts.py): resource loader · Bundled font handling. · `core/fonts.py`
- [Icons](https://github.com/smeshidojoe/snatchr/blob/main/core/icons.py): resource loader · App icon and visual asset handling. · `core/icons.py`
- [i18n](https://github.com/smeshidojoe/snatchr/blob/main/core/i18n.py): localization · Language and text indirection. · `core/i18n.py`
- [Logs](https://github.com/smeshidojoe/snatchr/blob/main/core/logbook.py): logging · Structured diagnostics and operational logging. · `core/logbook.py`

### External boundary

Downloader backend and remote media sources.

- **yt-dlp**: external backend · Third-party downloader engine.
- **Media sites**: external sources · Remote sites and media endpoints being accessed.

## Connections

- main.py → app.py: starts · Entry bootstrap hands control to the app shell.
- app.py → tray.py: creates · App shell initializes tray-first lifecycle.
- app.py → Main page: shows · Main workflow page is wired into the UI.
- app.py → Settings: shows · Settings surface is wired into the UI.
- app.py → About: shows · About surface is wired into the UI.
- Main page → Workers: starts jobs · User actions enqueue background work.
- Main page → Widgets: composes · Main page uses shared controls.
- Main page → Animation: animates · UI motion supports the visible workflow.
- Settings → Config: edits · Preferences are persisted locally.
- About → Themes: uses · Presentation reflects bundled themes.
- app.py → i18n: localizes · UI text and labels are language-aware.
- app.py → Logs: logs · Application events and failures are recorded.
- Workers → Downloader: fetches · Background jobs invoke the media downloader.
- Workers → Convert: post-processes · Downloads can flow through conversion steps.
- Workers → Updater: updates · Worker layer can manage update tasks.
- Workers → Config: reads/writes · Job execution depends on persisted preferences.
- Workers → Cache: stores · Runtime state is cached locally.
- Downloader → yt-dlp: wraps · Repo depends on the external downloader backend.
- yt-dlp → Media sites: accesses · Backend reaches remote media sources.
- Themes → Fonts: loads · Theme composition uses bundled fonts.
- Themes → Icons: loads · Theme composition uses icons and artwork.
- app.py → Themes: applies · Application shell applies bundled presentation themes.
- app.py → Config: loads · Bootstrap reads persisted app settings.
