Example #1
0
        def as_dict(self):
            from mailpile.urlmap import UrlMap

            um = UrlMap(self.session)
            rv = {
                "command": self.command_name,
                "state": {
                    "command_url": um.ui_url(self.command_obj),
                    "context_url": um.context_url(self.command_obj),
                    "query_args": self.command_obj.state_as_query_args(),
                    "cache_id": self.command_obj.cache_id(),
                    "context": self.command_obj.context or "",
                },
                "status": self.status,
                "message": self.message,
                "result": self.result,
                "event_id": self.command_obj.event.event_id,
                "elapsed": "%.3f" % self.session.ui.time_elapsed,
            }
            csrf_token = self.session.ui.html_variables.get("csrf_token")
            if csrf_token:
                rv["state"]["csrf_token"] = csrf_token
            if self.error_info:
                rv["error"] = self.error_info
            for ui_key in [k for k in self.command_obj.data.keys() if k.startswith("ui_")]:
                rv[ui_key] = self.command_obj.data[ui_key][0]
            ev = self.command_obj.event
            if ev and ev.data.get("password_needed"):
                rv["password_needed"] = ev.private_data["password_needed"]
            return rv
Example #2
0
    def command(self, save=True, auto=False):
        session, config = self.session, self.session.config

        urlmap = UrlMap(session)
        res = {"api_methods": [], "javascript_classes": [], "css_files": []}

        for method in ("GET", "POST", "UPDATE", "DELETE"):
            for cmd in urlmap._api_commands(method, strict=True):
                cmdinfo = {"url": cmd.SYNOPSIS[2], "method": method}
                if hasattr(cmd, "HTTP_QUERY_VARS"):
                    cmdinfo["query_vars"] = cmd.HTTP_QUERY_VARS
                if hasattr(cmd, "HTTP_POST_VARS"):
                    cmdinfo["post_vars"] = cmd.HTTP_POST_VARS
                if hasattr(cmd, "HTTP_OPTIONAL_VARS"):
                    cmdinfo["optional_vars"] = cmd.OPTIONAL_VARS
                res["api_methods"].append(cmdinfo)

        for cls, filename in config.plugins.get_js_classes().iteritems():
            try:
                with open(filename, "rb") as fd:
                    res["javascript_classes"].append({"classname": cls, "code": fd.read().decode("utf-8")})
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        for cls, filename in config.plugins.get_css_files().iteritems():
            try:
                with open(filename, "rb") as fd:
                    res["css_files"].append({"classname": cls, "css": fd.read().decode("utf-8")})
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        return res
Example #3
0
    def command(self, save=True, auto=False):
        res = {
            'api_methods': [],
            'javascript_classes': [],
            'css_files': []
        }
        if self.args:
            # Short-circuit if we're serving templates...
            return self._success(_('Serving up API content'), result=res)

        session, config = self.session, self.session.config
        urlmap = UrlMap(session)
        for method in ('GET', 'POST', 'UPDATE', 'DELETE'):
            for cmd in urlmap._api_commands(method, strict=True):
                cmdinfo = {
                    "url": cmd.SYNOPSIS[2],
                    "method": method
                }
                if hasattr(cmd, 'HTTP_QUERY_VARS'):
                    cmdinfo["query_vars"] = cmd.HTTP_QUERY_VARS
                if hasattr(cmd, 'HTTP_POST_VARS'):
                    cmdinfo["post_vars"] = cmd.HTTP_POST_VARS
                if hasattr(cmd, 'HTTP_OPTIONAL_VARS'):
                    cmdinfo["optional_vars"] = cmd.OPTIONAL_VARS
                res['api_methods'].append(cmdinfo)

        created_js = []
        for cls, filename in sorted(list(
                config.plugins.get_js_classes().iteritems())):
            try:
                parts = cls.split('.')[:-1]
                for i in range(1, len(parts)):
                    parent = '.'.join(parts[:i+1])
                    if parent not in created_js:
                        res['javascript_classes'].append({
                            'classname': parent,
                            'code': ''
                        })
                        created_js.append(parent)
                with open(filename, 'rb') as fd:
                    res['javascript_classes'].append({
                        'classname': cls,
                        'code': fd.read().decode('utf-8')
                    })
                    created_js.append(cls)
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        for cls, filename in sorted(list(
                config.plugins.get_css_files().iteritems())):
            try:
                with open(filename, 'rb') as fd:
                    res['css_files'].append({
                        'classname': cls,
                        'css': fd.read().decode('utf-8')
                    })
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        return self._success(_('Generated Javascript API'), result=res)
Example #4
0
 def as_dict(self):
     from mailpile.urlmap import UrlMap
     um = UrlMap(self.session)
     rv = {
         'command': self.command_name,
         'state': {
             'command_url': um.ui_url(self.command_obj),
             'context_url': um.context_url(self.command_obj),
             'query_args': self.command_obj.state_as_query_args(),
             'cache_id': self.command_obj.cache_id(),
             'context': self.command_obj.context or ''
         },
         'status': self.status,
         'message': self.message,
         'result': self.result,
         'event_id': self.command_obj.event.event_id,
         'elapsed': '%.3f' % self.session.ui.time_elapsed,
     }
     csrf_token = self.session.ui.html_variables.get('csrf_token')
     if csrf_token:
         rv['state']['csrf_token'] = csrf_token
     if self.error_info:
         rv['error'] = self.error_info
     for ui_key in [
             k for k in self.command_obj.data.keys()
             if k.startswith('ui_')
     ]:
         rv[ui_key] = self.command_obj.data[ui_key][0]
     ev = self.command_obj.event
     if ev and ev.data.get('password_needed'):
         rv['password_needed'] = ev.private_data['password_needed']
     return rv
Example #5
0
 def as_dict(self):
     from mailpile.urlmap import UrlMap
     um = UrlMap(self.session)
     rv = {
         'command': self.command_name,
         'state': {
             'command_url': um.ui_url(self.command_obj),
             'context_url': um.context_url(self.command_obj),
             'query_args': self.command_obj.state_as_query_args(),
             'cache_id': self.command_obj.cache_id(),
             'context': self.command_obj.context or ''
         },
         'status': self.status,
         'message': self.message,
         'result': self.result,
         'event_id': self.command_obj.event.event_id,
         'elapsed': '%.3f' % self.session.ui.time_elapsed,
     }
     csrf_token = self.session.ui.html_variables.get('csrf_token')
     if csrf_token:
         rv['state']['csrf_token'] = csrf_token
     if self.error_info:
         rv['error'] = self.error_info
     for ui_key in [k for k in self.command_obj.data.keys()
                    if k.startswith('ui_')]:
         rv[ui_key] = self.command_obj.data[ui_key][0]
     ev = self.command_obj.event
     if ev and ev.data.get('password_needed'):
         rv['password_needed'] = ev.private_data['password_needed']
     return rv
