Пример #1
0
def decorate(mlist, template, what, extradict=None):
    # `what' is just a descriptive phrase used in the log message
    #
    # BAW: We've found too many situations where Python can be fooled into
    # interpolating too much revealing data into a format string.  For
    # example, a footer of "% silly %(real_name)s" would give a header
    # containing all list attributes.  While we've previously removed such
    # really bad ones like `password' and `passwords', it's much better to
    # provide a whitelist of known good attributes, then to try to remove a
    # blacklist of known bad ones.
    d = SafeDict({'real_name'     : mlist.real_name,
                  'list_name'     : mlist.internal_name(),
                  # For backwards compatibility
                  '_internal_name': mlist.internal_name(),
                  'host_name'     : mlist.host_name,
                  'web_page_url'  : mlist.web_page_url,
                  'description'   : mlist.description,
                  'info'          : mlist.info,
                  'cgiext'        : mm_cfg.CGIEXT,
                  })
    if extradict is not None:
        d.update(extradict)
    # Using $-strings?
    if getattr(mlist, 'use_dollar_strings', 0):
        template = Utils.to_percent(template)
    # Interpolate into the template
    try:
        text = re.sub(r'(?m)(?<!^--) +(?=\n)', '',
                      re.sub(r'\r\n', r'\n', template % d))
    except (ValueError, TypeError), e:
        syslog('error', 'Exception while calculating %s:\n%s', what, e)
        text = template
Пример #2
0
def decorate(mlist, template, what, extradict=None):
    # `what' is just a descriptive phrase used in the log message
    #
    # BAW: We've found too many situations where Python can be fooled into
    # interpolating too much revealing data into a format string.  For
    # example, a footer of "% silly %(real_name)s" would give a header
    # containing all list attributes.  While we've previously removed such
    # really bad ones like `password' and `passwords', it's much better to
    # provide a whitelist of known good attributes, then to try to remove a
    # blacklist of known bad ones.
    d = SafeDict({
        'real_name': mlist.real_name,
        'list_name': mlist.internal_name(),
        # For backwards compatibility
        '_internal_name': mlist.internal_name(),
        'host_name': mlist.host_name,
        'web_page_url': mlist.web_page_url,
        'description': mlist.description,
        'info': mlist.info,
        'cgiext': mm_cfg.CGIEXT,
    })
    if extradict is not None:
        d.update(extradict)
    # Using $-strings?
    if getattr(mlist, 'use_dollar_strings', 0):
        template = Utils.to_percent(template)
    # Interpolate into the template
    try:
        text = re.sub(r'(?m)(?<!^--) +(?=\n)', '',
                      re.sub(r'\r\n', r'\n', template % d))
    except (ValueError, TypeError), e:
        syslog('error', 'Exception while calculating %s:\n%s', what, e)
        text = template
Пример #3
0
def _(s):
    if s == '':
        return s
    assert s
    # Do translation of the given string into the current language, and do
    # Ping-string interpolation into the resulting string.
    #
    # This lets you write something like:
    #
    #     now = time.ctime(time.time())
    #     print _('The current time is: %(now)s')
    #
    # and have it Just Work.  Note that the lookup order for keys in the
    # original string is 1) locals dictionary, 2) globals dictionary.
    #
    # First, get the frame of the caller
    frame = sys._getframe(1)
    # A `safe' dictionary is used so we won't get an exception if there's a
    # missing key in the dictionary.
    dict = SafeDict(frame.f_globals.copy())
    dict.update(frame.f_locals)
    # Translating the string returns an encoded 8-bit string.  Rather than
    # turn that into a Unicode, we turn any Unicodes in the dictionary values
    # into encoded 8-bit strings.  BAW: Returning a Unicode here broke too
    # much other stuff and _() has many tentacles.  Eventually I think we want
    # to use Unicode everywhere.
    tns = _translation.gettext(s)
    charset = _translation.charset()
    if not charset:
        charset = 'us-ascii'
    for k, v in dict.items():
        if isinstance(v, UnicodeType):
            dict[k] = v.encode(charset, 'replace')
    return tns % dict
