def __init__(self, ct, f, next=None, uribase='thismessage:/', seekable=0, **kw): # Get the boundary. It's too bad I have to write this myself, # but no way am I going to import cgi for 10 lines of code! for param in ct.split(';'): a = param.strip() if a.startswith('boundary='): if a[9] in [ '"', "'" ]: boundary = a[10:-1] else: boundary = a[9:] break else: raise ValueError('boundary parameter not found') self.id_dict, self.loc_dict, self.parts = {}, {}, [] self.next = next self.base = uribase mf = multifile.MultiFile(f, seekable) mf.push(boundary) while next(mf): head = mimetools.Message(mf) body = StringIO.StringIO() mimetools.decode(mf, body, head.getencoding()) body.seek(0) part = (head, body) self.parts.append(part) key = head.get('content-id') if key: if key[0] == '<' and key[-1] == '>': key = key[1:-1] self.id_dict[key] = part key = head.get('content-location') if key: self.loc_dict[key] = part mf.pop()
def test_main(): global boundaries, linecount boundaries = 0 linecount = 0 f = cStringIO.StringIO(msg) getMIMEMsg(multifile.MultiFile(f)) assert boundaries == 2 assert linecount == 9
def process_multi_part(file, msg, current): mf = multifile.MultiFile(file) mf.push(msg.getparam("boundary")) while mf.next(): submsg = mimetools.Message(file) if submsg.has_key("Content-Disposition"): maybe_add_attachment(current, mf, submsg) else: # This is the message body itself (always?), so process # accordingly process_mime_body(current, mf, submsg)
def extract_mime_part_matching(stream, mimetype): mfile = multifile.MultiFile(stream) mfile.push("_BOUNDRY_02468_STRING_13579_XXXXXXX") while 1: submsg = mimetools.Message(mfile) data = StringIO.StringIO() mimetools.decode(mfile, data, submsg.getencoding()) if (not mfile.next()) or submsg.gettype() == mimetype: break mfile.pop() return data.getvalue()
def getbodyparts(self): if self.getmaintype() != 'multipart': raise Error, 'Content-Type is not multipart/*' bdry = self.getparam('boundary') if not bdry: raise Error, 'multipart/* without boundary param' self.fp.seek(self.startofbody) mf = multifile.MultiFile(self.fp) mf.push(bdry) parts = [] while mf.next(): n = str(self.number) + '.' + ` 1 + len(parts) ` part = SubMessage(self.folder, n, mf) parts.append(part) mf.pop() return parts
def getbodyparts(self): """Only for multipart messages: return the message's body as a list of SubMessage objects. Each submessage object behaves (almost) as a Message object.""" if self.getmaintype() != 'multipart': raise Error, 'Content-Type is not multipart/*' bdry = self.getparam('boundary') if not bdry: raise Error, 'multipart/* without boundary param' self.fp.seek(self.startofbody) mf = multifile.MultiFile(self.fp) mf.push(bdry) parts = [] while mf.next(): n = "%s.%r" % (self.number, 1 + len(parts)) part = SubMessage(self.folder, n, mf) parts.append(part) mf.pop() return parts
def read_odbmulti(fname): """Read data from opendatabank multi files. :see: http://www.american.edu/econ/pytrix/opendatabank.txt """ import multifile fp = open(fname, 'r') mfp = multifile.MultiFile(fp) mfp.push('series-boundary') comments = mfp.read() #print comments while mfp.next(): try: data, smpl, comments = read_db(mfp) except multifile.Error: break fp.close() print data fp.close()
def mimedecode(self, msg=None, id=""): if not msg: self.rewind() msg = mimetools.Message(self, 0) type = msg.gettype() if (len(id) > 5): # Emergency abort! return [["(diagnostic)", "text/plain", \ "Attachments too deeply nested --- aborting (probably hit the Multifile bug)", \ id+"A"]] disposition = msg.getheader("Content-Disposition") disposition = sqmail.utils.parse_mimeheader(disposition) name = msg.getparam("name") index = 65 if not name: name = sqmail.utils.get_mime_param(disposition, "filename") if not name: name = "<unnamed>" if (type[:10] == "multipart/"): multi = multifile.MultiFile(msg.fp, 0) multi.push(msg.getparam("boundary")) l = [] while multi.next(): l.append(self.mimedecode(mimetools.Message(multi, 0), id+chr(index))[0]) index = index + 1 if (index > 65+32): # Emergency abort! raise MIMEDecodeAbortException multi.pop() return [[name, type, l, ""]] else: encoding = msg.getencoding() if (encoding != "7bit") and (encoding != "8bit"): data = cStringIO.StringIO() mimetools.decode(msg.fp, data, msg.getencoding()) return [[name, type, data.getvalue(), id]] else: return [[name, type, string.join(msg.fp.readlines(), ""), id]]
def __init__(self, headers, infile, maintype = None, subtype = None): Part.__init__(self, headers, infile, maintype, subtype) if self.maintype <> "multipart": raise ValueError self.parts = [] boundary = headers.getparam("boundary") if boundary is None: # They are cheating on us! Try to survive. boundary = "=-=-=-EmergencyBoundary%d" % os.getpid() mf = multifile.MultiFile(infile, seekable = 0) mf.push(boundary) # We should skip all data before the first section marker, # so the loop condition below works. while mf.next(): subheaders = mimetools.Message(mf) if subheaders.getmaintype() == "multipart": self.parts.append(MultiPart(subheaders, mf)) else: self.parts.append(DiscretePart(subheaders, mf)) mf.pop()
def _extractMimeParts(stream): msg = mimetools.Message(stream) msgtype = msg.gettype() params = msg.getplist() files = [] raw_data = cStringIO.StringIO() if msgtype[:10] == "multipart/": f = multifile.MultiFile(stream) f.push(msg.getparam("boundary")) while f.next(): submsg = mimetools.Message(f) filename = submsg.getheader(MIME_FILE_HEADER) content_hash = submsg.getheader(MIME_HASH_HEADER) try: raw_data = cStringIO.StringIO() mimetools.decode(f, raw_data, submsg.getencoding()) except ValueError: continue files.append((filename, content_hash, raw_data.getvalue())) f.pop() return files
import multifile import cgi, rfc822 infile = open("samples/sample.msg") message = rfc822.Message(infile) # print parsed header for k, v in message.items(): print k, "=", v # use cgi support function to parse content-type header type, params = cgi.parse_header(message["content-type"]) if type[:10] == "multipart/": # multipart message boundary = params["boundary"] file = multifile.MultiFile(infile) file.push(boundary) while file.next(): submessage = rfc822.Message(file) # print submessage print "-" * 68 for k, v in submessage.items(): print k, "=", v print print file.read() file.pop() else: # plain message print infile.read()
def unpackMail(mailString): """ returns body, content-type, html-body and attachments for mail-string. """ return unpackMultifile(multifile.MultiFile(StringIO.StringIO(mailString)))
def process(stream, i): # vado all'inizio del file stream.seek(0) # creo un'istanza di msg di posta elettronica msg = mimetools.Message(stream) # tipo di messaggio msgtype = msg.gettype() # codifica del messaggio encoding = msg.getencoding() # ricavo il mittente e la data sender = msg.get("From") date = parsedate(msg.get("Date")) # se il messaggio e' un multipart lo devo processare in maniera # un po' particolare if msgtype[:10] == "multipart/": # creo un istanza multifile file = multifile.MultiFile(stream) # ricavo il boundary file.push(msg.getparam("boundary")) # scorro i vari pezzi del file while file.next(): # ricavo il sottomessaggio submsg = mimetools.Message(file) try: # provo a decodificare il sottomessaggio data = StringIO.StringIO() mimetools.decode(file, data, submsg.getencoding()) except ValueError: # in caso di errore faccio finta di niente print "### ERRORI DI FORMATO NEL MSG %s (SENDER: %s)" % ( i, sender) continue # vado al file successivo file.pop() # se il messaggio e' singolo tento # di decodificare il singolo messaggio else: try: data = StringIO.StringIO() mimetools.decode(msg.fp, data, msg.getencoding()) except ValueError: print "### CAZZI NEL DECODING MIME DEL MSG %s (SENDER: %s)" % ( i, sender) # ecco che ho i dati del form depurati dalla codifica del client di posta elettronica form_data = data.getvalue() # rimuovo i ritorni a capo form_data = string.replace(form_data, "\n", "") # inserisco i dati nel database insertintodb(sender, date, form_data) # incremento il contatore i = i + 1 # torno il valore del contatore return i
def GetClearSig(Msg, Paranoid=0): Error = 'MIME Error' # See if this is a MIME encoded multipart signed message if Msg.gettype() == "multipart/signed": Boundary = Msg.getparam("boundary") if not Boundary: raise Error, "multipart/* without a boundary parameter" # Create the multipart handler. Regrettably their implementation # Needs seeking.. SkMessage = StringIO.StringIO() SkMessage.write(Msg.fp.read()) SkMessage.seek(0) mf = multifile.MultiFile(SkMessage) mf.push(Msg.getparam("boundary")) # Check the first bit of the message.. if Paranoid != 0: Pos = mf.tell() while 1: x = mf.readline() if not x: break if len(string.strip(x)) != 0: raise Error, "Unsigned text in message (at start)" mf.seek(Pos) # Get the first part of the multipart message if not mf.next(): raise Error, "Invalid pgp/mime encoding [no section]" # Get the part as a safe seekable stream Signed = StringIO.StringIO() Signed.write(mf.read()) InnerMsg = mimetools.Message(Signed) # Make sure it is the right type if InnerMsg.gettype() != "text/plain": raise Error, "Invalid pgp/mime encoding [wrong plaintext type]" # Get the next part of the multipart message if not mf.next(): raise Error, "Invalid pgp/mime encoding [no section]" InnerMsg = mimetools.Message(mf) if InnerMsg.gettype() != "application/pgp-signature": raise Error, "Invalid pgp/mime encoding [wrong signature type]" Signature = string.joinfields(mf.readlines(), '') # Check the last bit of the message.. if Paranoid != 0: mf.pop() Pos = mf.tell() while 1: x = mf.readline() if not x: break if len(string.strip(x)) != 0: raise Error, "Unsigned text in message (at end)" mf.seek(Pos) # Append the PGP boundary header and the signature text to re-form the # original signed block [needs to convert to \r\n] Output = "-----BEGIN PGP SIGNED MESSAGE-----\r\n" # Semi-evil hack to get the proper hash type inserted in the message if Msg.getparam('micalg') != None: Output = Output + "Hash: MD5,SHA1,%s\r\n" % (string.upper( Msg.getparam('micalg')[4:])) Output = Output + "\r\n" Output = Output + string.replace(Signed.getvalue(), "\n-", "\n- -") + Signature return (Output, 1) else: if Paranoid == 0: # Just return the message body return (string.joinfields(Msg.fp.readlines(), ''), 0) Body = "" State = 1 for x in Msg.fp.readlines(): Body = Body + x Tmp = string.strip(x) if len(Tmp) == 0: continue # Leading up to the signature if State == 1: if Tmp == "-----BEGIN PGP SIGNED MESSAGE-----": State = 2 else: raise Error, "Unsigned text in message (at start)" continue # In the signature plain text if State == 2: if Tmp == "-----BEGIN PGP SIGNATURE-----": State = 3 continue # In the signature if State == 3: if Tmp == "-----END PGP SIGNATURE-----": State = 4 continue # Past the end if State == 4: raise Error, "Unsigned text in message (at end)" return (Body, 0)
def main(): f = cStringIO.StringIO(msg) getMIMEMsg(multifile.MultiFile(f)) assert boundaries == 2 assert linecount == 9
"""MH interface -- purely object-oriented (well, almost)