diff --git a/hydrus/client/caches/ClientCaches.py b/hydrus/client/caches/ClientCaches.py index f07b0cf0..e1e3608a 100644 --- a/hydrus/client/caches/ClientCaches.py +++ b/hydrus/client/caches/ClientCaches.py @@ -746,7 +746,7 @@ class ThumbnailCache( object ): self._special_thumbs = {} - names = [ 'hydrus', 'pdf', 'psd', 'clip', 'sai', 'krita', 'xcf', 'svg', 'audio', 'video', 'zip' ] + names = [ 'hydrus', 'pdf', 'psd', 'clip', 'sai', 'krita', 'xcf', 'svg', 'audio', 'video', 'zip', 'epub' ] bounding_dimensions = self._controller.options[ 'thumbnail_dimensions' ] thumbnail_scale_type = self._controller.new_options.GetInteger( 'thumbnail_scale_type' ) @@ -861,6 +861,7 @@ class ThumbnailCache( object ): elif mime in HC.AUDIO: return self._special_thumbs[ 'audio' ] elif mime in HC.VIDEO: return self._special_thumbs[ 'video' ] elif mime == HC.APPLICATION_PDF: return self._special_thumbs[ 'pdf' ] + elif mime == HC.APPLICATION_EPUB: return self._special_thumbs[ 'epub' ] elif mime == HC.APPLICATION_PSD: return self._special_thumbs[ 'psd' ] elif mime == HC.APPLICATION_SAI2: return self._special_thumbs[ 'sai' ] elif mime == HC.APPLICATION_KRITA: return self._special_thumbs[ 'krita' ] diff --git a/hydrus/core/HydrusArchiveHandling.py b/hydrus/core/HydrusArchiveHandling.py index 7d3ee8e1..787d207e 100644 --- a/hydrus/core/HydrusArchiveHandling.py +++ b/hydrus/core/HydrusArchiveHandling.py @@ -1,5 +1,7 @@ import zipfile +from hydrus.core import HydrusConstants as HC + def ExtractSingleFileFromZip( path_to_zip, filename_to_extract, extract_into_file_path ): with zipfile.ZipFile( path_to_zip ) as zip_handle: @@ -26,3 +28,18 @@ def ReadSingleFileFromZip( path_to_zip, filename_to_extract ): def GetZipAsPath( path_to_zip, path_in_zip="" ): return zipfile.Path( path_to_zip, at=path_in_zip ) + + +def MimeFromOpenDocument( path ): + + try: + + mimetype_data = GetZipAsPath( path, 'mimetype' ).read_text() + + filetype = HC.mime_enum_lookup.get(mimetype_data, None) + + return filetype if filetype in HC.OPEN_DOCUMENT_ZIPS else None + + except: + + return None diff --git a/hydrus/core/HydrusConstants.py b/hydrus/core/HydrusConstants.py index 809338ef..d057e97b 100644 --- a/hydrus/core/HydrusConstants.py +++ b/hydrus/core/HydrusConstants.py @@ -730,6 +730,7 @@ UNDETERMINED_GIF = 67 IMAGE_GIF = 68 APPLICATION_PROCREATE = 69 IMAGE_QOI = 70 +APPLICATION_EPUB = 71 APPLICATION_OCTET_STREAM = 100 APPLICATION_UNKNOWN = 101 @@ -778,6 +779,7 @@ SEARCHABLE_MIMES = { APPLICATION_XCF, APPLICATION_PROCREATE, APPLICATION_PDF, + APPLICATION_EPUB, APPLICATION_ZIP, APPLICATION_RAR, APPLICATION_7Z, @@ -861,7 +863,8 @@ VIDEO = [ APPLICATIONS = [ APPLICATION_FLASH, - APPLICATION_PDF + APPLICATION_PDF, + APPLICATION_EPUB ] IMAGE_PROJECT_FILES = [ @@ -883,6 +886,9 @@ ARCHIVES = [ VIEWABLE_IMAGE_PROJECT_FILES = { APPLICATION_PSD } +# zip files that have a `mimetype` file inside +OPEN_DOCUMENT_ZIPS = { APPLICATION_KRITA, APPLICATION_EPUB } + general_mimetypes_to_mime_groups = { GENERAL_APPLICATION : APPLICATIONS, GENERAL_APPLICATION_ARCHIVE : ARCHIVES, @@ -968,6 +974,7 @@ mime_enum_lookup = { 'application/x-yaml' : APPLICATION_YAML, 'PDF document' : APPLICATION_PDF, 'application/pdf' : APPLICATION_PDF, + 'application/epub+zip' : APPLICATION_EPUB, 'application/zip' : APPLICATION_ZIP, 'application/vnd.rar' : APPLICATION_RAR, 'application/x-7z-compressed' : APPLICATION_7Z, @@ -1031,6 +1038,7 @@ mime_string_lookup = { APPLICATION_JSON : 'json', APPLICATION_CBOR : 'cbor', APPLICATION_PDF : 'pdf', + APPLICATION_EPUB : 'epub', APPLICATION_PSD : 'psd', APPLICATION_CLIP : 'clip', APPLICATION_SAI2 : 'sai2', @@ -1108,6 +1116,7 @@ mime_mimetype_string_lookup = { APPLICATION_JSON : 'application/json', APPLICATION_CBOR : 'application/cbor', APPLICATION_PDF : 'application/pdf', + APPLICATION_EPUB : 'application/epub+zip', APPLICATION_PSD : 'image/vnd.adobe.photoshop', APPLICATION_CLIP : 'application/clip', # made up APPLICATION_SAI2: 'application/sai2', # made up @@ -1183,6 +1192,7 @@ mime_ext_lookup = { APPLICATION_YAML : '.yaml', APPLICATION_JSON : '.json', APPLICATION_PDF : '.pdf', + APPLICATION_EPUB : '.epub', APPLICATION_PSD : '.psd', APPLICATION_CLIP : '.clip', APPLICATION_SAI2: '.sai2', diff --git a/hydrus/core/HydrusFileHandling.py b/hydrus/core/HydrusFileHandling.py index 25db2fef..122539d0 100644 --- a/hydrus/core/HydrusFileHandling.py +++ b/hydrus/core/HydrusFileHandling.py @@ -5,6 +5,7 @@ from hydrus.core import HydrusAnimationHandling from hydrus.core import HydrusAudioHandling from hydrus.core import HydrusPSDHandling from hydrus.core import HydrusClipHandling +from hydrus.core import HydrusArchiveHandling from hydrus.core import HydrusConstants as HC from hydrus.core import HydrusData from hydrus.core import HydrusDocumentHandling @@ -75,6 +76,8 @@ headers_and_mime.extend( [ ( ( ( 42, b'application/x-krita' ), ), HC.APPLICATION_KRITA ), # https://gitlab.freedesktop.org/xdg/shared-mime-info/-/blob/master/data/freedesktop.org.xml.in#L2829 ( ( ( 58, b'application/x-krita' ), ), HC.APPLICATION_KRITA ), ( ( ( 63, b'application/x-krita' ), ), HC.APPLICATION_KRITA ), + ( ( ( 38, b'application/epub+zip' ), ), HC.APPLICATION_EPUB ), + ( ( ( 43, b'application/epub+zip' ), ), HC.APPLICATION_EPUB ), ( ( ( 0, b'PK\x03\x04' ), ), HC.APPLICATION_ZIP ), ( ( ( 0, b'PK\x05\x06' ), ), HC.APPLICATION_ZIP ), ( ( ( 0, b'PK\x07\x08' ), ), HC.APPLICATION_ZIP ), @@ -620,19 +623,18 @@ def GetMime( path, ok_to_look_for_hydrus_updates = False ): if it_passes: if mime == HC.APPLICATION_ZIP: + + opendoc_mime = HydrusArchiveHandling.MimeFromOpenDocument( path ) + + if opendoc_mime is not None: + + return opendoc_mime - # TODO: since we'll be expanding this to other zip-likes, we should make the zipfile object up here and pass that to various checkers downstream - if HydrusKritaHandling.ZipLooksLikeAKrita( path ): - - return HC.APPLICATION_KRITA - - elif HydrusProcreateHandling.ZipLooksLikeProcreate( path ): + if HydrusProcreateHandling.ZipLooksLikeProcreate( path ): return HC.APPLICATION_PROCREATE - else: - - return HC.APPLICATION_ZIP + return HC.APPLICATION_ZIP if mime in ( HC.UNDETERMINED_WM, HC.UNDETERMINED_MP4 ): diff --git a/hydrus/core/HydrusKritaHandling.py b/hydrus/core/HydrusKritaHandling.py index 85a608ef..01f1d733 100644 --- a/hydrus/core/HydrusKritaHandling.py +++ b/hydrus/core/HydrusKritaHandling.py @@ -6,7 +6,6 @@ import re KRITA_FILE_THUMB = "preview.png" KRITA_FILE_MERGED = "mergedimage.png" -KRITA_MIMETYPE = 'mimetype' def ExtractZippedImageToPath( path_to_zip, temp_path_file ): @@ -63,29 +62,11 @@ def GetKraProperties( path ): if width is not None and height is not None: break - + - - - except KeyError: raise HydrusExceptions.NoResolutionFileException( f'This krita file had no {DOCUMENT_INFO_FILE}!' ) return ( width, height ) - - -def ZipLooksLikeAKrita( path ): - - try: - - mimetype_data = HydrusArchiveHandling.ReadSingleFileFromZip( path, KRITA_MIMETYPE ) - - return b'application/x-krita' in mimetype_data - - except KeyError: - - return False - - diff --git a/hydrus/core/HydrusPaths.py b/hydrus/core/HydrusPaths.py index 06d122a9..ee1c2960 100644 --- a/hydrus/core/HydrusPaths.py +++ b/hydrus/core/HydrusPaths.py @@ -22,6 +22,7 @@ from hydrus.core import HydrusTime mimes_to_default_thumbnail_paths = collections.defaultdict( lambda: os.path.join( HC.STATIC_DIR, 'hydrus.png' ) ) mimes_to_default_thumbnail_paths[ HC.APPLICATION_PDF ] = os.path.join( HC.STATIC_DIR, 'pdf.png' ) +mimes_to_default_thumbnail_paths[ HC.APPLICATION_EPUB ] = os.path.join( HC.STATIC_DIR, 'epub.png' ) mimes_to_default_thumbnail_paths[ HC.APPLICATION_PSD ] = os.path.join( HC.STATIC_DIR, 'psd.png' ) mimes_to_default_thumbnail_paths[ HC.APPLICATION_CLIP ] = os.path.join( HC.STATIC_DIR, 'clip.png' ) mimes_to_default_thumbnail_paths[ HC.APPLICATION_SAI2 ] = os.path.join( HC.STATIC_DIR, 'sai.png' ) diff --git a/static/epub.png b/static/epub.png new file mode 100644 index 00000000..fc3979d4 Binary files /dev/null and b/static/epub.png differ