Ejemplo n.º 1
0
def main(args):
    try:
        opts, args = getopt.getopt(args, "hd:S:H:f:",
                                   ["help", "database=", "spamfile=",
                                    "hamfile=", "feature="])
    except getopt.GetoptError as msg:
        usage(msg)
        return 1
    charset = locale.getdefaultlocale()[1]
    if not charset:
        charset = 'us-ascii'
    mapfile = spamfile = hamfile = None
    features = set()
    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage()
            return 0
        elif opt in ("-d", "--database"):
            mapfile = arg
        elif opt in ("-H", "--hamfile"):
            hamfile = arg
        elif opt in ("-S", "--spamfile"):
            spamfile = arg
        elif opt in ("-f", "--feature"):
            features.add(str(arg, charset))
    if hamfile is None and spamfile is None:
        usage("At least one of -S or -H are required")
        return 1
    if mapfile is None:
        usage("'-d mapfile' is required")
        return 1
    try:
        mapd = pickle_read(mapfile)
    except IOError:
        usage("Mapfile %s does not exist" % mapfile)
        return 1
    if not features and not args:
        usage("Require at least one feature (-f) arg or one message file")
        return 1
    if not features:
        for f in args:
            for msg in getmbox(f):
                evidence = msg.get("X-Spambayes-Evidence", "")
                evidence = re.sub(r"\s+", " ", evidence)
                l = [e.rsplit(": ", 1)[0]
                     for e in evidence.split("; ")[2:]]
                for s in l:
                    try:
                        s = make_header(decode_header(s)).__unicode__()
                    except:
                        s = str(s, 'us-ascii', 'replace')
                    features.add(s)
        if not features:
            usage("No X-Spambayes-Evidence headers found")
            return 1
    if spamfile is not None:
        spamfile = file(spamfile, "w")
    if hamfile is not None:
        hamfile = file(hamfile, "w")
    extractmessages(features, mapd, hamfile, spamfile)
Ejemplo n.º 2
0
def mailread(src):
    """生メールから件名,本文,添付ファイル(画像)を取り出す
    """
    # Messageオブジェクトを作る
    m = email.message_from_string(src)
    # ヘッダをデコード
    subj = decode_header(m["Subject"])
    # ヘッダを表示
    try:
        print unicode(make_header(subj))
    except:
        pass
    print "-" * 70
    # 全パートをスキャン
    for part in m.walk():
        type = part.get_content_maintype()  # maintypeを得る
        if type and type.find("image") != -1:
            # 画像の添付が見つかったら,ファイルに保存
            filename = part.get_filename("notitle.img")
            f = open(filename, "wb")
            f.write(part.get_payload(decode=True))
            f.close()
        if type and type.find("text") != -1:
            # テキストは表示
            enc = part.get_charsets()[0] or "us-ascii"
            print part.get_payload().decode(enc, "ignore")
Ejemplo n.º 3
0
def sendmail(to, subject, message):
    #authorization data
    username = '******'
    password = '******'
    #message generating
    msg = MIMEMultipart()
    #header
    hdr = make_header([(subject, icharset)])
    #params
    msg['From'] = username
    msg['To'] = to
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = hdr
    #message body: encoding->html->cp866
    msg.attach(MIMEText(message, 'html', icharset))
    #connection
    srv = smtplib.SMTP(server, port)
    srv.ehlo()
    #starting ssl
    srv.starttls()
    srv.ehlo()
    #authorization
    srv.login(username, password)
    #sending
    srv.sendmail(username, to, msg.as_string())
    #closing connection
    srv.close()
Ejemplo n.º 4
0
 def __decode_header(header):
     """Decode a qp-encoded e-mail header as per rfc2047"""
     try:
         words_enc = decode_header(header)
         hobj = make_header(words_enc)
     except Exception, ex:
         raise CmdException, "header decoding error: %s" % str(ex)
Ejemplo n.º 5
0
    def update(self):
        super(SendNewsletter, self).update()

        if 'form.send' in self.request:
            subs = ISubscribersManagement(self.context.__parent__)

            emails = []
            for principal in subs.getSubscribers():
                mail = IMailAddress(principal, None)
                if mail is not None:
                    email = mail.address

                    if email:
                        emails.append(
                            formataddr((principal.title or principal.id, email)))

            if emails:
                message = self.generateMessage()
                message['Subject'] = make_header(((self.context.title, 'utf-8'),))

                mailer = getUtility(IMailer)

                from_address = str(formataddr(
                    (mailer.email_from_name, mailer.email_from_address)))

                message['From'] = from_address
                mailer.send(from_address, emails, message.as_string())

                IStatusMessage(self.request).add(_('Newsletter has been sent.'))
