books

package
v0.0.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 28, 2026 License: MIT Imports: 36 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RegisterRoutesWithGroup

func RegisterRoutesWithGroup(g *echo.Group, db *bun.DB, cfg *config.Config, authMiddleware *auth.Middleware, scanner Scanner, pm *plugins.Manager, dlCache *downloadcache.Cache)

RegisterRoutesWithGroup registers book routes on a pre-configured group.

Types

type AuthorInput

type AuthorInput struct {
	Name string  `json:"name" validate:"required,max=200"`
	Role *string `json:"role,omitempty" validate:"omitempty,oneof=writer penciller inker colorist letterer cover_artist editor translator"`
}

AuthorInput represents an author with an optional role (for CBZ files).

type DeleteBookAndFilesResult added in v0.0.12

type DeleteBookAndFilesResult struct {
	FilesDeleted int
}

DeleteBookAndFilesResult contains the results of deleting a book and its files.

type DeleteBookResponse added in v0.0.12

type DeleteBookResponse struct {
	FilesDeleted int `json:"files_deleted"`
}

DeleteBookResponse is the response for deleting a book.

type DeleteBooksAndFilesResult added in v0.0.12

type DeleteBooksAndFilesResult struct {
	BooksDeleted int
	FilesDeleted int
}

DeleteBooksAndFilesResult contains the results of bulk book deletion.

type DeleteBooksRequest added in v0.0.12

type DeleteBooksRequest struct {
	BookIDs []int `json:"book_ids"`
}

DeleteBooksRequest is the request body for bulk book deletion.

type DeleteBooksResponse added in v0.0.12

type DeleteBooksResponse struct {
	BooksDeleted int `json:"books_deleted"`
	FilesDeleted int `json:"files_deleted"`
}

DeleteBooksResponse is the response for bulk book deletion.

type DeleteFileAndCleanupResult added in v0.0.12

type DeleteFileAndCleanupResult struct {
	BookDeleted    bool
	BookID         int
	PromotedFileID *int // ID of supplement file that was promoted to main, if any
}

DeleteFileAndCleanupResult contains the results of deleting a file.

type DeleteFileResponse added in v0.0.12

type DeleteFileResponse struct {
	BookDeleted bool `json:"book_deleted"`
}

DeleteFileResponse is the response for deleting a file.

type IdentifierPayload

type IdentifierPayload struct {
	Type  string `json:"type" validate:"required,min=1,max=50"`
	Value string `json:"value" validate:"required,max=100"`
}

IdentifierPayload represents an identifier in update requests.

type ListBooksOptions

type ListBooksOptions struct {
	Limit      *int
	Offset     *int
	LibraryID  *int
	LibraryIDs []int // Filter by multiple library IDs (for access control)
	SeriesID   *int
	FileTypes  []string // Filter by file types (e.g., ["epub", "cbz"])
	GenreIDs   []int    // Filter by genre IDs
	TagIDs     []int    // Filter by tag IDs
	IDs        []int    // Filter by specific book IDs
	Search     *string  // Search query for title/author
	// contains filtered or unexported fields
}

type ListBooksQuery

type ListBooksQuery struct {
	Limit     int      `query:"limit" json:"limit,omitempty" default:"24" validate:"min=1,max=50"`
	Offset    int      `query:"offset" json:"offset,omitempty" validate:"min=0"`
	LibraryID *int     `query:"library_id" json:"library_id,omitempty" validate:"omitempty,min=1" tstype:"number"`
	SeriesID  *int     `query:"series_id" json:"series_id,omitempty" validate:"omitempty,min=1" tstype:"number"`
	Search    *string  `query:"search" json:"search,omitempty" validate:"omitempty,max=100" tstype:"string"`
	FileTypes []string `query:"file_types" json:"file_types,omitempty"` // Filter by file types (e.g., ["epub", "m4b"])
	GenreIDs  []int    `query:"genre_ids" json:"genre_ids,omitempty"`   // Filter by genre IDs
	TagIDs    []int    `query:"tag_ids" json:"tag_ids,omitempty"`       // Filter by tag IDs
	IDs       []int    `query:"ids" json:"ids,omitempty"`               // Filter by specific book IDs
}

type ListFilesOptions

type ListFilesOptions struct {
	Limit  *int
	Offset *int
	BookID *int
	// contains filtered or unexported fields
}

