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