Ejemplo n.º 6
0
def mailread(src):
    """生メールから件名、本文、添付ファイル(画像)を取り出す
    """
    # Messageオブジェクトを作る
    m = email.message_from_string(src)
    # ヘッダをデコード
    subj = decode_header(m["Subject"])
    # ヘッダを表示
    try:
        print unicode(make_header(subj))
    except: pass;
    print "-" * 70
    # 全パートをスキャン
    for part in m.walk():
        type = part.get_content_maintype() # maintypeを得る
        if type and type.find("image") != -1:
            # 画像の添付が見つかったら、ファイルに保存
            filename = part.get_filename("notitle.img")
            f = open(filename, "wb")
            f.write(part.get_payload(decode = True))
            f.close()
        elif type and type.find("text") != -1:
            # テキストは表示
            enc ~ part.get_charsets()[0] or "us-ascii"
            print part.get_payload().decode(enc, "ignore")
Ejemplo n.º 7
0
def sendmail(to, subject, message):
    # данные авторизации
    username = '******'
    password = '******'

    ### генерация передаваемого содобщения
    msg = MIMEMultipart()

    # заголовок
    hdr = make_header([(subject, icharset)])
    # параметры письма (отправитель, получатель, дата, тема письма
    msg['From'] = username
    msg['To'] = to
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = hdr
    # добавление к содержимому текста сообщения
    msg.attach(MIMEText(message, _charset=icharset))

    ### передача сообщения
    # установка соединения
    srv = smtplib.SMTP(server, port)
    srv.ehlo()
    # запуск шифрования (SSL соединение)
    srv.starttls()
    srv.ehlo()
    # авторизация
    srv.login(username, password)
    # передача сообщения
    srv.sendmail(username, to, msg.as_string())
    # завершение соединения
    srv.close()
Ejemplo n.º 8
0
def send_mail(to, subject, text, attach):
    ###
    if settings.DEBUG:
        logger.debug(u"\n{}\n{}\n{}\n".format(to, subject, text))
        return
    ###
    try:
        msg = MIMEMultipart('related')
        organization = settings.MAIL_SENDER_ORGANIZATION
        mailer = settings.MAIL_SENDER_MAILER
        msg['Message-ID'] = msgid()
        msg['Organization'] = make_header([(organization, 'UTF-8')])
        msg['X-Mailer'] = make_header([(mailer, 'UTF-8')])
        msg['From'] = make_header([(mailer, 'UTF-8'), ('<' + settings.MAIL_SENDER_SENDER + '>', 'us-ascii')])
        msg['To'] = make_header([(to, 'us-ascii')])
        msg['Subject'] = make_header([(subject, 'UTF-8')])
        msg.preamble = "This is a multi-part message in MIME format."
        msg.epilogue = "End of message"
        # alternative part
        msgAlternative = MIMEMultipart('alternative')
        msg.attach(msgAlternative)
        msgText = MIMEText(text, '', 'utf-8')
        msgAlternative.attach(msgText)
        # html part
        to_attach = MIMEText(text.encode('utf-8'), 'html', 'utf-8')
        msgAlternative.attach(to_attach)

        if attach:
            part = MIMEBase('application', 'octet-stream')
            part.set_payload(open(attach, 'rb').read())
            encode_base64(part)
            part.add_header('Content-Disposition',
                            'attachment; filename="%s"' % os.path.basename(attach))
            msg.attach(part)

        mailServer = smtplib.SMTP(settings.MAIL_SENDER_SERVER, settings.MAIL_SENDER_PORT)
        mailServer.ehlo()
        mailServer.starttls()
        mailServer.ehlo()
        mailServer.login(settings.MAIL_SENDER_USER, settings.MAIL_SENDER_PASSWORD)
        mailServer.sendmail(settings.MAIL_SENDER_SENDER, to, msg.as_string())
        # Should be mailServer.quit(), but that crashes...
        mailServer.close()
    except Exception as e:
        logger.error(u'\n\nMessage to "{}" with subject "{}" was not sended\nException message: "{}"\n'.format(to, subject, e.message))
        return
Ejemplo n.º 9
0
Archivo: mail.py Proyecto: mcdonc/ptah
    def setHeaders(self, message):
        charset = str(self.context.charset)

        extra = list(self.context.getHeaders())
        for key, val, encode in self._headers.values() + extra:
            if encode:
                message[key] = make_header(((val, charset),))
            else:
                message[key] = val