type MergeBooksPayload added in v0.0.8

type MergeBooksPayload struct {
	SourceBookIDs []int `json:"source_book_ids" validate:"required,min=1,dive,min=1"`
	TargetBookID  int   `json:"target_book_id" validate:"required,min=1"`
}

MergeBooksPayload is the payload for merging multiple books.

type MergeBooksResponse added in v0.0.8

type MergeBooksResponse struct {
	TargetBook   *models.Book `json:"target_book"`
	FilesMoved   int          `json:"files_moved"`
	BooksDeleted int          `json:"books_deleted"`
}

MergeBooksResponse is the response from a merge books operation.

type MoveFilesOptions added in v0.0.8

type MoveFilesOptions struct {
	FileIDs         []int    // IDs of files to move
	TargetBookID    *int     // Target book ID (nil to create a new book)
	LibraryID       int      // Library ID for validation
	IgnoredPatterns []string // Patterns for ignored files during cleanup (e.g., ".DS_Store", ".*")
}

MoveFilesOptions contains the parameters for moving files between books.

type MoveFilesPayload added in v0.0.8

type MoveFilesPayload struct {
	FileIDs      []int `json:"file_ids" validate:"required,min=1,dive,min=1"`
	TargetBookID *int  `json:"target_book_id,omitempty" validate:"omitempty,min=1" tstype:"number"`
}

MoveFilesPayload is the payload for moving files to another book.

type MoveFilesResponse added in v0.0.8

type MoveFilesResponse struct {
	TargetBook        *models.Book `json:"target_book"`
	FilesMoved        int          `json:"files_moved"`
	SourceBookDeleted bool         `json:"source_book_deleted"`
}

MoveFilesResponse is the response from a move files operation.

type MoveFilesResult added in v0.0.8

type MoveFilesResult struct {
	TargetBook        *models.Book // The target book (with relations loaded)
	FilesMoved        int          // Number of files successfully moved
	SourceBookDeleted bool         // True if any source book was deleted
	DeletedBookIDs    []int        // IDs of books that were deleted
	NewBookCreated    bool         // True if a new book was created
}

MoveFilesResult contains the result of a move files operation.

type ResyncPayload

type ResyncPayload struct {
	Refresh bool `json:"refresh"`
}

ResyncPayload contains the request parameters for resync operations.

type RetrieveBookOptions

type RetrieveBookOptions struct {
	ID        *int
	Filepath  *string
	LibraryID *int
}

type RetrieveFileOptions

type RetrieveFileOptions struct {
	ID        *int
	Filepath  *string
	LibraryID *int
}

type ScanOptions

type ScanOptions struct {
	FileID       int  // Single file resync: file already in DB
	BookID       int  // Book resync: scan all files in book
	ForceRefresh bool // Bypass priority checks, overwrite all metadata
}

ScanOptions configures a scan operation. Entry points are mutually exclusive - exactly one of FileID or BookID must be set.

type ScanResult

type ScanResult struct {
	File        *models.File // The scanned/updated file (nil if deleted)
	Book        *models.Book // The parent book (nil if deleted)
	FileDeleted bool         // True if file was deleted (no longer on disk)
	BookDeleted bool         // True if book was also deleted (was last file)
}

ScanResult contains the results of a scan operation.

type Scanner

type Scanner interface {
	Scan(ctx context.Context, opts ScanOptions) (*ScanResult, error)
}

Scanner defines the interface for scanning file and book metadata. This interface is implemented by the worker package to avoid circular dependencies.

type SeriesInput

type SeriesInput struct {
	Name   string   `json:"name" validate:"required,max=200"`
	Number *float64 `json:"number,omitempty"`
}

SeriesInput represents a series association with optional number.

type Service

type Service struct {
	// contains filtered or unexported fields
}

func NewService

func NewService(db *bun.DB) *Service

func (*Service) BulkCreateAuthors added in v0.0.11

func (svc *Service) BulkCreateAuthors(ctx context.Context, authors []*models.Author) error

BulkCreateAuthors creates multiple book-author associations in a single query. Returns nil if the slice is empty.

func (*Service) BulkCreateBookGenres added in v0.0.11

func (svc *Service) BulkCreateBookGenres(ctx context.Context, bookGenres []*models.BookGenre) error

BulkCreateBookGenres creates multiple book-genre associations in a single query. Returns nil if the slice is empty.

