{"id":13523476,"url":"https://github.com/sentriz/betanin","last_synced_at":"2025-05-15T07:04:34.357Z","repository":{"id":38987531,"uuid":"142905169","full_name":"sentriz/betanin","owner":"sentriz","description":"beets based mitm of your torrent client and music player","archived":false,"fork":false,"pushed_at":"2025-05-05T13:13:15.000Z","size":3549,"stargazers_count":389,"open_issues_count":19,"forks_count":24,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-05T14:30:13.810Z","etag":null,"topics":["automation","beets","docker","flask","htpc","plex","self-hosted","torrent","transmission","vue"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sentriz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":["sentriz"]}},"created_at":"2018-07-30T17:10:02.000Z","updated_at":"2025-05-05T13:12:18.000Z","dependencies_parsed_at":"2023-12-26T02:23:39.885Z","dependency_job_id":"ea86f82a-02e5-4d04-94f7-7442b0026244","html_url":"https://github.com/sentriz/betanin","commit_stats":{"total_commits":317,"total_committers":8,"mean_commits":39.625,"dds":"0.12933753943217663","last_synced_commit":"b11f7a916455e3da40b5e13574aa6450af89a2a2"},"previous_names":[],"tags_count":63,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sentriz%2Fbetanin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sentriz%2Fbetanin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sentriz%2Fbetanin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sentriz%2Fbetanin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sentriz","download_url":"https://codeload.github.com/sentriz/betanin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254292039,"owners_count":22046426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["automation","beets","docker","flask","htpc","plex","self-hosted","torrent","transmission","vue"],"created_at":"2024-08-01T06:01:00.466Z","updated_at":"2025-05-15T07:04:29.342Z","avatar_url":"https://github.com/sentriz.png","language":"Python","funding_links":["https://github.com/sponsors/sentriz"],"categories":["Tools for Self-Hosting","Python","Software","Music"],"sub_categories":["Automation","Music Automation"],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg width=\"300\" src=\"https://github.com/sentriz/betanin/raw/master/.github/logo.png\"\u003e\n\u003c/p\u003e\n\u003ch4 align=\"center\"\u003e\n\u003ca href=\"http://beets.io/\"\u003ebeets.io\u003c/a\u003e based man-in-the-middle of your\ntorrent client and music player\n\u003c/h4\u003e\n\u003cp align=\"center\"\u003e\n\u003ca href=\"http://hub.docker.com/r/sentriz/betanin\"\u003e\u003cimg src=\"https://img.shields.io/docker/pulls/sentriz/betanin.svg\"\u003e\u003c/a\u003e\n\u003cimg src=\"https://img.shields.io/github/issues/sentriz/betanin.svg\"\u003e\n\u003cimg src=\"https://img.shields.io/github/issues-pr/sentriz/betanin.svg\"\u003e\n\u003c/p\u003e\n\u003chr\u003e\n\n### workflow\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/sentriz/betanin/raw/master/.github/flow.png\"\u003e\n\u003c/p\u003e\n\u003chr\u003e\n\n### notifiers\n\nbetanin uses [apprise](https://github.com/caronc/apprise) for\nnotifications. so anything supported there will work. but some include\n\n- email\n- discord\n- telegram\n- emby\n\n\u003chr\u003e\n\n### installation\n\n```shell\npip install --user betanin\n```\n\n\u003chr\u003e\n\n### usage\n\n```shell\n# start server\nbetanin\n# a config file will be created, add your credentials to it\n# start again\nbetanin [--host=\u003chost\u003e] [--port=\u003cport\u003e]\n# ui will be available at port\n# you may also use env vars instead, eg\nBETANIN_HOST=0.0.0.0 betanin\nBETANIN_PORT=4030 betanin\n\n# optionally start cli (for db operations, debugging)\nbetanin-shell\n# or if docker\ndocker exec -it \u003ccontainer_id\u003e betanin-shell\n```\n\n\u003chr\u003e\n\n### screenshots\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/sentriz/betanin/raw/master/.github/scrot_1.png\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/sentriz/betanin/raw/master/.github/scrot_2.png\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/sentriz/betanin/raw/master/.github/scrot_3.png\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/sentriz/betanin/raw/master/.github/scrot_4.png\"\u003e\n\u003c/p\u003e\n\u003chr\u003e\n\n### docker\n\n###### image\n\n`docker pull sentriz/betanin`\n\n###### volumes `/b/.local/share/betanin/` for a persistent database\n\n`/b/.config/betanin/` for a persistent betanin config  \n`/b/.config/beets/` for a persistent beets home (point this to your\ncurrent beets home if you have one)  \n`/music/` so beets can access your music  \n`/downloads/` so beets can access your downloads\n\n###### compose\n\n```yml\nbetanin:\n  image: sentriz/betanin\n  ports:\n    - 9393:9393\n  restart: unless-stopped\n  environment:\n    - UID=1000 # (optionally) set user id\n    - GID=1000 # (optionally) set group id\n  volumes:\n    - ${DATA}/betanin/data:/b/.local/share/betanin/\n    - ${DATA}/betanin/config:/b/.config/betanin/\n    - ${DATA}/betanin/beets:/b/.config/beets/\n    - ${MEDIA}/music:/music/\n    - ${MEDIA}/downloads:/downloads/\n```\n\n\u003chr\u003e\n\n### transmission\n\ncreate a script named `done.sh` or anything you like, and make it\nexecutable:  \n`chmod +x done.sh`\n\n###### settings.json (example excerpt)\n\n```json\n...\n\"script-torrent-done-enabled\": true,\n\"script-torrent-done-filename\": \"/scripts/done.sh\",\n...\n```\n\n###### done script\n\n```bash\n#!/bin/sh\n\ncurl \\\n    --request POST \\\n    --data-urlencode \"path=\u003cpath_to_transmission_downloads\u003e\" \\\n    --data-urlencode \"name=$TR_TORRENT_NAME\" \\\n    --header \"X-API-Key: \u003cyour_api_key\u003e\" \\\n    \"https://betanin.example.com/api/torrents\"\n```\n\n###### transmission docker compose (excerpt)\n\n```yaml\nvolumes:\n  - ${DATA}/transmission/config:/config\n  - ${DATA}/transmission/scripts:/scripts\n  - ${MEDIA}/download:/downloads\n```\n\n\u003chr\u003e\n\n### deluge\n\ncreate a script named `done.sh` or anything you like, and make it\nexecutable:  \n`chmod +x done.sh`  \nyou must also be using the\n[Execute](https://dev.deluge-torrent.org/wiki/Plugins/Execute) plugin,\nset to the `Torrent Complete` event\n\n###### done script\n\n```bash\n#!/bin/sh\n\ncurl \\\n    --request POST \\\n    --data-urlencode \"path=\u003cpath_to_deluge_downloads\u003e\" \\\n    --data-urlencode \"name=$2\" \\\n    --header \"X-API-Key: \u003cyour_api_key\u003e\" \\\n    \"https://betanin.example.com/api/torrents\"\n```\n\n\u003chr\u003e\n\n### qbittorrent\n\ncreate a script named `done.sh` or anything you like, and make it\nexecutable:  \n`chmod +x done.sh`\n\nopen qbittorrent `Tools` \u003e `Options` \u003e check `Run external program on torrent completion`\n\nset the path to the above `done.sh` and arguments such as\n\n```\n/path/to/done.sh \"%L\" \"%R\"\n```\n\n###### done script\n\n```bash\n#!/bin/sh\n\necho \"category: $1\"\necho \"path: $2\"\n\n[ \"$1\" != \"music\" ] \u0026\u0026 exit\n\ncurl \\\n    --request POST \\\n    --data-urlencode \"both=$2\" \\\n    --header \"X-API-Key: \u003cyour_api_key\u003e\" \\\n    \"https://betanin.example.com/api/torrents\"\n```\n\nnow any music downloaded to the **music** category will be imported by betanin\n\n\u003chr\u003e\n\n### developing\n\n###### working on the backend\n\nthere is not much else to do, write your code,\n`python -m betanin.entry.betanin`, kill it, write your code, etc. the\nwebserver will be available at _\u003chttp://localhost:9393/\u003e_. the static\nfrontend is served at `/`, and the api is served at `/api`. (there is a\nswagger ui there too) also see `python -m betanin.entry.shell`.  \nif you need to do a manual migration do\n`env FLASK_APP='betanin.application:create' flask db migrate --directory betanin_migrations/`\n(then upgrades are automatically done on betanin start)\n\n###### working on the frontend\n\nstart the backend with `python -m betanin.entry.betanin`, but don’t use\nthe static frontend served at _\u003chttp://localhost:9393/\u003e_. Instead, in a\nnew shell, do `npm --prefix betanin_client/ run serve` and use the\nfrontend served at _\u003chttp://localhost:8081/\u003e_. it will look for a backend\nlistening on port 9393 locally. after that you can edit anything in\n`betanin_client/src`, it will be linted and automatically reflected in\nyour web browser.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsentriz%2Fbetanin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsentriz%2Fbetanin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsentriz%2Fbetanin/lists"}