{"id":47622845,"url":"https://github.com/thrill-burn/auditorr","last_synced_at":"2026-04-01T22:24:45.703Z","repository":{"id":345519182,"uuid":"1183812828","full_name":"thrill-burn/auditorr","owner":"thrill-burn","description":"auditorr audits your torrent-based media library, detecting duplicates, orphaned files, missing links, and calculates cross-seeding efficiency","archived":false,"fork":false,"pushed_at":"2026-03-27T02:16:45.000Z","size":876,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-27T13:14:16.810Z","etag":null,"topics":["arr","docker","media-server","qbittorrent","radarr","self-hosted","sonarr","unraid"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thrill-burn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-17T01:15:09.000Z","updated_at":"2026-03-26T21:25:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/thrill-burn/auditorr","commit_stats":null,"previous_names":["thrill-burn/auditorr"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/thrill-burn/auditorr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thrill-burn%2Fauditorr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thrill-burn%2Fauditorr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thrill-burn%2Fauditorr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thrill-burn%2Fauditorr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thrill-burn","download_url":"https://codeload.github.com/thrill-burn/auditorr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thrill-burn%2Fauditorr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31292639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arr","docker","media-server","qbittorrent","radarr","self-hosted","sonarr","unraid"],"created_at":"2026-04-01T22:24:45.066Z","updated_at":"2026-04-01T22:24:45.692Z","avatar_url":"https://github.com/thrill-burn.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# auditorr\n\nauditorr shows you exactly what’s happening inside your media library.\n\nIt cross-references your hardlinked torrent and media directories with qBittorrent to generate a real-time health score, detecting orphaned files, duplicates, missing links, and calculates tracker statistics.\n\n![Dashboard](docs/dashboard.png)\n\n- **Health score (0–100)** — see how clean and efficient your library is\n- **Find wasted disk space** — duplicates, orphaned files, unlinked torrents with one-click delete and dedupe scripts\n- **Upload analytics \u0026 library yield** — daily upload volume per tracker, yield % over time, tracker leaderboard\n- **Cross-seeding insights** — weighted average seed multiplier, segmented disk bar, per-tracker breakdown\n- **Powerful file explorer** — tree and flat views, filter by status, tracker, seed count, size, filename\n- **Sonarr/Radarr integration** — open orphaned media directly in Sonarr or Radarr for interactive search\n- **Guided setup** — first-run wizard connects qBittorrent, verifies your paths, and optionally sets up Sonarr/Radarr\n\n---\n\n## Who is this for?\n\nauditorr is built for self-hosted media setups using qBittorrent + Sonarr/Radarr with hardlinks, following the [TRaSH Guides](https://trash-guides.info/File-and-Folder-Structure/).\n\nThe health score reflects how well your library is actually connected and seeding.\n\n---\n\n## Installation\n\n### Instant Quick Start\n\n```bash\ndocker run -d \\\n  --name auditorr \\\n  -p 8677:8677 \\\n  -v /mnt/user/appdata/auditorr/data:/app/data \\\n  -v /mnt/user/data:/data:ro \\\n  ghcr.io/thrill-burn/auditorr:latest\n```\n\nThen open `http://your-server-ip:8677`. On first launch, a setup wizard will guide you through connecting qBittorrent and configuring your data paths.\n\n### unRaid (Recommended)\n\nDocker tab → Add Container button at the bottom and fill in the blanks:\n\n- **Name:** `auditorr`\n- **Repository:** `ghcr.io/thrill-burn/auditorr:latest`\n- **Icon URL:** `https://raw.githubusercontent.com/thrill-burn/auditorr/main/docs/icon.png`\n- **WebUI:** `http://[IP]:[PORT:8677]/`\n- **App Path:** `/mnt/user/appdata/auditorr/data` → `/app/data`\n- **Data Path:** `/mnt/user/data` → `/data`\n- **Port Mapping:** `8677 → 8677`\n\nPress the Apply button, let the container install, then open `http://your-server-ip:8677`. The setup wizard will guide you through the rest.\n\n### Docker Compose\n\n```yaml\nservices:\n  auditorr:\n    image: ghcr.io/thrill-burn/auditorr:latest\n    container_name: auditorr\n    restart: unless-stopped\n    ports:\n      - \"8677:8677\"\n    volumes:\n      - /mnt/user/appdata/auditorr/data:/app/data\n      - /mnt/user/data:/data:ro\n      # TRaSH folder defaults, change if required\n    environment:\n      - AUDITORR_PORT=8677\n      # Uncomment to enable authentication:\n      # - AUDITORR_SECRET=your-secret-key\n```\n\n### Build from source\n\n```bash\ngit clone https://github.com/thrill-burn/auditorr.git\ncd auditorr\ndocker build -t auditorr .\ndocker run -d \\\n  --name auditorr \\\n  -p 8677:8677 \\\n  -v /mnt/user/appdata/auditorr/data:/app/data \\\n  -v /mnt/user/data:/data:ro \\\n  auditorr\n```\n\n---\n## Important\n\nauditorr assumes a **hardlink-based setup**.\n\nIf you are not using hardlinks, your health score will be low even if your library appears functional.\n\n---\n\n## Will this break my library?\n\nNo. auditorr is designed from the ground up to be read-only and non-destructive.\n\n- **Your media is physically read-only** — the Docker volume mount uses the `:ro` flag. auditorr cannot write, move, or delete any file in your media or torrent directories at the OS level, regardless of what any code does.\n- **qBittorrent access is read-only** — auditorr only calls qBittorrent's read endpoints (torrent list, file list, tracker list). It never pauses, removes, or modifies any torrent or tracker.\n- **No direct tracker communication** — auditorr never connects to your trackers. All tracker information (names, stats, upload data) is pulled from qBittorrent's local API, which already has that data. Your tracker relationships stay between you and qBittorrent.\n- **Scripts are yours to review** — the delete and dedupe scripts are plain text bash files. auditorr never executes them — you download, read, and run them yourself.\n- **Your credentials stay local** — Sonarr, Radarr, and qBittorrent credentials are stored in a SQLite database on your server and masked in the UI. Never sent anywhere except your own LAN instances.\n- **No external connections** — auditorr makes no outbound requests to the internet. Every API call goes to your own qBittorrent, Sonarr, or Radarr on your LAN.\n- **LAN-only by default** — the web UI is accessible only from private network IP ranges. No telemetry, no analytics, no phone-home.\n\n---\n## Configuration\n\nAll configuration is done through the **Config** tab in the UI.\n\n| Setting | Description |\n|---|---|\n| **qBittorrent Host** | URL of your qBittorrent instance, e.g. `http://192.168.1.x:8080` |\n| **Test Connection** | Verifies credentials and shows qBittorrent version, torrent count, and seeding size |\n| **qBit Save Path** | The path qBittorrent reports via its API. Use **Fetch from qBittorrent** to auto-populate. |\n| **Local Torrent Path** | Where those files actually live from auditorr's perspective (may differ if qBit runs in its own container) |\n| **Media Path** | Your final media library directory |\n| **Test Paths** | Verifies that Media Path and Local Torrent Path are visible inside the container, with per-path ✓/✗ feedback |\n| **Browse container filesystem** | Expandable `/data` directory browser — click any directory to fill Media Path or Local Torrent Path |\n| **Watchdog Cooldown** | Seconds to wait after a filesystem change before running an audit (default: 60) |\n| **Scheduled Interval** | Fallback audit interval in minutes (default: 360) |\n| **Thresholds** | Percentage of library at which each category loses all its points |\n| **Sonarr URL** | URL of your Sonarr instance, e.g. `http://192.168.1.x:8989`. Must be browser-accessible (LAN IP). |\n| **Sonarr API Key** | Found in Sonarr → Settings → General |\n| **Radarr URL** | URL of your Radarr instance, e.g. `http://192.168.1.x:7878`. Must be browser-accessible (LAN IP). |\n| **Radarr API Key** | Found in Radarr → Settings → General |\n| **Sonarr Remote Path** | Path to downloads as Sonarr sees it inside its container. Leave blank if paths are the same. |\n| **Radarr Remote Path** | Same for Radarr. |\n| **Exclusion Patterns** | Glob patterns (one per line) to exclude files from health scoring. e.g. `*.srt`, `@eaDir` |\n\n### Environment variables\n\n| Variable | Default | Description |\n|---|---|---|\n| `AUDITORR_PORT` | `8677` | Port to listen on |\n| `AUDITORR_SECRET` | *(unset)* | If set, all API routes require `X-Auditorr-Secret: \u003cvalue\u003e` header |\n| `DATA_DIR` | `/app/data` | Where config, history, and SQLite db are stored |\n\n---\n\n## Health Score\n\n| Component | Max Points | Description |\n|---|---|---|\n| Hardlinked Media | 70 | % of media library hardlinked back to a torrent file |\n| Orphaned Torrents | 10 | Files in media folder unknown to qBittorrent |\n| Not Imported | 10 | Seeding torrents with no matching media file |\n| Duplicate Files | 10 | Bit-for-bit identical files sharing no inode |\n\nFor the 10-point categories, points are lost linearly as problem data grows toward the configured threshold. At the threshold, all 10 points are gone.\n\n---\n\n## License\n\nMIT — see [LICENSE](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthrill-burn%2Fauditorr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthrill-burn%2Fauditorr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthrill-burn%2Fauditorr/lists"}