This script automates the process of moving audiobook files from OpenAudible or Libation to an organized folder structure and updates AudioBookShelf accordingly. It handles file organization, metadata mapping, and interaction with the AudioBookShelf API.
- Automated File Organization: Organizes audiobooks into a structured directory based on author and series.
- Multiple Download Sources: Supports both OpenAudible and Libation as download sources.
- Metadata Mapping: Extracts relevant metadata from JSON files generated by either OpenAudible or Libation.
- AudioBookShelf Integration: Scans the library, matches books with Audible, and updates AudioBookShelf.
- File Management: Optionally cleans up source folders after processing (for Libation).
- Error Handling and Logging: Provides informative logging and error messages.
- Desktop Notifications: Uses notify-send to display processing status.
- Configurable: Allows customization through command-line arguments.
- CLI or YAML Arguments: Accepts either CLI flags or a yaml file with arguments
- Python 3.8+: Ensure Python 3.8 or higher is installed on your system.
- Required Python Packages: Install the necessary packages using:
pip install -r requirements.txtCore dependencies include:
requests- For API communicationpyyaml- For YAML configuration file supportopenai- For AI-powered search (optional feature)pydantic- For structured data validationbs4(BeautifulSoup) - For web scraping support
Development dependencies (optional, for contributors):
black,flake8,mypy,isort- Code formatting and lintingpytest,pytest-cov,pytest-mock- Testing framework
- OpenAudible or Libation: This script assumes you have either OpenAudible or Libation installed and configured.
- AudioBookShelf: You need a running instance of AudioBookShelf and its API details.
- notify-send: For desktop notifications.
Note
Libation Auto-Export: As of the latest version, if you're using Libation and haven't provided a --books-json-path or the file doesn't exist, the script will automatically generate libation.json for you by calling libationcli export. The file will be created in your --source-audio-book-directory (where your Libation audiobooks are stored). This means you no longer need to manually export your library! However, you must have libationcli available in your PATH.
The script can be run from the command line with various arguments or using a YAML configuration file. Here are examples for both methods:
Libation example (with auto-generation - recommended, requires libationcli in PATH):
python openaudible_to_ab.py \
--server-url "http://audiobooks.example.com" \
--abs-api-token "YOUR_API_TOKEN" \
--library-id "1cc175ca-88b9-4910-abe5-bf10b8aaa702" \
--source-audio-book-directory "~/Libation/Books/" \
--destination-book-directory "/AudioBookShelf/library1" \
--log-file-path "/tmp/book_processing.txt" \
--audio-file-extension ".m4b" \
--purchased-how-long-ago 7 \
--download-program "Libation" \
--libation-folder-cleanup TrueTip
Notice that --books-json-path is not required! The script will automatically generate libation.json in your source audio book directory (~/Libation/Books/ in this example).
Libation example (with FileLocationsV2.json and explicit books.json path):
python openaudible_to_ab.py \
--server-url "http://audiobooks.example.com" \
--abs-api-token "YOUR_API_TOKEN" \
--library-id "1cc175ca-88b9-4910-abe5-bf10b8aaa702" \
--books-json-path "~/Libation/books.json" \
--libation-file-locations-path "~/Libation/FileLocationsV2.json" \
--source-audio-book-directory "~/Libation/Books/" \
--destination-book-directory "/AudioBookShelf/library1" \
--log-file-path "/tmp/book_processing.txt" \
--audio-file-extension ".m4b" \
--purchased-how-long-ago 7 \
--download-program "Libation" \
--libation-folder-cleanup TrueLibation example (without FileLocationsV2.json - legacy mode):
python openaudible_to_ab.py \
--server-url "http://audiobooks.example.com" \
--abs-api-token "YOUR_API_TOKEN" \
--library-id "1cc175ca-88b9-4910-abe5-bf10b8aaa702" \
--books-json-path "~/Libation/books.json" \
--source-audio-book-directory "~/Libation/Books/" \
--destination-book-directory "/AudioBookShelf/library1" \
--log-file-path "/tmp/book_processing.txt" \
--audio-file-extension ".m4b" \
--purchased-how-long-ago 7 \
--download-program "Libation" \
--libation-folder-cleanup TrueOpenAudible Example:
python openaudible_to_ab.py \
--server-url "http://audiobooks.example.com" \
--abs-api-token "YOUR_API_TOKEN" \
--library-id "1cc175ca-88b9-4910-abe5-bf10b8aaa702" \
--books-json-path "~/OpenAudible/books.json" \
--source-audio-book-directory "~/OpenAudible/books/" \
--destination-book-directory "/AudioBookShelf/library1" \
--log-file-path "/tmp/book_processing.txt" \
--audio-file-extension ".m4b" \
--purchased-how-long-ago 7 \
--download-program "OpenAudible"Note
There is an example YAML file arguments.yaml which is included in the repo.
This file currently looks like:
abs_api_token: ""
books_json_path: ""
purchased_how_long_ago: 0
destination_book_directory: ""
download_program: OpenAudible
audio_file_extension: ".m4b"
copy_instead_of_move: false
libation_folder_cleanup: false
libation_file_locations_path: ""
library_id: ""
log_file_path: "/tmp/book_processing.txt"
server_url: "http://example.com"
source_audio_book_directory: "/tmp/OpenAudible/books"- --abs-api-token: Your AudioBookShelf API token.
- --books-json-path: Path to the JSON file exported from OpenAudible or Libation containing book information. (Optional for Libation - will be auto-generated if not provided or if file doesn't exist)
- --purchased-how-long-ago: Number of days to look back for recently purchased books (defaults to 7).
- --destination-book-directory: The destination directory where you want to organize your audiobooks.
- --download-program: Specify the download program - OpenAudible or Libation (defaults to OpenAudible).
- --audio-file-extension: Audio file extension (defaults to .m4b).
- --copy-instead-of-move: Copy files instead of moving them (useful for debugging/testing). Defaults to False.
- --libation-folder-cleanup: Whether to delete the source folder in Libation directory after processing (defaults to False).
- --libation-file-locations-path: Path to Libation's FileLocationsV2.json file (optional, for Libation users). When provided, the script will use the exact file paths from this file instead of constructing them. This is more reliable than the legacy path construction method.
- --library-id: The ID of your library in AudioBookShelf.
- --log-file-path: Path to the log file.
- --server-url: The base URL of your AudioBookShelf instance.
- --source-audio-book-directory: The directory where your download program saves audiobook files.
- --generate-yaml: This option writes your current flag choices to a YAML file without running the program.
- --yaml: Path to YAML configuration file.
-
Export Book Data: Export your OpenAudible or Libation library as a JSON file.
- OpenAudible: Automatically creates
books.jsonwhen you first login. - Libation: The script will automatically generate
libation.jsonif it doesn't exist (requireslibationcliin PATH). You can also manually export:libationcli export --path $HOME/libation/libation.json --json
- OpenAudible: Automatically creates
-
Configuration: Set the required command-line arguments or use a YAML configuration file.
-
Execution: Run the script. It will:
- (Libation only) Auto-generate
libation.jsonif needed - Process books purchased within the specified timeframe
- Move audiobook files to the organized directory structure
- Scan the AudioBookShelf library
- Match the moved books in AudioBookShelf with Audible metadata
- (Libation only) Auto-generate
-
Review Logs: Check the log file for any errors or information about the processed books.
The script organizes audiobooks in the following structure:
destination_dir/
├── Author_Name/
│ ├── Series_Name/
│ │ └── Book_Title/
│ │ └── audiobook_file.m4b
│ └── Standalone_Book/
│ └── audiobook_file.m4b
└── Another_Author/
└── ...
{
"asin": "B0123456789",
"author": "Author Name",
"summary": "Book summary...",
"filename": "book_filename",
"purchase_date": "2024-01-01",
"series_name": "Series Name",
"title_short": "Short Title",
"title": "Full Book Title",
"series_sequence": 1
}{
"AudibleProductId": "B0123456789",
"AuthorNames": "Author Name",
"Description": "Book description...",
"Title": "Book Title",
"Subtitle": "Book Subtitle",
"DateAdded": "2024-01-01T12:00:00.0+00:00",
"SeriesNames": "Series Name",
"SeriesOrder": "1"
}Libation maintains a FileLocationsV2.json file that contains the exact file paths for all downloaded audiobooks. Using this file is recommended as it eliminates the need for path construction and handles edge cases (like titles with colons) more reliably.
{
"Dictionary": {
"B0123456789": [
{
"Id": "B0123456789",
"FileType": 2,
"Path": {
"Path": "/path/to/DownloadsInProgress/B0123456789.aaxc"
}
},
{
"Id": "B0123456789",
"FileType": 1,
"Path": {
"Path": "/path/to/Books/Book Title [B0123456789]/Book Title: Subtitle [B0123456789].m4b"
}
}
]
}
}Note
FileType 1 indicates the actual audiobook file, while FileType 2 indicates temporary download files. The script automatically extracts the correct path for the audiobook file.
Contributions are welcome! Feel free to open issues or submit pull requests.
AGPL V3