func (*Service) BulkCreateBookSeries added in v0.0.11

func (svc *Service) BulkCreateBookSeries(ctx context.Context, bookSeries []*models.BookSeries) error

BulkCreateBookSeries creates multiple book-series associations in a single query. Returns nil if the slice is empty.

func (*Service) BulkCreateBookTags added in v0.0.11

func (svc *Service) BulkCreateBookTags(ctx context.Context, bookTags []*models.BookTag) error

BulkCreateBookTags creates multiple book-tag associations in a single query. Returns nil if the slice is empty.

func (*Service) BulkCreateFileIdentifiers added in v0.0.11

func (svc *Service) BulkCreateFileIdentifiers(ctx context.Context, identifiers []*models.FileIdentifier) error

BulkCreateFileIdentifiers creates multiple file identifier records in a single query. Returns nil if the slice is empty.

func (*Service) BulkCreateNarrators added in v0.0.11

func (svc *Service) BulkCreateNarrators(ctx context.Context, narrators []*models.Narrator) error

BulkCreateNarrators creates multiple file-narrator associations in a single query. Returns nil if the slice is empty.

func (*Service) CleanupOrphanedSeries

func (svc *Service) CleanupOrphanedSeries(ctx context.Context) (int, error)

CleanupOrphanedSeries soft-deletes series with no books. This is duplicated from series service to avoid import cycles.

func (*Service) CreateAuthor

func (svc *Service) CreateAuthor(ctx context.Context, author *models.Author) error

CreateAuthor creates a book-author association.

func (*Service) CreateBook

func (svc *Service) CreateBook(ctx context.Context, book *models.Book) error

func (*Service) CreateBookGenre

func (svc *Service) CreateBookGenre(ctx context.Context, bookGenre *models.BookGenre) error

CreateBookGenre creates a book-genre association.

func (*Service) CreateBookSeries

func (svc *Service) CreateBookSeries(ctx context.Context, bookSeries *models.BookSeries) error

CreateBookSeries creates a book-series association.

func (*Service) CreateBookTag

func (svc *Service) CreateBookTag(ctx context.Context, bookTag *models.BookTag) error

CreateBookTag creates a book-tag association.

func (*Service) CreateFile

func (svc *Service) CreateFile(ctx context.Context, file *models.File) error

func (*Service) CreateFileIdentifier

func (svc *Service) CreateFileIdentifier(ctx context.Context, identifier *models.FileIdentifier) error

CreateFileIdentifier creates a new file identifier record.

func (*Service) CreateNarrator

func (svc *Service) CreateNarrator(ctx context.Context, narrator *models.Narrator) error

CreateNarrator creates a file-narrator association.

func (*Service) DeleteAuthors

func (svc *Service) DeleteAuthors(ctx context.Context, bookID int) error

DeleteAuthors deletes all author associations for a book.

func (*Service) DeleteBook

func (svc *Service) DeleteBook(ctx context.Context, bookID int) error

DeleteBook deletes a book and all its associated records (files, authors, series, genres, tags).

func (*Service) DeleteBookAndFiles added in v0.0.12

func (svc *Service) DeleteBookAndFiles(ctx context.Context, bookID int, library *models.Library) (*DeleteBookAndFilesResult, error)

DeleteBookAndFiles deletes a book and all its files from both disk and database. If library.OrganizeFileStructure is true, the entire book directory is deleted. Otherwise, each file is deleted individually with its cover and sidecar.

func (*Service) DeleteBookGenres

func (svc *Service) DeleteBookGenres(ctx context.Context, bookID int) error

DeleteBookGenres deletes all genre associations for a book.

func (*Service) DeleteBookSeries

func (svc *Service) DeleteBookSeries(ctx context.Context, bookID int) error

DeleteBookSeries deletes all series associations for a book.

func (*Service) DeleteBookTags

func (svc *Service) DeleteBookTags(ctx context.Context, bookID int) error

DeleteBookTags deletes all tag associations for a book.

func (*Service) DeleteBooksAndFiles added in v0.0.12

func (svc *Service) DeleteBooksAndFiles(ctx context.Context, bookIDs []int, library *models.Library) (*DeleteBooksAndFilesResult, error)

DeleteBooksAndFiles deletes multiple books and all their files from disk and database.

func (*Service) DeleteBooksByIDs added in v0.0.21