Ejemplo n.º 10
0
 def decode_email(self, file):
   # Prepare result
   theMail = {
     'attachment_list': [],
     'body': '',
     # Place all the email header in the headers dictionary in theMail
     'headers': {}
   }
   # Get Message
   msg = email.message_from_string(file)
   # Back up original file
   theMail['__original__'] = file
   # Recode headers to UTF-8 if needed
   for key, value in msg.items():
     decoded_value_list = decode_header(value)
     unicode_value = make_header(decoded_value_list)
     new_value = unicode_value.__unicode__().encode('utf-8')
     theMail['headers'][key.lower()] = new_value
   # Filter mail addresses
   for header in ('resent-to', 'resent-from', 'resent-cc', 'resent-sender',
                  'to', 'from', 'cc', 'sender', 'reply-to'):
     header_field = theMail['headers'].get(header)
     if header_field:
         theMail['headers'][header] = parseaddr(header_field)[1]
   # Get attachments
   body_found = 0
   for part in msg.walk():
     content_type = part.get_content_type()
     file_name = part.get_filename()
     # multipart/* are just containers
     # XXX Check if data is None ?
     if content_type.startswith('multipart'):
       continue
     # message/rfc822 contains attached email message
     # next 'part' will be the message itself
     # so we ignore this one to avoid doubling
     elif content_type == 'message/rfc822':
       continue
     elif content_type in ("text/plain", "text/html"):
       charset = part.get_content_charset()
       payload = part.get_payload(decode=True)
       #LOG('CMFMailIn -> ',0,'charset: %s, payload: %s' % (charset,payload))
       if charset:
         payload = unicode(payload, charset).encode('utf-8')
       if body_found:
         # Keep the content type
         theMail['attachment_list'].append((file_name,
                                            content_type, payload))
       else:
         theMail['body'] = payload
         body_found = 1
     else:
       payload = part.get_payload(decode=True)
       # Keep the content type
       theMail['attachment_list'].append((file_name, content_type,
                                          payload))
   return theMail
Ejemplo n.º 11
0
def header(text):
    if not text:
        text = ''
    if not isinstance(text, text_type):
        text = text.decode('latin1')
    try:
        text = html2text(text).strip()
    except UnicodeError:
        pass
    return make_header([(text, 'utf-8')]).encode()
Ejemplo n.º 12
0
 def decode_charset(self, field):
     # TK: This function was rewritten for unifying to Unicode.
     # Convert 'field' into Unicode one line string.
     try:
         pairs = decode_header(field)
         ustr = make_header(pairs).__unicode__()
     except (LookupError, UnicodeError, ValueError, HeaderParseError):
         # assume list's language
         cset = Utils.GetCharSet(self._mlist.preferred_language)
         if cset == 'us-ascii':
             cset = 'iso-8859-1'  # assume this for English list
         ustr = unicode(field, cset, 'replace')
     return u''.join(ustr.splitlines())
Ejemplo n.º 13
0
 def decode_charset(self, field):
     # TK: This function was rewritten for unifying to Unicode.
     # Convert 'field' into Unicode one line string.
     try:
         pairs = decode_header(field)
         ustr = make_header(pairs).__unicode__()
     except (LookupError, UnicodeError, ValueError, HeaderParseError):
         # assume list's language
         cset = Utils.GetCharSet(self._mlist.preferred_language)
         if cset == 'us-ascii':
             cset = 'iso-8859-1' # assume this for English list
         ustr = unicode(field, cset, 'replace')
     return u''.join(ustr.splitlines())
Ejemplo n.º 14
0
 def __init__(self, mlist, msg, msgdata):
     self.mlist = mlist
     self.msg = msg
     self.msgdata = msgdata
     # Only set returnaddr if the response is to go to someone other than
     # the address specified in the From: header (e.g. for the password
     # command).
     self.returnaddr = None
     self.commands = []
     self.results = []
     self.ignored = []
     self.lineno = 0
     self.subjcmdretried = 0
     self.respond = True
     # Extract the subject header and do RFC 2047 decoding.  Note that
     # Python 2.1's unicode() builtin doesn't call obj.__unicode__().
     subj = msg.get('subject', '')
     try:
         subj = make_header(decode_header(subj)).__unicode__()
         # TK: Currently we don't allow 8bit or multibyte in mail command.
         # MAS: However, an l10n 'Re:' may contain non-ascii so ignore it.
         subj = subj.encode('us-ascii', 'ignore')
         # Always process the Subject: header first
         self.commands.append(subj)
     except (HeaderParseError, UnicodeError, LookupError):
         # We couldn't parse it so ignore the Subject header
         pass
     # Find the first text/plain part
     part = None
     for part in typed_subpart_iterator(msg, 'text', 'plain'):
         break
     if part is None or part is not msg:
         # Either there was no text/plain part or we ignored some
         # non-text/plain parts.
         self.results.append(_('Ignoring non-text/plain MIME parts'))
     if part is None:
         # E.g the outer Content-Type: was text/html
         return
     # convert message into unicode because 'utf-8' message increasing
     mcset = part.get_content_charset('us-ascii')
     body = unicode(part.get_payload(decode=True), mcset, 'replace')
     # text/plain parts better have string payloads
     assert isinstance(body, StringType) or isinstance(body, UnicodeType)
     lines = body.splitlines()
     # Use no more lines than specified
     self.commands.extend(lines[:mm_cfg.DEFAULT_MAIL_COMMANDS_MAX_LINES])
     self.ignored.extend(lines[mm_cfg.DEFAULT_MAIL_COMMANDS_MAX_LINES:])
