From 440332072706c5e422e6c54a2ec0ebb88e09c85c Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Sun, 24 Apr 2022 15:50:07 -0700 Subject: [PATCH] Rewrite audio.py to jive with image.py (#91886) Similar to the rewrite of email/mime/image.py and associated test after the deprecation of imghdr.py, thisrewrites email/mime/audio.py and associated tests after the deprecation of sndhdr.py. Closes #91885 --- Lib/email/mime/audio.py | 108 +++++++++--------- Lib/test/test_email/data/sndhdr.aifc | Bin 0 -> 106 bytes Lib/test/test_email/data/sndhdr.aiff | Bin 0 -> 108 bytes .../data/{audiotest.au => sndhdr.au} | Bin Lib/test/test_email/data/sndhdr.wav | Bin 0 -> 64 bytes Lib/test/test_email/test_email.py | 34 ++++-- 6 files changed, 78 insertions(+), 64 deletions(-) create mode 100644 Lib/test/test_email/data/sndhdr.aifc create mode 100644 Lib/test/test_email/data/sndhdr.aiff rename Lib/test/test_email/data/{audiotest.au => sndhdr.au} (100%) create mode 100644 Lib/test/test_email/data/sndhdr.wav diff --git a/Lib/email/mime/audio.py b/Lib/email/mime/audio.py index e859c2e8a2b6..8815f5c5ec06 100644 --- a/Lib/email/mime/audio.py +++ b/Lib/email/mime/audio.py @@ -11,58 +11,6 @@ from email import encoders from email.mime.nonmultipart import MIMENonMultipart -_tests = [] - -def _test_aifc_aiff(h, f): - if not h.startswith(b'FORM'): - return None - if h[8:12] in {b'AIFC', b'AIFF'}: - return 'x-aiff' - else: - return None - -_tests.append(_test_aifc_aiff) - - -def _test_au(h, f): - if h.startswith(b'.snd'): - return 'basic' - else: - return None - -_tests.append(_test_au) - - -def _test_wav(h, f): - import wave - # 'RIFF' 'WAVE' 'fmt ' - if not h.startswith(b'RIFF') or h[8:12] != b'WAVE' or h[12:16] != b'fmt ': - return None - else: - return "x-wav" - -_tests.append(_test_wav) - - -# There are others in sndhdr that don't have MIME types. :( -# Additional ones to be added to sndhdr? midi, mp3, realaudio, wma?? -def _whatsnd(data): - """Try to identify a sound file type. - - sndhdr.what() has a pretty cruddy interface, unfortunately. This is why - we re-do it here. It would be easier to reverse engineer the Unix 'file' - command and use the standard 'magic' file, as shipped with a modern Unix. - """ - hdr = data[:512] - fakefile = BytesIO(hdr) - for testfn in _tests: - res = testfn(hdr, fakefile) - if res is not None: - return res - else: - return None - - class MIMEAudio(MIMENonMultipart): """Class for generating audio/* MIME documents.""" @@ -89,10 +37,64 @@ class MIMEAudio(MIMENonMultipart): header. """ if _subtype is None: - _subtype = _whatsnd(_audiodata) + _subtype = _what(_audiodata) if _subtype is None: raise TypeError('Could not find audio MIME subtype') MIMENonMultipart.__init__(self, 'audio', _subtype, policy=policy, **_params) self.set_payload(_audiodata) _encoder(self) + + +_rules = [] + + +# Originally from the sndhdr module. +# +# There are others in sndhdr that don't have MIME types. :( +# Additional ones to be added to sndhdr? midi, mp3, realaudio, wma?? +def _what(data): + # Try to identify a sound file type. + # + # sndhdr.what() had a pretty cruddy interface, unfortunately. This is why + # we re-do it here. It would be easier to reverse engineer the Unix 'file' + # command and use the standard 'magic' file, as shipped with a modern Unix. + hdr = data[:512] + fakefile = BytesIO(hdr) + for testfn in _rules: + if res := testfn(hdr, fakefile): + return res + else: + return None + + +def rule(rulefunc): + _rules.append(rulefunc) + return rulefunc + + +@rule +def _aiff(h, f): + if not h.startswith(b'FORM'): + return None + if h[8:12] in {b'AIFC', b'AIFF'}: + return 'x-aiff' + else: + return None + + +@rule +def _au(h, f): + if h.startswith(b'.snd'): + return 'basic' + else: + return None + + +@rule +def _wav(h, f): + # 'RIFF' 'WAVE' 'fmt ' + if not h.startswith(b'RIFF') or h[8:12] != b'WAVE' or h[12:16] != b'fmt ': + return None + else: + return "x-wav" diff --git a/Lib/test/test_email/data/sndhdr.aifc b/Lib/test/test_email/data/sndhdr.aifc new file mode 100644 index 0000000000000000000000000000000000000000..8aae4e730bdafeaf888a40d2e6950fab4de43ec5 GIT binary patch literal 106 zc-nLG5AtPTU`TTGbaQqKa}5HrSr#<}Iyn3Lg2dGrn1CcJgMb6y8W#pI@bmX`<;%-2 ZQAp0uEhtJYE>2Bh2oClG$;vR`0RT5j5OV+k literal 0 Hc-jL100001 diff --git a/Lib/test/test_email/data/sndhdr.aiff b/Lib/test/test_email/data/sndhdr.aiff new file mode 100644 index 0000000000000000000000000000000000000000..8c279a762f1c7074f9e91356b7b81b3da420db03 GIT binary patch literal 108 zc-nLG5AtPTU`TQFbaQj|_YDEEr5G4bB$=NDvIGK(@{?1Gi&Ik+k}4H~^CN&NK&pip Zn1CcJgMb6y8W#pI2oClGv1AzV005nl5B~rF literal 0 Hc-jL100001 diff --git a/Lib/test/test_email/data/audiotest.au b/Lib/test/test_email/data/sndhdr.au similarity index 100% rename from Lib/test/test_email/data/audiotest.au rename to Lib/test/test_email/data/sndhdr.au diff --git a/Lib/test/test_email/data/sndhdr.wav b/Lib/test/test_email/data/sndhdr.wav new file mode 100644 index 0000000000000000000000000000000000000000..0dca36739cde302167f1f9356213ec5ef3148f9e GIT binary patch literal 64 xc-jl{baS&{U|