Skip to content

Commit e1de364

Browse files
authored
Merge pull request #75 from geigerzaehler/replace-imghdr
Replace deprecated `imghdr` package with `filetype`
2 parents 6accdc4 + 182f3dd commit e1de364

File tree

5 files changed

+7
-53
lines changed

5 files changed

+7
-53
lines changed

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ v0.13.0
141141
- Add a mapping compatible with Plex and ffmpeg for the "original date"
142142
fields.
143143
- Remove an unnecessary dependency on `six`.
144+
- Replace `imghdr` with `filetype` to support Python 3.13.
144145
145146
v0.12.0
146147
'''''''

mediafile.py

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
import codecs
4747
import datetime
4848
import enum
49+
import filetype
4950
import functools
50-
import imghdr
5151
import logging
5252
import math
5353
import os
@@ -78,8 +78,6 @@
7878
'wav': 'WAVE',
7979
}
8080

81-
PREFERRED_IMAGE_EXTENSIONS = {'jpeg': 'jpg'}
82-
8381

8482
# Exceptions.
8583

@@ -346,52 +344,17 @@ def _sc_encode(gain, peak):
346344

347345

348346
# Cover art and other images.
349-
def _imghdr_what_wrapper(data):
350-
"""A wrapper around imghdr.what to account for jpeg files that can only be
351-
identified as such using their magic bytes
352-
See #1545
353-
See https://github.com/file/file/blob/master/magic/Magdir/jpeg#L12
354-
"""
355-
# imghdr.what returns none for jpegs with only the magic bytes, so
356-
# _wider_test_jpeg is run in that case. It still returns None if it didn't
357-
# match such a jpeg file.
358-
return imghdr.what(None, h=data) or _wider_test_jpeg(data)
359-
360-
361-
def _wider_test_jpeg(data):
362-
"""Test for a jpeg file following the UNIX file implementation which
363-
uses the magic bytes rather than just looking for the bytes that
364-
represent 'JFIF' or 'EXIF' at a fixed position.
365-
"""
366-
if data[:2] == b'\xff\xd8':
367-
return 'jpeg'
368-
369347

370348
def image_mime_type(data):
371349
"""Return the MIME type of the image data (a bytestring).
372350
"""
373-
# This checks for a jpeg file with only the magic bytes (unrecognized by
374-
# imghdr.what). imghdr.what returns none for that type of file, so
375-
# _wider_test_jpeg is run in that case. It still returns None if it didn't
376-
# match such a jpeg file.
377-
kind = _imghdr_what_wrapper(data)
378-
if kind in ['gif', 'jpeg', 'png', 'tiff', 'bmp']:
379-
return 'image/{0}'.format(kind)
380-
elif kind == 'pgm':
381-
return 'image/x-portable-graymap'
382-
elif kind == 'pbm':
383-
return 'image/x-portable-bitmap'
384-
elif kind == 'ppm':
385-
return 'image/x-portable-pixmap'
386-
elif kind == 'xbm':
387-
return 'image/x-xbitmap'
388-
else:
389-
return 'image/x-{0}'.format(kind)
351+
return filetype.guess_mime(data)
390352

391353

392354
def image_extension(data):
393-
ext = _imghdr_what_wrapper(data)
394-
return PREFERRED_IMAGE_EXTENSIONS.get(ext, ext)
355+
ext = filetype.guess_extension(data)
356+
# imghdr returned "tiff", so we should keep returning it with filetype.
357+
return ext if ext != 'tif' else 'tiff'
395358

396359

397360
class ImageType(enum.Enum):

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ home-page = "https://github.com/beetbox/mediafile"
1010
description-file = "README.rst"
1111
requires = [
1212
"mutagen>=1.46",
13+
"filetype>=1.2.0",
1314
]
1415
requires-python = ">=3.7"
1516
classifiers = [

test/rsrc/only-magic-bytes.jpg

-622 Bytes
Binary file not shown.

test/test_mediafile_edge.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,6 @@ def test_old_ape_version_bitrate(self):
7878
f = mediafile.MediaFile(media_file)
7979
self.assertEqual(f.bitrate, 0)
8080

81-
def test_only_magic_bytes_jpeg(self):
82-
# Some jpeg files can only be recognized by their magic bytes and as
83-
# such aren't recognized by imghdr. Ensure that this still works thanks
84-
# to our own follow up mimetype detection based on
85-
# https://github.com/file/file/blob/master/magic/Magdir/jpeg#L12
86-
magic_bytes_file = os.path.join(_common.RSRC, b'only-magic-bytes.jpg')
87-
with open(magic_bytes_file, 'rb') as f:
88-
jpg_data = f.read()
89-
self.assertEqual(
90-
mediafile._imghdr_what_wrapper(jpg_data), 'jpeg')
91-
9281
def test_soundcheck_non_ascii(self):
9382
# Make sure we don't crash when the iTunes SoundCheck field contains
9483
# non-ASCII binary data.

0 commit comments

Comments
 (0)