def _getStringStream(self, filename, prefer='unicode'): """Gets a string representation of the requested filename. Checks for both ASCII and Unicode representations and returns a value if possible. If there are both ASCII and Unicode versions, then the parameter /prefer/ specifies which will be returned. """ if isinstance(filename, list): # Join with slashes to make it easier to append the type filename = "/".join(filename) asciiVersion = self._getStream(filename + '001E') unicodeVersion = windowsUnicode(self._getStream(filename + '001F')) if asciiVersion is None: return unicodeVersion elif unicodeVersion is None: try: return decode_utf7(asciiVersion) except Exception: return "".join(map(chr, asciiVersion)) else: if prefer == 'unicode': return unicodeVersion else: try: return decode_utf7(asciiVersion) except Exception: return "".join(map(chr, asciiVersion))
def analyze_file(self, path): m = Message(path) def xstr(s): return '' if s is None else str(s) attachments = m.attachments a = [] for attachment in attachments: sha256 = hashlib.sha256() sha256.update(attachment.data) a.append({'name': attachment.longFilename, 'sha256': sha256.hexdigest(), 'mimeinfo': magic.Magic(uncompress=True).from_buffer(attachment.data) }) email = {'header': xstr(m.header), 'from': xstr(m.sender), 'to': xstr(m.to), 'cc': xstr(m.cc), 'subject': xstr(m.subject), 'date': xstr(m.date), 'body': decode_utf7(m.body), 'attachments': a } self.add_result_subsection('Email details', email) return self.results
def analyze_file(self, path): m = Message(path) def xstr(s): return '' if s is None else str(s) attachments = m.attachments a = [] for attachment in attachments: sha256 = hashlib.sha256() sha256.update(attachment.data) a.append({ 'name': attachment.longFilename, 'sha256': sha256.hexdigest(), 'mimeinfo': magic.Magic(uncompress=True).from_buffer(attachment.data) }) email = { 'header': xstr(m.header), 'from': xstr(m.sender), 'to': xstr(m.to), 'cc': xstr(m.cc), 'subject': xstr(m.subject), 'date': xstr(m.date), 'body': decode_utf7(m.body), 'attachments': a } self.add_result_subsection('Email details', email) return self.results
def toJson(self): def xstr(s): return '' if s is None else str(s) attachmentNames = [] # Save the attachments # for attachment in self.attachments: # attachmentNames.append(attachment.save()) attachmentsJson = [a.toJson() for a in self.attachments] self.body = imapclient.decode_utf7(self.body) emailObj = { 'from': xstr(self.sender), 'to': xstr(self.to), 'cc': xstr(self.cc), 'subject': xstr(self.subject), 'date': xstr(self.date), 'attachments': attachmentNames, 'body': self.body, 'date': self.parsedDate, 'attachments': attachmentsJson, 'header': self.headerStr } return emailObj
def getJson(self): """ Returns the JSON representation of the Message. """ return json.dumps({ 'from': inputToString(self.sender, 'utf-8'), 'to': inputToString(self.to, 'utf-8'), 'cc': inputToString(self.cc, 'utf-8'), 'subject': inputToString(self.subject, 'utf-8'), 'date': inputToString(self.date, 'utf-8'), 'body': decode_utf7(self.body) })
def analyze_file(self, path): m = Message(path) def xstr(s): return "" if s is None else str(s) attachments = m.attachments a = [] observables = [] outdir = tempfile.mkdtemp() for attachment in attachments: sha256 = hashlib.sha256() if type(attachment.data) is not Message: sha256.update(attachment.data) minfo = magic.Magic(uncompress=True).from_buffer( attachment.data) a.append({ "name": attachment.longFilename, "sha256": sha256.hexdigest(), "mimeinfo": minfo, }) with open(os.path.join(outdir, attachment.longFilename), "wb") as f: f.write(attachment.data) observables.append( os.path.join(outdir, attachment.longFilename)) email = { "header": xstr(m.header), "from": xstr(m.sender), "to": xstr(m.to), "cc": xstr(m.cc), "subject": xstr(m.subject), "date": xstr(m.date), "body": decode_utf7(m.body), "attachments": a, } self.add_result_subsection("Email details", email) return self.results, observables
def _getStringStream(self, filename): """Gets a string representation of the requested filename. Checks for both ASCII and Unicode representations and returns a value if possible. If there are both ASCII and Unicode versions, then the parameter /prefer/ specifies which will be returned. """ if isinstance(filename, list): # Join with slashes to make it easier to append the type filename = "/".join(filename) value = windowsUnicode(self._getStream(filename + '001F')) if value is None: raw = self._getStream(filename + '001E') try: value = decode_utf7(raw) except Exception: encoding = guess_encoding(raw) value = raw.decode(encoding, 'replace') if value is not None and len(value): return remove_unsafe_chars(value)
def save(self, toJson=False, useFileName=False, raw=False, ContentId=False): '''Saves the message body and attachments found in the message. Setting toJson to true will output the message body as JSON-formatted text. The body and attachments are stored in a folder. Setting useFileName to true will mean that the filename is used as the name of the folder; otherwise, the message's date and subject are used as the folder name.''' if useFileName: # strip out the extension dirName = self.filename.split('/').pop().split('.')[0] else: # Create a directory based on the date and subject of the message d = self.parsedDate if d is not None: dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format(*d) else: dirName = 'UnknownDate' if self.subject is None: subject = '[No subject]' else: subject = ''.join(i for i in self.subject if i not in r'\/:*?"<>|') dirName = dirName + ' ' + subject try: os.makedirs(dirName) except Exception: newDirName = addNumToDir(dirName) if newDirName is not None: dirName = newDirName else: raise Exception( "Failed to create directory '%s'. Does it already exist?" % dirName ) oldDir = os.getcwd() try: os.chdir(dirName) # Save the message body fext = 'json' if toJson else 'text' f = open('message.' + fext, 'w') # From, to , cc, subject, date attachmentNames = [] # Save the attachments for attachment in self.attachments: attachmentNames.append(attachment.save(ContentId)) if toJson: emailObj = {'from': xstr(self.sender), 'to': xstr(self.to), 'cc': xstr(self.cc), 'subject': xstr(self.subject), 'date': xstr(self.date), 'attachments': attachmentNames, 'body': decode_utf7(self.body)} f.write(json.dumps(emailObj, ensure_ascii=True)) else: f.write('From: ' + xstr(self.sender) + self.__crlf) f.write('To: ' + xstr(self.to) + self.__crlf) f.write('CC: ' + xstr(self.cc) + self.__crlf) f.write('Subject: ' + xstr(self.subject) + self.__crlf) f.write('Date: ' + xstr(self.date) + self.__crlf) f.write('-----------------' + self.__crlf + self.__crlf) f.write(self.body) f.close() except Exception as e: self.saveRaw() raise finally: # Return to previous directory os.chdir(oldDir)
def save(self, toJson=False, useFileName=False, raw=False): '''Saves the message body and attachments found in the message. Setting toJson to true will output the message body as JSON-formatted text. The body and attachments are stored in a folder. Setting useFileName to true will mean that the filename is used as the name of the folder; otherwise, the message's date and subject are used as the folder name.''' ## if useFileName: ## # strip out the extension ## dirName = filename.split('/').pop().split('.')[0] ## else: ## # Create a directory based on the date and subject of the message ## d = self.parsedDate ## if d is not None: ## dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format(*d) ## else: ## dirName = "UnknownDate" ## ## if self.subject is None: ## subject = "[No subject]" ## else: ## subject = "".join(i for i in self.subject if i not in r'\/:*?"<>|') ## ## dirName = dirName + " " + subject ## ## def addNumToDir(dirName): ## # Attempt to create the directory with a '(n)' appended ## ## for i in range(2, 100): ## try: ## newDirName = dirName + " (" + str(i) + ")" ## os.makedirs(newDirName) ## return newDirName ## except Exception: ## pass ## return None ## ## try: ## os.makedirs(dirName) ## except Exception: ## newDirName = addNumToDir(dirName) ## if newDirName is not None: ## dirName = newDirName ## else: ## raise Exception( ## "Failed to create directory '%s'. Does it already exist?" % ## dirName ## ) ## ## oldDir = os.getcwd() try: os.chdir(dirName) # Save the message body fext = 'json' if toJson else 'text' f = open("message." + fext, "w") # From, to , cc, subject, date def xstr(s): return '' if s is None else str(s) attachmentNames = [] # Save the attachments for attachment in self.attachments: attachmentNames.append(attachment.save()) if toJson: import json from imapclient.imapclient import decode_utf7 emailObj = { 'from': xstr(self.sender), 'to': xstr(self.to), 'cc': xstr(self.cc), 'subject': xstr(self.subject), 'date': xstr(self.date), 'attachments': attachmentNames, 'body': decode_utf7(self.body) } f.write(json.dumps(emailObj, ensure_ascii=True)) else: f.write("From: " + xstr(self.sender) + "\n") f.write("To: " + xstr(self.to) + "\n") f.write("CC: " + xstr(self.cc) + "\n") f.write("Subject: " + xstr(self.subject) + "\n") f.write("Date: " + xstr(self.date) + "\n") f.write("-----------------\n\n") f.write(self.body.encode("utf-16")) f.close() except Exception: self.saveRaw() raise finally: # Return to previous directory os.chdir(oldDir)
def save(self, toJson=True, useFileName=False, raw=False, ContentId=False): '''Saves the message body and attachments found in the message. Setting toJson to true will output the message body as JSON-formatted text. The body and attachments are stored in a folder. Setting useFileName to true will mean that the filename is used as the name of the folder; otherwise, the message's date and subject are used as the folder name.''' if useFileName: # strip out the extension dirName = self.filename.split('/').pop().split('.')[0] else: # Create a directory based on the date and subject of the message d = self.parsedDate if d is not None: dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format(*d) else: dirName = 'UnknownDate' if self.subject is None: subject = '[No subject]' else: subject = ''.join(i for i in self.subject if i not in r'\/:*?"<>|') dirName = dirName + ' ' + subject oldDir = os.getcwd() try: # os.chdir(dirName) # Save the message body fext = 'json' if toJson else 'text' # f = open('message.' + fext, 'w') # From, to , cc, subject, date ret_messages = [] toJson = True attachmentNames = [] # Save the attachments for attachment in self.attachments: if attachment._Attachment__type == 'msg': ret_messages += attachment.save() attachmentNames.append(attachment.save()) if toJson: urls = re.findall( r'(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?\xab\xbb\u201c\u201d\u2018\u2019]))', decode_utf7(self.body)) uniq_urls = [] for url in urls: for i in url: if 'http' in i and i not in uniq_urls: uniq_urls.append(i) emailObj = { 'from': xstr(self.sender), 'to': xstr(self.to), 'cc': xstr(self.cc), 'subject': xstr(self.subject), 'date': xstr(self.date), 'attachments': attachmentNames, 'body': decode_utf7(self.body), 'urls': uniq_urls } ret_messages.append(emailObj) return ret_messages else: # print('From: ' + xstr(self.sender) + self.__crlf) # print('To: ' + xstr(self.to) + self.__crlf) # print('CC: ' + xstr(self.cc) + self.__crlf) # print('Subject: ' + xstr(self.subject) + self.__crlf) # print('Date: ' + xstr(self.date) + self.__crlf) # print('-----------------' + self.__crlf + self.__crlf) # print(self.body) return 'abc' except Exception as e: print e raise finally: # Return to previous directory os.chdir(oldDir)
def save(self, toJson=False, useFileName=False, raw=False, ContentId=False, customPath=None, customFilename=None ): #, html = False, rtf = False, allowFallback = False): """ Saves the message body and attachments found in the message. The body and attachments are stored in a folder. Setting useFileName to true will mean that the filename is used as the name of the folder; otherwise, the message's date and subject are used as the folder name. Here is the absolute order of prioity for the name of the folder: 1. customFilename 2. self.filename if useFileName 3. {date} {subject} """ #There are several parameters used to determine how the message will be saved. #By default, the message will be saved as plain text. Setting one of the #following parameters to True will change that: # * :param html: will try to output the message in HTML format. # * :param json: will output the message in JSON format. # * :param raw: will output the message in a raw format. # * :param rtf: will output the message in RTF format. # #Usage of more than one formatting parameter will raise an exception. # #Using HTML or RTF will raise an exception if they could not be retrieved #unless you have :param allowFallback: set to True. Fallback will go in this #order, starting at the top most format that is set: # * HTML # * RTF # * Plain text #""" count = 1 if toJson else 0 #count += 1 if html else 0 #count += 1 if rtf else 0 count += 1 if raw else 0 if count > 1: raise IncompatibleOptionsError( 'Only one of the following options may be used at a time: toJson, raw, html, rtf' ) crlf = inputToBytes(self.crlf, 'utf-8') if customFilename != None and customFilename != '': dirName = customFilename else: if useFileName: # strip out the extension if self.filename is not None: dirName = self.filename.split('/').pop().split('.')[0] else: ValueError( 'Filename must be specified, or path must have been an actual path, to save using filename' ) else: # Create a directory based on the date and subject of the message d = self.parsedDate if d is not None: dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format( *d) else: dirName = 'UnknownDate' if self.subject is None: subject = '[No subject]' else: subject = prepareFilename(self.subject) dirName = dirName + ' ' + subject if customPath != None and customPath != '': if customPath[-1] != '/' or customPath[-1] != '\\': customPath += '/' dirName = customPath + dirName try: os.makedirs(dirName) except Exception: newDirName = addNumToDir(dirName) if newDirName is not None: dirName = newDirName else: raise Exception( "Failed to create directory '%s'. Does it already exist?" % dirName) oldDir = os.getcwdu() try: os.chdir(dirName) attachmentNames = [] # Save the attachments for attachment in self.attachments: attachmentNames.append( attachment.save(ContentId, toJson, useFileName, raw) ) #, html = html, rtf = rtf, allowFallback = allowFallback)) # Save the message body fext = 'json' if toJson else 'txt' useHtml = False useRtf = False #if html: # if self.htmlBody is not None: # useHtml = True # fext = 'html' #elif not allowFallback: # raise DataNotFoundError('Could not find the htmlBody') #if rtf or (html and not useHtml): # if self.rtfBody is not None: # useRtf = True # fext = 'rtf' #elif not allowFallback: # raise DataNotFoundError('Could not find the rtfBody') with open('message.' + fext, 'wb') as f: if toJson: emailObj = { 'from': inputToString(self.sender, 'utf-8'), 'to': inputToString(self.to, 'utf-8'), 'cc': inputToString(self.cc, 'utf-8'), 'subject': inputToString(self.subject, 'utf-8'), 'date': inputToString(self.date, 'utf-8'), 'attachments': attachmentNames, 'body': decode_utf7(self.body) } f.write(inputToBytes(json.dumps(emailObj), 'utf-8')) else: if useHtml: # Do stuff pass elif useRtf: # Do stuff pass else: f.write(b'From: ' + inputToBytes(self.sender, 'utf-8') + crlf) f.write(b'To: ' + inputToBytes(self.to, 'utf-8') + crlf) f.write(b'CC: ' + inputToBytes(self.cc, 'utf-8') + crlf) f.write(b'Subject: ' + inputToBytes(self.subject, 'utf-8') + crlf) f.write(b'Date: ' + inputToBytes(self.date, 'utf-8') + crlf) f.write(b'-----------------' + crlf + crlf) f.write(inputToBytes(self.body, 'utf-8')) except Exception as e: self.saveRaw() raise finally: # Return to previous directory os.chdir(oldDir) # Return the instance so that functions can easily be chained. return self
def save(self, raw=False): # Create a directory based on the date and subject of the message d = self.parsedDate if d is not None: dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format(*d) else: dirName = "UnknownDate" if self.subject is None: subject = "[No subject]" else: subject = "".join(i for i in self.subject if i not in r'\/:*?"<>|') dirName = dirName + " " + subject def addNumToDir(dirName): # Attempt to create the directory with a '(n)' appended dirCreated = False for i in range(2, 100): try: newDirName = dirName + " (" + str(i) + ")" os.makedirs(newDirName) return dirName except Exception: pass return None try: os.makedirs(dirName) except Exception: newDirName = addNumToDir(dirName) if newDirName is not None: dirName = newDirName else: raise Exception( "Failed to create directory '%s'. Does it already exist?" % dirName ) oldDir = os.getcwd() try: os.chdir(dirName) # Save the message body fext = 'json' if toJson else 'text' f = open("message." + ext, "w") # From, to , cc, subject, date def xstr(s): return '' if s is None else str(s) attachmentNames = [] # Save the attachments for attachment in self.attachments: attachmentNames.append(attachment.save()) if toJson: import json from imapclient import imapclient self.body = imapclient.decode_utf7(self.body) emailObj = {'from': xstr(self.sender), 'to': xstr(self.to), 'cc': xstr(self.cc), 'subject': xstr(self.subject), 'date': xstr(self.date), 'attachments': attachmentNames, 'body': self.body} f.write(json.dumps(emailObj, ensure_ascii=True)) else: f.write("From: " + xstr(self.sender) + "\n") f.write("To: " + xstr(self.to) + "\n") f.write("CC: " + xstr(self.cc) + "\n") f.write("Subject: " + xstr(self.subject) + "\n") f.write("Date: " + xstr(self.date) + "\n") f.write("-----------------\n\n") f.write(self.body) f.close() except Exception: self.saveRaw() raise finally: # Return to previous directory os.chdir(oldDir)
def save(self, raw=False): if useFileName: # strip out the extension dirName = filename.split('/').pop().split('.')[0] else: # Create a directory based on the date and subject of the message d = self.parsedDate if d is not None: dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format(*d) else: dirName = "UnknownDate" if self.subject is None: subject = "[No subject]" else: subject = "".join(i for i in self.subject if i not in r'\/:*?"<>|') dirName = dirName + " " + subject def addNumToDir(dirName): # Attempt to create the directory with a '(n)' appended for i in range(2, 100): try: newDirName = dirName + " (" + str(i) + ")" #os.makedirs(newDirName) return dirName except Exception: pass return None newDirName = addNumToDir(dirName) if newDirName is not None: dirName = newDirName else: raise Exception( "Failed to create directory '%s'. Does it already exist?" % dirName) oldDir = os.getcwd() #os.chdir(dirName) # Save the message body # From, to , cc, subject, date def xstr(s): return '' if s is None else str(s) attachmentNames = [] # Save the attachments for attachment in self.attachments: attachmentNames.append(attachment.save()) import json from imapclient.imapclient import decode_utf7 from_author, from_mail = format_mail(xstr(self.sender)) cc = xstr(self.cc).strip() if len(cc) == 0: to_author, to_mail = format_mail(xstr(self.to)) else: to_author, to_mail = format_mail(xstr(self.to) + ", " + cc) emailObj = { 'from_author': from_author, 'from_mail': from_mail, 'to_author': to_author, 'to_mail': to_mail, 'subject': xstr(self.subject), 'date': get_timestamp(xstr(self.date)), 'body': remove_eol( remove_tags(decode_utf7(self.body)) + " " + " ".join(attachmentNames)) } print json.dumps(emailObj)
def save(self, toJson=False, useFileName=False, raw=False, ContentId=False, customPath=None, customFilename=None, html=False, rtf=False): """ Saves the message body and attachments found in the message. Setting toJson to true will output the message body as JSON-formatted text. The body and attachments are stored in a folder. Setting useFileName to true will mean that the filename is used as the name of the folder; otherwise, the message's date and subject are used as the folder name. Here is the absolute order of prioity for the name of the folder: 1. customFilename 2. self.filename if useFileName 3. {date} {subject} """ crlf = inputToBytes(self.__crlf, 'utf-8') if customFilename != None and customFilename != '': dirName = customFilename else: if useFileName: # strip out the extension if self.filename is not None: dirName = self.filename.split('/').pop().split('.')[0] else: ValueError( 'Filename must be specified, or path must have been an actual path, to save using filename' ) else: # Create a directory based on the date and subject of the message d = self.parsedDate if d is not None: dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format( *d) else: dirName = 'UnknownDate' if self.subject is None: subject = '[No subject]' else: subject = ''.join(i for i in self.subject if i not in r'\/:*?"<>|') dirName = dirName + ' ' + subject if customPath != None and customPath != '': if customPath[-1] != '/' or customPath[-1] != '\\': customPath += '/' dirName = customPath + dirName try: os.makedirs(dirName) except Exception: newDirName = addNumToDir(dirName) if newDirName is not None: dirName = newDirName else: raise Exception( "Failed to create directory '%s'. Does it already exist?" % dirName) oldDir = os.getcwdu() try: os.chdir(dirName) attachmentNames = [] # Save the attachments for attachment in self.attachments: attachmentNames.append( attachment.save(ContentId, toJson, useFileName, raw, html=html, rtf=rtf)) # Save the message body fext = 'json' if toJson else 'txt' useHtml = False useRtf = False #if html: # if self.htmlBody is not None: # useHtml = True # fext = 'html' #elif rtf: # if self.htmlBody is not None: # useRtf = True # fext = 'rtf' with open('message.' + fext, 'wb') as f: if toJson: emailObj = { 'from': inputToString(self.sender, 'utf-8'), 'to': inputToString(self.to, 'utf-8'), 'cc': inputToString(self.cc, 'utf-8'), 'subject': inputToString(self.subject, 'utf-8'), 'date': inputToString(self.date, 'utf-8'), 'attachments': attachmentNames, 'body': decode_utf7(self.body) } f.write(inputToBytes(json.dumps(emailObj), 'utf-8')) else: if useHtml: # Do stuff pass elif useRtf: # Do stuff pass else: f.write(b'From: ' + inputToBytes(self.sender, 'utf-8') + crlf) f.write(b'To: ' + inputToBytes(self.to, 'utf-8') + crlf) f.write(b'CC: ' + inputToBytes(self.cc, 'utf-8') + crlf) f.write(b'Subject: ' + inputToBytes(self.subject, 'utf-8') + crlf) f.write(b'Date: ' + inputToBytes(self.date, 'utf-8') + crlf) f.write(b'-----------------' + crlf + crlf) f.write(inputToBytes(self.body, 'utf-8')) except Exception as e: self.saveRaw() raise finally: # Return to previous directory os.chdir(oldDir)
def save(self, toJson=True, useFileName=False, raw=False, ContentId=False): '''Saves the message body and attachments found in the message. Setting toJson to true will output the message body as JSON-formatted text. The body and attachments are stored in a folder. Setting useFileName to true will mean that the filename is used as the name of the folder; otherwise, the message's date and subject are used as the folder name.''' if useFileName: # strip out the extension dirName = self.filename.split('/').pop().split('.')[0] else: # Create a directory based on the date and subject of the message d = self.parsedDate if d is not None: dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format(*d) else: dirName = 'UnknownDate' if self.subject is None: subject = '[No subject]' else: subject = ''.join(i for i in self.subject if i not in r'\/:*?"<>|') dirName = dirName + ' ' + subject oldDir = os.getcwd() try: #os.chdir(dirName) # Save the message body fext = 'json' if toJson else 'text' #f = open('message.' + fext, 'w') # From, to , cc, subject, date toJson=True attachmentNames = [] attaches = [] # Save the attachments for attachment in self.attachments: attachmentNames.append(str(attachment.save())) if toJson: urls = re.findall('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', decode_utf7(self.body)) uniq_urls = [] for i in urls: if i not in uniq_urls: uniq_urls.append(i) emailObj = {'from': xstr(self.sender), 'to': xstr(self.to), 'cc': xstr(self.cc), 'subject': xstr(self.subject), 'date': xstr(self.date), 'attachments': attachmentNames, 'body': decode_utf7(xstr(self.body)), 'urls': uniq_urls} return emailObj else: #print('From: ' + xstr(self.sender) + self.__crlf) #print('To: ' + xstr(self.to) + self.__crlf) #print('CC: ' + xstr(self.cc) + self.__crlf) #print('Subject: ' + xstr(self.subject) + self.__crlf) #print('Date: ' + xstr(self.date) + self.__crlf) #print('-----------------' + self.__crlf + self.__crlf) #print(self.body) return 'abc' except Exception as e: print e raise finally: # Return to previous directory os.chdir(oldDir)
def save(self, toJson=False, useFileName=False, raw=False, ContentId=False, customPath=None, customFilename=None): """ Saves the message body and attachments found in the message. Setting toJson to true will output the message body as JSON-formatted text. The body and attachments are stored in a folder. Setting useFileName to true will mean that the filename is used as the name of the folder; otherwise, the message's date and subject are used as the folder name. Here is the absolute order of prioity for the name of the folder: 1. customFilename 2. self.filename if useFileName 3. {date} {subject} """ if customFilename != None and customFilename != '': dirName = customFilename else: if useFileName: # strip out the extension if self.filename is not None: dirName = self.filename.split('/').pop().split('.')[0] else: ValueError( 'Filename must be specified, or path must have been an actual path, to save using filename') else: # Create a directory based on the date and subject of the message d = self.parsedDate if d is not None: dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format(*d) else: dirName = 'UnknownDate' if self.subject is None: subject = '[No subject]' else: subject = ''.join(i for i in self.subject if i not in r'\/:*?"<>|') dirName = dirName + ' ' + subject if customPath != None and customPath != '': if customPath[-1] != '/' or customPath[-1] != '\\': customPath += '/' dirName = customPath + dirName try: os.makedirs(dirName) except Exception: newDirName = addNumToDir(dirName) if newDirName is not None: dirName = newDirName else: raise Exception( "Failed to create directory '%s'. Does it already exist?" % dirName ) oldDir = os.getcwdu() try: os.chdir(dirName) # Save the message body fext = 'json' if toJson else 'text' f = open('message.' + fext, 'w') # From, to , cc, subject, date attachmentNames = [] # Save the attachments for attachment in self.attachments: attachmentNames.append(attachment.save(ContentId, toJson)) if toJson: emailObj = {'from': xstr(self.sender), 'to': xstr(self.to), 'cc': xstr(self.cc), 'subject': xstr(self.subject), 'date': xstr(self.date), 'attachments': attachmentNames, 'body': decode_utf7(self.body)} f.write(json.dumps(emailObj, ensure_ascii=True)) else: f.write('From: ' + xstr(self.sender) + self.__crlf) f.write('To: ' + xstr(self.to) + self.__crlf) f.write('CC: ' + xstr(self.cc) + self.__crlf) f.write('Subject: ' + xstr(self.subject) + self.__crlf) f.write('Date: ' + xstr(self.date) + self.__crlf) f.write('-----------------' + self.__crlf + self.__crlf) f.write(self.body) f.close() except Exception as e: self.saveRaw() raise finally: # Return to previous directory os.chdir(oldDir)
def save(self, toJson=False, useFileName=False, raw=False): '''Saves the message body and attachments found in the message. Setting toJson to true will output the message body as JSON-formatted text. The body and attachments are stored in a folder. Setting useFileName to true will mean that the filename is used as the name of the folder; otherwise, the message's date and subject are used as the folder name.''' if useFileName: # strip out the extension dirName = filename.split('/').pop().split('.')[0] else: # Create a directory based on the date and subject of the message d = self.parsedDate if d is not None: dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format(*d) else: dirName = "UnknownDate" if self.subject is None: subject = "[No subject]" else: subject = "".join(i for i in self.subject if i not in r'\/:*?"<>|') dirName = dirName + " " + subject def addNumToDir(dirName): # Attempt to create the directory with a '(n)' appended for i in range(2, 100): try: newDirName = dirName + " (" + str(i) + ")" os.makedirs(newDirName) return newDirName except Exception: traceback.format_exc() pass return None try: if not toJson: os.makedirs(dirName) except Exception: newDirName = addNumToDir(dirName) if newDirName is not None: dirName = newDirName else: raise Exception( "Failed to create directory '%s'. Does it already exist?" % dirName ) oldDir = os.getcwd() try: if not toJson: os.chdir(dirName) # Save the message body fext = 'json' if toJson else 'text' f = open("message." + fext, "w") # From, to , cc, subject, date def xstr(s): return '' if s is None else str(s) attachmentNames = [] # Save the attachments #print(str(self._getStream(["__attach_version1.0_#00000000", '__substg1.0_37010102']))) for attachment in self.attachments: if not None is attachment and not None is attachment.data: if not toJson: attachmentNames.append(attachment.save()) else: attachmentNames.append(attachment.dump()) if toJson: import json emailObj = {'from': xstr(self.sender), 'to': xstr(self.to), 'cc': xstr(self.cc), 'subject': xstr(self.subject), 'date': xstr(self.date), 'attachments': attachmentNames, 'body': decode_utf7(self.body)} # f.write(json.dumps(emailObj, ensure_ascii=True,indent=4)) ##print(json.dumps(emailObj, ensure_ascii=True,indent=4)) else: f.write("From: " + xstr(self.sender) + "\n") f.write("To: " + xstr(self.to) + "\n") f.write("CC: " + xstr(self.cc) + "\n") f.write("Subject: " + xstr(self.subject) + "\n") f.write("Date: " + xstr(self.date) + "\n") f.write("-----------------\n\n") f.write(self.body) f.close() except Exception: self.saveRaw() raise finally: # Return to previous directory os.chdir(oldDir)
def save(self, toJson=False, useFileName=False, raw=False, ContentId=False, customPath=None, customFilename=None): """ Saves the message body and attachments found in the message. Setting toJson to true will output the message body as JSON-formatted text. The body and attachments are stored in a folder. Setting useFileName to true will mean that the filename is used as the name of the folder; otherwise, the message's date and subject are used as the folder name. Here is the absolute order of prioity for the name of the folder: 1. customFilename 2. self.filename if useFileName 3. {date} {subject} """ if customFilename != None and customFilename != '': dirName = customFilename else: if useFileName: # strip out the extension if self.filename is not None: dirName = self.filename.split('/').pop().split('.')[0] else: ValueError( 'Filename must be specified, or path must have been an actual path, to save using filename' ) else: # Create a directory based on the date and subject of the message d = self.parsedDate if d is not None: dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format( *d) else: dirName = 'UnknownDate' if self.subject is None: subject = '[No subject]' else: subject = ''.join(i for i in self.subject if i not in r'\/:*?"<>|') dirName = dirName + ' ' + subject if customPath != None and customPath != '': if customPath[-1] != '/' or customPath[-1] != '\\': customPath += '/' dirName = customPath + dirName try: os.makedirs(dirName) except Exception: newDirName = addNumToDir(dirName) if newDirName is not None: dirName = newDirName else: raise Exception( "Failed to create directory '%s'. Does it already exist?" % dirName) oldDir = os.getcwdu() try: os.chdir(dirName) # Save the message body fext = 'json' if toJson else 'text' f = open('message.' + fext, 'w', encoding="utf-8") # From, to , cc, subject, date attachmentNames = [] # Save the attachments for attachment in self.attachments: attachmentNames.append(attachment.save(ContentId, toJson)) if toJson: emailObj = { 'from': xstr(self.sender), 'to': xstr(self.to), 'cc': xstr(self.cc), 'subject': xstr(self.subject), 'date': xstr(self.date), 'attachments': attachmentNames, 'body': decode_utf7(self.body) } f.write(json.dumps(emailObj, ensure_ascii=True)) else: f.write('From: ' + xstr(self.sender) + self.__crlf) f.write('To: ' + xstr(self.to) + self.__crlf) f.write('CC: ' + xstr(self.cc) + self.__crlf) f.write('Subject: ' + xstr(self.subject) + self.__crlf) f.write('Date: ' + xstr(self.date) + self.__crlf) f.write('-----------------' + self.__crlf + self.__crlf) f.write(self.body) f.close() except Exception as e: self.saveRaw() raise finally: # Return to previous directory os.chdir(oldDir)
def dump(self, toJson=False, useFileName=False, raw=False): '''Saves the message body and attachments found in the message. Setting toJson to true will output the message body as JSON-formatted text. The body and attachments are stored in a folder. Setting useFileName to true will mean that the filename is used as the name of the folder; otherwise, the message's date and subject are used as the folder name.''' if useFileName: # strip out the extension dirName = filename.split('/').pop().split('.')[0] else: # Create a directory based on the date and subject of the message d = self.parsedDate if d is not None: dirName = '{0:02d}-{1:02d}-{2:02d}_{3:02d}{4:02d}'.format(*d) else: dirName = "UnknownDate" if self.subject is None: subject = "[No subject]" else: subject = "".join(i for i in self.subject if i not in r'\/:*?"<>|') dirName = dirName + " " + subject def addNumToDir(dirName): # Attempt to create the directory with a '(n)' appended for i in range(2, 100): try: newDirName = dirName + " (" + str(i) + ")" os.makedirs(newDirName) return newDirName except Exception: traceback.format_exc() return None try: def xstr(s): #return s try: return '' if s is None else str(unidecode.unidecode(s)) except Exception: ##print("<<<<"+s+">>>>") raise return s attachmentNames = [] for attachment in self.attachments: if not None is attachment and not None is attachment.data: attachmentNames.append(attachment.dump()) if toJson: import json emailObj = {'from': xstr(self.sender), 'to': xstr(self.to), 'cc': xstr(self.cc), 'subject': xstr(self.subject), 'date': xstr(self.date), 'attachments': attachmentNames, 'body': decode_utf7(self.body), 'embeddedheader':self.embeddedheader } return emailObj except Exception: traceback.format_exc() raise