def main(): # Setup logging to stdout, indicate running from cli CLI_LOGGING = 'extract_msg_cli' args = utils.get_command_args(sys.argv[1:]) level = logging.INFO if args.verbose else logging.WARNING currentdir = os.getcwdu( ) # Store this just in case the paths that have been given are relative if args.out_path: if not os.path.exists(args.out_path): os.makedirs(args.out_path) out = args.out_path else: out = currentdir if args.dev: import extract_msg.dev extract_msg.dev.main(args, sys.argv[1:]) elif args.validate: import json import pprint import time from extract_msg import validation val_results = {x[0]: validation.validate(x[0]) for x in args.msgs} filename = 'validation {}.json'.format(int(time.time())) print('Validation Results:') pprint.pprint(val_results) print('These results have been saved to {}'.format(filename)) with open(filename, 'w') as fil: fil.write(json.dumps(val_results)) utils.get_input('Press enter to exit...') else: if not args.dump_stdout: utils.setup_logging(args.config_path, level, args.log, args.file_logging) for x in args.msgs: try: with Message(x[0]) as msg: # Right here we should still be in the path in currentdir if args.dump_stdout: print(msg.body) else: os.chdir(out) msg.save(toJson=args.json, useFileName=args.use_filename, ContentId=args.cid ) #, html = args.html, rtf = args.html) except Exception as e: print("Error with file '" + x[0] + "': " + traceback.format_exc()) os.chdir(currentdir)
def saveRaw(self): # Create a 'raw' folder oldDir = os.getcwdu() try: rawDir = 'raw' os.makedirs(rawDir) os.chdir(rawDir) sysRawDir = os.getcwdu() # Loop through all the directories for dir_ in self.listdir(): sysdir = '/'.join(dir_) code = dir_[-1][-8:] if code in constants.PROPERTIES: sysdir = sysdir + ' - ' + constants.PROPERTIES[code] os.makedirs(sysdir) os.chdir(sysdir) # Generate appropriate filename if dir_[-1].endswith('001E'): filename = 'contents.txt' else: filename = 'contents' # Save contents of directory with open(filename, 'wb') as f: f.write(self._getStream(dir_)) # Return to base directory os.chdir(sysRawDir) finally: os.chdir(oldDir)
def main(args, argv): """ Please only run this from the command line. Attempting to use this otherwise is likely to fail. :param args: is the class instance returned by `extract_msg.utils.get_command_args`. :param argv: is the list of arguments that were the input to the aforementioned function. """ setup_dev_logger(args.config_path, args.log) currentdir = os.getcwdu( ) # Store this just in case the paths that have been given are relative if args.out_path: if not os.path.exists(args.out_path): os.makedirs(args.out_path) out = args.out_path else: out = currentdir logger.log(5, 'ARGV: {}'.format(argv)) for y, x in enumerate(args.msgs): logger.log(5, '---- RUNNING DEVELOPER MODE ON FILE {} ----'.format(x[0])) logger.log(5, 'EXCEPTION CHECK:') try: with Message(x[0]) as msg: # Right here we should still be in the path in currentdir os.chdir(out) msg.save(toJson=args.json, useFileName=args.use_filename, ContentId=args.cid) except Exception as e: logger.exception(e) else: logger.log(5, 'No exceptions raised.') logger.log(5, 'DEVELOPER CLASS OUTPUT:') os.chdir(currentdir) dev_classes.Message(x[0]) logger.log(5, '---- END OF DEVELOPER LOG ----') logpath = None for x in logging.root.handlers: try: logpath = x.baseFilename except AttributeError: pass print('Logging complete. Log has been saved to {}'.format(logpath))
def main(args, argv): """ Please only run this from the command line. Attempting to use this otherwise is likely to fail. :param args: is the class instance returned by `extract_msg.utils.get_command_args`. :param argv: is the list of arguments that were the input to the aforementioned function. """ setup_dev_logger(args.config_path, args.log) currentdir = os.getcwdu() # Store this just in case the paths that have been given are relative if args.out_path: if not os.path.exists(args.out_path): os.makedirs(args.out_path) out = args.out_path else: out = currentdir logger.log(5, 'ARGV: {}'.format(argv)) for y, x in enumerate(args.msgs): logger.log(5, '---- RUNNING DEVELOPER MODE ON FILE {} ----'.format(x[0])) logger.log(5, 'EXCEPTION CHECK:') try: with Message(x[0]) as msg: # Right here we should still be in the path in currentdir os.chdir(out) msg.save(toJson = args.json, useFileName = args.use_filename, ContentId = args.cid) except Exception as e: logger.exception(e) else: logger.log(5, 'No exceptions raised.') logger.log(5, 'DEVELOPER CLASS OUTPUT:') os.chdir(currentdir) dev_classes.Message(x[0]) logger.log(5, '---- END OF DEVELOPER LOG ----') logpath = None; for x in logging.root.handlers: try: logpath = x.baseFilename except AttributeError: pass; print('Logging complete. Log has been saved to {}'.format(logpath))
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)
import pprint import time from extract_msg import validation val_results = {x[0]: validation.validate(x[0]) for x in args.msgs} filename = 'validation {}.json'.format(int(time.time())) print('Validation Results:') pprint.pprint(val_results) print('These results have been saved to {}'.format(filename)) with open(filename, 'w') as fil: fil.write(json.dumps(val_results)) utils.get_input('Press enter to exit...') else: utils.setup_logging(args.config_path, level, args.log, args.file_logging) for x in args.msgs: try: with Message(x[0]) as msg: # Right here we should still be in the path in currentdir os.chdir(out) msg.save(toJson=args.json, useFileName=args.use_filename, ContentId=args.cid, html=args.html, rtf=args.html) except Exception as e: print("Error with file '" + x[0] + "': " + traceback.format_exc()) os.chdir(currentdir)
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)
if args.dev: import extract_msg.dev extract_msg.dev.main(args, sys.argv[1:]) elif args.validate: import json import pprint import time from extract_msg import validation val_results = {x[0]: validation.validate(x[0]) for x in args.msgs} filename = 'validation {}.json'.format(int(time.time())) print('Validation Results:') pprint.pprint(val_results) print('These results have been saved to {}'.format(filename)) with open(filename, 'w') as fil: fil.write(json.dumps(val_results)) utils.get_input('Press enter to exit...') else: utils.setup_logging(args.config_path, level, args.log, args.file_logging) for x in args.msgs: try: with Message(x[0]) as msg: # Right here we should still be in the path in currentdir os.chdir(out) msg.save(toJson = args.json, useFileName = args.use_filename, ContentId = args.cid) except Exception as e: print("Error with file '" + x[0] + "': " + traceback.format_exc()) os.chdir(currentdir)
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, 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)