Example #6
0
    def command(self, save=True, auto=False):
        res = {
            'api_methods': [],
            'javascript_classes': [],
            'css_files': []
        }
        if self.args:
            # Short-circuit if we're serving templates...
            return self._success(_('Serving up API content'), result=res)

        session, config = self.session, self.session.config
        urlmap = UrlMap(session)
        for method in ('GET', 'POST', 'UPDATE', 'DELETE'):
            for cmd in urlmap._api_commands(method, strict=True):
                cmdinfo = {
                    "url": cmd.SYNOPSIS[2],
                    "method": method
                }
                if hasattr(cmd, 'HTTP_QUERY_VARS'):
                    cmdinfo["query_vars"] = cmd.HTTP_QUERY_VARS
                if hasattr(cmd, 'HTTP_POST_VARS'):
                    cmdinfo["post_vars"] = cmd.HTTP_POST_VARS
                if hasattr(cmd, 'HTTP_OPTIONAL_VARS'):
                    cmdinfo["optional_vars"] = cmd.OPTIONAL_VARS
                res['api_methods'].append(cmdinfo)

        created_js = []
        for cls, filename in sorted(list(
                config.plugins.get_js_classes().iteritems())):
            try:
                parts = cls.split('.')[:-1]
                for i in range(1, len(parts)):
                    parent = '.'.join(parts[:i+1])
                    if parent not in created_js:
                        res['javascript_classes'].append({
                            'classname': parent,
                            'code': ''
                        })
                        created_js.append(parent)
                with open(filename, 'rb') as fd:
                    res['javascript_classes'].append({
                        'classname': cls,
                        'code': fd.read().decode('utf-8')
                    })
                    created_js.append(cls)
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        for cls, filename in sorted(list(
                config.plugins.get_css_files().iteritems())):
            try:
                with open(filename, 'rb') as fd:
                    res['css_files'].append({
                        'classname': cls,
                        'css': fd.read().decode('utf-8')
                    })
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        return self._success(_('Generated Javascript API'), result=res)
Example #7
0
    def do_GET(self, post_data={}, suppress_body=False, method='GET'):
        (scheme, netloc, path, params, query, frag) = urlparse(self.path)
        query_data = parse_qs(query)
        path = unquote(path)

        # HTTP is stateless, so we create a new session for each request.
        config = self.server.session.config

        if 'http' in config.sys.debug:
            sys.stderr.write(('%s: %s qs=%s post=%s\n') %
                             (method, path, query_data, post_data))

        # Static things!
        if path == '/favicon.ico':
            path = '/static/favicon.ico'
        if path.startswith('/_/'):
            path = path[2:]
        if path.startswith('/static/'):
            return self.send_file(config, path[len('/static/'):])

        session = Session(config)
        session.ui = HttpUserInteraction(self, config)

        idx = session.config.index
        session.ui.html_variables = {
            'csrf': self.csrf(),
            'http_host': self.headers.get('host', 'localhost'),
            'http_hostname': self.http_host(),
            'http_method': method,
            'message_count': (idx and len(idx.INDEX) or 0),
            'name': session.config.get_profile().get('name',
                                                     'Chelsea Manning'),
            'title': 'Mailpile dummy title',
            'url_protocol': self.headers.get('x-forwarded-proto', 'http'),
            'mailpile_size': idx and len(idx.INDEX) or 0
        }

        try:
            try:
                commands = UrlMap(session).map(self, method, path, query_data,
                                               post_data)
            except UsageError:
                if (not path.endswith('/') and not session.config.sys.debug
                        and method == 'GET'):
                    commands = UrlMap(session).map(self, method, path + '/',
                                                   query_data, post_data)
                    url = quote(path) + '/'
                    if query:
                        url += '?' + query
                    return self.send_http_redirect(url)
                else:
                    raise

            results = [cmd.run() for cmd in commands]
            session.ui.display_result(results[-1])
        except UrlRedirectException, e:
            return self.send_http_redirect(e.url)
Example #8
0
def GetTagInfo(cfg, tn, stats=False, unread=None, exclude=None, subtags=None):
    tag = GetTag(cfg, tn)
    tid = tag._key
    info = {
        'tid': tid,
        'url': UrlMap(config=cfg).url_tag(tid),
    }
    for k in tag.all_keys():
        #       if k not in INFO_HIDES_TAG_METADATA:
        info[k] = tag[k]
    if subtags:
        info['subtag_ids'] = [t._key for t in subtags]
    exclude = exclude or set()
    if stats and (unread is not None):
        messages = (cfg.index.TAGS.get(tid, set()) - exclude)
        stats_all = len(messages)
        info['stats'] = {
            'all': stats_all,
            'new': len(messages & unread),
            'not': len(cfg.index.INDEX) - stats_all
        }
        if subtags:
            for subtag in subtags:
                messages |= cfg.index.TAGS.get(subtag._key, set())
            info['stats'].update({
                'sum_all': len(messages),
                'sum_new': len(messages & unread),
            })

    return info
Example #9
0
def GetTagInfo(cfg, tn, stats=False, unread=None, exclude=None, subtags=None):
    tag = GetTag(cfg, tn)
    tid = tag._key
    info = {
        'tid': tid,
        'url': UrlMap(config=cfg).url_tag(tid),
    }
    for k in tag.all_keys():
        if k in ('display_order', ):
            if str(tag[k]) == 'nan':
                tag[k] = 0.01 * len(info)
        info[k] = tag[k]
    if subtags:
        info['subtag_ids'] = [t._key for t in subtags]
    exclude = exclude or set()
    if stats and (unread is not None):
        messages = (cfg.index.TAGS.get(tid, set()) - exclude)
        stats_all = len(messages)
        info['name'] = _(info['name'])
        info['stats'] = {
            'all': stats_all,
            'new': len(messages & unread),
            'not': len(cfg.index.INDEX) - stats_all
        }
        if subtags:
            for subtag in subtags:
                messages |= cfg.index.TAGS.get(subtag._key, set())
            info['stats'].update({
                'sum_all': len(messages),
                'sum_new': len(messages & unread),
            })

    return info
Example #10
0
 def cache_id(self, sqa=None):
     if self.COMMAND_CACHE_TTL < 1:
         return ''
     from mailpile.urlmap import UrlMap
     args = sorted(list((sqa or self.state_as_query_args()).iteritems()))
     # The replace() stuff makes these usable as CSS class IDs
     return ('%s-%s' % (UrlMap(self.session).ui_url(self), md5_hex(
         str(args)))).replace('/', '-').replace('.', '-')
Example #11
0
    def command(self, save=True, auto=False):
        session, config = self.session, self.session.config

        urlmap = UrlMap(session)
        res = {
            'api_methods': [],
            'javascript_classes': [],
            'css_files': []
        }

        for method in ('GET', 'POST', 'UPDATE', 'DELETE'):
            for cmd in urlmap._api_commands(method, strict=True):
                cmdinfo = {
                    "url": cmd.SYNOPSIS[2],
                    "method": method
                }
                if hasattr(cmd, 'HTTP_QUERY_VARS'):
                    cmdinfo["query_vars"] = cmd.HTTP_QUERY_VARS
                if hasattr(cmd, 'HTTP_POST_VARS'):
                    cmdinfo["post_vars"] = cmd.HTTP_POST_VARS
                if hasattr(cmd, 'HTTP_OPTIONAL_VARS'):
                    cmdinfo["optional_vars"] = cmd.OPTIONAL_VARS
                res['api_methods'].append(cmdinfo)

        for cls, filename in config.plugins.get_js_classes().iteritems():
            try:
                with open(filename, 'rb') as fd:
                    res['javascript_classes'].append({
                        'classname': cls,
                        'code': fd.read().decode('utf-8')
                    })
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        for cls, filename in config.plugins.get_css_files().iteritems():
            try:
                with open(filename, 'rb') as fd:
                    res['css_files'].append({
                        'classname': cls,
                        'css': fd.read().decode('utf-8')
                    })
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        return res
Example #12
0
    def command(self, save=True, auto=False):
        res = {"api_methods": [], "javascript_classes": [], "css_files": []}
        if self.args:
            # Short-circuit if we're serving templates...
            return self._success(_("Serving up API content"), result=res)

        session, config = self.session, self.session.config
        urlmap = UrlMap(session)
        for method in ("GET", "POST", "UPDATE", "DELETE"):
            for cmd in urlmap._api_commands(method, strict=True):
                cmdinfo = {"url": cmd.SYNOPSIS[2], "method": method}
                if hasattr(cmd, "HTTP_QUERY_VARS"):
                    cmdinfo["query_vars"] = cmd.HTTP_QUERY_VARS
                if hasattr(cmd, "HTTP_POST_VARS"):
                    cmdinfo["post_vars"] = cmd.HTTP_POST_VARS
                if hasattr(cmd, "HTTP_OPTIONAL_VARS"):
                    cmdinfo["optional_vars"] = cmd.OPTIONAL_VARS
                res["api_methods"].append(cmdinfo)

        created_js = []
        for cls, filename in sorted(list(config.plugins.get_js_classes().iteritems())):
            try:
                parts = cls.split(".")[:-1]
                for i in range(1, len(parts)):
                    parent = ".".join(parts[: i + 1])
                    if parent not in created_js:
                        res["javascript_classes"].append({"classname": parent, "code": ""})
                        created_js.append(parent)
                with open(filename, "rb") as fd:
                    res["javascript_classes"].append({"classname": cls, "code": fd.read().decode("utf-8")})
                    created_js.append(cls)
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        for cls, filename in sorted(list(config.plugins.get_css_files().iteritems())):
            try:
                with open(filename, "rb") as fd:
                    res["css_files"].append({"classname": cls, "css": fd.read().decode("utf-8")})
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        return self._success(_("Generated Javascript API"), result=res)
Example #13
0
        def as_dict(self):
            from mailpile.urlmap import UrlMap

            rv = {
                "command": self.command_name,
                "state": {
                    "command_url": UrlMap.ui_url(self.command_obj),
                    "context_url": UrlMap.context_url(self.command_obj),
                    "query_args": self.command_obj.state_as_query_args(),
                },
                "status": self.status,
                "message": self.message,
                "result": self.result,
                "elapsed": "%.3f" % self.session.ui.time_elapsed,
            }
            if self.error_info:
                rv["error"] = self.error_info
            for ui_key in [k for k in self.kwargs.keys() if k.startswith("ui_")]:
                rv[ui_key] = self.kwargs[ui_key]
            return rv
Example #14
0
    def command(self, save=True, auto=False):
        session, config = self.session, self.session.config

        urlmap = UrlMap(session)
        res = {'api_methods': [], 'javascript_classes': [], 'css_files': []}

        for method in ('GET', 'POST', 'UPDATE', 'DELETE'):
            for cmd in urlmap._api_commands(method, strict=True):
                cmdinfo = {"url": cmd.SYNOPSIS[2], "method": method}
                if hasattr(cmd, 'HTTP_QUERY_VARS'):
                    cmdinfo["query_vars"] = cmd.HTTP_QUERY_VARS
                if hasattr(cmd, 'HTTP_POST_VARS'):
                    cmdinfo["post_vars"] = cmd.HTTP_POST_VARS
                if hasattr(cmd, 'HTTP_OPTIONAL_VARS'):
                    cmdinfo["optional_vars"] = cmd.OPTIONAL_VARS
                res['api_methods'].append(cmdinfo)

        for cls, filename in config.plugins.get_js_classes().iteritems():
            try:
                with open(filename, 'rb') as fd:
                    res['javascript_classes'].append({
                        'classname':
                        cls,
                        'code':
                        fd.read().decode('utf-8')
                    })
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        for cls, filename in config.plugins.get_css_files().iteritems():
            try:
                with open(filename, 'rb') as fd:
                    res['css_files'].append({
                        'classname': cls,
                        'css': fd.read().decode('utf-8')
                    })
            except (OSError, IOError, UnicodeDecodeError):
                self._ignore_exception()

        return res
Example #15
0
    def command(self):
        result, idx = [], self._idx()

        args = []
        search = {}
        for arg in self.args:
            if '=' in arg:
                kw, val = arg.split('=', 1)
                search[kw.strip()] = val.strip()
            else:
                args.append(arg)
        for kw in self.data:
            if kw in self.session.config.tags.rules:
                search[kw] = self.data[kw]

        wanted = [t.lower() for t in args if not t.startswith('!')]
        unwanted = [t[1:].lower() for t in args if t.startswith('!')]
        wanted.extend([t.lower() for t in self.data.get('only', [])])
        unwanted.extend([t.lower() for t in self.data.get('not', [])])

        for tag in self.session.config.get_tags(**search):
            if wanted and tag.slug.lower() not in wanted:
                continue
            if unwanted and tag.slug.lower() in unwanted:
                continue
            tid = tag._key
            info = {
                'tid': tid,
                'url': UrlMap(self.session).url_tag(tid),
            }
            for k in tag.all_keys():
                if k not in self.HIDE_TAG_METADATA:
                    info[k] = tag[k]
            info['stats'] = {
                'all': int(idx.STATS.get(tid, [0, 0])[0]),
                'new': int(idx.STATS.get(tid, [0, 0])[1]),
                'not': len(idx.INDEX) - int(idx.STATS.get(tid, [0, 0])[0])
            }
            subtags = self.session.config.get_tags(parent=tid)
            if subtags and '_recursing' not in self.data:
                info['subtags'] = ListTags(self.session,
                                           arg=[t.slug for t in subtags],
                                           data={
                                               '_recursing': 1
                                           }).run().result['tags']
            result.append(info)
        return {
            'search': search,
            'wanted': wanted,
            'unwanted': unwanted,
            'tags': result
        }
Example #16
0
 def _explain_msg_summary(self, info):
   msg_ts = long(info[6], 36)
   days_ago = (time.time() - msg_ts) / (24*3600)
   msg_date = datetime.date.fromtimestamp(msg_ts)
   date = '%4.4d-%2.2d-%2.2d' % (msg_date.year, msg_date.month, msg_date.day)
   urlmap = UrlMap(self.session)
   expl = {
     'idx': info[0],
     'id': info[1],
     'from': info[2],
     'to': info[3],
     'subject': info[4],
     'snippet': info[5],
     'timestamp': msg_ts,
     'date': date,
     'friendly_date': _friendly_date(days_ago, date),
     'tag_ids': info[7],
     'url': urlmap.url_thread(info[0])
   }
   if info[8]:
     expl['editing_url'] = urlmap.url_compose(info[0])
   return expl
Example #17
0
 def _explain_msg_summary(self, info):
   msg_ts = long(info[6], 36)
   days_ago = (time.time() - msg_ts) / (24*3600)
   msg_date = datetime.datetime.fromtimestamp(msg_ts)
   date = msg_date.strftime("%Y-%m-%d")
   urlmap = UrlMap(self.session)
   expl = {
     'mid': info[0],
     'id': info[1],
     'from': info[2],
     'to': info[3],
     'subject': info[4],
     'snippet': info[5],
     'timestamp': msg_ts,
     'shorttime': msg_date.strftime("%H:%M"),
     'date': date,
     'tag_ids': info[7],
     'url': urlmap.url_thread(info[0])
   }
   if info[8]:
     expl['editing_url'] = urlmap.url_edit(info[0])
   return expl
Example #18
0
 def _explain_msg_summary(self, info):
     msg_ts = long(info[6], 36)
     days_ago = (time.time() - msg_ts) / (24 * 3600)
     msg_date = datetime.datetime.fromtimestamp(msg_ts)
     date = msg_date.strftime("%Y-%m-%d")
     urlmap = UrlMap(self.session)
     expl = {
         "mid": info[0],
         "id": info[1],
         "from": info[2],
         "from_email": ", ".join(ExtractEmails(info[2])),
         "to": info[3],
         "subject": info[4],
         "snippet": info[5],
         "timestamp": msg_ts,
         "shorttime": msg_date.strftime("%H:%M"),
         "date": date,
         "tag_ids": info[7],
         "url": urlmap.url_thread(info[0]),
     }
     if info[8]:
         expl["editing_url"] = urlmap.url_edit(info[0])
     return expl
Example #19
0
 def _explain_msg_summary(self, info):
     msg_ts = long(info[6], 36)
     days_ago = (time.time() - msg_ts) / (24 * 3600)
     msg_date = datetime.datetime.fromtimestamp(msg_ts)
     date = msg_date.strftime("%Y-%m-%d")
     urlmap = UrlMap(self.session)
     expl = {
         'mid': info[0],
         'id': info[1],
         'from': info[2],
         'from_email': ', '.join(ExtractEmails(info[2])),
         'to': info[3],
         'subject': info[4],
         'snippet': info[5],
         'timestamp': msg_ts,
         'shorttime': msg_date.strftime("%H:%M"),
         'date': date,
         'tag_ids': info[7],
         'url': urlmap.url_thread(info[0])
     }
     if info[8]:
         expl['editing_url'] = urlmap.url_edit(info[0])
     return expl
Example #20
0
def GetTagInfo(cfg, tn, stats=False, unread=None):
    tag = GetTag(cfg, tn)
    tid = tag._key
    info = {
        'tid': tid,
        'url': UrlMap(config=cfg).url_tag(tid),
    }
    for k in tag.all_keys():
        if k not in INFO_HIDES_TAG_METADATA:
            info[k] = tag[k]
    if stats and (unread is not None):
        stats_all = len(cfg.index.TAGS.get(tid, []))
        info['stats'] = {
            'all': stats_all,
            'new': len(cfg.index.TAGS.get(tid, set()) & unread),
            'not': len(cfg.index.INDEX) - stats_all
        }
    return info
Example #21
0
    def __init__(self,
                 session,
                 idx,
                 results=None,
                 start=0,
                 end=None,
                 num=None,
                 emails=None,
                 view_pairs=None,
                 people=None,
                 suppress_data=False,
                 full_threads=True):
        dict.__init__(self)
        self.session = session
        self.people = people
        self.emails = emails or []
        self.view_pairs = view_pairs or {}
        self.idx = idx
        self.urlmap = UrlMap(self.session)

        results = self.results = results or session.results or []

        num = num or session.config.prefs.num_results
        if end:
            start = end - num
        if start > len(results):
            start = len(results)
        if start < 0:
            start = 0

        try:
            threads = [b36(r) for r in results[start:start + num]]
        except TypeError:
            results = threads = []
            start = end = 0

        self.session.ui.mark(
            _('Parsing metadata for %d results '
              '(full_threads=%s)') % (len(threads), full_threads))

        self.update({
            'summary': _('Search: %s') % ' '.join(session.searched),
            'stats': {
                'count': len(threads),
                'start': start + 1,
                'end': start + min(num,
                                   len(results) - start),
                'total': len(results),
            },
            'search_terms': session.searched,
            'address_ids': [],
            'message_ids': [],
            'view_pairs': view_pairs,
            'thread_ids': threads,
        })
        if 'tags' in self.session.config:
            search_tags = [
                idx.config.get_tag(t.split(':')[1], {})
                for t in session.searched
                if t.startswith('in:') or t.startswith('tag:')
            ]
            search_tag_ids = [t._key for t in search_tags if t]
            self.update({
                'search_tag_ids': search_tag_ids,
            })
            if search_tag_ids:
                self['summary'] = ' & '.join(
                    [t.name for t in search_tags if t])
        else:
            search_tag_ids = []

        if suppress_data or (not results and not emails):
            return

        self.update({
            'data': {
                'addresses': {},
                'metadata': {},
                'messages': {},
                'threads': {}
            }
        })
        if 'tags' in self.session.config:
            th = self['data']['tags'] = {}
            for tid in search_tag_ids:
                if tid not in th:
                    th[tid] = self._tag(tid, {'searched': True})

        idxs = results[start:start + num]

        for e in emails or []:
            self.add_email(e, idxs)

        done_idxs = set()
        while idxs:
            idxs = list(set(idxs) - done_idxs)
            for idx_pos in idxs:
                done_idxs.add(idx_pos)
                msg_info = idx.get_msg_at_idx_pos(idx_pos)
                self.add_msg_info(b36(idx_pos),
                                  msg_info,
                                  full_threads=full_threads,
                                  idxs=idxs)

        if emails and len(emails) == 1:
            self['summary'] = emails[0].get_msg_info(MailIndex.MSG_SUBJECT)
Example #22
0
    def _process_manifest_pass_two(self, full_name,
                                   manifest=None, plugin_path=None):
        """
        Pass two of processing the manifest data. This maps templates and
        data to API commands and links registers classes and methods as
        hooks here and there. As these things depend both on configuration
        and the URL map, this happens as a second phase.
        """
        if not manifest:
            return

        manifest_path = lambda *p: self._mf_path(manifest, *p)
        manifest_iteritems = lambda *p: self._mf_iteritems(manifest, *p)

        # Register javascript classes
        for fn in manifest.get('code', {}).get('javascript', []):
            class_name = fn.replace('/', '.').rsplit('.', 1)[0]
            # FIXME: Is this a good idea?
            if full_name.endswith('.'+class_name):
                parent, class_name = full_name.rsplit('.', 1)
            else:
                parent = full_name
            self.register_js(parent, class_name,
                             os.path.join(plugin_path, fn))

        # Register CSS files
        for fn in manifest.get('code', {}).get('css', []):
            file_name = fn.replace('/', '.').rsplit('.', 1)[0]
            self.register_css(full_name, file_name,
                              os.path.join(plugin_path, fn))

        # Register web assets
        if plugin_path:
            from mailpile.urlmap import UrlMap
            um = UrlMap(session=self.session, config=self.config)
            for url, info in manifest_iteritems('routes'):
                filename = os.path.join(plugin_path, info['file'])

                # Short-cut for static content
                if url.startswith('/static/'):
                    self.register_web_asset(full_name, url[8:], filename,
                        mimetype=info.get('mimetype', None))
                    continue

                # Finds the right command class and register asset in
                # the right place for that particular command.
                commands = []
                if (not url.startswith('/api/')) and 'api' in info:
                    url = '/api/%d%s' % (info['api'], url)
                    if url[-1] == '/':
                        url += 'as.html'
                for method in ('GET', 'POST', 'PUT', 'UPDATE', 'DELETE'):
                    try:
                        commands = um.map(None, method, url, {}, {})
                        break
                    except UsageError:
                        pass

                output = [o.get_render_mode()
                          for o in commands if hasattr(o, 'get_render_mode')]
                output = output and output[-1] or 'html'
                if commands:
                    command = commands[-1]
                    tpath = command.template_path(output.split('.')[-1],
                                                  template=output)
                    self.register_web_asset(full_name,
                                            'html/' + tpath,
                                            filename)
                else:
                    print 'FIXME: Un-routable URL in manifest %s' % url

        # Register email content/crypto hooks
        s = self
        for which, reg in (
            ('outgoing_content', s.register_outgoing_email_content_transform),
            ('outgoing_crypto', s.register_outgoing_email_crypto_transform),
            ('incoming_crypto', s.register_incoming_email_crypto_transform),
            ('incoming_content', s.register_incoming_email_content_transform)
        ):
            for item in manifest_path('email_transforms', which):
                name = '%3.3d_%s' % (int(item.get('priority', 999)), full_name)
                reg(name, self._get_class(full_name, item['class']))

        # Register search keyword extractors
        s = self
        for which, reg in (
            ('meta', s.register_meta_kw_extractor),
            ('text', s.register_text_kw_extractor),
            ('data', s.register_data_kw_extractor)
        ):
            for item in manifest_path('keyword_extractors', which):
                reg('%s.%s' % (full_name, item),
                    self._get_class(full_name, item))

        # Register contact/vcard hooks
        for which, reg in (
            ('importers', self.register_vcard_importers),
            ('exporters', self.register_contact_exporters),
            ('context', self.register_contact_context_providers)
        ):
            for item in manifest_path('contacts', which):
                reg(self._get_class(full_name, item))

        # Register periodic jobs
        def reg_job(info, spd, register):
            interval, cls = info['interval'], info['class']
            callback = self._get_class(full_name, cls)
            register('%s.%s/%s-%s' % (full_name, cls, spd, interval),
                     interval, callback)
        for info in manifest_path('periodic_jobs', 'fast'):
            reg_job(info, 'fast', self.register_fast_periodic_job)
        for info in manifest_path('periodic_jobs', 'slow'):
            reg_job(info, 'slow', self.register_slow_periodic_job)

        ucfull_name = full_name.capitalize()
        for ui_type, elems in manifest.get('user_interface', {}).iteritems():
            for hook in elems:
                if 'javascript_setup' in hook:
                    js = hook['javascript_setup']
                    if not js.startswith('Mailpile.'):
                       hook['javascript_setup'] = '%s.%s' % (ucfull_name, js)
                if 'javascript_events' in hook:
                    for event, call in hook['javascript_events'].iteritems():
                        if not call.startswith('Mailpile.'):
                            hook['javascript_events'][event] = '%s.%s' \
                                % (ucfull_name, call)
                self.register_ui_element(ui_type, **hook)
Example #23
0
    def _process_manifest_pass_two(self, full_name,
                                   manifest=None, plugin_path=None):
        """
        Pass two of processing the manifest data. This maps templates and
        data to API commands and links registers classes and methods as
        hooks here and there. As these things depend both on configuration
        and the URL map, this happens as a second phase.
        """
        if not manifest:
            return

        manifest_path = lambda *p: self._mf_path(manifest, *p)
        manifest_iteritems = lambda *p: self._mf_iteritems(manifest, *p)

        # Register javascript classes
        for fn in manifest.get('code', {}).get('javascript', []):
            class_name = fn.replace('/', '.').rsplit('.', 1)[0]
            # FIXME: Is this a good idea?
            if full_name.endswith('.'+class_name):
                parent, class_name = full_name.rsplit('.', 1)
            else:
                parent = full_name
            self.register_js(parent, class_name,
                             os.path.join(plugin_path, fn))

        # Register CSS files
        for fn in manifest.get('code', {}).get('css', []):
            file_name = fn.replace('/', '.').rsplit('.', 1)[0]
            self.register_css(full_name, file_name,
                              os.path.join(plugin_path, fn))

        # Register web assets
        if plugin_path:
            from mailpile.urlmap import UrlMap
            um = UrlMap(session=self.session, config=self.config)
            for url, info in manifest_iteritems('routes'):
                filename = os.path.join(plugin_path, info['file'])

                # Short-cut for static content
                if url.startswith('/static/'):
                    self.register_web_asset(full_name, url[8:], filename,
                        mimetype=info.get('mimetype', None))
                    continue

                # Finds the right command class and register asset in
                # the right place for that particular command.
                commands = []
                if (not url.startswith('/api/')) and 'api' in info:
                    url = '/api/%d%s' % (info['api'], url)
                    if url[-1] == '/':
                        url += 'as.html'
                for method in ('GET', 'POST', 'PUT', 'UPDATE', 'DELETE'):
                    try:
                        commands = um.map(None, method, url, {}, {})
                        break
                    except UsageError:
                        pass

                output = [o.get_render_mode()
                          for o in commands if hasattr(o, 'get_render_mode')]
                output = output and output[-1] or 'html'
                if commands:
                    command = commands[-1]
                    tpath = command.template_path(output.split('.')[-1],
                                                  template=output)
                    self.register_web_asset(full_name,
                                            'html/' + tpath,
                                            filename)
                else:
                    print 'FIXME: Un-routable URL in manifest %s' % url

        # Register email content/crypto hooks
        s = self
        for which, reg in (
            ('outgoing_content', s.register_outgoing_email_content_transform),
            ('outgoing_crypto', s.register_outgoing_email_crypto_transform),
            ('incoming_crypto', s.register_incoming_email_crypto_transform),
            ('incoming_content', s.register_incoming_email_content_transform)
        ):
            for item in manifest_path('email_transforms', which):
                name = '%3.3d_%s' % (int(item.get('priority', 999)), full_name)
                reg(name, self._get_class(full_name, item['class']))

        # Register search keyword extractors
        s = self
        for which, reg in (
            ('meta', s.register_meta_kw_extractor),
            ('text', s.register_text_kw_extractor),
            ('data', s.register_data_kw_extractor)
        ):
            for item in manifest_path('keyword_extractors', which):
                reg('%s.%s' % (full_name, item),
                    self._get_class(full_name, item))

        # Register contact/vcard hooks
        for which, reg in (
            ('importers', self.register_vcard_importers),
            ('exporters', self.register_contact_exporters),
            ('context', self.register_contact_context_providers)
        ):
            for item in manifest_path('contacts', which):
                reg(self._get_class(full_name, item))

        # Register periodic jobs
        def reg_job(info, spd, register):
            interval, cls = info['interval'], info['class']
            callback = self._get_class(full_name, cls)
            register('%s.%s/%s-%s' % (full_name, cls, spd, interval),
                     interval, callback)
        for info in manifest_path('periodic_jobs', 'fast'):
            reg_job(info, 'fast', self.register_fast_periodic_job)
        for info in manifest_path('periodic_jobs', 'slow'):
            reg_job(info, 'slow', self.register_slow_periodic_job)

        ucfull_name = full_name.capitalize()
        for ui_type, elems in manifest.get('user_interface', {}).iteritems():
            for hook in elems:
                if 'javascript_setup' in hook:
                    js = hook['javascript_setup']
                    if not js.startswith('Mailpile.'):
                       hook['javascript_setup'] = '%s.%s' % (ucfull_name, js)
                if 'javascript_events' in hook:
                    for event, call in hook['javascript_events'].iteritems():
                        if not call.startswith('Mailpile.'):
                            hook['javascript_events'][event] = '%s.%s' \
                                % (ucfull_name, call)
                self.register_ui_element(ui_type, **hook)
Example #24
0
 def _use_data_view(self, view_name, result):
     self._debug('use_data_view(%s, ...)' % (view_name))
     dv = UrlMap(self.env.session).map(None, 'GET', view_name, {}, {})[-1]
     return dv.view(result)
Example #25
0
    def _process_manifest_pass_two(self, full_name, manifest=None, plugin_path=None):
        """
        Pass two of processing the manifest data. This maps templates and
        data to API commands and links registers classes and methods as
        hooks here and there. As these things depend both on configuration
        and the URL map, this happens as a second phase.
        """
        if not manifest:
            return

        manifest_path = lambda *p: self._mf_path(manifest, *p)
        manifest_iteritems = lambda *p: self._mf_iteritems(manifest, *p)

        # Register javascript classes
        for fn in manifest.get("code", {}).get("javascript", []):
            class_name = fn.replace("/", ".").rsplit(".", 1)[0]
            # FIXME: Is this a good idea?
            if full_name.endswith("." + class_name):
                parent, class_name = full_name.rsplit(".", 1)
            else:
                parent = full_name
            self.register_js(parent, class_name, os.path.join(plugin_path, fn))

        # Register CSS files
        for fn in manifest.get("code", {}).get("css", []):
            file_name = fn.replace("/", ".").rsplit(".", 1)[0]
            self.register_css(full_name, file_name, os.path.join(plugin_path, fn))

        # Register web assets
        if plugin_path:
            from mailpile.urlmap import UrlMap

            um = UrlMap(session=self.session, config=self.config)
            for url, info in manifest_iteritems("routes"):
                filename = os.path.join(plugin_path, info["file"])

                # Short-cut for static content
                if url.startswith("/static/"):
                    self.register_web_asset(full_name, url[8:], filename, mimetype=info.get("mimetype", None))
                    continue

                # Finds the right command class and register asset in
                # the right place for that particular command.
                commands = []
                if (not url.startswith("/api/")) and "api" in info:
                    url = "/api/%d%s" % (info["api"], url)
                    if url[-1] == "/":
                        url += "as.html"
                for method in ("GET", "POST", "PUT", "UPDATE", "DELETE"):
                    try:
                        commands = um.map(None, method, url, {}, {})
                        break
                    except UsageError:
                        pass

                output = [o.get_render_mode() for o in commands if hasattr(o, "get_render_mode")]
                output = output and output[-1] or "html"
                if commands:
                    command = commands[-1]
                    tpath = command.template_path(output.split(".")[-1], template=output)
                    self.register_web_asset(full_name, "html/" + tpath, filename)
                else:
                    print "FIXME: Un-routable URL in manifest %s" % url

        # Register email content/crypto hooks
        s = self
        for which, reg in (
            ("outgoing_content", s.register_outgoing_email_content_transform),
            ("outgoing_crypto", s.register_outgoing_email_crypto_transform),
            ("incoming_crypto", s.register_incoming_email_crypto_transform),
            ("incoming_content", s.register_incoming_email_content_transform),
        ):
            for item in manifest_path("email_transforms", which):
                name = "%3.3d_%s" % (int(item.get("priority", 999)), full_name)
                reg(name, self._get_class(full_name, item["class"]))

        # Register search keyword extractors
        s = self
        for which, reg in (
            ("meta", s.register_meta_kw_extractor),
            ("text", s.register_text_kw_extractor),
            ("data", s.register_data_kw_extractor),
        ):
            for item in manifest_path("keyword_extractors", which):
                reg("%s.%s" % (full_name, item), self._get_class(full_name, item))

        # Register contact/vcard hooks
        for which, reg in (
            ("importers", self.register_vcard_importers),
            ("exporters", self.register_contact_exporters),
            ("context", self.register_contact_context_providers),
        ):
            for item in manifest_path("contacts", which):
                reg(self._get_class(full_name, item))

        # Register periodic jobs
        def reg_job(info, spd, register):
            interval, cls = info["interval"], info["class"]
            callback = self._get_class(full_name, cls)
            register("%s.%s/%s-%s" % (full_name, cls, spd, interval), interval, callback)

        for info in manifest_path("periodic_jobs", "fast"):
            reg_job(info, "fast", self.register_fast_periodic_job)
        for info in manifest_path("periodic_jobs", "slow"):
            reg_job(info, "slow", self.register_slow_periodic_job)

        ucfull_name = full_name.capitalize()
        for ui_type, elems in manifest.get("user_interface", {}).iteritems():
            for hook in elems:
                if "javascript_setup" in hook:
                    js = hook["javascript_setup"]
                    if not js.startswith("Mailpile."):
                        hook["javascript_setup"] = "%s.%s" % (ucfull_name, js)
                if "javascript_events" in hook:
                    for event, call in hook["javascript_events"].iteritems():
                        if not call.startswith("Mailpile."):
                            hook["javascript_events"][event] = "%s.%s" % (ucfull_name, call)
                self.register_ui_element(ui_type, **hook)
 def _use_data_view(self, view_name, result):
     dv = UrlMap(self.env.session).map(None, 'GET', view_name, {}, {})[-1]
     return dv.view(result)
Example #27
0
 def _use_data_view(self, view_name, result):
     self._debug('use_data_view(%s, ...)' % (view_name))
     dv = UrlMap(self.env.session).map(None, 'GET', view_name, {}, {})[-1]
     return dv.view(result)
Example #28
0
    def _process_manifest_pass_two(self,
                                   full_name,
                                   manifest=None,
                                   plugin_path=None):
        """
        Pass two of processing the manifest data. This maps templates and
        data to API commands and links registers classes and methods as
        hooks here and there. As these things depend both on configuration
        and the URL map, this happens as a second phase.
        """
        if not manifest:
            return

        manifest_path = lambda *p: self._mf_path(manifest, *p)
        manifest_iteritems = lambda *p: self._mf_iteritems(manifest, *p)

        # Register contact/vcard hooks
        for importer in manifest_path('contacts', 'importers'):
            self.register_vcard_importers(self._get_class(full_name, importer))
        for exporter in manifest_path('contacts', 'exporters'):
            self.register_contact_exporters(
                self._get_class(full_name, exporter))
        for context in manifest_path('contacts', 'context'):
            self.register_contact_context_providers(
                self._get_class(full_name, context))

        # Register javascript classes
        for fn in manifest.get('code', {}).get('javascript', []):
            class_name = fn.replace('/', '.').rsplit('.', 1)[0]
            self.register_js(full_name, class_name,
                             os.path.join(plugin_path, fn))

        # Register CSS files
        for fn in manifest.get('code', {}).get('css', []):
            file_name = fn.replace('/', '.').rsplit('.', 1)[0]
            self.register_css(full_name, file_name,
                              os.path.join(plugin_path, fn))

        # Register web assets
        if plugin_path:
            try:
                from mailpile.urlmap import UrlMap
                um = UrlMap(session=self.session, config=self.config)
                for url, info in manifest_iteritems('routes'):
                    filename = os.path.join(plugin_path, info['file'])

                    # Short-cut for static content
                    if url.startswith('/static/'):
                        self.register_web_asset(full_name,
                                                url[8:],
                                                filename,
                                                mimetype=info.get(
                                                    'mimetype', None))
                        continue

                    # Finds the right command class and register asset in
                    # the right place for that particular command.
                    commands = []
                    if (not url.startswith('/api/')) and 'api' in info:
                        url = '/api/%d%s' % (info['api'], url)
                        if url[-1] == '/':
                            url += 'as.html'
                    for method in ('GET', 'POST', 'PUT', 'UPDATE', 'DELETE'):
                        try:
                            commands = um.map(None, method, url, {}, {})
                            break
                        except UsageError:
                            pass

                    output = [
                        o.get_render_mode() for o in commands
                        if hasattr(o, 'get_render_mode')
                    ]
                    output = output and output[-1] or 'html'
                    if commands:
                        command = commands[-1]
                        tpath = command.template_path(output.split('.')[-1],
                                                      template=output)
                        self.register_web_asset(full_name, 'html/' + tpath,
                                                filename)
                    else:
                        print 'FIXME: Un-routable URL in manifest %s' % url
            except:
                import traceback
                traceback.print_exc()
Example #29
0
 def _use_data_view(self, view_name, result):
     dv = UrlMap(self.env.session).map(None, 'GET', view_name, {}, {})[-1]
     return dv.view(result)
Example #30
0
    def _process_manifest_pass_two(self, full_name,
                                   manifest=None, plugin_path=None):
        """
        Pass two of processing the manifest data. This maps templates and
        data to API commands and links registers classes and methods as
        hooks here and there. As these things depend both on configuration
        and the URL map, this happens as a second phase.
        """
        if not manifest:
            return

        manifest_path = lambda *p: self._mf_path(manifest, *p)
        manifest_iteritems = lambda *p: self._mf_iteritems(manifest, *p)

        # Register contact/vcard hooks
        for importer in manifest_path('contacts', 'importers'):
            self.register_vcard_importers(self._get_class(full_name, importer))
        for exporter in manifest_path('contacts', 'exporters'):
            self.register_contact_exporters(self._get_class(full_name,
                                                            exporter))
        for context in manifest_path('contacts', 'context'):
            self.register_contact_context_providers(self._get_class(full_name,
                                                                    context))

        # Register javascript classes
        for fn in manifest.get('code', {}).get('javascript', []):
            class_name = fn.replace('/', '.').rsplit('.', 1)[0]
            self.register_js(full_name, class_name,
                             os.path.join(plugin_path, fn))

        # Register CSS files
        for fn in manifest.get('code', {}).get('css', []):
            file_name = fn.replace('/', '.').rsplit('.', 1)[0]
            self.register_css(full_name, file_name,
                              os.path.join(plugin_path, fn))

        # Register web assets
        if plugin_path:
          try:
            from mailpile.urlmap import UrlMap
            um = UrlMap(session=self.session, config=self.config)
            for url, info in manifest_iteritems('routes'):
                filename = os.path.join(plugin_path, info['file'])

                # Short-cut for static content
                if url.startswith('/static/'):
                    self.register_web_asset(full_name, url[8:], filename,
                        mimetype=info.get('mimetype', None))
                    continue

                # Finds the right command class and register asset in
                # the right place for that particular command.
                commands = []
                if (not url.startswith('/api/')) and 'api' in info:
                    url = '/api/%d%s' % (info['api'], url)
                    if url[-1] == '/':
                        url += 'as.html'
                for method in ('GET', 'POST', 'PUT', 'UPDATE', 'DELETE'):
                    try:
                        commands = um.map(None, method, url, {}, {})
                        break
                    except UsageError:
                        pass

                output = [o.get_render_mode()
                          for o in commands if hasattr(o, 'get_render_mode')]
                output = output and output[-1] or 'html'
                if commands:
                    command = commands[-1]
                    tpath = command.template_path(output.split('.')[-1],
                                                  template=output)
                    self.register_web_asset(full_name,
                                            'html/' + tpath,
                                            filename)
                else:
                    print 'FIXME: Un-routable URL in manifest %s' % url
          except:
            import traceback
            traceback.print_exc()
Example #31
0
    def _real_do_GET(self, post_data={}, suppress_body=False, method='GET'):
        (scheme, netloc, path, params, query, frag) = urlparse(self.path)
        query_data = parse_qs(query)
        opath = path = unquote(path)

        # HTTP is stateless, so we create a new session for each request.
        self.session, config = self.server.session, self.server.session.config
        server_session = self.server.session

        # Debugging...
        if 'httpdata' in config.sys.debug:
            self.wfile = DebugFileWrapper(sys.stderr, self.wfile)

        # Path manipulation...
        if path == '/favicon.ico':
            path = '%s/static/favicon.ico' % (config.sys.http_path or '')
        if config.sys.http_path:
            if not path.startswith(config.sys.http_path):
                self.send_full_response(_("File not found (invalid path)"),
                                        code=404,
                                        mimetype='text/plain')
                return None
            path = path[len(config.sys.http_path):]
        if path.startswith('/_/'):
            path = path[2:]
        for static in ('/static/', '/bower_components/'):
            if path.startswith(static):
                return self.send_file(config,
                                      path[len(static):],
                                      suppress_body=suppress_body)

        self.session = session = Session(config)
        session.ui = HttpUserInteraction(self,
                                         config,
                                         log_parent=server_session.ui)
        if 'context' in post_data:
            session.load_context(post_data['context'][0])
        elif 'context' in query_data:
            session.load_context(query_data['context'][0])

        mark_name = 'Processing HTTP API request at %s' % time.time()
        session.ui.start_command(mark_name, [], {})

        if 'http' in config.sys.debug:
            session.ui.warning = server_session.ui.warning
            session.ui.notify = server_session.ui.notify
            session.ui.error = server_session.ui.error
            session.ui.debug = server_session.ui.debug
            session.ui.debug('%s: %s qs = %s post = %s' %
                             (method, opath, query_data, post_data))

        idx = session.config.index
        if session.config.loaded_config:
            name = session.config.get_profile().get('name', 'Chelsea Manning')
        else:
            name = 'Chelsea Manning'

        http_headers = []
        http_session = self.http_session()
        csrf_token = security.make_csrf_token(self.server.secret, http_session)
        session.ui.html_variables = {
            'csrf_token':
            csrf_token,
            'csrf_field':
            ('<input type="hidden" name="csrf" value="%s">' % csrf_token),
            'http_host':
            self.headers.get('host', 'localhost'),
            'http_hostname':
            self.http_host(),
            'http_method':
            method,
            'http_session':
            http_session,
            'http_request':
            self,
            'http_response_headers':
            http_headers,
            'message_count': (idx and len(idx.INDEX) or 0),
            'name':
            name,
            'title':
            'Mailpile dummy title',
            'url_protocol':
            self.headers.get('x-forwarded-proto', 'http'),
            'mailpile_size':
            idx and len(idx.INDEX) or 0
        }
        session.ui.valid_csrf_token = lambda token: security.valid_csrf_token(
            self.server.secret, http_session, token)

        try:
            try:
                need_auth = not (mailpile.util.TESTING
                                 or session.config.sys.http_no_auth)
                commands = UrlMap(session).map(self,
                                               method,
                                               path,
                                               query_data,
                                               post_data,
                                               authenticate=need_auth)
            except UsageError:
                if (not path.endswith('/') and not session.config.sys.debug
                        and method == 'GET'):
                    commands = UrlMap(session).map(self, method, path + '/',
                                                   query_data, post_data)
                    url = quote(path) + '/'
                    if query:
                        url += '?' + query
                    return self.send_http_redirect(url)
                else:
                    raise

            cachectrl = None
            if 'http' not in config.sys.debug:
                etag_data = []
                max_ages = []
                have_ed = 0
                for c in commands:
                    max_ages.append(c.max_age())
                    ed = c.etag_data()
                    have_ed += 1 if ed else 0
                    etag_data.extend(ed)
                if have_ed == len(commands):
                    etag = self._mk_etag(*etag_data)
                    conditional = self.headers.get('if-none-match')
                    if conditional == etag:
                        self.send_full_response('OK',
                                                code=304,
                                                msg='Unmodified')
                        return None
                    else:
                        http_headers.append(('ETag', etag))
                max_age = min(max_ages) if max_ages else 10
                if max_age:
                    cachectrl = 'must-revalidate, max-age=%d' % max_age
                else:
                    cachectrl = 'must-revalidate, no-store, max-age=0'

            global LIVE_HTTP_REQUESTS
            hang_fix = 1 if ([1 for c in commands
                              if c.IS_HANGING_ACTIVITY]) else 0
            try:
                LIVE_HTTP_REQUESTS -= hang_fix

                session.ui.mark('Running %d commands' % len(commands))
                results = [cmd.run() for cmd in commands]

                session.ui.mark('Displaying final result')
                session.ui.display_result(results[-1])
            finally:
                LIVE_HTTP_REQUESTS += hang_fix

            session.ui.mark('Rendering response')
            mimetype, content = session.ui.render_response(session.config)

            session.ui.mark('Sending response')
            self.send_full_response(content,
                                    mimetype=mimetype,
                                    header_list=http_headers,
                                    cachectrl=cachectrl)

        except UrlRedirectException as e:
            return self.send_http_redirect(e.url)
        except SuppressHtmlOutput:
            return None
        except AccessError:
            self.send_full_response(_('Access Denied'),
                                    code=403,
                                    mimetype='text/plain')
            return None
        except:
            e = traceback.format_exc()
            session.ui.debug(e)
            if not session.config.sys.debug:
                e = _('Internal Error')
            self.send_full_response(e, code=500, mimetype='text/plain')
            return None

        finally:
            session.ui.report_marks(
                details=('timing' in session.config.sys.debug))
            session.ui.finish_command(mark_name)