Ejemplo n.º 15
0
def makeEmail(mtext, context, headers={}):
    """ Make email message.
    """
    ptool = getUtility(IPropertiesTool)
    email_charset = ptool.getProperty('email_charset', None) or 'utf-8'
    try:
        msg = MIMEText(mtext.encode('ascii'), 'plain')
    except UnicodeEncodeError:
        msg = MIMEText(mtext.encode(email_charset), 'plain', email_charset)
    for k, val in headers.items():
        if isinstance(val, str):
            val = decode(val, context)
        if isinstance(val, i18n.Message):
            val = translate(val, context)
        header = make_header([ (w, email_charset) for w in val.split(' ') ])
        msg[k] = str(header)
    return msg.as_string()
Ejemplo n.º 16
0
def makeEmail(mtext, context, headers={}):
    """ Make email message.
    """
    ptool = getUtility(IPropertiesTool)
    email_charset = ptool.getProperty('email_charset', None) or 'utf-8'
    try:
        msg = MIMEText(mtext.encode(), 'plain')
    except UnicodeEncodeError:
        msg = MIMEText(mtext.encode(email_charset), 'plain', email_charset)
    for k, val in headers.items():
        if isinstance(val, str):
            val = decode(val, context)
        if isinstance(val, i18n.Message):
            val = translate(val, context)
        header = make_header([(w, email_charset) for w in val.split(' ')])
        msg[k] = str(header)
    return msg.as_string()
Ejemplo n.º 17
0
 def __init__(self, mlist, msg, msgdata):
     self.mlist = mlist
     self.msg = msg
     self.msgdata = msgdata
     # Only set returnaddr if the response is to go to someone other than
     # the address specified in the From: header (e.g. for the password
     # command).
     self.returnaddr = None
     self.commands = []
     self.results = []
     self.ignored = []
     self.lineno = 0
     self.subjcmdretried = 0
     self.respond = True
     # Extract the subject header and do RFC 2047 decoding.  Note that
     # Python 2.1's unicode() builtin doesn't call obj.__unicode__().
     subj = msg.get('subject', '')
     try:
         subj = make_header(decode_header(subj)).__unicode__()
         # TK: Currently we don't allow 8bit or multibyte in mail command.
         # MAS: However, an l10n 'Re:' may contain non-ascii so ignore it.
         subj = subj.encode('us-ascii', 'ignore')
         # Always process the Subject: header first
         self.commands.append(subj)
     except (HeaderParseError, UnicodeError, LookupError):
         # We couldn't parse it so ignore the Subject header
         pass
     # Find the first text/plain part
     part = None
     for part in typed_subpart_iterator(msg, 'text', 'plain'):
         break
     if part is None or part is not msg:
         # Either there was no text/plain part or we ignored some
         # non-text/plain parts.
         self.results.append(_('Ignoring non-text/plain MIME parts'))
     if part is None:
         # E.g the outer Content-Type: was text/html
         return
     body = part.get_payload(decode=True)
     # text/plain parts better have string payloads
     assert isinstance(body, StringType) or isinstance(body, UnicodeType)
     lines = body.splitlines()
     # Use no more lines than specified
     self.commands.extend(lines[:mm_cfg.DEFAULT_MAIL_COMMANDS_MAX_LINES])
     self.ignored.extend(lines[mm_cfg.DEFAULT_MAIL_COMMANDS_MAX_LINES:])
Ejemplo n.º 18
0
    def handleSendTesting(self, action):
        data, errors = self.extractData()
        if errors:
            IStatusMessage(self.request).add(
                (self.formErrorsMessage,) + errors, 'formError')
        else:
            message = self.generateMessage()
            message['Subject'] = make_header(
                ((u'Test message: %s'%self.context.title, 'utf-8'),))

            mailer = getUtility(IMailer)

            from_address = formataddr(
                (mailer.email_from_name, mailer.email_from_address))
            mailer.send(from_address, (data['email'],), message.as_string())

            IStatusMessage(self.request).add(
                _('Test mail for newsletter has been sent.'))
Ejemplo n.º 19
0
    def __init__(self, message):
        """Create a new user-to-user email entry.

        :param message: the message being sent
        :type message: `email.message.Message`
        """
        super(UserToUserEmail, self).__init__()
        person_set = getUtility(IPersonSet)
        # Find the person who is sending this message.
        realname, address = parseaddr(message['from'])
        assert address, 'Message has no From: field'
        sender = person_set.getByEmail(address)
        assert sender is not None, 'No person for sender email: %s' % address
        # Find the person who is the recipient.
        realname, address = parseaddr(message['to'])
        assert address, 'Message has no To: field'
        recipient = person_set.getByEmail(address)
        assert recipient is not None, ('No person for recipient email: %s' %
                                       address)
        # Convert the date string into a UTC datetime.
        date = message['date']
        assert date is not None, 'Message has no Date: field'
        self.date_sent = utcdatetime_from_field(date)
        # Find the subject and message-id.
        message_id = message['message-id']
        assert message_id is not None, 'Message has no Message-ID: field'
        subject = message['subject']
        assert subject is not None, 'Message has no Subject: field'
        # Initialize.
        self.sender = sender
        self.recipient = recipient
        self.message_id = unicode(message_id, 'ascii')
        self.subject = unicode(make_header(decode_header(subject)))
        # Add the object to the store of the sender.  Our StormMigrationGuide
        # recommends against this saying "Note that the constructor should not
        # usually add the object to a store -- leave that for a FooSet.new()
        # method, or let it be inferred by a relation."
        #
        # On the other hand, we really don't need a UserToUserEmailSet for any
        # other purpose.  There isn't any other relationship that can be
        # inferred, so in this case I think it makes fine sense for the
        # constructor to add self to the store.  Also, this closely mimics
        # what the SQLObject compatibility layer does.
        Store.of(sender).add(self)
