Exemple #1
0
    def load(self, session, filename=None):
        self._mkworkdir(session)
        self.index = None
        self.reset(rules=False, data=True)

        filename = filename or self.conffile
        lines = []
        try:
            fd = open(filename, 'rb')
            try:
                decrypt_and_parse_lines(fd, lambda l: lines.append(l), None)
            except ValueError:
                pass
            fd.close()
        except IOError:
            pass

        # Discover plugins and update the config rule to match
        from mailpile.plugins import PluginManager
        self.plugins = PluginManager(config=self, builtin=True).discover([
            os.path.join(os.path.dirname(os.path.realpath(__file__)), '..',
                         'plugins'),
            os.path.join(self.workdir, 'plugins')
        ])
        self.sys.plugins.rules['_any'][1] = self.plugins.available()

        # Parse once (silently), to figure out which plugins to load...
        self.parse_config(None, '\n'.join(lines), source=filename)

        if len(self.sys.plugins) == 0:
            self.sys.plugins.extend(self.plugins.DEFAULT)
        self.load_plugins(session)

        # Now all the plugins are loaded, reset and parse again!
        self.reset_rules_from_source()
        self.parse_config(session, '\n'.join(lines), source=filename)

        # Open event log
        self.event_log = EventLog(
            self.data_directory('event_log', mode='rw', mkdir=True),
            # FIXME: Disbled encryption for now
            lambda: False and self.prefs.obfuscate_index).load()

        # Enable translations
        translation = self.get_i18n_translation(session)

        # Configure jinja2
        self.jinja_env = Environment(
            loader=MailpileJinjaLoader(self),
            autoescape=True,
            trim_blocks=True,
            extensions=[
                'jinja2.ext.i18n', 'jinja2.ext.with_', 'jinja2.ext.do',
                'mailpile.jinjaextensions.MailpileCommand'
            ])
        self.jinja_env.install_gettext_translations(translation, newstyle=True)

        # Load VCards
        self.vcards = VCardStore(
            self, self.data_directory('vcards', mode='rw', mkdir=True))
Exemple #2
0
    def data_file_and_mimetype(self, ftype, fpath, *args, **kwargs):
        # The theme gets precedence
        core_path = self.data_directory(ftype, *args, **kwargs)
        path, mimetype = os.path.join(core_path, fpath), None

        # If there's nothing there, check our plugins
        if not os.path.exists(path):
            from mailpile.plugins import PluginManager
            path, mimetype = PluginManager().get_web_asset(fpath, path)

        if os.path.exists(path):
            return path, mimetype
        else:
            return None, None
Exemple #3
0
from gettext import gettext as _

from mailpile.plugins import PluginManager
from mailpile.commands import Command, Action
from mailpile.mailutils import Email, ExtractEmails, ExtractEmailAndName
from mailpile.vcard import SimpleVCard, VCardLine, AddressInfo
from mailpile.util import *


_plugins = PluginManager(builtin=__file__)


##[ VCards ]########################################

class VCardCommand(Command):
    VCARD = "vcard"
    IS_USER_ACTIVITY = True

    class CommandResult(Command.CommandResult):
        IGNORE = ('line_id', 'pid', 'x-rank')

        def as_text(self):
            try:
                return self._as_text()
            except (KeyError, ValueError, IndexError, TypeError):
                return ''

        def _as_text(self):
            if isinstance(self.result, dict):
                co = self.command_obj
                if co.VCARD in self.result:
Exemple #4
0
#coding:utf-8
import os
from gettext import gettext as _

from mailpile.plugins import PluginManager
from mailpile.crypto.gpgi import GnuPG
from mailpile.vcard import *


_plugins = PluginManager(builtin=__file__)


# User default GnuPG key file
DEF_GNUPG_HOME = os.path.expanduser('~/.gnupg')


class GnuPGImporter(VCardImporter):
    FORMAT_NAME = 'GnuPG'
    FORMAT_DESCRIPTION = _('Import contacts from GnuPG keyring')
    SHORT_NAME = 'gpg'
    CONFIG_RULES = {
        'active': [_('Enable this importer'), bool, True],
        'gpg_home': [_('Location of keyring'), 'path', DEF_GNUPG_HOME],
    }
    VCL_KEY_FMT = 'data:application/x-pgp-fingerprint,%s'

    MERGE_BY = ['key', 'email']  # Merge by Key ID first, email if that fails
    UPDATE_INDEX = True          # Update the index's email->name mapping

    def get_vcards(self):
        if not self.config.active:
 def _get_ui_elements(self, ui_type, state, context=None):
     ctx = context or state.get('context_url', '')
     return copy.deepcopy(PluginManager().get_ui_elements(ui_type, ctx))
Exemple #6
0
import time
import copy
from pgpdump.utils import PgpdumpException

from mailpile.i18n import gettext
from mailpile.plugins import PluginManager
from mailpile.plugins.keylookup import LookupHandler
from mailpile.plugins.keylookup import register_crypto_key_lookup_handler
from mailpile.plugins.search import Search
from mailpile.mailutils import Email

import pgpdump


_ = lambda t: t
_plugins = PluginManager(builtin=__file__)


GLOBAL_KEY_CACHE = {}


def _PRUNE_GLOBAL_KEY_CACHE():
    global GLOBAL_KEY_CACHE
    for k in GLOBAL_KEY_CACHE.keys()[10:]:
        del GLOBAL_KEY_CACHE[k]


PGP_KEY_SUFFIXES = ('pub', 'asc', 'key', 'pgp')

def _might_be_pgp_key(filename, mimetype):
    filename = (filename or '').lower()
Exemple #7
0
import mailpile.security as security
from mailpile.commands import Command
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.mailutils import Email, FormatMbxId, AddressHeaderParser
from mailpile.mailutils import ExtractEmails, ExtractEmailAndName
from mailpile.plugins import PluginManager
from mailpile.search import MailIndex
from mailpile.urlmap import UrlMap
from mailpile.util import *
from mailpile.ui import SuppressHtmlOutput
from mailpile.vfs import vfs, FilePath
from mailpile.vcard import AddressInfo

_plugins = PluginManager(builtin=__file__)

##[ Shared basic Search Result class]#########################################


class SearchResults(dict):

    _NAME_TITLES = ('the', 'mr', 'ms', 'mrs', 'sir', 'dr', 'lord')

    def _name(self, sender, short=True, full_email=False):
        words = re.sub('["<>]', '', sender).split()
        nomail = [w for w in words if not '@' in w]
        if nomail:
            if short:
                if len(nomail) > 1 and nomail[0].lower() in self._NAME_TITLES:
                    return nomail[1]