def quick_maketext(templatefile, dict=None, lang=None, mlist=None):
    """Create an output using a template"""
    # Used by various html output functions such as as_html, html_TOC and write_index_entry
    if mlist is None:
        listname = ''
    else:
        listname = mlist._internal_name
    if lang is None:
        if mlist is None:
            lang = mm_cfg.DEFAULT_SERVER_LANGUAGE
        else:
            lang = mlist.preferred_language
    cachekey = (templatefile, lang, listname)
    filepath =  _templatefilepathcache.get(cachekey)
    if filepath:
        template = _templatecache.get(filepath)
    if filepath is None or template is None:
        # Use the basic maketext, with defaults to get the raw template
        template, filepath = Utils.findtext(templatefile, lang=lang,
                                            raw=True, mlist=mlist)
        _templatefilepathcache[cachekey] = filepath
        _templatecache[filepath] = template
    # Copied from Utils.maketext()
    text = template
    if dict is not None:
        try:
            sdict = SafeDict(dict)
            try:
                text = sdict.interpolate(template)
            except UnicodeError:
                # Try again after coercing the template to unicode
                utemplate = unicode(template,
                                    Utils.GetCharSet(lang),
                                    'replace')
                text = sdict.interpolate(utemplate)
        except (TypeError, ValueError):
            # The template is really screwed up
            pass
    # Make sure the text is in the given character set, or html-ify any bogus
    # characters.
    return Utils.uncanonstr(text, lang)
Пример #5
0
 def ExternalArchive(self, ar, txt):
     d = SafeDict({
         'listname': self.internal_name(),
         'hostname': self.host_name,
     })
     cmd = ar % d
     extarch = os.popen(cmd, 'w')
     extarch.write(txt)
     status = extarch.close()
     if status:
         syslog('error', 'external archiver non-zero exit status: %d\n',
                (status & 0xff00) >> 8)
Пример #6
0
def _(s, frame=1):
    if s == '':
        return s
    assert s
    # Do translation of the given string into the current language, and do
    # Ping-string interpolation into the resulting string.
    #
    # This lets you write something like:
    #
    #     now = time.ctime(time.time())
    #     print _('The current time is: %(now)s')
    #
    # and have it Just Work.  Note that the lookup order for keys in the
    # original string is 1) locals dictionary, 2) globals dictionary.
    #
    # First, get the frame of the caller
    frame = sys._getframe(frame)
    # A `safe' dictionary is used so we won't get an exception if there's a
    # missing key in the dictionary.
    dict = SafeDict(frame.f_globals.copy())
    dict.update(frame.f_locals)
    # Translating the string returns an encoded 8-bit string.  Rather than
    # turn that into a Unicode, we turn any Unicodes in the dictionary values
    # into encoded 8-bit strings.  BAW: Returning a Unicode here broke too
    # much other stuff and _() has many tentacles.  Eventually I think we want
    # to use Unicode everywhere.
    tns = _translation.gettext(s)
    charset = _translation.charset()
    if not charset:
        charset = 'us-ascii'
    for k, v in list(dict.items()):
        if isinstance(v, str):
            dict[k] = v
        if isinstance(v, (bytes, bytearray)):
            dict[k] = v.decode(charset, 'replace')
    try:
        return tns % dict
    except (ValueError, TypeError):
        # Bad interpolation format. Punt.
        return tns
Пример #7
0
def quick_maketext(templatefile, dict=None, lang=None, mlist=None):
    if mlist is None:
        listname = ''
    else:
        listname = mlist._internal_name
    if lang is None:
        if mlist is None:
            lang = mm_cfg.DEFAULT_SERVER_LANGUAGE
        else:
            lang = mlist.preferred_language
    cachekey = (templatefile, lang, listname)
    filepath =  _templatefilepathcache.get(cachekey)
    if filepath:
        template = _templatecache.get(filepath)
    if filepath is None or template is None:
        # Use the basic maketext, with defaults to get the raw template
        template, filepath = Utils.findtext(templatefile, lang=lang,
                                            raw=True, mlist=mlist)
        _templatefilepathcache[cachekey] = filepath
        _templatecache[filepath] = template
    # Copied from Utils.maketext()
    text = template
    if dict is not None:
        try:
            sdict = SafeDict(dict)
            try:
                text = sdict.interpolate(template)
            except UnicodeError:
                # Try again after coercing the template to unicode
                utemplate = unicode(template,
                                    Utils.GetCharSet(lang),
                                    'replace')
                text = sdict.interpolate(utemplate)
        except (TypeError, ValueError):
            # The template is really screwed up
            pass
    # Make sure the text is in the given character set, or html-ify any bogus
    # characters.
    return Utils.uncanonstr(text, lang)
