package services import ( "bookhoard/internal/database" "context" "fmt" "log" "os" "path/filepath" "strings" "github.com/jackc/pgx/v5/pgtype" ) type LibraryService struct { db *database.Queries } func NewLibraryService(db *database.Queries) *LibraryService { return &LibraryService{ db: db, } } // Library type definitions and file extensions const ( LibraryTypeEbooks = "ebooks" LibraryTypeComics = "comics" LibraryTypeManga = "manga" LibraryTypeAudiobooks = "audiobooks" ) var AllowedExtensions = map[string][]string{ LibraryTypeEbooks: {".epub", ".pdf", ".mobi", ".azw", ".azw3", ".txt", ".rtf", ".docx", ".fb2", ".pdb"}, LibraryTypeComics: {".cbz", ".cbr", ".cb7", ".cbt", ".epub", ".pdf"}, LibraryTypeManga: {".cbz", ".cbr", ".epub", ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp", ".avif", ".tiff", ".tif"}, // All four decided breadth formats registered from day one (the // DOC/LIT doctrine: extensions are a deliberate list); only m4b // scans richly in Batch A — the chapter abstraction carries the rest. LibraryTypeAudiobooks: {".m4b", ".m4a", ".mp3", ".flac"}, } var MimeTypes = map[string]string{ // Images (manga) ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".bmp": "image/bmp", ".webp": "image/webp", ".avif": "image/avif", ".tiff": "image/tiff", ".tif": "image/tiff", // Comics ".cbz": "application/vnd.comicbook+zip", ".cbr": "application/vnd.comicbook-rar", ".cb7": "application/x-cb7", ".cbt": "application/x-cbt", // Ebooks ".epub": "application/epub+zip", ".pdf": "application/pdf", ".mobi": "application/x-mobipocket-ebook", ".azw": "application/vnd.amazon.ebook", ".azw3": "application/vnd.amazon.ebook", ".txt": "text/plain", ".rtf": "application/rtf", ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", ".fb2": "application/x-fictionbook+xml", ".pdb": "application/vnd.palm", // Audiobooks — audio/mp4 for the MP4-family containers is what // every platform decoder expects from an