xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/email/mime/audio.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker# Copyright (C) 2001-2007 Python Software Foundation
2*cda5da8dSAndroid Build Coastguard Worker# Author: Anthony Baxter
3*cda5da8dSAndroid Build Coastguard Worker# Contact: [email protected]
4*cda5da8dSAndroid Build Coastguard Worker
5*cda5da8dSAndroid Build Coastguard Worker"""Class representing audio/* type MIME documents."""
6*cda5da8dSAndroid Build Coastguard Worker
7*cda5da8dSAndroid Build Coastguard Worker__all__ = ['MIMEAudio']
8*cda5da8dSAndroid Build Coastguard Worker
9*cda5da8dSAndroid Build Coastguard Workerfrom io import BytesIO
10*cda5da8dSAndroid Build Coastguard Workerfrom email import encoders
11*cda5da8dSAndroid Build Coastguard Workerfrom email.mime.nonmultipart import MIMENonMultipart
12*cda5da8dSAndroid Build Coastguard Worker
13*cda5da8dSAndroid Build Coastguard Worker
14*cda5da8dSAndroid Build Coastguard Workerclass MIMEAudio(MIMENonMultipart):
15*cda5da8dSAndroid Build Coastguard Worker    """Class for generating audio/* MIME documents."""
16*cda5da8dSAndroid Build Coastguard Worker
17*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, _audiodata, _subtype=None,
18*cda5da8dSAndroid Build Coastguard Worker                 _encoder=encoders.encode_base64, *, policy=None, **_params):
19*cda5da8dSAndroid Build Coastguard Worker        """Create an audio/* type MIME document.
20*cda5da8dSAndroid Build Coastguard Worker
21*cda5da8dSAndroid Build Coastguard Worker        _audiodata contains the bytes for the raw audio data.  If this data
22*cda5da8dSAndroid Build Coastguard Worker        can be decoded as au, wav, aiff, or aifc, then the
23*cda5da8dSAndroid Build Coastguard Worker        subtype will be automatically included in the Content-Type header.
24*cda5da8dSAndroid Build Coastguard Worker        Otherwise, you can specify  the specific audio subtype via the
25*cda5da8dSAndroid Build Coastguard Worker        _subtype parameter.  If _subtype is not given, and no subtype can be
26*cda5da8dSAndroid Build Coastguard Worker        guessed, a TypeError is raised.
27*cda5da8dSAndroid Build Coastguard Worker
28*cda5da8dSAndroid Build Coastguard Worker        _encoder is a function which will perform the actual encoding for
29*cda5da8dSAndroid Build Coastguard Worker        transport of the image data.  It takes one argument, which is this
30*cda5da8dSAndroid Build Coastguard Worker        Image instance.  It should use get_payload() and set_payload() to
31*cda5da8dSAndroid Build Coastguard Worker        change the payload to the encoded form.  It should also add any
32*cda5da8dSAndroid Build Coastguard Worker        Content-Transfer-Encoding or other headers to the message as
33*cda5da8dSAndroid Build Coastguard Worker        necessary.  The default encoding is Base64.
34*cda5da8dSAndroid Build Coastguard Worker
35*cda5da8dSAndroid Build Coastguard Worker        Any additional keyword arguments are passed to the base class
36*cda5da8dSAndroid Build Coastguard Worker        constructor, which turns them into parameters on the Content-Type
37*cda5da8dSAndroid Build Coastguard Worker        header.
38*cda5da8dSAndroid Build Coastguard Worker        """
39*cda5da8dSAndroid Build Coastguard Worker        if _subtype is None:
40*cda5da8dSAndroid Build Coastguard Worker            _subtype = _what(_audiodata)
41*cda5da8dSAndroid Build Coastguard Worker        if _subtype is None:
42*cda5da8dSAndroid Build Coastguard Worker            raise TypeError('Could not find audio MIME subtype')
43*cda5da8dSAndroid Build Coastguard Worker        MIMENonMultipart.__init__(self, 'audio', _subtype, policy=policy,
44*cda5da8dSAndroid Build Coastguard Worker                                  **_params)
45*cda5da8dSAndroid Build Coastguard Worker        self.set_payload(_audiodata)
46*cda5da8dSAndroid Build Coastguard Worker        _encoder(self)
47*cda5da8dSAndroid Build Coastguard Worker
48*cda5da8dSAndroid Build Coastguard Worker
49*cda5da8dSAndroid Build Coastguard Worker_rules = []
50*cda5da8dSAndroid Build Coastguard Worker
51*cda5da8dSAndroid Build Coastguard Worker
52*cda5da8dSAndroid Build Coastguard Worker# Originally from the sndhdr module.
53*cda5da8dSAndroid Build Coastguard Worker#
54*cda5da8dSAndroid Build Coastguard Worker# There are others in sndhdr that don't have MIME types. :(
55*cda5da8dSAndroid Build Coastguard Worker# Additional ones to be added to sndhdr? midi, mp3, realaudio, wma??
56*cda5da8dSAndroid Build Coastguard Workerdef _what(data):
57*cda5da8dSAndroid Build Coastguard Worker    # Try to identify a sound file type.
58*cda5da8dSAndroid Build Coastguard Worker    #
59*cda5da8dSAndroid Build Coastguard Worker    # sndhdr.what() had a pretty cruddy interface, unfortunately.  This is why
60*cda5da8dSAndroid Build Coastguard Worker    # we re-do it here.  It would be easier to reverse engineer the Unix 'file'
61*cda5da8dSAndroid Build Coastguard Worker    # command and use the standard 'magic' file, as shipped with a modern Unix.
62*cda5da8dSAndroid Build Coastguard Worker    hdr = data[:512]
63*cda5da8dSAndroid Build Coastguard Worker    fakefile = BytesIO(hdr)
64*cda5da8dSAndroid Build Coastguard Worker    for testfn in _rules:
65*cda5da8dSAndroid Build Coastguard Worker        if res := testfn(hdr, fakefile):
66*cda5da8dSAndroid Build Coastguard Worker            return res
67*cda5da8dSAndroid Build Coastguard Worker    else:
68*cda5da8dSAndroid Build Coastguard Worker        return None
69*cda5da8dSAndroid Build Coastguard Worker
70*cda5da8dSAndroid Build Coastguard Worker
71*cda5da8dSAndroid Build Coastguard Workerdef rule(rulefunc):
72*cda5da8dSAndroid Build Coastguard Worker    _rules.append(rulefunc)
73*cda5da8dSAndroid Build Coastguard Worker    return rulefunc
74*cda5da8dSAndroid Build Coastguard Worker
75*cda5da8dSAndroid Build Coastguard Worker
76*cda5da8dSAndroid Build Coastguard Worker@rule
77*cda5da8dSAndroid Build Coastguard Workerdef _aiff(h, f):
78*cda5da8dSAndroid Build Coastguard Worker    if not h.startswith(b'FORM'):
79*cda5da8dSAndroid Build Coastguard Worker        return None
80*cda5da8dSAndroid Build Coastguard Worker    if h[8:12] in {b'AIFC', b'AIFF'}:
81*cda5da8dSAndroid Build Coastguard Worker        return 'x-aiff'
82*cda5da8dSAndroid Build Coastguard Worker    else:
83*cda5da8dSAndroid Build Coastguard Worker        return None
84*cda5da8dSAndroid Build Coastguard Worker
85*cda5da8dSAndroid Build Coastguard Worker
86*cda5da8dSAndroid Build Coastguard Worker@rule
87*cda5da8dSAndroid Build Coastguard Workerdef _au(h, f):
88*cda5da8dSAndroid Build Coastguard Worker    if h.startswith(b'.snd'):
89*cda5da8dSAndroid Build Coastguard Worker        return 'basic'
90*cda5da8dSAndroid Build Coastguard Worker    else:
91*cda5da8dSAndroid Build Coastguard Worker        return None
92*cda5da8dSAndroid Build Coastguard Worker
93*cda5da8dSAndroid Build Coastguard Worker
94*cda5da8dSAndroid Build Coastguard Worker@rule
95*cda5da8dSAndroid Build Coastguard Workerdef _wav(h, f):
96*cda5da8dSAndroid Build Coastguard Worker    # 'RIFF' <len> 'WAVE' 'fmt ' <len>
97*cda5da8dSAndroid Build Coastguard Worker    if not h.startswith(b'RIFF') or h[8:12] != b'WAVE' or h[12:16] != b'fmt ':
98*cda5da8dSAndroid Build Coastguard Worker        return None
99*cda5da8dSAndroid Build Coastguard Worker    else:
100*cda5da8dSAndroid Build Coastguard Worker        return "x-wav"
101