示例#1
0
    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)
示例#2
0
    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)
示例#3
0
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 as e:
            pass
    return None
示例#4
0
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 as e:
            pass
    return None
示例#5
0
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)
示例#6
0
文件: dev.py 项目: olexsahka/plagi
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))
示例#7
0
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))
示例#8
0
    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)
示例#9
0
from extract_msg import __doc__, utils
from extract_msg.compat import os_ as os
from extract_msg.message import Message

if __name__ == '__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()))
示例#10
0
def setup_logging(default_path=None, default_level=logging.WARN, logfile=None, enable_file_logging=False,
                  env_key='EXTRACT_MSG_LOG_CFG'):
    """
    Setup logging configuration

    Args:
        default_path (str): Default path to use for the logging configuration file
        default_level (int): Default logging level
        env_key (str): Environment variable name to search for, for setting logfile path

    Returns:
        bool: True if the configuration file was found and applied, False otherwise
    """
    shipped_config = getContFileDir(__file__) + '/logging-config/'
    if os.name == 'nt':
        null = 'NUL'
        shipped_config += 'logging-nt.json'
    elif os.name == 'posix':
        null = '/dev/null'
        shipped_config += 'logging-posix.json'
    # Find logging.json if not provided
    if not default_path:
        default_path = shipped_config

    paths = [
        default_path,
        'logging.json',
        '../logging.json',
        '../../logging.json',
        shipped_config,
    ]

    path = None

    for config_path in paths:
        if os.path.exists(config_path):
            path = config_path
            break

    value = os.getenv(env_key, None)
    if value and os.path.exists(value):
        path = value

    if path is None:
        print('Unable to find logging.json configuration file')
        print('Make sure a valid logging configuration file is referenced in the default_path'
              ' argument, is inside the extract_msg install location, or is available at one '
              'of the following file-paths:')
        print(str(paths[1:]))
        logging.basicConfig(level=default_level)
        logging.warning('The extract_msg logging configuration was not found - using a basic configuration.'
                        'Please check the extract_msg installation directory for "logging-{}.json".'.format(os.name))
        return False

    with open(path, 'rt') as f:
        config = json.load(f)

    for x in config['handlers']:
        if 'filename' in config['handlers'][x]:
            if enable_file_logging:
                config['handlers'][x]['filename'] = tmp = os.path.expanduser(
                    os.path.expandvars(logfile if logfile else config['handlers'][x]['filename']))
                tmp = getContFileDir(tmp)
                if not os.path.exists(tmp):
                    os.makedirs(tmp)
            else:
                config['handlers'][x]['filename'] = null

    try:
        logging.config.dictConfig(config)
    except ValueError as e:
        print('Failed to configure the logger. Did your installation get messed up?')
        print(e)

    logging.getLogger().setLevel(default_level)
    return True
示例#11
0
    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)
示例#12
0
import traceback

from extract_msg import __doc__, utils
from extract_msg.compat import os_ as os
from extract_msg.message import Message

if __name__ == '__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()))
示例#13
0
def setup_logging(default_path=None, default_level=logging.WARN, logfile=None, enable_file_logging=False,
                  env_key='EXTRACT_MSG_LOG_CFG'):
    """
    Setup logging configuration

    Args:
        default_path (str): Default path to use for the logging configuration file
        default_level (int): Default logging level
        env_key (str): Environment variable name to search for, for setting logfile path

    Returns:
        bool: True if the configuration file was found and applied, False otherwise
    """
    shipped_config = getContFileDir(__file__) + '/logging-config/'
    if os.name == 'nt':
        null = 'NUL'
        shipped_config += 'logging-nt.json'
    elif os.name == 'posix':
        null = '/dev/null'
        shipped_config += 'logging-posix.json'
    # Find logging.json if not provided
    if not default_path:
        default_path = shipped_config

    paths = [
        default_path,
        'logging.json',
        '../logging.json',
        '../../logging.json',
        shipped_config,
    ]

    path = None

    for config_path in paths:
        if os.path.exists(config_path):
            path = config_path
            break

    value = os.getenv(env_key, None)
    if value and os.path.exists(value):
        path = value

    if path is None:
        print('Unable to find logging.json configuration file')
        print('Make sure a valid logging configuration file is referenced in the default_path'
              ' argument, is inside the extract_msg install location, or is available at one '
              'of the following file-paths:')
        print(str(paths[1:]))
        logging.basicConfig(level=default_level)
        logging.warning('The extract_msg logging configuration was not found - using a basic configuration.'
                        'Please check the extract_msg installation directory for "logging-{}.json".'.format(os.name))
        return False

    with open(path, 'rt') as f:
        config = json.load(f)

    for x in config['handlers']:
        if 'filename' in config['handlers'][x]:
            if enable_file_logging:
                config['handlers'][x]['filename'] = tmp = os.path.expanduser(
                    os.path.expandvars(logfile if logfile else config['handlers'][x]['filename']))
                tmp = getContFileDir(tmp)
                if not os.path.exists(tmp):
                    os.makedirs(tmp)
            else:
                config['handlers'][x]['filename'] = null

    try:
        logging.config.dictConfig(config)
    except ValueError as e:
        print('Failed to configure the logger. Did your installation get messed up?')
        print(e)

    logging.getLogger().setLevel(default_level)
    return True
示例#14
0
    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
示例#15
0
    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)