Skip to content

Commit

Permalink
Add support for EPUB files (#1439)
Browse files Browse the repository at this point in the history
* Add support for EPUB files

Also generalize open document zip mime detection

* Fix exception handling in MimeFromOpenDocument
  • Loading branch information
floogulinc authored Sep 23, 2023
1 parent f8ffeb9 commit c79355f
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 31 deletions.
3 changes: 2 additions & 1 deletion hydrus/client/caches/ClientCaches.py
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ def Clear( self ):

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' )
Expand Down Expand Up @@ -861,6 +861,7 @@ def GetThumbnail( self, media ):
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' ]
Expand Down
17 changes: 17 additions & 0 deletions hydrus/core/HydrusArchiveHandling.py
Original file line number Diff line number Diff line change
@@ -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:
Expand All @@ -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
12 changes: 11 additions & 1 deletion hydrus/core/HydrusConstants.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,7 @@
IMAGE_GIF = 68
APPLICATION_PROCREATE = 69
IMAGE_QOI = 70
APPLICATION_EPUB = 71
APPLICATION_OCTET_STREAM = 100
APPLICATION_UNKNOWN = 101

Expand Down Expand Up @@ -778,6 +779,7 @@
APPLICATION_XCF,
APPLICATION_PROCREATE,
APPLICATION_PDF,
APPLICATION_EPUB,
APPLICATION_ZIP,
APPLICATION_RAR,
APPLICATION_7Z,
Expand Down Expand Up @@ -861,7 +863,8 @@

APPLICATIONS = [
APPLICATION_FLASH,
APPLICATION_PDF
APPLICATION_PDF,
APPLICATION_EPUB
]

IMAGE_PROJECT_FILES = [
Expand All @@ -883,6 +886,9 @@

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,
Expand Down Expand Up @@ -968,6 +974,7 @@
'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,
Expand Down Expand Up @@ -1031,6 +1038,7 @@
APPLICATION_JSON : 'json',
APPLICATION_CBOR : 'cbor',
APPLICATION_PDF : 'pdf',
APPLICATION_EPUB : 'epub',
APPLICATION_PSD : 'psd',
APPLICATION_CLIP : 'clip',
APPLICATION_SAI2 : 'sai2',
Expand Down Expand Up @@ -1108,6 +1116,7 @@
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
Expand Down Expand Up @@ -1183,6 +1192,7 @@
APPLICATION_YAML : '.yaml',
APPLICATION_JSON : '.json',
APPLICATION_PDF : '.pdf',
APPLICATION_EPUB : '.epub',
APPLICATION_PSD : '.psd',
APPLICATION_CLIP : '.clip',
APPLICATION_SAI2: '.sai2',
Expand Down
20 changes: 11 additions & 9 deletions hydrus/core/HydrusFileHandling.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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
Expand Down Expand Up @@ -75,6 +76,8 @@
( ( ( 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 ),
Expand Down Expand Up @@ -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 ):
Expand Down
21 changes: 1 addition & 20 deletions hydrus/core/HydrusKritaHandling.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

KRITA_FILE_THUMB = "preview.png"
KRITA_FILE_MERGED = "mergedimage.png"
KRITA_MIMETYPE = 'mimetype'

def ExtractZippedImageToPath( path_to_zip, temp_path_file ):

Expand Down Expand Up @@ -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


1 change: 1 addition & 0 deletions hydrus/core/HydrusPaths.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
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' )
Expand Down
Binary file added static/epub.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c79355f

Please sign in to comment.