func (svc *Service) DeleteBooksByIDs(ctx context.Context, bookIDs []int) error

DeleteBooksByIDs deletes multiple books and all their associated records in a single transaction. Used during scan cleanup to remove books with no remaining files.

func (*Service) DeleteFile

func (svc *Service) DeleteFile(ctx context.Context, fileID int) error

DeleteFile deletes a file and its associated records (narrators, identifiers). If the deleted file was the book's primary file, promotes another file to primary.

func (*Service) DeleteFileAndCleanup added in v0.0.12

func (svc *Service) DeleteFileAndCleanup(ctx context.Context, fileID int, library *models.Library, supportedTypes map[string]struct{}, ignoredPatterns []string) (*DeleteFileAndCleanupResult, error)

DeleteFileAndCleanup deletes a file from disk and database. If this was the last main file in the book, it checks if any supplement files can be promoted to main (based on supportedTypes). If a promotable supplement exists, the oldest one is promoted. If no promotable supplements exist, the book and remaining files are deleted. ignoredPatterns are glob patterns for files to ignore during directory cleanup (e.g., ".DS_Store", ".*").

func (*Service) DeleteFileIdentifiers

func (svc *Service) DeleteFileIdentifiers(ctx context.Context, fileID int) error

DeleteFileIdentifiers deletes all identifiers for a file.

func (*Service) DeleteFilesByIDs added in v0.0.21

func (svc *Service) DeleteFilesByIDs(ctx context.Context, fileIDs []int) error

DeleteFilesByIDs batch-deletes files and their associated records (narrators, identifiers, chapters). Unlike DeleteFile, it does NOT handle primary file promotion — the caller manages that separately. Returns nil if fileIDs is empty.

func (*Service) DeleteIdentifiersForFile

func (svc *Service) DeleteIdentifiersForFile(ctx context.Context, fileID int) (int, error)

DeleteIdentifiersForFile deletes all identifiers for a file.

func (*Service) DeleteNarratorsForFile

func (svc *Service) DeleteNarratorsForFile(ctx context.Context, fileID int) (int, error)

DeleteNarratorsForFile deletes all narrators for a file.

func (*Service) FindOrCreateSeries

func (svc *Service) FindOrCreateSeries(ctx context.Context, name string, libraryID int, nameSource string) (*models.Series, error)

FindOrCreateSeries finds an existing series or creates a new one (case-insensitive match). This is duplicated from series service to avoid import cycles.

func (*Service) GetBookSeriesForBook

func (svc *Service) GetBookSeriesForBook(ctx context.Context, bookID int) ([]*models.BookSeries, error)

GetBookSeriesForBook returns all series associations for a book.

func (*Service) GetFirstBookInSeriesByID

func (svc *Service) GetFirstBookInSeriesByID(ctx context.Context, seriesID int) (*models.Book, error)

GetFirstBookInSeriesByID returns the first book in a series, ordered by series number.

func (*Service) ListBooks

func (svc *Service) ListBooks(ctx context.Context, opts ListBooksOptions) ([]*models.Book, error)

func (*Service) ListBooksWithTotal

func (svc *Service) ListBooksWithTotal(ctx context.Context, opts ListBooksOptions) ([]*models.Book, int, error)

func (*Service) ListFiles

func (svc *Service) ListFiles(ctx context.Context, opts ListFilesOptions) ([]*models.File, error)

func (*Service) ListFilesForLibrary

func (svc *Service) ListFilesForLibrary(ctx context.Context, libraryID int) ([]*models.File, error)

ListFilesForLibrary returns all main files for a library. Used for orphan cleanup during batch scans - only main files are tracked, supplements don't need orphan cleanup.

func (*Service) ListFilesWithTotal

func (svc *Service) ListFilesWithTotal(ctx context.Context, opts ListFilesOptions) ([]*models.File, int, error)

func (*Service) MoveFilesToBook added in v0.0.8

func (svc *Service) MoveFilesToBook(ctx context.Context, opts MoveFilesOptions) (*MoveFilesResult, error)

MoveFilesToBook moves files from their current books to a target book. If TargetBookID is nil, a new book is created from the first file's directory. This method handles physical file relocation when the library has OrganizeFileStructure enabled.

func (*Service) PromoteNextPrimaryFile added in v0.0.21

func (svc *Service) PromoteNextPrimaryFile(ctx context.Context, bookID int) error