Пример #8
0
def quick_maketext(templatefile, dict=None, lang=None, mlist=None):
    if mlist is None:
        listname = ''
    else:
        listname = mlist._internal_name
    if lang is None:
        if mlist is None:
            lang = mm_cfg.DEFAULT_SERVER_LANGUAGE
        else:
            lang = mlist.preferred_language
    cachekey = (templatefile, lang, listname)
    filepath =  _templatefilepathcache.get(cachekey)
    if filepath:
        template = _templatecache.get(filepath)
    if filepath is None or template is None:
        # Use the basic maketext, with defaults to get the raw template
        template, filepath = Utils.findtext(templatefile, lang=lang,
                                            raw=True, mlist=mlist)
        _templatefilepathcache[cachekey] = filepath
        _templatecache[filepath] = template
    # Copied from Utils.maketext()
    text = template
    if dict is not None:
        try:
            sdict = SafeDict(dict)
            try:
                text = sdict.interpolate(template)
            except UnicodeError:
                # Try again after coercing the template to unicode
                utemplate = unicode(template,
                                    Utils.GetCharSet(lang),
                                    'replace')
                text = sdict.interpolate(utemplate)
        except (TypeError, ValueError), e:
            # The template is really screwed up
            syslog('error', 'broken template: %s\n%s', filepath, e)
Пример #9
0
    if fp is None:
        # Try one last time with the distro English template, which, unless
        # you've got a really broken installation, must be there.
        try:
            filename = os.path.join(mm_cfg.TEMPLATE_DIR, 'en', templatefile)
            fp = open(filename)
        except IOError, e:
            if e.errno <> errno.ENOENT: raise
            # We never found the template.  BAD!
            raise IOError(errno.ENOENT, 'No template file found', templatefile)
    template = fp.read()
    fp.close()
    text = template
    if dict is not None:
        try:
            sdict = SafeDict(dict)
            try:
                text = sdict.interpolate(template)
            except UnicodeError:
                # Try again after coercing the template to unicode
                utemplate = unicode(template, GetCharSet(lang), 'replace')
                text = sdict.interpolate(utemplate)
        except (TypeError, ValueError), e:
            # The template is really screwed up
            syslog('error', 'broken template: %s\n%s', filename, e)
            pass
    if raw:
        return text, filename
    return wrap(text), filename

