package sync import ( "path/filepath" "strings" ) // FormatGroup represents the three main format categories type FormatGroup string const ( FormatGroupReflowable FormatGroup = "reflowable" FormatGroupFixedLayout FormatGroup = "fixed_layout" FormatGroupComicArchive FormatGroup = "comic_archive" FormatGroupUnknown FormatGroup = "unknown" ) // MimeType mappings for common ebook formats var mimeTypes = map[string]string{ ".epub": "application/epub+zip", ".mobi": "application/x-mobipocket-ebook", ".azw": "application/x-mobipocket-ebook", ".azw3": "application/vnd.amazon.mobi8-ebook", ".pdf": "application/pdf", ".djvu": "image/vnd.djvu", ".cbz": "application/x-cbz", ".cbr": "application/x-cbr", ".cb7": "application/x-cb7", ".cbt": "application/x-cbt", ".fb2": "application/x-fictionbook+xml", ".txt": "text/plain", ".rtf": "application/rtf", ".doc": "application/msword", ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", ".lit": "application/x-ms-reader", ".pdb": "application/vnd.palm", ".prc": "application/vnd.palm", } // ReflowableFormats are formats that support text reflow var ReflowableFormats = map[string]bool{ ".epub": true, ".mobi": true, ".azw": true, ".azw3": true, ".fb2": true, ".txt": true, ".rtf": true, ".doc": true, ".docx": true, ".lit": true, ".pdb": true, ".prc": true, } // FixedLayoutFormats are formats with fixed page layouts var FixedLayoutFormats = map[string]bool{ ".pdf": true, ".djvu": true, } // ComicArchiveFormats are comic archive formats var ComicArchiveFormats = map[string]bool{ ".cbz": true, ".cbr": true, ".cb7": true, ".cbt": true, } // DetectFormatGroup determines the format group based on mimetype and file path func DetectFormatGroup(mimetype string, filePath string) FormatGroup { ext := strings.ToLower(filepath.Ext(filePath)) // Check by mimetype first switch mimetype { case "application/epub+zip", "application/x-mobipocket-ebook", "application/vnd.amazon.mobi8-ebook", "application/x-fictionbook+xml", "text/plain": return FormatGroupReflowable case "application/pdf", "image/vnd.djvu": return FormatGroupFixedLayout case "application/x-cbr", "application/x-cbz", "application/x-cb7", "application/x-cbt": return FormatGroupComicArchive } // Fall back to file extension if ReflowableFormats[ext] { return FormatGroupReflowable } if FixedLayoutFormats[ext] { return FormatGroupFixedLayout } if ComicArchiveFormats[ext] { return FormatGroupComicArchive } return FormatGroupUnknown } // GetMimeType returns the mimetype for a given file extension func GetMimeType(filePath string) string { ext := strings.ToLower(filepath.Ext(filePath)) if mt, ok := mimeTypes[ext]; ok { return mt } return "" } // IsReflowable checks if a format is reflowable func IsReflowable(formatGroup FormatGroup) bool { return formatGroup == FormatGroupReflowable } // HasFixedLayout checks if a format has fixed layout func HasFixedLayout(formatGroup FormatGroup) bool { return formatGroup == FormatGroupFixedLayout } // IsComicArchive checks if a format is a comic archive func IsComicArchive(formatGroup FormatGroup) bool { return formatGroup == FormatGroupComicArchive }