mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-03-04 06:59:41 +00:00
65 lines
3.6 KiB
Markdown
65 lines
3.6 KiB
Markdown
# Consolidate Book Feature Specification
|
|
|
|
## Overview
|
|
|
|
The "Consolidate" feature allows users to organize their book library by renaming a book's folder to a standard `Author - Book Name` format and moving it to the root of the library folder. This helps in flattening nested structures and maintaining a consistent naming convention.
|
|
|
|
## User Interface
|
|
|
|
### Frontend
|
|
|
|
- Context menu on Book Card (Library View).
|
|
- Context menu on Book View page.
|
|
- A new option "Consolidate" will be added to the book card's context menu (the "meatball" menu).
|
|
- **Visibility**:
|
|
- Only available for Books (not Podcasts).
|
|
- Only available if the user has "Update" permissions.
|
|
- Only available if the item is a folder (not a single file).
|
|
- **Interaction**:
|
|
- Clicking "Consolidate" triggers a confirmation dialog explaining the action.
|
|
- Upon confirmation, the operation is performed.
|
|
- A toast notification indicates success or failure.
|
|
|
|
## Backend Logic
|
|
|
|
- **Endpoint**: `POST /api/items/:id/consolidate`
|
|
- **Controller**: `LibraryItemController.consolidate`
|
|
- **Logic**:
|
|
1. **Retrieve Item**: Fetch the library item by ID. Verify it is a book and the user has permissions.
|
|
2. **Determine New Name**: Construct the folder name using the pattern `${Author} - ${Title}`.
|
|
- `Author`: Primary author name.
|
|
- `Title`: Book title.
|
|
- **Sanitization**: Ensure the name is safe for the file system (remove illegal characters).
|
|
3. **Determine New Path**:
|
|
- `Target Library Folder`: The root path of the library the item belongs to.
|
|
- `New Path`: `Path.join(LibraryRoot, NewFolderName)`.
|
|
4. **Validation**:
|
|
- Check if `New Path` already exists.
|
|
- If it exists and is the same as the current path, return success (no-op).
|
|
- If it exists and is different, return an error (or handle collision - for now, error).
|
|
5. **Execution**:
|
|
- Move the directory from `Old Path` to `New Path`.
|
|
- Update the `path` and `relPath` in the `libraryItems` table.
|
|
- Update paths of all associated files (audio files, ebook files, cover, etc.) in the database.
|
|
- Update `libraryFolderId` to the root folder ID (if applicable/tracked).
|
|
6. **Cleanup**:
|
|
- If the old folder was inside another folder (e.g., `Author/Series/Book`), check if the parent folders are now empty and delete them if so (similar to how Move or Delete handles it). _Note: The existing `move` logic might handle this or we can reuse `handleMoveLibraryItem` if we can trick it or modify it._
|
|
- Actually, `handleMoveLibraryItem` takes a `targetFolder`. If we pass the library root as `targetFolder` and rename the directory before/during move?
|
|
- `handleMoveLibraryItem` assumes `itemFolderName` is `Path.basename(libraryItem.path)`. It does NOT rename the folder name itself.
|
|
- So we need a custom logic or a modified helper that supports renaming.
|
|
- **Response**: JSON object indicating success and the updated item.
|
|
- **Robustness Improvements**:
|
|
- Enhanced `handleMoveLibraryItem` to detect if the source and destination paths are identical.
|
|
- Skips file move operation if the paths match, preventing "Destination already exists" Errors.
|
|
- Ensures `Watcher` ignore directories are correctly managed even when paths are identical.
|
|
|
|
## Batch Consolidation
|
|
|
|
- **Endpoint**: `POST /api/items/batch/consolidate`
|
|
- **Controller**: `LibraryItemController.batchConsolidate`
|
|
- **Logic**: Iterates through selected item IDs and calls the consolidation logic for each.
|
|
- **Response**: Summary of successful and failed consolidation operations.
|
|
|
|
## Artifacts
|
|
|
|
- This specification is saved as `artifacts/2026-02-13/consolidate.md`.
|