Ejemplo n.º 20
0
    def __init__(self, message):
        """Create a new user-to-user email entry.

        :param message: the message being sent
        :type message: `email.message.Message`
        """
        super(UserToUserEmail, self).__init__()
        person_set = getUtility(IPersonSet)
        # Find the person who is sending this message.
        realname, address = parseaddr(message['from'])
        assert address, 'Message has no From: field'
        sender = person_set.getByEmail(address)
        assert sender is not None, 'No person for sender email: %s' % address
        # Find the person who is the recipient.
        realname, address = parseaddr(message['to'])
        assert address, 'Message has no To: field'
        recipient = person_set.getByEmail(address)
        assert recipient is not None, (
            'No person for recipient email: %s' % address)
        # Convert the date string into a UTC datetime.
        date = message['date']
        assert date is not None, 'Message has no Date: field'
        self.date_sent = utcdatetime_from_field(date)
        # Find the subject and message-id.
        message_id = message['message-id']
        assert message_id is not None, 'Message has no Message-ID: field'
        subject = message['subject']
        assert subject is not None, 'Message has no Subject: field'
        # Initialize.
        self.sender = sender
        self.recipient = recipient
        self.message_id = unicode(message_id, 'ascii')
        self.subject = unicode(make_header(decode_header(subject)))
        # Add the object to the store of the sender.  Our StormMigrationGuide
        # recommends against this saying "Note that the constructor should not
        # usually add the object to a store -- leave that for a FooSet.new()
        # method, or let it be inferred by a relation."
        #
        # On the other hand, we really don't need a UserToUserEmailSet for any
        # other purpose.  There isn't any other relationship that can be
        # inferred, so in this case I think it makes fine sense for the
        # constructor to add self to the store.  Also, this closely mimics
        # what the SQLObject compatibility layer does.
        Store.of(sender).add(self)
Ejemplo n.º 21
0
    def __call__(self, multipart_format='mixed', *args, **kw):
        context = self.context
        message = self.message(multipart_format, *args, **kw)

        message['Date'] = formatdate()
        message['Message-ID'] = context.messageId

        if not message.has_key('X-Mailer'):
            message['X-mailer'] = 'zojax.mailer'

        # update externals headers
        charset = str(context.charset)

        for name, adapter in getAdapters(
            (context, context.context), IMailHeaders):
            for name, value, encode in adapter.headers:
                if encode:
                    message[name] = make_header(((value, charset),))
                else:
                    message[name] = value

        return message.as_string()
Ejemplo n.º 22
0
def ch_oneline(headerstr):
    # Decode header string in one line and convert into single charset
    # copied and modified from ToDigest.py and Utils.py
    # return (string, cset) tuple as check for failure
    try:
        d = decode_header(headerstr)
        # at this point, we should rstrip() every string because some
        # MUA deliberately add trailing spaces when composing return
        # message.
        d = [(s.rstrip(), c) for (s,c) in d]
        cset = 'us-ascii'
        for x in d:
            # search for no-None charset
            if x[1]:
                cset = x[1]
                break
        h = make_header(d)
        ustr = h.__unicode__()
        oneline = u''.join(ustr.splitlines())
        return oneline.encode(cset, 'replace'), cset
    except (LookupError, UnicodeError, ValueError, HeaderParseError):
        # possibly charset problem. return with undecoded string in one line.
        return ''.join(headerstr.splitlines()), 'us-ascii'
Ejemplo n.º 23
0
def ch_oneline(headerstr):
    # Decode header string in one line and convert into single charset
    # copied and modified from ToDigest.py and Utils.py
    # return (string, cset) tuple as check for failure
    try:
        d = decode_header(headerstr)
        # at this point, we should rstrip() every string because some
        # MUA deliberately add trailing spaces when composing return
        # message.
        d = [(s.rstrip(), c) for (s, c) in d]
        cset = 'us-ascii'
        for x in d:
            # search for no-None charset
            if x[1]:
                cset = x[1]
                break
        h = make_header(d)
        ustr = h.__unicode__()
        oneline = u''.join(ustr.splitlines())
        return oneline.encode(cset, 'replace'), cset
    except (LookupError, UnicodeError, ValueError, HeaderParseError):
        # possibly charset problem. return with undecoded string in one line.
        return ''.join(headerstr.splitlines()), 'us-ascii'
