# manuel-alcocer/amularr architecture

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

- Interactive diagram: https://gitdiagram.com/manuel-alcocer/amularr
- Repository: https://github.com/manuel-alcocer/amularr

## Overview

amularr bridges Prowlarr and Sonarr/Radarr to aMule: searches become Torznab magnet results, which the qBittorrent-compatible API turns back into ed2k downloads. The bridge reports queue progress and completion, then *arr apps import completed files from aMule’s Incoming directory. A background wanted-item searcher helps surface new episodes and movies in RSS feeds. The graph includes the runtime entry point and EC protocol layer; unsampled modules and wiring are included only where the README or SOURCE INDEX supports them.

Main entry points: [`amularr/qbittorrent.py`](https://github.com/manuel-alcocer/amularr/blob/main/amularr/qbittorrent.py) (qBittorrent API), [`amularr/httpd.py`](https://github.com/manuel-alcocer/amularr/blob/main/amularr/httpd.py) (HTTP server), [`amularr/cli.py`](https://github.com/manuel-alcocer/amularr/blob/main/amularr/cli.py) (Service startup), [`amularr/torznab.py`](https://github.com/manuel-alcocer/amularr/blob/main/amularr/torznab.py) (Torznab API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["HTTP runtime"]
  node_cli["Service startup<br/>[cli.py]"]
  node_httpd["HTTP server<br/>[httpd.py]"]
  node_responses["HTTP responses<br/>[web.py]"]
end

subgraph group_search["Search and indexer"]
  node_torznab["Torznab API<br/>[torznab.py]"]
  node_search_service["Search service<br/>[search.py]"]
  node_wanted["Wanted searches<br/>[wanted.py]"]
end

subgraph group_downloads["Download bridge"]
  node_qbt["qBittorrent API<br/>[qbittorrent.py]"]
  node_state[("Download state<br/>[state.py]")]
end

subgraph group_ec["aMule protocol"]
  node_ec_client["EC client<br/>[client.py]"]
  node_ec_tags["Packet encoding<br/>[tag.py]"]
  node_ec_codes["EC constants<br/>[codes.py]"]
end

subgraph group_shared["Shared services"]
  node_config["Configuration<br/>[config.py]"]
end

node_prowlarr(("Prowlarr"))
node_arr_apps(("Sonarr / Radarr"))
node_amule["aMule core"]
node_incoming[("Incoming files")]

node_prowlarr -->|"sends Torznab requests"| node_httpd
node_arr_apps -->|"sends qBittorrent requests"| node_httpd
node_httpd -->|"routes indexer requests"| node_torznab
node_httpd -->|"routes download requests"| node_qbt
node_httpd -->|"uses responses"| node_responses
node_cli -->|"loads settings"| node_config
node_cli -->|"starts server"| node_httpd
node_torznab -->|"runs searches"| node_search_service
node_wanted -->|"searches wanted titles"| node_search_service
node_wanted -->|"builds search queries"| node_torznab
node_wanted -->|"fetches wanted items"| node_arr_apps
node_search_service -->|"runs aMule searches"| node_ec_client
node_torznab -->|"provides magnets"| node_qbt
node_qbt -->|"queues and manages downloads"| node_ec_client
node_qbt -->|"tracks downloads"| node_state
node_qbt -->|"checks completed files"| node_incoming
node_arr_apps -->|"imports completed files"| node_incoming
node_arr_apps -->|"deletes imported entries"| node_httpd
node_ec_client -->|"encodes EC packets"| node_ec_tags
node_ec_client -->|"uses protocol constants"| node_ec_codes
node_ec_tags -->|"uses tag constants"| node_ec_codes
node_amule -->|"serves EC requests"| node_ec_client
node_cli -->|"creates search service"| node_search_service
node_cli -->|"creates API facade"| node_qbt
node_cli -->|"creates indexer facade"| node_torznab
node_cli -->|"loads persistent state"| node_state
node_torznab -->|"returns API responses"| node_responses
node_qbt -->|"returns API responses"| node_responses
node_config -->|"maps search types"| node_ec_codes

click node_cli "https://github.com/manuel-alcocer/amularr/blob/main/amularr/cli.py"
click node_httpd "https://github.com/manuel-alcocer/amularr/blob/main/amularr/httpd.py"
click node_responses "https://github.com/manuel-alcocer/amularr/blob/main/amularr/web.py"
click node_torznab "https://github.com/manuel-alcocer/amularr/blob/main/amularr/torznab.py"
click node_search_service "https://github.com/manuel-alcocer/amularr/blob/main/amularr/search.py"
click node_wanted "https://github.com/manuel-alcocer/amularr/blob/main/amularr/wanted.py"
click node_qbt "https://github.com/manuel-alcocer/amularr/blob/main/amularr/qbittorrent.py"
click node_state "https://github.com/manuel-alcocer/amularr/blob/main/amularr/state.py"
click node_config "https://github.com/manuel-alcocer/amularr/blob/main/amularr/config.py"
click node_ec_client "https://github.com/manuel-alcocer/amularr/blob/main/amularr/ec/client.py"
click node_ec_tags "https://github.com/manuel-alcocer/amularr/blob/main/amularr/ec/tag.py"
click node_ec_codes "https://github.com/manuel-alcocer/amularr/blob/main/amularr/ec/codes.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_cli,node_httpd,node_responses toneBlue
class node_torznab,node_search_service,node_wanted,node_incoming toneAmber
class node_qbt,node_state toneMint
class node_ec_client,node_ec_tags,node_ec_codes toneRose
class node_config,node_prowlarr,node_arr_apps,node_amule toneIndigo
```

## Components

### HTTP runtime

- [Service startup](https://github.com/manuel-alcocer/amularr/blob/main/amularr/cli.py): `amularr/cli.py`
- [HTTP server](https://github.com/manuel-alcocer/amularr/blob/main/amularr/httpd.py): `amularr/httpd.py`
- [HTTP responses](https://github.com/manuel-alcocer/amularr/blob/main/amularr/web.py): `amularr/web.py`

### Search and indexer

- [Torznab API](https://github.com/manuel-alcocer/amularr/blob/main/amularr/torznab.py): `amularr/torznab.py`
- [Search service](https://github.com/manuel-alcocer/amularr/blob/main/amularr/search.py): `amularr/search.py`
- [Wanted searches](https://github.com/manuel-alcocer/amularr/blob/main/amularr/wanted.py): `amularr/wanted.py`

### Download bridge

- [qBittorrent API](https://github.com/manuel-alcocer/amularr/blob/main/amularr/qbittorrent.py): `amularr/qbittorrent.py`
- [Download state](https://github.com/manuel-alcocer/amularr/blob/main/amularr/state.py): `amularr/state.py`

### aMule protocol

- [EC client](https://github.com/manuel-alcocer/amularr/blob/main/amularr/ec/client.py): `amularr/ec/client.py`
- [Packet encoding](https://github.com/manuel-alcocer/amularr/blob/main/amularr/ec/tag.py): `amularr/ec/tag.py`
- [EC constants](https://github.com/manuel-alcocer/amularr/blob/main/amularr/ec/codes.py): `amularr/ec/codes.py`

### Shared services

- [Configuration](https://github.com/manuel-alcocer/amularr/blob/main/amularr/config.py): `amularr/config.py`

### Other components

- **Prowlarr**
- **Sonarr / Radarr**
- **aMule core**
- **Incoming files**

## Connections

- Prowlarr → HTTP server: sends Torznab requests (evidence: `README.md`)
- Sonarr / Radarr → HTTP server: sends qBittorrent requests (evidence: `README.md`)
- HTTP server → Torznab API: routes indexer requests (evidence: `amularr/httpd.py`)
- HTTP server → qBittorrent API: routes download requests (evidence: `amularr/httpd.py`)
- HTTP server → HTTP responses: uses responses (evidence: `amularr/httpd.py`)
- Service startup → Configuration: loads settings (evidence: `amularr/cli.py`)
- Service startup → HTTP server: starts server (evidence: `amularr/cli.py`)
- Torznab API → Search service: runs searches (evidence: `amularr/torznab.py`)
- Wanted searches → Search service: searches wanted titles (evidence: `amularr/wanted.py`)
- Wanted searches → Torznab API: builds search queries (evidence: `amularr/wanted.py`)
- Wanted searches → Sonarr / Radarr: fetches wanted items (evidence: `amularr/wanted.py`)
- Search service → EC client: runs aMule searches (evidence: `amularr/search.py`)
- Torznab API → qBittorrent API: provides magnets (evidence: `README.md`)
- qBittorrent API → EC client: queues and manages downloads (evidence: `README.md`)
- qBittorrent API → Download state: tracks downloads (evidence: `amularr/qbittorrent.py`)
- qBittorrent API → Incoming files: checks completed files (evidence: `README.md`)
- Sonarr / Radarr → Incoming files: imports completed files (evidence: `README.md`)
- Sonarr / Radarr → HTTP server: deletes imported entries (evidence: `README.md`)
- EC client → Packet encoding: encodes EC packets (evidence: `amularr/ec/client.py`)
- EC client → EC constants: uses protocol constants (evidence: `amularr/ec/client.py`)
- Packet encoding → EC constants: uses tag constants (evidence: `amularr/ec/tag.py`)
- aMule core → EC client: serves EC requests (evidence: `README.md`)
- Service startup → Search service: creates search service (evidence: `amularr/cli.py`)
- Service startup → qBittorrent API: creates API facade (evidence: `amularr/cli.py`)
- Service startup → Torznab API: creates indexer facade (evidence: `amularr/cli.py`)
- Service startup → Download state: loads persistent state (evidence: `amularr/cli.py`)
- Torznab API → HTTP responses: returns API responses (evidence: `amularr/torznab.py`)
- qBittorrent API → HTTP responses: returns API responses (evidence: `amularr/qbittorrent.py`)
- Configuration → EC constants: maps search types (evidence: `amularr/config.py`)