Пример #10
0
def process(mlist, msg, msgdata):
    # Normally, the replybot should get a shot at this message, but there are
    # some important short-circuits, mostly to suppress 'bot storms, at least
    # for well behaved email bots (there are other governors for misbehaving
    # 'bots).  First, if the original message has an "X-Ack: No" header, we
    # skip the replybot.  Then, if the message has a Precedence header with
    # values bulk, junk, or list, and there's no explicit "X-Ack: yes" header,
    # we short-circuit.  Finally, if the message metadata has a true 'noack'
    # key, then we skip the replybot too.
    ack = msg.get('x-ack', '').lower()
    if ack == 'no' or msgdata.get('noack'):
        return
    precedence = msg.get('precedence', '').lower()
    if ack <> 'yes' and precedence in ('bulk', 'junk', 'list'):
        return
    # Check to see if the list is even configured to autorespond to this email
    # message.  Note: the owner script sets the `toowner' key, and the various
    # confirm, join, leave, request, subscribe and unsubscribe scripts set the
    # keys we use for `torequest'.
    toadmin = msgdata.get('toowner')
    torequest = msgdata.get('torequest') or msgdata.get('toconfirm') or \
                    msgdata.get('tojoin') or msgdata.get('toleave')
    if ((toadmin and not mlist.autorespond_admin) or
           (torequest and not mlist.autorespond_requests) or \
           (not toadmin and not torequest and not mlist.autorespond_postings)):
        return
    # Now see if we're in the grace period for this sender.  graceperiod <= 0
    # means always autorespond, as does an "X-Ack: yes" header (useful for
    # debugging).
    sender = msg.get_sender()
    now = time.time()
    graceperiod = mlist.autoresponse_graceperiod
    if graceperiod > 0 and ack <> 'yes':
        if toadmin:
            quiet_until = mlist.admin_responses.get(sender, 0)
        elif torequest:
            quiet_until = mlist.request_responses.get(sender, 0)
        else:
            quiet_until = mlist.postings_responses.get(sender, 0)
        if quiet_until > now:
            return
    #
    # Okay, we know we're going to auto-respond to this sender, craft the
    # message, send it, and update the database.
    realname = mlist.real_name
    subject = _(
        'Auto-response for your message to the "%(realname)s" mailing list')
    # Do string interpolation
    d = SafeDict({'listname'    : realname,
                  'listurl'     : mlist.GetScriptURL('listinfo'),
                  'requestemail': mlist.GetRequestEmail(),
                  # BAW: Deprecate adminemail; it's not advertised but still
                  # supported for backwards compatibility.
                  'adminemail'  : mlist.GetBouncesEmail(),
                  'owneremail'  : mlist.GetOwnerEmail(),
                  })
    # Just because we're using a SafeDict doesn't mean we can't get all sorts
    # of other exceptions from the string interpolation.  Let's be ultra
    # conservative here.
    if toadmin:
        rtext = mlist.autoresponse_admin_text
    elif torequest:
        rtext = mlist.autoresponse_request_text
    else:
        rtext = mlist.autoresponse_postings_text
    # Using $-strings?
    if getattr(mlist, 'use_dollar_strings', 0):
        rtext = Utils.to_percent(rtext)
    try:
        text = rtext % d
    except Exception:
        syslog('error', 'Bad autoreply text for list: %s\n%s',
               mlist.internal_name(), rtext)
        text = rtext
    # Wrap the response.
    text = Utils.wrap(text)
    outmsg = Message.UserNotification(sender, mlist.GetBouncesEmail(),
                                      subject, text, mlist.preferred_language)
    outmsg['X-Mailer'] = _('The Mailman Replybot')
    # prevent recursions and mail loops!
    outmsg['X-Ack'] = 'No'
    outmsg.send(mlist)
    # update the grace period database
    if graceperiod > 0:
        # graceperiod is in days, we need # of seconds
        quiet_until = now + graceperiod * 24 * 60 * 60
        if toadmin:
            mlist.admin_responses[sender] = quiet_until
        elif torequest:
            mlist.request_responses[sender] = quiet_until
        else:
            mlist.postings_responses[sender] = quiet_until
Пример #11
0
    if fp is None:
        # Try one last time with the distro English template, which, unless
        # you've got a really broken installation, must be there.
        try:
            filename = os.path.join(mm_cfg.TEMPLATE_DIR, 'en', templatefile)
            fp = open(filename)
        except IOError, e:
            if e.errno <> errno.ENOENT: raise
            # We never found the template.  BAD!
            raise IOError(errno.ENOENT, 'No template file found', templatefile)
    template = fp.read()
    fp.close()
    text = template
    if dict is not None:
        try:
            sdict = SafeDict(dict)
            try:
                text = sdict.interpolate(template)
            except UnicodeError:
                # Try again after coercing the template to unicode
                utemplate = unicode(template, GetCharSet(lang), 'replace')
                text = sdict.interpolate(utemplate)
        except (TypeError, ValueError), e:
            # The template is really screwed up
            syslog('error', 'broken template: %s\n%s', filename, e)
            pass
    if raw:
        return text, filename
    return wrap(text), filename