PromoteNextPrimaryFile selects the best remaining file for a book and sets it as primary_file_id. Main files are preferred over supplements; among equal roles, the oldest file (by created_at) wins. If no files remain, primary_file_id is set to NULL. This is called after a batch file deletion completes its transaction.

func (*Service) PromoteSupplementToMain added in v0.0.12

func (svc *Service) PromoteSupplementToMain(ctx context.Context, fileID int) error

PromoteSupplementToMain promotes a supplement file to a main file. Used during scan cleanup when the last main file is deleted but a promotable supplement exists.

func (*Service) RetrieveBook

func (svc *Service) RetrieveBook(ctx context.Context, opts RetrieveBookOptions) (*models.Book, error)

func (*Service) RetrieveBookByFilePath

func (svc *Service) RetrieveBookByFilePath(ctx context.Context, filepath string, libraryID int) (*models.Book, error)

RetrieveBookByFilePath finds a book that contains a file with the specified filepath.

func (*Service) RetrieveFile

func (svc *Service) RetrieveFile(ctx context.Context, opts RetrieveFileOptions) (*models.File, error)

func (*Service) RetrieveFileWithRelations

func (svc *Service) RetrieveFileWithRelations(ctx context.Context, fileID int) (*models.File, error)

RetrieveFileWithRelations retrieves a file with all relations needed for sidecar writing and fingerprint generation (Narrators, Identifiers, Publisher, Imprint). Use this instead of RetrieveFile when you need to call WriteFileSidecarFromModel or ComputeFingerprint.

func (*Service) RetrieveSeriesByID

func (svc *Service) RetrieveSeriesByID(ctx context.Context, id int) (*models.Series, error)

RetrieveSeriesByID retrieves a series by its ID.

func (*Service) UpdateBook

func (svc *Service) UpdateBook(ctx context.Context, book *models.Book, opts UpdateBookOptions) error

func (*Service) UpdateFile

func (svc *Service) UpdateFile(ctx context.Context, file *models.File, opts UpdateFileOptions) error

type SetPrimaryFilePayload added in v0.0.12

type SetPrimaryFilePayload struct {
	FileID int `json:"file_id" validate:"required,gt=0"`
}

SetPrimaryFilePayload is the request body for setting a book's primary file.

type UpdateBookOptions

type UpdateBookOptions struct {
	Columns       []string
	UpdateAuthors bool
	Authors       []mediafile.ParsedAuthor // Authors with roles for updating (requires UpdateAuthors to be true)
	OrganizeFiles bool                     // Whether to rename files when metadata changes
}

type UpdateBookPayload

type UpdateBookPayload struct {
	Title       *string       `json:"title,omitempty" validate:"omitempty,max=300"`
	SortTitle   *string       `json:"sort_title,omitempty" validate:"omitempty,max=300"`
	Subtitle    *string       `json:"subtitle,omitempty" validate:"omitempty,max=500"`
	Description *string       `json:"description,omitempty" validate:"omitempty,max=10000"`
	Authors     []AuthorInput `json:"authors,omitempty"`
	Series      []SeriesInput `json:"series,omitempty"`
	Genres      []string      `json:"genres,omitempty" validate:"omitempty,dive,max=100"` // Genre names
	Tags        []string      `json:"tags,omitempty" validate:"omitempty,dive,max=100"`   // Tag names
}

type UpdateFileOptions

type UpdateFileOptions struct {
	Columns []string
}

type UpdateFilePayload

type UpdateFilePayload struct {
	FileRole    *string              `json:"file_role,omitempty" validate:"omitempty,oneof=main supplement"`
	Name        *string              `json:"name,omitempty" validate:"omitempty,max=500"`
	Narrators   []string             `json:"narrators,omitempty" validate:"omitempty,dive,max=200"`
	URL         *string              `json:"url,omitempty" validate:"omitempty,max=500,url"`
	Publisher   *string              `json:"publisher,omitempty" validate:"omitempty,max=200"`
	Imprint     *string              `json:"imprint,omitempty" validate:"omitempty,max=200"`
	ReleaseDate *string              `json:"release_date,omitempty" validate:"omitempty"` // ISO 8601 date string
	Identifiers *[]IdentifierPayload `json:"identifiers,omitempty" validate:"omitempty,dive"`
}

UpdateFilePayload is the payload for updating a file's metadata.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL