diff --git a/docs/getting_started_files.md b/docs/getting_started_files.md index 68dc7dba..0c621968 100644 --- a/docs/getting_started_files.md +++ b/docs/getting_started_files.md @@ -96,6 +96,7 @@ Now: * **application/vnd.rar** (.rar) * **application/zip** (.zip) * **application/x-7z-compressed** (.7z) +* **application/gzip** (.gz) Although some support is imperfect for the complicated filetypes. For the Windows and Linux built releases, hydrus now embeds an MPV player for video, audio and gifs, which provides smooth playback and audio, but some other environments may not support MPV and so will default when possible to the native hydrus software renderer, which does not support audio. When something does not render how you want, right-clicking on its thumbnail presents the option 'open externally', which will open the file in the appropriate default program (e.g. ACDSee, VLC). diff --git a/hydrus/client/caches/ClientCaches.py b/hydrus/client/caches/ClientCaches.py index d4884ada..ea27e90b 100644 --- a/hydrus/client/caches/ClientCaches.py +++ b/hydrus/client/caches/ClientCaches.py @@ -751,7 +751,7 @@ class ThumbnailCache( object ): self._special_thumbs = {} - names = [ 'hydrus', 'pdf', 'psd', 'clip', 'sai', 'krita', 'svg', 'audio', 'video', 'zip' ] + names = [ 'hydrus', 'pdf', 'psd', 'clip', 'sai', 'krita', 'xcf', 'svg', 'audio', 'video', 'zip' ] bounding_dimensions = self._controller.options[ 'thumbnail_dimensions' ] thumbnail_scale_type = self._controller.new_options.GetInteger( 'thumbnail_scale_type' ) @@ -869,6 +869,7 @@ class ThumbnailCache( object ): 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' ] + elif mime == HC.APPLICATION_XCF: return self._special_thumbs[ 'xcf' ] elif mime == HC.IMAGE_SVG: return self._special_thumbs[ 'svg' ] elif mime in HC.ARCHIVES: return self._special_thumbs[ 'zip' ] else: return self._special_thumbs[ 'hydrus' ] diff --git a/hydrus/client/networking/ClientLocalServerResources.py b/hydrus/client/networking/ClientLocalServerResources.py index b627c1d8..fea3f921 100644 --- a/hydrus/client/networking/ClientLocalServerResources.py +++ b/hydrus/client/networking/ClientLocalServerResources.py @@ -702,7 +702,7 @@ def ParseHashes( request: HydrusServerRequest.HydrusRequest ): if len( hash_ids_to_hashes ) > 0: - hashes.extend( hash_ids_to_hashes[ hash_id ] ) + hashes.append(hash_ids_to_hashes[ hash_id ]) diff --git a/hydrus/core/HydrusConstants.py b/hydrus/core/HydrusConstants.py index 82a01f09..f488ccb7 100644 --- a/hydrus/core/HydrusConstants.py +++ b/hydrus/core/HydrusConstants.py @@ -716,12 +716,14 @@ AUDIO_WAVPACK = 53 APPLICATION_SAI2 = 54 APPLICATION_KRITA = 55 IMAGE_SVG = 56 +APPLICATION_XCF = 57 +APPLICATION_GZIP = 58 APPLICATION_OCTET_STREAM = 100 APPLICATION_UNKNOWN = 101 GENERAL_FILETYPES = { GENERAL_APPLICATION, GENERAL_AUDIO, GENERAL_IMAGE, GENERAL_VIDEO, GENERAL_ANIMATION } -SEARCHABLE_MIMES = { IMAGE_JPEG, IMAGE_PNG, IMAGE_APNG, IMAGE_GIF, IMAGE_WEBP, IMAGE_TIFF, IMAGE_ICON, IMAGE_SVG, APPLICATION_FLASH, VIDEO_AVI, VIDEO_FLV, VIDEO_MOV, VIDEO_MP4, VIDEO_MKV, VIDEO_REALMEDIA, VIDEO_WEBM, VIDEO_OGV, VIDEO_MPEG, APPLICATION_CLIP, APPLICATION_PSD, APPLICATION_SAI2, APPLICATION_KRITA, APPLICATION_PDF, APPLICATION_ZIP, APPLICATION_RAR, APPLICATION_7Z, AUDIO_M4A, AUDIO_MP3, AUDIO_REALMEDIA, AUDIO_OGG, AUDIO_FLAC, AUDIO_WAVE, AUDIO_TRUEAUDIO, AUDIO_WMA, VIDEO_WMV, AUDIO_MKV, AUDIO_MP4, AUDIO_WAVPACK } +SEARCHABLE_MIMES = { IMAGE_JPEG, IMAGE_PNG, IMAGE_APNG, IMAGE_GIF, IMAGE_WEBP, IMAGE_TIFF, IMAGE_ICON, IMAGE_SVG, APPLICATION_FLASH, VIDEO_AVI, VIDEO_FLV, VIDEO_MOV, VIDEO_MP4, VIDEO_MKV, VIDEO_REALMEDIA, VIDEO_WEBM, VIDEO_OGV, VIDEO_MPEG, APPLICATION_CLIP, APPLICATION_PSD, APPLICATION_SAI2, APPLICATION_KRITA, APPLICATION_XCF, APPLICATION_PDF, APPLICATION_ZIP, APPLICATION_RAR, APPLICATION_7Z, APPLICATION_GZIP, AUDIO_M4A, AUDIO_MP3, AUDIO_REALMEDIA, AUDIO_OGG, AUDIO_FLAC, AUDIO_WAVE, AUDIO_TRUEAUDIO, AUDIO_WMA, VIDEO_WMV, AUDIO_MKV, AUDIO_MP4, AUDIO_WAVPACK } STORABLE_MIMES = set( SEARCHABLE_MIMES ).union( { APPLICATION_HYDRUS_UPDATE_CONTENT, APPLICATION_HYDRUS_UPDATE_DEFINITIONS } ) @@ -737,7 +739,7 @@ AUDIO = { AUDIO_M4A, AUDIO_MP3, AUDIO_OGG, AUDIO_FLAC, AUDIO_WAVE, AUDIO_WMA, AU VIDEO = { VIDEO_AVI, VIDEO_FLV, VIDEO_MOV, VIDEO_MP4, VIDEO_WMV, VIDEO_MKV, VIDEO_REALMEDIA, VIDEO_WEBM, VIDEO_OGV, VIDEO_MPEG } -APPLICATIONS = { IMAGE_SVG, APPLICATION_FLASH, APPLICATION_PSD, APPLICATION_CLIP, APPLICATION_SAI2, APPLICATION_KRITA, APPLICATION_PDF, APPLICATION_ZIP, APPLICATION_RAR, APPLICATION_7Z } +APPLICATIONS = { IMAGE_SVG, APPLICATION_FLASH, APPLICATION_PSD, APPLICATION_CLIP, APPLICATION_SAI2, APPLICATION_KRITA, APPLICATION_XCF, APPLICATION_PDF, APPLICATION_ZIP, APPLICATION_RAR, APPLICATION_7Z, APPLICATION_ZIP } VIEWABLE_APPLICATIONS = { APPLICATION_PSD } @@ -762,7 +764,7 @@ for ( general_mime_type, mimes_in_type ) in general_mimetypes_to_mime_groups.ite MIMES_THAT_DEFINITELY_HAVE_AUDIO = tuple( [ APPLICATION_FLASH ] + list( AUDIO ) ) MIMES_THAT_MAY_HAVE_AUDIO = tuple( list( MIMES_THAT_DEFINITELY_HAVE_AUDIO ) + list( VIDEO ) ) -ARCHIVES = { APPLICATION_ZIP, APPLICATION_HYDRUS_ENCRYPTED_ZIP, APPLICATION_RAR, APPLICATION_7Z } +ARCHIVES = { APPLICATION_ZIP, APPLICATION_HYDRUS_ENCRYPTED_ZIP, APPLICATION_RAR, APPLICATION_7Z, APPLICATION_GZIP } APPLICATIONS_WITH_THUMBNAILS = set({ IMAGE_SVG, APPLICATION_FLASH, APPLICATION_CLIP, APPLICATION_KRITA }).union( VIEWABLE_APPLICATIONS ) @@ -803,6 +805,7 @@ mime_enum_lookup = { 'application/clip' : APPLICATION_CLIP, 'application/sai2': APPLICATION_SAI2, 'application/x-krita': APPLICATION_KRITA, + 'image/x-xcf' : APPLICATION_XCF, 'application/octet-stream' : APPLICATION_OCTET_STREAM, 'application/x-yaml' : APPLICATION_YAML, 'PDF document' : APPLICATION_PDF, @@ -810,6 +813,7 @@ mime_enum_lookup = { 'application/zip' : APPLICATION_ZIP, 'application/vnd.rar' : APPLICATION_RAR, 'application/x-7z-compressed' : APPLICATION_7Z, + 'application/gzip': APPLICATION_GZIP, 'application/json' : APPLICATION_JSON, 'application/cbor': APPLICATION_CBOR, 'application/hydrus-encrypted-zip' : APPLICATION_HYDRUS_ENCRYPTED_ZIP, @@ -866,9 +870,11 @@ mime_string_lookup = { APPLICATION_CLIP : 'clip', APPLICATION_SAI2 : 'sai2', APPLICATION_KRITA : 'krita', + APPLICATION_XCF : 'xcf', APPLICATION_ZIP : 'zip', APPLICATION_RAR : 'rar', APPLICATION_7Z : '7z', + APPLICATION_GZIP: 'gzip', APPLICATION_WINDOWS_EXE : 'windows exe', APPLICATION_HYDRUS_ENCRYPTED_ZIP : 'application/hydrus-encrypted-zip', APPLICATION_HYDRUS_UPDATE_CONTENT : 'application/hydrus-update-content', @@ -928,9 +934,11 @@ mime_mimetype_string_lookup = { APPLICATION_CLIP : 'application/clip', APPLICATION_SAI2: 'application/sai2', APPLICATION_KRITA: 'application/x-krita', + APPLICATION_XCF : 'image/x-xcf', APPLICATION_ZIP : 'application/zip', APPLICATION_RAR : 'application/vnd.rar', APPLICATION_7Z : 'application/x-7z-compressed', + APPLICATION_GZIP: 'application/gzip', APPLICATION_WINDOWS_EXE : 'application/octet-stream', APPLICATION_HYDRUS_ENCRYPTED_ZIP : 'application/hydrus-encrypted-zip', APPLICATION_HYDRUS_UPDATE_CONTENT : 'application/hydrus-update-content', @@ -990,9 +998,11 @@ mime_ext_lookup = { APPLICATION_CLIP : '.clip', APPLICATION_SAI2: '.sai2', APPLICATION_KRITA: '.kra', + APPLICATION_XCF : '.xcf', APPLICATION_ZIP : '.zip', APPLICATION_RAR : '.rar', APPLICATION_7Z : '.7z', + APPLICATION_GZIP: '.gz', APPLICATION_WINDOWS_EXE : '.exe', APPLICATION_HYDRUS_ENCRYPTED_ZIP : '.zip.encrypted', APPLICATION_HYDRUS_UPDATE_CONTENT : '', diff --git a/hydrus/core/HydrusFileHandling.py b/hydrus/core/HydrusFileHandling.py index a611ce5e..5285293f 100644 --- a/hydrus/core/HydrusFileHandling.py +++ b/hydrus/core/HydrusFileHandling.py @@ -78,6 +78,7 @@ headers_and_mime.extend( [ ( ( ( 0, b'8BPS\x00\x02' ), ), HC.APPLICATION_PSD ), # PSB, which is basically PSD v2 and does giganto resolution ( ( ( 0, b'CSFCHUNK' ), ), HC.APPLICATION_CLIP ), ( ( ( 0, b'SAI-CANVAS' ), ), HC.APPLICATION_SAI2 ), + ( ( ( 0, b'gimp xcf ' ), ), HC.APPLICATION_XCF ), ( ( ( 38, b'application/x-krita' ), ), HC.APPLICATION_KRITA ), # important this comes before zip files because this is also a zip file ( ( ( 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 ), @@ -88,6 +89,7 @@ headers_and_mime.extend( [ ( ( ( 0, b'7z\xBC\xAF\x27\x1C' ), ), HC.APPLICATION_7Z ), ( ( ( 0, b'\x52\x61\x72\x21\x1A\x07\x00' ), ), HC.APPLICATION_RAR ), ( ( ( 0, b'\x52\x61\x72\x21\x1A\x07\x01\x00' ), ), HC.APPLICATION_RAR ), + ( ( ( 0, b'\x1f\x8b' ), ), HC.APPLICATION_GZIP ), ( ( ( 0, b'hydrus encrypted zip' ), ), HC.APPLICATION_HYDRUS_ENCRYPTED_ZIP ), ( ( ( 4, b'ftypmp4' ), ), HC.UNDETERMINED_MP4 ), ( ( ( 4, b'ftypisom' ), ), HC.UNDETERMINED_MP4 ), diff --git a/static/xcf.png b/static/xcf.png new file mode 100644 index 00000000..b1e4af88 Binary files /dev/null and b/static/xcf.png differ