Ejemplo n.º 24
0
def buildEmailMessage(from_url, to_url, msg=None,
                      subject=None, attachment_list=None,
                      extra_headers=None,
                      additional_headers=None,
                      cc_url=None, bcc_url=None):
  """
    Builds a mail message which is ready to be
    sent by Zope MailHost.

    * attachment_list is a list of dictionaries with those keys:
     - name : name of the attachment,
     - content: data of the attachment
     - mime_type: mime-type corresponding to the attachment
    * extra_headers is a dictionary of custom headers to add to the email.
      "X-" prefix is automatically added to those headers.
    * additional_headers is similar to extra_headers, but no prefix is added.
  """

  if attachment_list == None:
    # Create non multi-part MIME message.
    message = MIMEText(msg, _charset='utf-8')
    attachment_list = []
  else:
    # Create multi-part MIME message.
    message = MIMEMultipart()
    message.preamble = "If you can read this, your mailreader\n" \
                        "can not handle multi-part messages!\n"
    message.attach(MIMEText(msg, _charset='utf-8'))

  if extra_headers:
    for key, value in extra_headers.items():
      message.add_header('X-%s' % key, value)

  if additional_headers:
    for key, value in additional_headers.items():
      message.add_header(key, value)

  if subject:
    message.add_header('Subject',
                        make_header([(subject, 'utf-8')]).encode())
  if from_url:
    message.add_header('From', from_url)
  if to_url:
    message.add_header('To', to_url)
  if cc_url: 
    message.add_header('Cc', cc_url)
  if bcc_url: 
    message.add_header('Bcc', bcc_url)

  for attachment in attachment_list:
    attachment_name = attachment.get('name', '')
    attachment_name = attachment_name or '' # Prevent None params

    # try to guess the mime type
    if not attachment.has_key('mime_type'):
      mime_type, encoding = guess_type( attachment_name )
      if mime_type is not None:
        attachment['mime_type'] = mime_type
      else:
        attachment['mime_type'] = 'application/octet-stream'

    # attach it
    if attachment['mime_type'] == 'text/plain':
      part = MIMEText(attachment['content'], _charset='utf-8')
    else:
      major, minor = attachment['mime_type'].split('/', 1)
      if major == 'text':
        part = MIMEText(attachment['content'], _subtype=minor)
      elif major == 'image':
        part = MIMEImage(attachment['content'], _subtype=minor)
      elif major == 'audio':
        part = MIMEAudio(attachment['content'], _subtype=minor)
      else:
        #  encode non-plaintext attachment in base64      
        part = MIMEBase(major, minor)
        part.set_payload(attachment['content'])
        Encoders.encode_base64(part)

    part.add_header('Content-Disposition', 'attachment',
                    filename=attachment_name)
    part.add_header('Content-ID', '<%s>' % \
                    ''.join(['%s' % ord(i) for i in attachment_name]))
    message.attach(part)

  return message
Ejemplo n.º 25
0
 def _process_utf8(self, kw):
     # sort out what encoding we're going to use
     encoding = kw.get(
         'encoding',
         self.getProperty('encoding', BaseMailTemplate.default_encoding))
     text = self.__class__.__bases__[1].__call__(self, **kw)
     # ZPT adds newline at the end, but it breaks backward compatibility.
     # So I remove it.
     if text and text[-1] == '\n':
         text = text[:-1]
     if not self.html() and isinstance(text, unicode):
         text = text.encode(encoding, 'replace')
     # now turn the result into a MIMEText object
     msg = BaseMailTemplate.MIMEText(text.replace('\r', ''),
                                     self.content_type.split('/')[1],
                                     encoding)
     # sort out what headers and addresses we're going to use
     headers = {}
     values = {}
     # headers from the headers property
     for header in getattr(self, 'headers', ()):
         name, value = header.split(':', 1)
         headers[name] = value
     # headers from the headers parameter
     headers_param = kw.get('headers', {})
     headers.update(headers_param)
     # values and some specific headers
     for key, header in (('mfrom', 'From'), ('mto', 'To'), ('mcc', 'Cc'),
                         ('mbcc', 'Bcc'), ('subject', 'Subject')):
         value = kw.get(
             key,
             headers_param.get(header,
                               getattr(self, key, headers.get(header))))
         if value is not None:
             values[key] = value
             # turn some sequences in coma-seperated strings
             if isinstance(value, (tuple, list)):
                 value = ', '.join(value)
             # make sure we have no unicode headers
             if isinstance(value, unicode):
                 value = value.encode(encoding)
             if key == 'subject':
                 value = make_header([(value, 'utf-8')]).encode()
             headers[header] = value
     # check required values have been supplied
     errors = []
     for param in ('mfrom', 'mto', 'subject'):
         if not values.get(param):
             errors.append(param)
     if errors:
         raise TypeError(
             'The following parameters were required by not specified: ' +
             (', '.join(errors)))
     # add date header
     headers['Date'] = BaseMailTemplate.DateTime().rfc822()
     # add message-id header
     headers['Message-ID'] = make_msgid()
     # turn headers into an ordered list for predictable header order
     keys = headers.keys()
     keys.sort()
     return msg, values, [(key, headers[key]) for key in keys]
