{"id":13551527,"url":"https://github.com/djdembeck/bragibooks","last_synced_at":"2025-03-21T18:14:57.187Z","repository":{"id":37649504,"uuid":"361908267","full_name":"djdembeck/bragibooks","owner":"djdembeck","description":"An audiobook library cleanup and management tool built with Python and Django. Leveraging m4b-merge for audiobook standardization and editing. Ideal for enhancing audiobook library management.","archived":false,"fork":false,"pushed_at":"2024-09-17T16:17:03.000Z","size":1555,"stargazers_count":145,"open_issues_count":23,"forks_count":20,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-09-17T20:31:23.445Z","etag":null,"topics":["audible","audiobook-cleanup","audiobooks","audnexus","django","docker","library-management","m4b","metadata-management","metadata-parser","python"],"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/djdembeck.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}},"created_at":"2021-04-26T22:15:28.000Z","updated_at":"2024-09-03T05:29:43.000Z","dependencies_parsed_at":"2023-10-15T17:00:10.974Z","dependency_job_id":"8c87936b-b4f4-47f1-a710-d1ffddcddf4b","html_url":"https://github.com/djdembeck/bragibooks","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djdembeck%2Fbragibooks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djdembeck%2Fbragibooks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djdembeck%2Fbragibooks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djdembeck%2Fbragibooks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/djdembeck","download_url":"https://codeload.github.com/djdembeck/bragibooks/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244844530,"owners_count":20519790,"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":["audible","audiobook-cleanup","audiobooks","audnexus","django","docker","library-management","m4b","metadata-management","metadata-parser","python"],"created_at":"2024-08-01T12:01:49.880Z","updated_at":"2025-03-21T18:14:57.150Z","avatar_url":"https://github.com/djdembeck.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\r\n  \u003ca href=\"\" rel=\"noopener\"\u003e\r\n \u003cimg width=200px height=200px src=\"../assets/logos/logo.png?raw=true\" alt=\"Project logo\"\u003e\u003c/a\u003e\r\n\u003c/p\u003e\r\n\r\n\u003ch3 align=\"center\"\u003eBragibooks\u003c/h3\u003e\r\n\r\n\u003cdiv align=\"center\"\u003e\r\n\r\n[![Status](https://img.shields.io/badge/status-active-success.svg)]()\r\n[![GitHub Issues](https://img.shields.io/github/issues/djdembeck/bragibooks.svg)](https://github.com/djdembeck/bragibooks/issues)\r\n[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/djdembeck/bragibooks.svg)](https://github.com/djdembeck/bragibooks/pulls)\r\n[![License](https://img.shields.io/github/license/djdembeck/bragibooks)](https://github.com/djdembeck/bragibooks/blob/develop/LICENSE)\r\n[![Docker](https://github.com/djdembeck/bragibooks/actions/workflows/docker-publish.yml/badge.svg)](https://github.com/djdembeck/bragibooks/actions/workflows/docker-publish.yml)\r\n[![Docker Pulls](https://img.shields.io/docker/pulls/djdembeck/bragibooks)](https://hub.docker.com/r/djdembeck/bragibooks)\r\n[![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/djdembeck/bragibooks)](https://hub.docker.com/r/djdembeck/bragibooks)\r\n[![Docker Image Version (latest by date)](https://img.shields.io/docker/v/djdembeck/bragibooks)](https://hub.docker.com/r/djdembeck/bragibooks)\r\n[![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/djdembeck/bragibooks)](https://www.codefactor.io/repository/github/djdembeck/bragibooks)\r\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\r\n[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-)\r\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\r\n\r\n\u003c/div\u003e\r\n\r\n---\r\n\r\n\u003cp align=\"center\"\u003e An audiobook library cleanup \u0026 management app, written as a frontend for web use of \u003ca href=\"https://github.com/djdembeck/m4b-merge\"\u003em4b-merge\u003c/a\u003e.\r\n    \u003cbr\u003e \r\n\u003c/p\u003e\r\n\r\n## 📝 Table of Contents\r\n\r\n- [About](#about)\r\n- [Getting Started](#getting_started)\r\n- [Usage](#usage)\r\n- [Built Using](#built_using)\r\n- [Contributing](../CONTRIBUTING.md)\r\n- [Authors](#authors)\r\n- [Contributors](#contributors)\r\n\r\n## 🧐 About \u003ca name = \"about\"\u003e\u003c/a\u003e\r\n\r\n**Bragi - (god of poetry in [Norse mythology](https://en.wikipedia.org/wiki/Bragi)):**\r\nBragibooks provides a minimal and straightforward webserver that you can run remotely or locally on your server. Since Bragibooks runs in a docker, you no longer need to install dependencies on whichever OS you are on. You can\r\n\r\nSome basics of what Bragi does:\r\n- Merge multiple files\r\n- Convert mp3(s)\r\n- Cleanup existing data on an m4b file\r\n- More features on [m4b-merge's help page](https://github.com/djdembeck/m4b-merge)\r\n\r\n### Screens\r\n\r\nFolder/file selection             |  ASIN input\r\n:-------------------------:|:-------------------------:\r\n![file-selection](../assets/screens/file_picker.png)  |  ![asin-auto-search](../assets/screens/auto_search_panel.png)\r\n\r\nFolder/file selection             |  Post-proccess overview\r\n:-------------------------:|:-------------------------:\r\n![asin-custom-search](../assets/screens/custom_search.png)  |  ![post-process](../assets/screens/processing_panel.png)\r\n\r\n## 🏁 Getting Started \u003ca name = \"getting_started\"\u003e\u003c/a\u003e\r\n\r\nYou can either install this project directly or run it prepackaged in Docker.\r\n\r\n### Prerequisites\r\n\r\n#### Docker\r\n- All prerequisites are included in the image.\r\n\r\n#### Direct (Gunicorn)\r\n- You'll need to install m4b-tool and it's dependants from [the project's readme](https://github.com/sandreas/m4b-tool#installation)\r\n- Run `pip install -r requirements.txt` from this project's directory.\r\n\r\n### Installing\r\n\r\n#### Docker\r\nTo run Bragibooks as a container, you need to pass some paramaters in the run command:\r\n\r\n  | Parameter | Function |\r\n  | :----: | --- |\r\n  | `-v /path/to/input:/input` | Input folder |\r\n  | `-v /path/to/output:/output` | Output folder |\r\n  | `-v /appdata/bragibooks/config:/config` | Persistent config storage |\r\n  | `-p 8000:8000/tcp` | Port for your browser to use |\r\n  | `-e LOG_LEVEL=WARNING` | Choose any [logging level](https://www.loggly.com/ultimate-guide/python-logging-basics/) |\r\n  | `-e DEBUG=False` | Turn django debug on or off (default False) |\r\n  | `-e UID=99` | User ID to run the container as (default 99)|\r\n  | `-e GID=100` | Group ID to run the container as (default 100)|\r\n  | `-e CELERY_WORKERS=1` | The number or celery workers for processing books (default 1)|\r\n  | `-e CSRF_TRUSTED_ORIGINS=https://bragibooks.mydomain.com` | Domains to trust if bragibooks is hosted behind a reverse proxy. |\r\n\r\n\r\nWhich all together should look like: \r\n\r\n\tdocker run --rm -d --name bragibooks -v /path/to/input:/input -v /path/to/output:/output -v /appdata/bragibooks/config:/config -p 8000:8000/tcp -e LOG_LEVEL=WARNING ghcr.io/djdembeck/bragibooks:main\r\n\r\n## Docker Compose\r\n```\r\nversion: '3'\r\n\r\nservices:\r\n  bragi:\r\n    image: ghcr.io/djdembeck/bragibooks:main\r\n    container_name: bragibooks\r\n    environment:\r\n      - CSRF_TRUSTED_ORIGINS=https://bragibooks.mydomain.com\r\n      - LOG_LEVEL=INFO\r\n      - DEBUG=False\r\n      - UID=1000\r\n      - GID=1000\r\n    volumes:\r\n      - path/to/config:/config\r\n      - path/to/input:/input\r\n      - path/to/output/output:/output\r\n      - path/to/done:/done\r\n    ports:\r\n      - 8000:8000\r\n    restart: unless-stopped\r\n```\r\n\r\n\r\n#### Direct Build (Gunicorn)\r\n  - Copy static assets to  project folder:\r\n    ```\r\n    python manage.py collectstatic\r\n    ```\r\n  - Create the database:\r\n    ```\r\n    python manage.py migrate\r\n    ```\r\n  - Run the celery worker for processing books:\r\n    ```\r\n    celery -A bragibooks_proj worker \\\r\n    --loglevel=info \\ \r\n    --concurrency 1 \\\r\n    -E\r\n    ```\r\n  - Run the web server:\r\n    ```\r\n    gunicorn bragibooks_proj.wsgi \\\r\n    --bind 0.0.0.0:8000 \\\r\n    --timeout 1200 \\\r\n    --worker-tmp-dir /dev/shm \\\r\n    --workers=2 \\\r\n    --threads=4 \\\r\n    --worker-class=gthread \\\r\n    --reload \\\r\n    --enable-stdio-inheritance\r\n    ```\r\n\r\n## 🎈 Usage \u003ca name=\"usage\"\u003e\u003c/a\u003e\r\n\r\nThe Bragibooks process is a linear, 3 step process:\r\n1. __Select input__ - Use the file multi-select box to choose which books to process this session, and click next.\r\n2. __Submit ASINs__ - Bragi will auto search for the audiobook data on [Audible.com](https://www.audible.com) (US only). If the data found is incorrect you can do a custom search to find the correct title and then submit for processing.\r\n3. Wait for books to finish processing. This can take anywhere from 10 seconds to a few hours, depending on the number and type of files submitted. This will be done in the background.\r\n4. __Books page__ - Page where you can see the data assigned to each book after it has finished processing. You can also check the status of the books still being processed.\r\n\r\n## ⛏️ Built Using \u003ca name = \"built_using\"\u003e\u003c/a\u003e\r\n\r\n- [Django](https://www.djangoproject.com/) - Server/web framework\r\n- [Celery](https://docs.celeryq.dev/en/stable/getting-started/introduction.html) - Task queue and worker\r\n- [Bulma](https://bulma.io/) - Frontend CSS framework\r\n- [audnexus](https://github.com/laxamentumtech/audnexus) - API backend for metadata\r\n- [m4b-merge](https://github.com/djdembeck/m4b-merge) - File merging and tagging\r\n\r\n## ✍️ Authors \u003ca name = \"authors\"\u003e\u003c/a\u003e\r\n  \u003cimg src=\"https://github.com/djdembeck.png?size=100\"/\u003e\r\n  \r\n  [@djdembeck](https://github.com/djdembeck) - Idea \u0026 Initial work\r\n\r\n## Contributors ✨\r\n\r\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\r\n\r\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\r\n\u003c!-- prettier-ignore-start --\u003e\r\n\u003c!-- markdownlint-disable --\u003e\r\n\u003ctable\u003e\r\n  \u003ctbody\u003e\r\n    \u003ctr\u003e\r\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://koby.huckabee.dev\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/14910857?v=4?s=100\" width=\"100px;\" alt=\"Koby Huckabee\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eKoby Huckabee\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/djdembeck/bragibooks/commits?author=AceTugboat\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"#ideas-AceTugboat\" title=\"Ideas, Planning, \u0026 Feedback\"\u003e🤔\u003c/a\u003e \u003ca href=\"https://github.com/djdembeck/bragibooks/commits?author=AceTugboat\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\r\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://pilabor.com\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/2050604?v=4?s=100\" width=\"100px;\" alt=\"Andreas\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAndreas\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#tool-sandreas\" title=\"Tools\"\u003e🔧\u003c/a\u003e\u003c/td\u003e\r\n    \u003c/tr\u003e\r\n  \u003c/tbody\u003e\r\n\u003c/table\u003e\r\n\r\n\u003c!-- markdownlint-restore --\u003e\r\n\u003c!-- prettier-ignore-end --\u003e\r\n\r\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\r\n\r\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjdembeck%2Fbragibooks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjdembeck%2Fbragibooks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjdembeck%2Fbragibooks/lists"}