Exemple #8
0
    """De-authenticate a user (log out)"""
    SYNOPSIS = (None, 'logout', 'auth/logout', '[<session ID>]')
    ORDER = ('Internals', 5)
    SPLIT_ARG = False
    IS_INTERACTIVE = True
    CONFIG_REQUIRED = False
    HTTP_AUTH_REQUIRED = False
    HTTP_CALLABLE = ('GET', 'POST')

    def command(self):
        # FIXME: Should this only be a POST request?
        # FIXME: This needs CSRF protection.

        session_id = self.session.ui.html_variables.get('http_session')
        if self.args and not session_id:
            session_id = self.args[0]

        if session_id:
            try:
                self.session.ui.debug('Logging out %s' % session_id)
                del SESSION_CACHE[session_id]
                return self._success(_('Goodbye!'))
            except KeyError:
                pass

        return self._error(_('No session found!'))


plugin_manager = PluginManager(builtin=True)
plugin_manager.register_commands(Authenticate, DeAuthenticate)
Exemple #9
0
import os
from gettext import gettext as _
from datetime import date

from mailpile.plugins import PluginManager
from mailpile.plugins import __all__ as PLUGINS
from mailpile.commands import Command
from mailpile.crypto.gpgi import GnuPG, SignatureInfo, EncryptionInfo
from mailpile.util import *
from mailpile.plugins.migrate import Migrate

from mailpile.plugins.tags import AddTag, Filter

_plugins = PluginManager(builtin=__file__)

##[ Commands ]################################################################


class Setup(Command):
    """Perform initial setup"""
    SYNOPSIS = (None, 'setup', None, None)
    ORDER = ('Internals', 0)
    LOG_PROGRESS = True

    TAGS = {
        'New': {
            'type': 'unread',
            'label': False,
            'display': 'invisible',
            'icon': 'icon-new',
            'label_color': '03-gray-dark',
Exemple #10
0
#coding:utf-8
import os

import mailpile.security as security
from mailpile.commands import Command
from mailpile.eventlog import GetThreadEvent
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.crypto.gpgi import GnuPG
from mailpile.vcard import *


_plugins = PluginManager(builtin=__file__)


# User default GnuPG key file
DEF_GNUPG_HOME = os.path.expanduser('~/.gnupg')


class GnuPGImporter(VCardImporter):
    FORMAT_NAME = 'GnuPG'
    FORMAT_DESCRIPTION = _('Import contacts from GnuPG keyring')
    SHORT_NAME = 'gpg'
    CONFIG_RULES = {
        'active': [_('Enable this importer'), bool, True],
        'gpg_home': [_('Location of keyring'), 'path', DEF_GNUPG_HOME],
    }
    VCL_KEY_FMT = 'data:application/x-pgp-fingerprint,%s'

    # Merge by own identifier, email or key (in that order)
Exemple #11
0
from mailpile.crypto.gpgi import GnuPG
from mailpile.crypto.gpgi import OpenPGPMimeSigningWrapper
from mailpile.crypto.gpgi import OpenPGPMimeEncryptingWrapper
from mailpile.crypto.gpgi import OpenPGPMimeSignEncryptWrapper
from mailpile.crypto.mime import UnwrapMimeCrypto, MessageAsString
from mailpile.crypto.mime import OBSCURE_HEADERS_MILD, OBSCURE_HEADERS_EXTREME
from mailpile.crypto.mime import ObscureSubject
from mailpile.crypto.state import EncryptionInfo, SignatureInfo
from mailpile.eventlog import GetThreadEvent
from mailpile.mailutils.addresses import AddressHeaderParser
from mailpile.mailutils.emails import Email, MakeContentID, ClearParseCache
from mailpile.plugins import PluginManager, EmailTransform
from mailpile.plugins.vcard_gnupg import PGPKeysImportAsVCards
from mailpile.plugins.search import Search

_plugins = PluginManager(builtin=__file__)


##[ GnuPG e-mail processing ]#################################################

class ContentTxf(EmailTransform):
    def _wrap_key_in_html(self, title, keydata):
        return ((
            "<html><head><meta charset='utf-8'></head><body>\n"
            "<h1>%(title)s</h1><p>\n\n%(description)s\n\n</p>"
            "<pre>\n%(key)s\n</pre><hr>"
            "<i><a href='%(ad_url)s'>%(ad)s</a>.</i></body></html>"
            ) % self._wrap_key_in_html_vars(title, keydata)).encode('utf-8')

    def _wrap_key_in_html_vars(self, title, keydata):
        return {
Exemple #12
0
import mailbox
import os
import time
from gettext import gettext as _

import mailpile.config
from mailpile.plugins import PluginManager
from mailpile.util import *
from mailpile.commands import Command
from mailpile.mailutils import Email

_plugins = PluginManager(builtin=os.path.basename(__file__)[:-3])

##[ Configuration ]###########################################################

MAILBOX_FORMATS = ('mbox', 'maildir')

_plugins.register_config_variables(
    'prefs', {
        'export_format':
        ['Default format for exporting mail', MAILBOX_FORMATS, 'mbox'],
    })

##[ Commands ]################################################################


class ExportMail(Command):
    """Export messages to an external mailbox"""
    SYNOPSIS = (None, 'export', None, '<msgs> [flat] [<fmt>:<path>]')
    ORDER = ('Searching', 99)
Exemple #13
0
import time

from mailpile.commands import Command
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.util import *


_plugins = PluginManager(builtin=__file__)


class Events(Command):
    """Display events from the event log"""
    SYNOPSIS = (None, 'eventlog', 'eventlog',
                '[incomplete] [wait] [<count>] [<field>=<val> ...]')
    ORDER = ('Internals', 9)
    HTTP_CALLABLE = ('GET', )
    HTTP_QUERY_VARS = {
        'wait': 'seconds to wait for new data',
        'incomplete': 'incomplete events only?',
        # Filtering by event attributes
        'event_id': 'an event ID',
        'flag': 'require a flag',
        'flags': 'match all flags',
        'since': 'wait for new data?',
        'source': 'source class',
        # Filtering by event data (syntax is a bit weird)
        'data': 'var:value',
        'private_data': 'var:value'
    }
Exemple #14
0
import datetime
import re
import time

from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.commands import Command
from mailpile.plugins.search import Search
from mailpile.mailutils import Email

_plugins = PluginManager(builtin=__file__)


class GPGKeySearch(Command):
    """Search for a GPG Key."""
    ORDER = ('', 0)
    SYNOPSIS = (None, 'crypto/gpg/searchkey', 'crypto/gpg/searchkey',
                '<terms>')
    HTTP_CALLABLE = ('GET', )
    HTTP_QUERY_VARS = {'q': 'search terms'}

    class CommandResult(Command.CommandResult):
        def as_text(self):
            if self.result:
                return '\n'.join([
                    "%s: %s <%s>" % (keyid, x["name"], x["email"])
                    for keyid, det in self.result.iteritems()
                    for x in det["uids"]
                ])
            else:
Exemple #15
0
import random
import time

from mailpile.plugins import PluginManager
from mailpile.commands import Command, Action
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.mailutils import Email, ExtractEmails, ExtractEmailAndName
from mailpile.mailutils import AddressHeaderParser
from mailpile.vcard import VCardLine, VCardStore, MailpileVCard, AddressInfo
from mailpile.util import *

_plugins = PluginManager(builtin=__file__)

##[ VCards ]########################################


class VCardCommand(Command):
    VCARD = "vcard"
    IS_USER_ACTIVITY = True

    class CommandResult(Command.CommandResult):
        IGNORE = ('line_id', 'pid', 'x-rank')

        def as_text(self):
            try:
                return self._as_text()
            except (KeyError, ValueError, IndexError, TypeError):
                return ''

        def _as_text(self):
Exemple #16
0
from mailpile.plugins.contacts import ListProfiles
from mailpile.plugins.migrate import Migrate
from mailpile.plugins.tags import AddTag
from mailpile.commands import Command
from mailpile.config import SecurePassphraseStorage
from mailpile.crypto.gpgi import GnuPG, SignatureInfo, EncryptionInfo
from mailpile.crypto.gpgi import GnuPGKeyGenerator, GnuPGKeyEditor
from mailpile.httpd import BLOCK_HTTPD_LOCK, Idle_HTTPD
from mailpile.smtp_client import SendMail, SendMailError
from mailpile.urlmap import UrlMap
from mailpile.ui import Session
from mailpile.util import *


_ = lambda s: s
_plugins = PluginManager(builtin=__file__)


##[ Commands ]################################################################

class SetupMagic(Command):
    """Perform initial setup"""
    SYNOPSIS = (None, None, None, None)
    ORDER = ('Internals', 0)
    LOG_PROGRESS = True

    TAGS = {
        'New': {
            'type': 'unread',
            'label': False,
            'display': 'invisible',
Exemple #17
0
from mailpile.commands import Command
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.plugins.tags import AddTag, DeleteTag, Filter
from mailpile.plugins.contacts import *


_plugins = PluginManager(builtin=__file__)


##[ Search terms ]############################################################

def search(config, idx, term, hits):
    group = config._vcards.get(term.split(':', 1)[1])
    rt, emails = [], []
    if group and group.kind == 'group':
        for email, attrs in group.get('EMAIL', []):
            group = config._vcards.get(email.lower(), None)
            if group:
                emails.extend([e[0].lower() for e in group.get('EMAIL', [])])
            else:
                emails.append(email.lower())
    fromto = term.startswith('group:') and 'from' or 'to'
    for email in set(emails):
        rt.extend(hits('{0!s}:{1!s}'.format(email, fromto)))
    return rt

_plugins.register_search_term('group', search)
_plugins.register_search_term('togroup', search)
Exemple #18
0
            try:
                from markdown import markdown
                html = markdown(str(self.result['urlmap']))
            except:
                import traceback
                print traceback.format_exc()
                html = '<pre>%s</pre>' % escape_html(self.result['urlmap'])
            self.result['markdown'] = html
            return Command.CommandResult.as_html(self, *args, **kwargs)

    def command(self):
        prefix = self.args[0] if self.args else None
        return {'urlmap': UrlMap(self.session).map_as_markdown(prefix=prefix)}


plugin_manager = PluginManager(builtin=True)
if __name__ != "__main__":
    plugin_manager.register_commands(HelpUrlMap, UrlRedirect,
                                     UrlRedirectEdit, UrlRedirectThread)

else:
    # If run as a python script, print map and run doctests.
    import doctest
    import sys
    import mailpile.app
    import mailpile.config.defaults as defaults
    import mailpile.config.manager as cfg_manager
    import mailpile.plugins
    import mailpile.ui

    # Import all the default plugins
Exemple #19
0
import time

import mailpile.util
import mailpile.security as security
from mailpile.commands import Command
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.util import *

_plugins = PluginManager(builtin=__file__)


class Events(Command):
    """Display events from the event log"""
    SYNOPSIS = (None, 'eventlog', 'eventlog', '[incomplete] [wait] [<count>] '
                '[<field>=<val> <f>!=<v> <f>=~<re> ...]')
    ORDER = ('Internals', 9)
    HTTP_CALLABLE = ('GET', )
    HTTP_QUERY_VARS = {
        'wait': 'seconds to wait for new data',
        'gather': 'gather time (minimum wait), seconds',
        'incomplete': 'incomplete events only?',
        # Filtering by event attributes
        'event_id': 'an event ID',
        'flag': 'require a flag',
        'flags': 'match all flags',
        'since': 'wait for new data?',
        'source': 'source class',
        # Filtering by event data (syntax is a bit weird)
        'data': 'var:value',
Exemple #20
0
# which should allow us to actually introspect a bit into the behavior
# of the classifier.

import math
import time
import datetime

from mailpile.commands import Command
from mailpile.config.base import ConfigDict
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.mailutils import Email
from mailpile.plugins import PluginManager
from mailpile.util import *

_plugins = PluginManager(builtin=__file__)

##[ Configuration ]###########################################################

TAGGERS = {}
TRAINERS = {}

AUTO_TAG_CONFIG = {
    'match_tag': ['Tag we are adding to automatically', str, ''],
    'unsure_tag': ['If unsure, add to this tag', str, ''],
    'exclude_tags': ['Tags on messages we should never match (ham)', str, []],
    'ignore_kws': ['Ignore messages with these keywords', str, []],
    'corpus_size': ['How many messages do we train on?', int, 1200],
    'threshold': ['Size of the sure/unsure ranges', float, 0.1],
    'tagger': ['Internal class name or |shell command', str, ''],
    'trainer': ['Internal class name or |shell commant', str, '']
Exemple #21
0
import os
from gettext import gettext as _

import mailpile.commands
from mailpile.plugins import PluginManager


_plugins = PluginManager(builtin=__file__)


class Plugins(mailpile.commands.Command):
    """List the currently available plugins."""
    SYNOPSIS = (None, 'plugins', 'plugins', '[<plugins>]')
    ORDER = ('Config', 9)

    def command(self):
        pm = self.session.config.plugins
        wanted = self.args

        info = dict((d, {
            'loaded': d in pm.LOADED,
            'builtin': d not in pm.DISCOVERED
        }) for d in pm.available() if (not wanted or d in wanted))

        for plugin in info:
            if plugin in pm.DISCOVERED:
                info[plugin]['manifest'] = pm.DISCOVERED[plugin][1]

        return self._success(_('Listed available plugins'), info)

Exemple #22
0
from mailpile.crypto.gpgi import GnuPG
from mailpile.crypto.gpgi import OpenPGPMimeSigningWrapper
from mailpile.crypto.gpgi import OpenPGPMimeEncryptingWrapper
from mailpile.crypto.gpgi import OpenPGPMimeSignEncryptWrapper
from mailpile.crypto.mime import UnwrapMimeCrypto, MessageAsString
from mailpile.crypto.state import EncryptionInfo, SignatureInfo
from mailpile.eventlog import GetThreadEvent
from mailpile.mailutils.emails import Email, ExtractEmails, ClearParseCache
from mailpile.mailutils.emails import MakeContentID
from mailpile.plugins import PluginManager, EmailTransform
from mailpile.plugins.vcard_gnupg import PGPKeysImportAsVCards
from mailpile.plugins.search import Search
from mailpile.plugins.keylookup.email_keylookup import get_pgp_key_keywords
from mailpile.util import sha1b64

_plugins = PluginManager(builtin=__file__)

##[ Misc. AutoCrypt-related API commands ]####################################


# FIXME: This really should be a record store, not an in-memory dict
def save_AutoCrypt_DB(config):
    if config.autocrypt_db:
        config.save_pickle(config.autocrypt_db, 'autocrypt_db')


def get_AutoCrypt_DB(config):
    if not config.real_hasattr('autocrypt_db'):
        try:
            db = config.load_pickle('autocrypt_db')
        except (IOError, EOFError):
Exemple #23
0
from gettext import gettext as _

import mailpile.config
from mailpile.plugins import PluginManager
from mailpile.commands import Command
from mailpile.util import *
from mailpile.mail_source.mbox import MboxMailSource
from mailpile.mail_source.maildir import MaildirMailSource

_plugins = PluginManager(builtin=__file__)

# We might want to do this differently at some point, but
# for now it's fine.


def migrate_routes(session):
    # Migration from route string to messageroute structure
    def route_parse(route):
        if route.startswith('|'):
            command = route[1:].strip()
            return {
                "name": command.split()[0],
                "protocol": "local",
                "command": command
            }
        else:
            res = re.split(
                "([\w]+)://([^:]+):([^@]+)@([\w\d.]+):([\d]+)[/]{0,1}", route)
            if len(res) >= 5:
                return {
                    "name": _("%(user)s on %(host)s") % {
Exemple #24
0
import mailpile.security as security
from mailpile.commands import Command
from mailpile.config.defaults import APPVER
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.mail_source.local import LocalMailSource
from mailpile.plugins import PluginManager
from mailpile.util import *
from mailpile.vcard import *


_plugins = PluginManager(builtin=__file__)

# We might want to do this differently at some point, but
# for now it's fine.


def migrate_routes(session):
    # Migration from route string to messageroute structure
    def route_parse(route):
        if route.startswith('|'):
            command = route[1:].strip()
            return {
                "name": command.split()[0],
                "protocol": "local",
                "command": command
            }
        else:
            res = re.split(
                "([\w]+)://([^:]+):([^@]+)@([\w\d.]+):([\d]+)[/]{0,1}", route)
            if len(res) >= 5:
Exemple #25
0
import sys
from datetime import datetime as dtime
from urllib2 import urlopen

from mailpile.commands import Command
from mailpile.config.base import PublicConfigRule as p
from mailpile.config.defaults import APPVER
from mailpile.conn_brokers import Master as ConnBroker
from mailpile.plugins import PluginManager
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.util import *


_ = lambda t: t
_plugins = PluginManager(builtin=__file__)


# MARS is the Mailpile Analytics Reporting System. Pretty fancy, huh?
#
# Details:
#  https://github.com/mailpile/Mailpile/wiki/Mailpile-Analytics-Reporting-System
#
MOTD_MARS    = '/motd/%(ver)s-%(os)s/motd.json?lang=%(lang)s&py=%(py)s'
MOTD_NO_MARS = '/motd/latest/motd.json'
#
MOTD_URL_DEFAULT          = 'https://www.mailpile.is' + MOTD_MARS
MOTD_URL_TOR_ONLY         = 'http://clgs64523yi2bkhz.onion' + MOTD_MARS
MOTD_URL_NO_MARS          = 'https://www.mailpile.is' + MOTD_NO_MARS
MOTD_URL_TOR_ONLY_NO_MARS = 'http://clgs64523yi2bkhz.onion' + MOTD_NO_MARS
MOTD_URLS = {
Exemple #26
0
from mailpile.commands import Command
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.plugins.tags import AddTag, DeleteTag, Filter
from mailpile.plugins.contacts import *

_plugins = PluginManager(builtin=__file__)

##[ Search terms ]############################################################


def search(config, idx, term, hits):
    group = config._vcards.get(term.split(':', 1)[1])
    rt, emails = [], []
    if group and group.kind == 'group':
        for email, attrs in group.get('EMAIL', []):
            group = config._vcards.get(email.lower(), None)
            if group:
                emails.extend([e[0].lower() for e in group.get('EMAIL', [])])
            else:
                emails.append(email.lower())
    fromto = term.startswith('group:') and 'from' or 'to'
    for email in set(emails):
        rt.extend(hits('%s:%s' % (email, fromto)))
    return rt


_plugins.register_search_term('group', search)
_plugins.register_search_term('togroup', search)
Exemple #27
0
#
from urllib2 import urlopen, HTTPError

import mailpile.security as security
from mailpile.commands import Command
from mailpile.conn_brokers import Master as ConnBroker
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.plugins.core import RenderPage
from mailpile.ui import SuppressHtmlOutput
from mailpile.urlmap import UrlMap
from mailpile.util import *


_plugins = PluginManager(builtin=__file__)


##[ Commands ]################################################################

class JsApi(RenderPage):
    """Output API bindings, plugin code and CSS as CSS or Javascript"""
    SYNOPSIS = (None, None, 'jsapi', None)
    ORDER = ('Internals', 0)
    HTTP_CALLABLE = ('GET', )
    HTTP_AUTH_REQUIRED = 'Maybe'
    HTTP_QUERY_VARS = {'ts': 'Cache busting timestamp'}

    def max_age(self):
        # Set a long TTL if we know which version of the config this request
        # applies to, as changed config should avoid the outdated cache.
Exemple #28
0
#coding:utf-8
import os
import random
import time
from gettext import gettext as _
from urllib2 import urlopen

import mailpile.util
from mailpile.plugins import PluginManager
from mailpile.util import *
from mailpile.vcard import *

_plugins = PluginManager(builtin=__file__)


class GravatarImporter(VCardImporter):
    """
    This importer will pull contact details down from a central server,
    using the Gravatar JSON API and caching thumbnail data locally.

    For details, see https://secure.gravatar.com/site/implement/

    The importer will only pull down a few contacts at a time, to limit
    the impact on Gravatar's servers and prevent network traffic from
    stalling the rescan process too much.
    """
    FORMAT_NAME = 'Gravatar'
    FORMAT_DESCRIPTION = _('Import contact info from a Gravatar server')
    SHORT_NAME = 'gravatar'
    CONFIG_RULES = {
        'active': [_('Enable this importer'), bool, True],
Exemple #29
0
from datetime import datetime, timedelta

import mailpile.security as security
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.vcard import VCardLine, AddressInfo
from mailpile.commands import Command
from mailpile.mailutils.emails import Email


_plugins = PluginManager(builtin=__file__)


VCARD_CRYPTO_POLICY = 'X-MAILPILE-CRYPTO-POLICY'
CRYPTO_POLICIES = ['none', 'sign', 'encrypt', 'sign-encrypt',
                   'best-effort', 'default']


##[ Commands ]################################################################

class CryptoPolicyBaseAction(Command):
    """ Base class for crypto policy commands """
    pass


class UpdateCryptoPolicyForUser(CryptoPolicyBaseAction):
    """ Update crypto policy for a single user """
    SYNOPSIS = (None, 'crypto_policy/set', 'crypto_policy/set',
                '<email address> none|sign|encrypt|sign-encrypt|default')
    ORDER = ('Internals', 9)
Exemple #30
0
# which should allow us to actually introspect a bit into the behavior
# of the classifier.

import math
import time
import datetime

import mailpile.config
from mailpile.commands import Command
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.mailutils import Email
from mailpile.plugins import PluginManager
from mailpile.util import *

_plugins = PluginManager(builtin=__file__)

##[ Configuration ]###########################################################

TAGGERS = {}
TRAINERS = {}

_plugins.register_config_section('prefs', 'autotag', [
    "Auto-tagging", {
        'match_tag': ['Tag we are adding to automatically', str, ''],
        'unsure_tag': ['If unsure, add to this tag', str, ''],
        'exclude_tags':
        ['Tags on messages we should never match (ham)', str, []],
        'ignore_kws': ['Ignore messages with these keywords', str, []],
        'corpus_size': ['How many messages do we train on?', int, 1200],
        'threshold': ['Size of the sure/unsure ranges', float, 0.1],
Exemple #31
0
        if self.data.get('_method', None) == 'POST':
            password = self.data.get('password', [None])[0]
        else:
            password = self.session.ui.get_password(
                _('Enter your password:'******' ')

        if policy == 'store':
            if fingerprint in config.passphrases:
                del config.passphrases[fingerprint]
            config.secrets[fingerprint] = {
                'password': password,
                'policy': policy
            }
            return happy(_('Password stored permanently'))

        elif policy == 'cache-only' and password:
            sps = SecurePassphraseStorage(password)
            if ttl > 0:
                sps.expiration = time.time() + ttl
            config.passphrases[fingerprint] = sps
            if fingerprint.lower() in config.secrets:
                del config.secrets[fingerprint.lower()]
            return happy(_('Password stored temporarily'))

        else:
            return self._error(_('Invalid password policy!'), result)


plugin_manager = PluginManager(builtin=True)
plugin_manager.register_commands(Authenticate, DeAuthenticate, SetPassphrase)
Exemple #32
0
import math
import time
import datetime

from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager


_plugins = PluginManager(builtin=__file__)


##[ Keywords ]################################################################


def meta_kw_extractor(index, msg_mid, msg, msg_size, msg_ts, **kwargs):
    """Create a search term with the floored log2 size of the message."""
    if msg_size <= 0:
        return []
    return ["%s:ln2sz" % int(math.log(msg_size, 2))]


_plugins.register_meta_kw_extractor("sizes", meta_kw_extractor)


##[ Search terms ]############################################################


_size_units = {"t": 40, "g": 30, "m": 20, "k": 10, "b": 0}
_range_keywords = ["..", "-"]
Exemple #33
0
import mailbox
import os
import time
from gettext import gettext as _

import mailpile.config
from mailpile.plugins import PluginManager
from mailpile.util import *
from mailpile.commands import Command
from mailpile.mailutils import Email


_plugins = PluginManager(builtin=True)


##[ Configuration ]###########################################################

MAILBOX_FORMATS = ('mbox', 'maildir')

_plugins.register_config_variables('prefs', {
    'export_format': ['Default format for exporting mail',
                      MAILBOX_FORMATS, 'mbox'],
})


##[ Commands ]################################################################

class ExportMail(Command):
    """Export messages to an external mailbox"""
    SYNOPSIS = (None, 'export', None, '<msgs> [flat] [<fmt>:<path>]')
    ORDER = ('Searching', 99)
Exemple #34
0
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.crypto.state import EncryptionInfo, SignatureInfo


_plugins = PluginManager(builtin=__file__)


##[ Keywords ]################################################################

def text_kw_extractor(index, msg, ctype, text):
    kw = set()
    if ('-----BEGIN PGP' in text and '\n-----END PGP' in text):
        kw.add('pgp:has')
        kw.add('crypto:has')
    return kw


def meta_kw_extractor(index, msg_mid, msg, msg_size, msg_ts):
    kw, enc, sig = set(), set(), set()
    def crypto_eval(part):
        # This is generic
        if part.encryption_info.get('status') != 'none':
            enc.add('mp_%s-%s' % ('enc', part.encryption_info['status']))
            kw.add('crypto:has')
        if part.signature_info.get('status') != 'none':
            sig.add('mp_%s-%s' % ('sig', part.signature_info['status']))
            kw.add('crypto:has')
        if 'cryptostate' in index.config.sys.debug:
            print 'part status(=%s): enc=%s sig=%s' % (msg_mid,
Exemple #35
0
        else:
            password = self.session.ui.get_password(_('Enter your password:'******' ')

        if policy == 'store':
            if fingerprint in config.passphrases:
                del config.passphrases[fingerprint]
            config.secrets[fingerprint] = {
                'password': password,
                'policy': policy
            }
            return happy(_('Password stored permanently'))

        elif policy == 'cache-only' and password:
            from mailpile.config import SecurePassphraseStorage
            sps = SecurePassphraseStorage(password)
            sps.expiration = time.time() + float(ttl)
            config.passphrases[fingerprint] = sps
            if fingerprint.lower() in config.secrets:
                del config.secrets[fingerprint.lower()]
            return happy(_('Password stored temporarily'))

        else:
            return self._error(_('Invalid password policy!'), result)


plugin_manager = PluginManager(builtin=True)
plugin_manager.register_commands(Authenticate,
                                 DeAuthenticate,
                                 SetPassphrase)
Exemple #36
0
import datetime
import re
import time

from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.commands import Command
from mailpile.plugins.search import Search
from mailpile.mailutils import Email

_plugins = PluginManager(builtin=__file__)


class GPGKeySearch(Command):
    """Search for a GPG Key."""
    ORDER = ('', 0)
    SYNOPSIS = (None, 'crypto/gpg/searchkey', 'crypto/gpg/searchkey', '<terms>')
    HTTP_CALLABLE = ('GET', )
    HTTP_QUERY_VARS = {'q': 'search terms'}

    class CommandResult(Command.CommandResult):
        def as_text(self):
            if self.result:
                return '\n'.join(["%s: %s <%s>" % (keyid, x["name"], x["email"]) for keyid, det in self.result.iteritems() for x in det["uids"]])
            else:
                return _("No results")

    def command(self):
        args = list(self.args)
        for q in self.data.get('q', []):
Exemple #37
0
import locale
import os
import sys

import mailpile.util
import mailpile.defaults
from mailpile.commands import COMMANDS, Command, Action
from mailpile.commands import Help, HelpSplash, Load, Rescan
from mailpile.config import ConfigManager
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.ui import ANSIColors, Session, UserInteraction, Completer
from mailpile.util import *

_plugins = PluginManager(builtin=__file__)

# This makes sure mailbox "plugins" get loaded... has to go somewhere?
from mailpile.mailboxes import *

# This is also a bit silly, should be somewhere else?
Help.ABOUT = mailpile.defaults.ABOUT

# We may try to load readline later on... maybe?
readline = None


##[ Main ]####################################################################


def Interact(session):
Exemple #38
0
#
from urllib2 import urlopen, HTTPError

import mailpile.security as security
from mailpile.commands import Command
from mailpile.conn_brokers import Master as ConnBroker
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.plugins.core import RenderPage
from mailpile.ui import SuppressHtmlOutput
from mailpile.urlmap import UrlMap
from mailpile.util import *


_plugins = PluginManager(builtin=__file__)


##[ Commands ]################################################################

class JsApi(RenderPage):
    """Output API bindings, plugin code and CSS as CSS or Javascript"""
    SYNOPSIS = (None, None, 'jsapi', None)
    ORDER = ('Internals', 0)
    HTTP_CALLABLE = ('GET', )
    HTTP_AUTH_REQUIRED = 'Maybe'
    HTTP_QUERY_VARS = {'ts': 'Cache busting timestamp'}

    def max_age(self):
        # Set a long TTL if we know which version of the config this request
        # applies to, as changed config should avoid the outdated cache.
Exemple #39
0
            sock  = org_sslwrap(sock, *args, **kwargs)
            Master.get_fd_context(
                sock.fileno()).encryption = _explain_encryption(sock)
        return sock

    ssl.wrap_socket = SslWrapOnlyOnce

    if have_ssl_context:
        # Same again with SSLContext, if we have it.

        def SslContextWrapOnlyOnce(self, sock, *args, **kwargs):
            if not isinstance(sock, ssl.SSLSocket):
                sock = org_context_wrap_socket(self, sock, *args, **kwargs)
                Master.get_fd_context(
                    sock.fileno()).encryption = _explain_encryption(sock)
            return sock

        ssl.SSLContext.wrap_socket = SslContextWrapOnlyOnce

    from mailpile.plugins import PluginManager
    _plugins = PluginManager(builtin=__file__)
    _plugins.register_commands(NetworkHistory)
else:
    import doctest
    import sys
    results = doctest.testmod(optionflags=doctest.ELLIPSIS,
                              extraglobs={})
    print '%s' % (results, )
    if results.failed:
        sys.exit(1)
from mailpile.i18n import ngettext as _n
from mailpile.commands import Command
from mailpile.crypto.gpgi import GnuPG
from mailpile.crypto.gpgi import OpenPGPMimeSigningWrapper
from mailpile.crypto.gpgi import OpenPGPMimeEncryptingWrapper
from mailpile.crypto.gpgi import OpenPGPMimeSignEncryptWrapper
from mailpile.crypto.mime import UnwrapMimeCrypto, MessageAsString
from mailpile.crypto.state import EncryptionInfo, SignatureInfo
from mailpile.eventlog import GetThreadEvent
from mailpile.mailutils import Email, ExtractEmails, ClearParseCache
from mailpile.mailutils import MakeContentID
from mailpile.plugins import PluginManager, EmailTransform
from mailpile.plugins.vcard_gnupg import PGPKeysImportAsVCards
from mailpile.plugins.search import Search

_plugins = PluginManager(builtin=__file__)

##[ GnuPG e-mail processing ]#################################################


class ContentTxf(EmailTransform):
    def TransformOutgoing(self, sender, rcpts, msg, **kwargs):
        matched = False
        gnupg = None
        sender_keyid = None

        # Prefer to just get everything from the profile VCard, in the
        # common case...
        profile = self.config.vcards.get_vcard(sender)
        if profile:
            sender_keyid = profile.pgp_key
Exemple #41
0
#coding:utf-8
import random
import time
from urllib2 import urlopen

import mailpile.util
from mailpile.conn_brokers import Master as ConnBroker
from mailpile.i18n import gettext as _
from mailpile.plugins import PluginManager
from mailpile.vcard import VCardImporter, MailpileVCard, VCardLine


_plugins = PluginManager(builtin=__file__)


class LibravatarImporter(VCardImporter):
    """
    This importer will pull contact details down from a central server,
    using the Libravatar JSON API and caching thumbnail data locally.

    For details, see https://wiki.libravatar.org/api/

    The importer will only pull down a few contacts at a time, to limit
    the impact on Libravatar's servers and prevent network traffic from
    stalling the rescan process too much.
    """
    FORMAT_NAME = 'Libravatar'
    FORMAT_DESCRIPTION = _('Import contact info from a Libravatar server')
    SHORT_NAME = 'libravatar'
    CONFIG_RULES = {
        'active': [_('Enable this importer'), bool, True],
Exemple #42
0
from mailpile.auth import VerifyAndStorePassphrase
from mailpile.config.defaults import APPVER
from mailpile.commands import Command
from mailpile.crypto.streamer import EncryptingStreamer, DecryptingStreamer
from mailpile.plugins import PluginManager
from mailpile.plugins.core import Quit
from mailpile.i18n import ActivateTranslation
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.ui import SuppressHtmlOutput
from mailpile.util import *
from mailpile.vfs import FilePath, vfs

_ = lambda t: t
_plugins = PluginManager(builtin=__file__)


def _gzip(filename, data):
    gzip_data = cStringIO.StringIO()
    gzip_obj = gzip.GzipFile(filename, 'w', 9, gzip_data, 0)
    gzip_obj.write(data)
    gzip_obj.close()
    return gzip_data.getvalue()


def _gunzip(data):
    with gzip.GzipFile('', 'rb', 0, cStringIO.StringIO(data)) as gzf:
        return gzf.read()

Exemple #43
0
import socket
import threading
import time

import mailpile.auth
import mailpile.util
from mailpile.conn_brokers import Master as ConnBroker
from mailpile.commands import Command
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.ui import Session
from mailpile.util import *


_plugins = PluginManager(builtin=__file__)
_GUIS = {}


def UpdateGUIState():
    for gui in _GUIS.values():
        gui.change_state()


def GetUserSecret(config):
    """Return a secret that only this Unix user could know."""
    return 'FIXME12345'


class GuiOMaticConnection(threading.Thread):
    def __init__(self, config, sock, main=False):
Exemple #44
0
 def _get_ui_elements(self, ui_type, state, context=None):
     self._debug('get_ui_element(%s, %s, ...)' % (ui_type, state))
     ctx = context or state.get('context_url', '')
     return copy.deepcopy(PluginManager().get_ui_elements(ui_type, ctx))
Exemple #45
0
import mailpile.config
import mailpile.security as security
from mailpile.commands import Command
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.urlmap import UrlMap
from mailpile.util import *

from mailpile.plugins.search import Search

_plugins = PluginManager(builtin=__file__)

##[ Configuration ]###########################################################

FILTER_TYPES = (
    'user',  # These are the default, user-created filters
    'incoming',  # These filters are only applied to new messages
    'system',  # Mailpile core internal filters
    'plugin')  # Filters created by plugins

_plugins.register_config_section(
    'tags',
    [
        "Tags",
        {
            'name': ['Tag name', 'str', ''],
            'slug': ['URL slug', 'slashslug', ''],

            # Functional attributes
            'type': [
Exemple #46
0
import threading
import traceback

import mailpile.config
import mailpile.security as security
from mailpile.commands import Command
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.mailutils import Email
from mailpile.plugins import PluginManager
from mailpile.smtp_client import sha512_512kCheck, sha512_512kCollide
from mailpile.smtp_client import SMTORP_HASHCASH_RCODE, SMTORP_HASHCASH_FORMAT
from mailpile.util import *


_plugins = PluginManager(builtin=__file__)


##[ Configuration ]##########################################################

_plugins.register_config_section(
    'sys', 'smtpd', [_('SMTP Daemon'), False, {
        'host': (_('Listening host for SMTP daemon'), 'hostname', 'localhost'),
        'port': (_('Listening port for SMTP daemon'), int, 0),
    }])


class SMTPChannel(smtpd.SMTPChannel):
    MAX_MESSAGE_SIZE = 1024 * 1024 * 50
    HASHCASH_WANT_BITS = 8  # Only 128-or-so expensive sha512_512k ops
    HASHCASH_URL = 'https://www.mailpile.is/hashcash/'
Exemple #47
0
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.plugins.tags import Tag
from mailpile.mailutils import ExtractEmails, ExtractEmailAndName, Email
from mailpile.mailutils import NotEditableError, AddressHeaderParser
from mailpile.mailutils import NoFromAddressError, PrepareMessage
from mailpile.smtp_client import SendMail
from mailpile.search import MailIndex
from mailpile.urlmap import UrlMap
from mailpile.util import *
from mailpile.vcard import AddressInfo

from mailpile.plugins.search import Search, SearchResults, View

_plugins = PluginManager(builtin=__file__)


class EditableSearchResults(SearchResults):
    def __init__(self, session, idx, new, sent, **kwargs):
        SearchResults.__init__(self, session, idx, **kwargs)
        self.new_messages = new
        self.sent_messages = sent
        if new:
            self['created'] = [m.msg_mid() for m in new]
        if sent:
            self['sent'] = [m.msg_mid() for m in new]
            self['summary'] = _('Sent: %s') % self['summary']


def AddComposeMethods(cls):
Exemple #48
0
            PGPKeysImportAsVCards(self.session, arg=fingerprints).run()
            # Previous crypto evaluations may now be out of date, so we
            # clear the cache so users can see results right away.
            ClearParseCache(pgpmime=True)

        # i18n note: Not translating things here, since messages are not
        #            generally use-facing and we want to reduce load on our
        #            translators.
        return self._success('Evaluated key TOFU', result={
            'missing_keys': missing,
            'imported_keys': imported,
            'status': status,
            'on_keychain': old})


PluginManager(builtin=__file__).register_commands(
    KeyLookup, KeyImport, KeyTofu)


##[ Basic lookup handlers ]###################################################

class LookupHandler:
    NAME = "NONE"
    TIMEOUT = 2
    PRIORITY = 10000
    LOCAL = False

    def __init__(self, session, known_keys_list):
        self.session = session
        self.known_keys = known_keys_list

    def _gnupg(self):
Exemple #49
0
from mailpile.mailutils import ExtractEmails, ExtractEmailAndName, Email
from mailpile.mailutils import NotEditableError, AddressHeaderParser
from mailpile.mailutils import NoFromAddressError, PrepareMessage
from mailpile.mailutils import MakeMessageID
from mailpile.search import MailIndex
from mailpile.smtp_client import SendMail
from mailpile.urlmap import UrlMap
from mailpile.util import *
from mailpile.vcard import AddressInfo

from mailpile.plugins.search import Search, SearchResults, View


GLOBAL_EDITING_LOCK = MboxRLock()

_plugins = PluginManager(builtin=__file__)


class EditableSearchResults(SearchResults):
    def __init__(self, session, idx, new, sent, **kwargs):
        SearchResults.__init__(self, session, idx, **kwargs)
        self.new_messages = new
        self.sent_messages = sent
        if new:
            self['created'] = [m.msg_mid() for m in new]
        if sent:
            self['sent'] = [m.msg_mid() for m in new]
            self['summary'] = _('Sent: %s') % self['summary']


def AddComposeMethods(cls):
Exemple #50
0
import mailpile.util
import mailpile.config.defaults
from mailpile.commands import COMMANDS, Command, Action
from mailpile.config.manager import ConfigManager
from mailpile.conn_brokers import DisableUnbrokeredConnections
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.plugins.core import Help, HelpSplash, HealthCheck
from mailpile.plugins.core import Load, Rescan, Quit
from mailpile.plugins.motd import MessageOfTheDay
from mailpile.ui import ANSIColors, Session, UserInteraction, Completer
from mailpile.util import *

_plugins = PluginManager(builtin=__file__)

# This makes sure mailbox "plugins" get loaded... has to go somewhere?
from mailpile.mailboxes import *

# This is also a bit silly, should be somewhere else?
Help.ABOUT = mailpile.config.defaults.ABOUT

# We may try to load readline later on... maybe?
readline = None

##[ Main ]####################################################################


def CatchUnixSignals(session):
    def quit_app(sig, stack):
Exemple #51
0
import random
import time
from gettext import gettext as _

from mailpile.plugins import PluginManager
from mailpile.commands import Command, Action
from mailpile.mailutils import Email, ExtractEmails, ExtractEmailAndName
from mailpile.mailutils import AddressHeaderParser
from mailpile.vcard import VCardLine, VCardStore, MailpileVCard, AddressInfo
from mailpile.util import *


_plugins = PluginManager(builtin=__file__)


##[ VCards ]########################################

class VCardCommand(Command):
    VCARD = "vcard"
    IS_USER_ACTIVITY = True

    class CommandResult(Command.CommandResult):
        IGNORE = ('line_id', 'pid', 'x-rank')

        def as_text(self):
            try:
                return self._as_text()
            except (KeyError, ValueError, IndexError, TypeError):
                return ''

        def _as_text(self):
Exemple #52
0
import datetime
import re
import time
from gettext import gettext as _

from mailpile.commands import Command, SearchResults
from mailpile.mailutils import Email, MBX_ID_LEN
from mailpile.mailutils import ExtractEmails, ExtractEmailAndName
from mailpile.plugins import PluginManager
from mailpile.search import MailIndex
from mailpile.urlmap import UrlMap
from mailpile.util import *
from mailpile.ui import SuppressHtmlOutput


_plugins = PluginManager(builtin=__file__)


##[ Commands ]################################################################

class Search(Command):
    """Search your mail!"""
    SYNOPSIS = ('s', 'search', 'search', '[@<start>] <terms>')
    ORDER = ('Searching', 0)
    HTTP_CALLABLE = ('GET', )
    HTTP_QUERY_VARS = {
        'q': 'search terms',
        'qr': 'search refinements',
        'order': 'sort order',
        'start': 'start position',
        'end': 'end position',
Exemple #53
0
import os
import random
from gettext import gettext as _
from datetime import date

from mailpile.plugins import PluginManager
from mailpile.plugins import __all__ as PLUGINS
from mailpile.commands import Command
from mailpile.crypto.gpgi import GnuPG, SignatureInfo, EncryptionInfo
from mailpile.util import *
from mailpile.plugins.migrate import Migrate

from mailpile.plugins.tags import AddTag


_plugins = PluginManager(builtin=__file__)


##[ Commands ]################################################################

class Setup(Command):
    """Perform initial setup"""
    SYNOPSIS = (None, 'setup', None, None)
    ORDER = ('Internals', 0)
    LOG_PROGRESS = True

    TAGS = {
        'New': {
            'type': 'unread',
            'label': False,
            'display': 'invisible',
Exemple #54
0
from gettext import gettext as _

from mailpile.plugins import PluginManager
from mailpile.commands import Command, Action
from mailpile.mailutils import Email, ExtractEmails, ExtractEmailAndName
from mailpile.vcard import SimpleVCard, VCardLine, AddressInfo
from mailpile.util import *

_plugins = PluginManager(builtin=__file__)

##[ VCards ]########################################


class VCardCommand(Command):
    VCARD = "vcard"

    class CommandResult(Command.CommandResult):
        IGNORE = ('line_id', 'pid', 'x-rank')

        def as_text(self):
            try:
                return self._as_text()
            except (KeyError, ValueError, IndexError, TypeError):
                return ''

        def _as_text(self):
            if isinstance(self.result, dict):
                co = self.command_obj
                if co.VCARD in self.result:
                    return self._vcards_as_text([self.result[co.VCARD]])
                if co.VCARD + 's' in self.result:
Exemple #55
0
#coding:utf-8
import os

import mailpile.security as security
from mailpile.commands import Command
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.crypto.gpgi import GnuPG
from mailpile.vcard import *


_plugins = PluginManager(builtin=__file__)


# User default GnuPG key file
DEF_GNUPG_HOME = os.path.expanduser('~/.gnupg')


class GnuPGImporter(VCardImporter):
    FORMAT_NAME = 'GnuPG'
    FORMAT_DESCRIPTION = _('Import contacts from GnuPG keyring')
    SHORT_NAME = 'gpg'
    CONFIG_RULES = {
        'active': [_('Enable this importer'), bool, True],
        'gpg_home': [_('Location of keyring'), 'path', DEF_GNUPG_HOME],
    }
    VCL_KEY_FMT = 'data:application/x-pgp-fingerprint,%s'

    # Merge by own identifier, email or key (in that order)
    MERGE_BY = ['x-gpg-mrgid', 'email']
Exemple #56
0
from gettext import gettext as _

import mailpile.config
from mailpile.commands import Command
from mailpile.plugins import PluginManager
from mailpile.urlmap import UrlMap
from mailpile.util import *

from mailpile.plugins.search import Search


_plugins = PluginManager(builtin=__file__)


##[ Configuration ]###########################################################


FILTER_TYPES = ('user',      # These are the default, user-created filters
                'incoming',  # These filters are only applied to new messages
                'system',    # Mailpile core internal filters
                'plugin')    # Filters created by plugins

_plugins.register_config_section('tags', ["Tags", {
    'name': ['Tag name', 'str', ''],
    'slug': ['URL slug', 'slashslug', ''],

    # Functional attributes
    'type': ['Tag type', [
        'tag', 'group', 'attribute', 'unread',
        # Maybe TODO: 'folder', 'shadow',
        'drafts', 'blank', 'outbox', 'sent',          # composing and sending
import time
import copy
from pgpdump.utils import PgpdumpException

from mailpile.i18n import gettext
from mailpile.plugins import PluginManager
from mailpile.plugins.keylookup import LookupHandler
from mailpile.plugins.keylookup import register_crypto_key_lookup_handler
from mailpile.plugins.search import Search
from mailpile.mailutils import Email

import pgpdump


_ = lambda t: t
_plugins = PluginManager(builtin=__file__)


GLOBAL_KEY_CACHE = {}


def _PRUNE_GLOBAL_KEY_CACHE():
    global GLOBAL_KEY_CACHE
    for k in GLOBAL_KEY_CACHE.keys()[10:]:
        del GLOBAL_KEY_CACHE[k]


PGP_KEY_SUFFIXES = ('pub', 'asc', 'key', 'pgp')

def _might_be_pgp_key(filename, mimetype):
    filename = (filename or '').lower()
Exemple #58
0
# using the appropriate proxying policies.
#
from urllib2 import urlopen, HTTPError

import mailpile.security as security
from mailpile.commands import Command
from mailpile.conn_brokers import Master as ConnBroker
from mailpile.i18n import gettext as _
from mailpile.i18n import ngettext as _n
from mailpile.plugins import PluginManager
from mailpile.plugins.core import RenderPage
from mailpile.ui import SuppressHtmlOutput
from mailpile.urlmap import UrlMap
from mailpile.util import *

_plugins = PluginManager(builtin=__file__)

##[ Commands ]################################################################


class JsApi(RenderPage):
    """Output API bindings, plugin code and CSS as CSS or Javascript"""
    SYNOPSIS = (None, None, 'jsapi', None)
    ORDER = ('Internals', 0)
    HTTP_CALLABLE = ('GET', )
    HTTP_AUTH_REQUIRED = 'Maybe'
    HTTP_QUERY_VARS = {'ts': 'Cache busting timestamp'}

    def max_age(self):
        # Set a long TTL if we know which version of the config this request
        # applies to, as changed config should avoid the outdated cache.