Ejemplo n.º 26
0
def getSubject(msg):
    """ get mail subject """
    return make_header(decode_header(msg.get('Subject').strip())).__unicode__()
Ejemplo n.º 27
0
 def _process_utf8(self,kw):
     # sort out what encoding we're going to use
     encoding = kw.get('encoding',
                       self.getProperty('encoding',
                                        BaseMailTemplate.default_encoding))
     text = self.__class__.__bases__[1].__call__(self,**kw)
     # ZPT adds newline at the end, but it breaks backward compatibility.
     # So I remove it.
     if text and text[-1]=='\n':
       text = text[:-1]
     if not self.html() and isinstance(text, unicode):
         text = text.encode(encoding,'replace')
     # now turn the result into a MIMEText object
     msg = BaseMailTemplate.MIMEText(
         text.replace('\r',''),
         self.content_type.split('/')[1],
         encoding
         )
     # sort out what headers and addresses we're going to use
     headers = {}
     values = {}
     # headers from the headers property
     for header in getattr(self,'headers',()):
         name,value = header.split(':',1)
         headers[name]=value
     # headers from the headers parameter
     headers_param = kw.get('headers',{})
     headers.update(headers_param)
     # values and some specific headers
     for key,header in (('mfrom','From'),
                        ('mto','To'),
                        ('mcc','Cc'),
                        ('mbcc','Bcc'),
                        ('subject','Subject')):
         value = kw.get(key,
                        headers_param.get(header,
                                          getattr(self,
                                                  key,
                                                  headers.get(header))))
         if value is not None:
             values[key]=value
             # turn some sequences in coma-seperated strings
             if isinstance(value, (tuple, list)):
                 value = ', '.join(value)
             # make sure we have no unicode headers
             if isinstance(value,unicode):
                 value = value.encode(encoding)
             if key=='subject':
                 value = make_header([(value, 'utf-8')]).encode()
             headers[header]=value
     # check required values have been supplied
     errors = []
     for param in ('mfrom','mto'):
         if not values.get(param):
             errors.append(param)
     if errors:
         raise TypeError(
             'The following parameters were required by not specified: '+(
             ', '.join(errors)
             ))
     # add date header
     headers['Date']=BaseMailTemplate.DateTime().rfc822()
     # add message-id header
     headers['Message-ID']=make_msgid()
     # turn headers into an ordered list for predictable header order
     keys = headers.keys()
     keys.sort()
     return msg,values,[(key,headers[key]) for key in keys]
Ejemplo n.º 28
0
def process(res, args):
    mlist = res.mlist
    digest = None
    password = None
    address = None
    realname = None
    # Parse the args
    argnum = 0
    for arg in args:
        if arg.lower().startswith('address='):
            address = arg[8:]
        elif argnum == 0:
            password = arg
        elif argnum == 1:
            if arg.lower() not in ('digest', 'nodigest'):
                res.results.append(_('Bad digest specifier: %(arg)s'))
                return STOP
            if arg.lower() == 'digest':
                digest = 1
            else:
                digest = 0
        else:
            res.results.append(_('Usage:'))
            res.results.append(gethelp(mlist))
            return STOP
        argnum += 1
    # Fix the password/digest issue
    if (digest is None and password
            and password.lower() in ('digest', 'nodigest')):
        if password.lower() == 'digest':
            digest = 1
        else:
            digest = 0
        password = None
    # Fill in empty defaults
    if digest is None:
        digest = mlist.digest_is_default
    if password is None:
        password = Utils.MakeRandomPassword()
    if address is None:
        realname, address = parseaddr(res.msg['from'])
        if not address:
            # Fall back to the sender address
            address = res.msg.get_sender()
        if not address:
            res.results.append(_('No valid address found to subscribe'))
            return STOP
        # Watch for encoded names
        try:
            h = make_header(decode_header(realname))
            # BAW: in Python 2.2, use just unicode(h)
            realname = h.__unicode__()
        except UnicodeError:
            realname = u''
        # Coerce to byte string if uh contains only ascii
        try:
            realname = realname.encode('us-ascii')
        except UnicodeError:
            pass
    # Create the UserDesc record and do a non-approved subscription
    listowner = mlist.GetOwnerEmail()
    userdesc = UserDesc(address, realname, password, digest)
    remote = res.msg.get_sender()
    try:
        mlist.AddMember(userdesc, remote)
    except Errors.MembershipIsBanned:
        res.results.append(
            _("""\
The email address you supplied is banned from this mailing list.
If you think this restriction is erroneous, please contact the list
owners at %(listowner)s."""))
        return STOP
    except Errors.MMBadEmailError:
        res.results.append(
            _("""\
Mailman won't accept the given email address as a valid address.
(E.g. it must have an @ in it.)"""))
        return STOP
    except Errors.MMHostileAddress:
        res.results.append(
            _("""\
Your subscription is not allowed because
the email address you gave is insecure."""))
        return STOP
    except Errors.MMAlreadyAMember:
        res.results.append(_('You are already subscribed!'))
        return STOP
    except Errors.MMCantDigestError:
        res.results.append(
            _('No one can subscribe to the digest of this list!'))
        return STOP
    except Errors.MMMustDigestError:
        res.results.append(_('This list only supports digest subscriptions!'))
        return STOP
    except Errors.MMSubscribeNeedsConfirmation:
        # We don't need to respond /and/ send a confirmation message.
        res.respond = 0
    except Errors.MMNeedApproval:
        res.results.append(
            _("""\
Your subscription request has been forwarded to the list administrator
at %(listowner)s for review."""))
    else:
        # Everything is a-ok
        res.results.append(_('Subscription request succeeded.'))
