Skip to content

About

I built this to organise my ebook collection

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Book Organizer for Audiobookshelf

A zero-dependency Python script that reorganises a flat folder of ebook files into the directory structure expected by Audiobookshelf.

Before                                     After
──────────────────────────────────         ──────────────────────────────────────────────────────
Adams, Douglas - Hitchhiker 01 -           Douglas Adams/
  The Hitchhiker's Guide to the              Hitchhiker/
  Galaxy.mobi                                  The Hitchhiker's Guide to the Galaxy/
Adams, Douglas - Hitchhiker 02 -                 The Hitchhiker's Guide to the Galaxy.mobi
  The Restaurant at the End of             Douglas Adams/
  the Universe.mobi                          Hitchhiker/
Atwood, Margaret -                             The Restaurant at the End of the Universe/
  The Handmaid's Tale.mobi                       The Restaurant at the End of the Universe.mobi
A Game of Thrones - Book 1.epub            Margaret Atwood/
A Clash of Kings - Book 2.epub               The Handmaid's Tale/
...                                              The Handmaid's Tale.mobi
                                           George R.R. Martin/
                                             A Song of Ice and Fire/
                                               A Game of Thrones/
                                                 A Game of Thrones.epub
                                               A Clash of Kings/
                                                 A Clash of Kings.epub

Features

  • Seven filename parsers handle the most common naming conventions found in the wild (see Supported formats below).
  • EPUB metadata fallback — files with unrecognisable names (e.g. hash-only filenames like 23d489d6b8b8f6fe54f886ff15f21136) are identified by reading the embedded dc:creator / dc:title from the OPF metadata inside the EPUB.
  • Series detection — series names are extracted from the filename and become an intermediate folder level (Author/Series/Title/file).
  • Conflict resolution — if two books would land in the same destination path the second one is renamed Title_2, Title_3, etc.
  • Dry-run mode — preview every planned move without touching any files.
  • Zero dependencies — standard library only; requires Python 3.10+.
  • Existing author sub-folders in the source are handled correctly.

Requirements

  • Python 3.10 or later (uses str | None union syntax)
  • No third-party packages required

Installation

git clone https://github.com/<you>/book-organizer.git
cd book-organizer

No virtual environment or pip install needed.


Configuration

Option A — environment variables

Copy .env.example to .env and fill in your paths, then source it before running:

cp .env.example .env
# edit .env, then:
source .env
python3 organize_books.py
Variable Description
BOOKS_SOURCE Required. Path to the existing flat ebook directory.
BOOKS_DEST Output directory. Defaults to <source>_organized if not set.

Option B — CLI flags (override env vars)

python3 organize_books.py --source DIR [--dest DIR] [--in-place] [--dry-run]
Flag Description
--source DIR Flat ebook source directory. Overrides $BOOKS_SOURCE.
--dest DIR Output directory. Overrides $BOOKS_DEST. Ignored with --in-place.
--in-place Reorganise directly inside the source folder.
--dry-run Print what would happen without moving any files.

Usage

1. Preview (recommended first step)

python3 organize_books.py --source /media/Books --dry-run

This prints every planned move and writes a full log to organize_books.log — no files are touched.

2. Move to a new folder

python3 organize_books.py --source /media/Books --dest /media/Books_organized

The original files stay in place until you delete them manually, giving you a chance to verify the organised output first.

3. Reorganise in-place

python3 organize_books.py --source /media/Books --in-place

Files are moved inside the source folder and empty leftover directories are removed afterwards.


Supported filename formats

Pattern Example input Resolved as
Lastname, First - Series ## - Title Adams, Douglas - Hitchhiker 01 - The Hitchhiker's Guide to the Galaxy.mobi Douglas Adams / Hitchhiker / The Hitchhiker's Guide…
Lastname, First - Title Atwood, Margaret - The Handmaid's Tale.mobi Margaret Atwood / The Handmaid's Tale
Name - Series ## - Title C.S. Lewis - The Chronicles of Narnia 01 - The Lion, the Witch and the Wardrobe.mobi C.S. Lewis / The Chronicles of Narnia / The Lion…
Name - Title Aesop - Aesop's Fables.mobi Aesop / Aesop's Fables
##. TITLE by Author 04. WHERE THE CRAWDADS SING by Delia Owens.epub Delia Owens / Where the Crawdads Sing
##_Title_words (year) 03_Blood_of_Elves (1994).epub Andrzej Sapkowski / The Witcher / Blood of Elves ¹
Title - Book N A Game of Thrones - Book 1.epub George R.R. Martin / A Song of Ice and Fire / A Game of Thrones ¹
[Author_Name]_Title_words [Shanna_Katz]_Some_Title.epub Shanna Katz / Some Title
Hash / no-metadata filename 23d489d6b8b8f6fe54f886ff15f21136 (EPUB) Reads embedded OPF metadata
Existing author sub-folder Charles Dickens/A Christmas Carol.pdf Charles Dickens / A Christmas Carol

¹ Requires the title to appear in the KNOWN_BOOKS dictionary (see below).

Adding custom series / author mappings

Open organize_books.py and add entries to the KNOWN_BOOKS dictionary near the top:

KNOWN_BOOKS: dict[str, tuple[str, str | None]] = {
    # "Exact Title as it appears in filename": ("Author Name", "Series Name or None"),
    "The Way of Kings": ("Brandon Sanderson", "The Stormlight Archive"),
    "Words of Radiance": ("Brandon Sanderson", "The Stormlight Archive"),
}

The lookup is case-insensitive and strips trailing year annotations like (1994).


Output structure

<dest>/
├── Author Name/
│   ├── Book Title/
│   │   └── Book Title.epub
│   └── Series Name/
│       ├── Book Title/
│       │   └── Book Title.mobi
│       └── Another Title/
│           └── Another Title.mobi
└── Unknown Author/
    └── Unrecognised Title/
        └── Unrecognised Title.pdf

Books whose author cannot be determined from the filename or EPUB metadata are placed under Unknown Author/ so they are still accessible in Audiobookshelf.


Log file

Every run appends to organize_books.log in the current working directory. Lines are prefixed with INFO, WARNING (skipped files), or ERROR (failed moves).


Supported file types

.epub .mobi .azw .azw3 .pdf .prc .fb2 .djvu .cbz .cbr .lit

Extension matching is case-insensitive (.MOBI is handled the same as .mobi). Extension-less EPUB files (detected by ZIP magic bytes) are also recognised.


License

MIT

About

I built this to organise my ebook collection

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages