| 1 | # Copyright (C) 2001-2006 Python Software Foundation
|
|---|
| 2 | # Author: Anthony Baxter
|
|---|
| 3 | # Contact: [email protected]
|
|---|
| 4 |
|
|---|
| 5 | """Class representing audio/* type MIME documents."""
|
|---|
| 6 |
|
|---|
| 7 | __all__ = ['MIMEAudio']
|
|---|
| 8 |
|
|---|
| 9 | import sndhdr
|
|---|
| 10 |
|
|---|
| 11 | from cStringIO import StringIO
|
|---|
| 12 | from email import encoders
|
|---|
| 13 | from email.mime.nonmultipart import MIMENonMultipart
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 | |
|---|
| 17 |
|
|---|
| 18 | _sndhdr_MIMEmap = {'au' : 'basic',
|
|---|
| 19 | 'wav' :'x-wav',
|
|---|
| 20 | 'aiff':'x-aiff',
|
|---|
| 21 | 'aifc':'x-aiff',
|
|---|
| 22 | }
|
|---|
| 23 |
|
|---|
| 24 | # There are others in sndhdr that don't have MIME types. :(
|
|---|
| 25 | # Additional ones to be added to sndhdr? midi, mp3, realaudio, wma??
|
|---|
| 26 | def _whatsnd(data):
|
|---|
| 27 | """Try to identify a sound file type.
|
|---|
| 28 |
|
|---|
| 29 | sndhdr.what() has a pretty cruddy interface, unfortunately. This is why
|
|---|
| 30 | we re-do it here. It would be easier to reverse engineer the Unix 'file'
|
|---|
| 31 | command and use the standard 'magic' file, as shipped with a modern Unix.
|
|---|
| 32 | """
|
|---|
| 33 | hdr = data[:512]
|
|---|
| 34 | fakefile = StringIO(hdr)
|
|---|
| 35 | for testfn in sndhdr.tests:
|
|---|
| 36 | res = testfn(hdr, fakefile)
|
|---|
| 37 | if res is not None:
|
|---|
| 38 | return _sndhdr_MIMEmap.get(res[0])
|
|---|
| 39 | return None
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 | |
|---|
| 43 |
|
|---|
| 44 | class MIMEAudio(MIMENonMultipart):
|
|---|
| 45 | """Class for generating audio/* MIME documents."""
|
|---|
| 46 |
|
|---|
| 47 | def __init__(self, _audiodata, _subtype=None,
|
|---|
| 48 | _encoder=encoders.encode_base64, **_params):
|
|---|
| 49 | """Create an audio/* type MIME document.
|
|---|
| 50 |
|
|---|
| 51 | _audiodata is a string containing the raw audio data. If this data
|
|---|
| 52 | can be decoded by the standard Python `sndhdr' module, then the
|
|---|
| 53 | subtype will be automatically included in the Content-Type header.
|
|---|
| 54 | Otherwise, you can specify the specific audio subtype via the
|
|---|
| 55 | _subtype parameter. If _subtype is not given, and no subtype can be
|
|---|
| 56 | guessed, a TypeError is raised.
|
|---|
| 57 |
|
|---|
| 58 | _encoder is a function which will perform the actual encoding for
|
|---|
| 59 | transport of the image data. It takes one argument, which is this
|
|---|
| 60 | Image instance. It should use get_payload() and set_payload() to
|
|---|
| 61 | change the payload to the encoded form. It should also add any
|
|---|
| 62 | Content-Transfer-Encoding or other headers to the message as
|
|---|
| 63 | necessary. The default encoding is Base64.
|
|---|
| 64 |
|
|---|
| 65 | Any additional keyword arguments are passed to the base class
|
|---|
| 66 | constructor, which turns them into parameters on the Content-Type
|
|---|
| 67 | header.
|
|---|
| 68 | """
|
|---|
| 69 | if _subtype is None:
|
|---|
| 70 | _subtype = _whatsnd(_audiodata)
|
|---|
| 71 | if _subtype is None:
|
|---|
| 72 | raise TypeError('Could not find audio MIME subtype')
|
|---|
| 73 | MIMENonMultipart.__init__(self, 'audio', _subtype, **_params)
|
|---|
| 74 | self.set_payload(_audiodata)
|
|---|
| 75 | _encoder(self)
|
|---|