Ejemplo n.º 29
0
    if not features and not args:
        usage("Require at least one feature (-f) arg or one message file")
        return 1

    if not features:
        # extract significant tokens from each message and identify
        # where they came from
        for f in args:
            for msg in getmbox(f):
                evidence = msg.get("X-Spambayes-Evidence", "")
                evidence = re.sub(r"\s+", " ", evidence)
                l = [e.rsplit(": ", 1)[0]
                     for e in evidence.split("; ")[2:]]
                for s in l:
                    try:
                        s = make_header(decode_header(s)).__unicode__()
                    except:
                        s = unicode(s, 'us-ascii', 'replace')
                    features.add(s)
        if not features:
            usage("No X-Spambayes-Evidence headers found")
            return 1

    if spamfile is not None:
        spamfile = file(spamfile, "w")
    if hamfile is not None:
        hamfile = file(hamfile, "w")

    extractmessages(features, mapd, hamfile, spamfile)

if __name__ == "__main__":
Ejemplo n.º 30
0
def getSubject(msg):
    """ get mail subject """
    return make_header(
        decode_header(msg.get('Subject').strip())).__unicode__()
Ejemplo n.º 31
0
def process(res, args):
    mlist = res.mlist
    digest = None
    password = None
    address = None
    realname = None
    # Parse the args
    argnum = 0
    for arg in args:
        if arg.lower().startswith('address='):
            address = arg[8:]
        elif argnum == 0:
            password = arg
        elif argnum == 1:
            if arg.lower() not in ('digest', 'nodigest'):
                res.results.append(_('Bad digest specifier: %(arg)s'))
                return STOP
            if arg.lower() == 'digest':
                digest = 1
            else:
                digest = 0
        else:
            res.results.append(_('Usage:'))
            res.results.append(gethelp(mlist))
            return STOP
        argnum += 1
    # Fix the password/digest issue
    if (digest is None
            and password and password.lower() in ('digest', 'nodigest')):
        if password.lower() == 'digest':
            digest = 1
        else:
            digest = 0
        password = None
    # Fill in empty defaults
    if digest is None:
        digest = mlist.digest_is_default
    if password is None:
        password = Utils.MakeRandomPassword()
    if address is None:
        realname, address = parseaddr(res.msg['from'])
        if not address:
            # Fall back to the sender address
            address = res.msg.get_sender()
        if not address:
            res.results.append(_('No valid address found to subscribe'))
            return STOP
        # Watch for encoded names
        try:
            h = make_header(decode_header(realname))
            # BAW: in Python 2.2, use just unicode(h)
            realname = h.__unicode__()
        except UnicodeError:
            realname = u''
        # Coerce to byte string if uh contains only ascii
        try:
            realname = realname.encode('us-ascii')
        except UnicodeError:
            pass
    # Create the UserDesc record and do a non-approved subscription
    listowner = mlist.GetOwnerEmail()
    userdesc = UserDesc(address, realname, password, digest)
    remote = res.msg.get_sender()
    try:
        mlist.AddMember(userdesc, remote)
    except Errors.MembershipIsBanned:
        res.results.append(_("""\
The email address you supplied is banned from this mailing list.
If you think this restriction is erroneous, please contact the list
owners at %(listowner)s."""))
        return STOP
    except Errors.MMBadEmailError:
        res.results.append(_("""\
Mailman won't accept the given email address as a valid address.
(E.g. it must have an @ in it.)"""))
        return STOP
    except Errors.MMHostileAddress:
        res.results.append(_("""\
Your subscription is not allowed because
the email address you gave is insecure."""))
        return STOP
    except Errors.MMAlreadyAMember:
        res.results.append(_('You are already subscribed!'))
        return STOP
    except Errors.MMCantDigestError:
        res.results.append(
            _('No one can subscribe to the digest of this list!'))
        return STOP
    except Errors.MMMustDigestError:
        res.results.append(_('This list only supports digest subscriptions!'))
        return STOP
    except Errors.MMSubscribeNeedsConfirmation:
        # We don't need to respond /and/ send a confirmation message.
        res.respond = 0
    except Errors.MMNeedApproval:
        res.results.append(_("""\
Your subscription request has been forwarded to the list administrator
at %(listowner)s for review."""))
    else:
        # Everything is a-ok
        res.results.append(_('Subscription request succeeded.'))