def __init__(self, fromlines=None, fromstring=None, fromfile=None): #self.log = Logger() self.recipient = None self.received_by = None self.received_from = None self.received_with = None self.__raw = None try: parser = Parser.BytesParser() parsestr = parser.parsebytes except: parser = Parser.Parser() parsestr = parser.parsestr # Message is instantiated with fromlines for POP3, fromstring for # IMAP (both of which can be badly-corrupted or invalid, i.e. spam, # MS worms, etc). It's instantiated with fromfile for the output # of filters, etc, which should be saner. if fromlines: try: self.__msg = parsestr(_NL.join(fromlines)) except Errors.MessageError as o: self.__msg = corrupt_message(o, fromlines=fromlines) self.__raw = _NL.join(fromlines) elif fromstring: try: self.__msg = parsestr(fromstring) except Errors.MessageError as o: self.__msg = corrupt_message(o, fromstring=fromstring) self.__raw = fromstring elif fromfile: try: self.__msg = parser.parse(fromfile) except Errors.MessageError as o: # Shouldn't happen self.__msg = corrupt_message(o, fromstring=fromfile.read()) # fromfile is only used by getmail_maildir, getmail_mbox, and # from reading the output of a filter. Ignore __raw here. else: # Can't happen? raise SystemExit('Message() called with wrong arguments') self.sender = address_no_brackets(self.__msg['Return-Path'] or self.__msg['Sender'] or 'unknown')
except email.Errors.MessageError, o: self.__msg = corrupt_message(o, fromstring=fromstring) self.__raw = fromstring elif fromfile: try: self.__msg = parser.parse(fromfile) except email.Errors.MessageError, o: # Shouldn't happen self.__msg = corrupt_message(o, fromstring=fromfile.read()) # fromfile is only used by getmail_maildir, getmail_mbox, and # from reading the output of a filter. Ignore __raw here. else: # Can't happen? raise SystemExit('Message() called with wrong arguments') self.sender = address_no_brackets(self.__msg['return-path'] or 'unknown') def content(self): return self.__msg def copyattrs(self, othermsg): for attr in message_attributes: setattr(self, attr, getattr(othermsg, attr)) def flatten(self, delivered_to, received, mangle_from=False, include_from=False): '''Return a string with native EOL convention. The email module apparently doesn't always use native EOL, so we force it by writing out what we need, letting the generator write out the message, splitting it into lines, and joining them with the platform
def go(configs): blurb() summary = [] for (configfile, retriever, _filters, destination, options) in configs: oplevel = options['verbose'] logverbose = options['message_log_verbose'] now = int(time.time()) msgs_retrieved = 0 bytes_retrieved = 0 msgs_skipped = 0 if options['message_log_syslog']: syslog.openlog('getmail', 0, syslog.LOG_MAIL) try: log.info('%s:\n' % retriever) logline = 'Initializing %s:' % retriever if options['logfile'] and logverbose: options['logfile'].write(logline) if options['message_log_syslog'] and logverbose: syslog.syslog(syslog.LOG_INFO, logline) retriever.initialize(options) destination.retriever_info(retriever) nummsgs = len(retriever) fmtlen = len(str(nummsgs)) for (msgnum, msgid) in enumerate(retriever): log.debug(' message %s ...\n' % msgid) msgnum += 1 retrieve = False reason = 'seen' delete = False timestamp = retriever.oldmail.get(msgid, None) size = retriever.getmsgsize(msgid) info = ('msg %*d/%*d (%d bytes)' % (fmtlen, msgnum, fmtlen, nummsgs, size)) logline = '%s msgid %s' % (info, msgid) if options['read_all'] or timestamp is None: retrieve = True if (options['max_message_size'] and size > options['max_message_size']): retrieve = False reason = 'oversized' if (options['max_bytes_per_session'] and (bytes_retrieved + size) > options['max_bytes_per_session']): retrieve = False reason = 'would surpass max_bytes_per_session' try: if retrieve: try: msg = retriever.getmsg(msgid) except getmailRetrievalError, o: log.error( 'Retrieval error: server for %s is broken; ' 'offered message %s but failed to provide it. ' 'Please notify the administrator of the ' 'server. Skipping message...\n' % (retriever, msgid)) continue msgs_retrieved += 1 bytes_retrieved += size if oplevel > 1: info += (' from <%s>' % address_no_brackets(msg.sender)) if msg.recipient is not None: info += (' to <%s>' % address_no_brackets(msg.recipient)) logline += (' from <%s>' % address_no_brackets(msg.sender)) if msg.recipient is not None: logline += (' to <%s>' % address_no_brackets(msg.recipient)) for mail_filter in _filters: log.debug(' passing to filter %s\n' % mail_filter) msg = mail_filter.filter_message(msg, retriever) if msg is None: log.debug(' dropped by filter %s\n' % mail_filter) info += (' dropped by filter %s' % mail_filter) logline += (' dropped by filter %s' % mail_filter) retriever.delivered(msgid) break if msg is not None: r = destination.deliver_message( msg, options['delivered_to'], options['received']) log.debug(' delivered to %s\n' % r) info += ' delivered' if oplevel > 1: info += (' to %s' % r) logline += (' delivered to %s' % r) retriever.delivered(msgid) if options['delete']: delete = True else: logline += ' not retrieved (%s)' % reason msgs_skipped += 1 log.debug(' not retrieving (timestamp %s)\n' % timestamp) if oplevel > 1: info += ' not retrieved (%s)' % reason if (options['delete_after'] and timestamp and (now - timestamp) / 86400 >= options['delete_after']): log.debug( ' older than %d days (%s seconds), will delete\n' % (options['delete_after'], (now - timestamp))) delete = True if options['delete'] and timestamp: log.debug(' will delete\n') delete = True if not retrieve and timestamp is None: # We haven't retrieved this message. Don't delete it. log.debug(' not yet retrieved, not deleting\n') delete = False if delete: retriever.delmsg(msgid) log.debug(' deleted\n') info += ', deleted' logline += ', deleted' except getmailDeliveryError, o: log.error('Delivery error (%s)\n' % o) info += ', delivery error (%s)' % o if options['logfile']: options['logfile'].write('Delivery error (%s)' % o) if options['message_log_syslog']: syslog.syslog(syslog.LOG_ERR, 'Delivery error (%s)' % o) except getmailFilterError, o: log.error('Filter error (%s)\n' % o) info += ', filter error (%s)' % o if options['logfile']: options['logfile'].write('Filter error (%s)' % o) if options['message_log_syslog']: syslog.syslog(syslog.LOG_ERR, 'Filter error (%s)' % o)
except email.Errors.MessageError, o: self.__msg = corrupt_message(o, fromstring=fromstring) self.__raw = fromstring elif fromfile: try: self.__msg = parser.parse(fromfile) except email.Errors.MessageError, o: # Shouldn't happen self.__msg = corrupt_message(o, fromstring=fromfile.read()) # fromfile is only used by getmail_maildir, getmail_mbox, and # from reading the output of a filter. Ignore __raw here. else: # Can't happen? raise SystemExit('Message() called with wrong arguments') self.sender = address_no_brackets(self.__msg['return-path'] or 'unknown') def content(self): return self.__msg def copyattrs(self, othermsg): for attr in message_attributes: setattr(self, attr, getattr(othermsg, attr)) def flatten(self, delivered_to, received, mangle_from=False, include_from=False): '''Return a string with native EOL convention.