From 8793c9168d196dde55d6dc35e3694c0dc4ab375f Mon Sep 17 00:00:00 2001 From: pazz Date: Sun, 24 Jul 2011 23:24:42 +0100 Subject: oop-idied settings --- alot/commandfactory.py | 6 +- alot/commands.py | 23 ++++--- alot/completion.py | 8 ++- alot/init.py | 11 ++-- alot/settings.py | 165 ++++++++++++++++++++++++++++--------------------- alot/ui.py | 13 ++-- 6 files changed, 128 insertions(+), 98 deletions(-) (limited to 'alot') diff --git a/alot/commandfactory.py b/alot/commandfactory.py index 80d321d0..9a6bb085 100644 --- a/alot/commandfactory.py +++ b/alot/commandfactory.py @@ -20,7 +20,7 @@ import logging import os -from settings import get_hook +from settings import hooks import commands COMMANDS = { @@ -68,8 +68,8 @@ def commandfactory(cmdname, **kwargs): else: parms[key] = value - parms['prehook'] = get_hook('pre_' + cmdname) - parms['posthook'] = get_hook('post_' + cmdname) + parms['prehook'] = hooks.get('pre_' + cmdname) + parms['posthook'] = hooks.get('post_' + cmdname) logging.debug('cmd parms %s' % parms) return cmdclass(**parms) diff --git a/alot/commands.py b/alot/commands.py index 6324988a..cab23947 100644 --- a/alot/commands.py +++ b/alot/commands.py @@ -29,10 +29,7 @@ from email.mime.text import MIMEText import tempfile import buffer -from settings import config -from settings import get_hook -from settings import get_account_by_address -from settings import get_accounts +import settings from db import DatabaseROError from db import DatabaseLockedError from completion import ContactsCompleter @@ -158,7 +155,9 @@ class ExternalCommand(Command): def thread_code(*args): cmd = self.commandstring if self.spawn: - cmd = config.get('general', 'terminal_cmd') + ' ' + cmd + cmd = '%s %s' % (settings.config.get('general', + 'terminal_cmd'), + cmd) ui.logger.info('calling external command: %s' % cmd) returncode = subprocess.call(cmd, shell=True) if returncode == 0: @@ -179,8 +178,8 @@ class EditCommand(ExternalCommand): if spawn != None: self.spawn = spawn else: - self.spawn = config.getboolean('general', 'spawn_editor') - editor_cmd = config.get('general', 'editor_cmd') + self.spawn = settings.config.getboolean('general', 'spawn_editor') + editor_cmd = settings.config.get('general', 'editor_cmd') cmd = editor_cmd + ' ' + self.path ExternalCommand.__init__(self, cmd, spawn=self.spawn, in_thread=self.spawn, @@ -293,7 +292,7 @@ class FlushCommand(Command): try: ui.dbman.flush() except DatabaseLockedError: - timeout = config.getint('general', 'flush_retry_timeout') + timeout = settings.config.getint('general', 'flush_retry_timeout') def f(*args): self.apply(ui) @@ -353,7 +352,7 @@ class SendMailCommand(Command): envelope = ui.current_buffer mail = envelope.get_email() sname, saddr = email.Utils.parseaddr(mail.get('From')) - account = get_account_by_address(saddr) + account = settings.accounts.get_account_by_address(saddr) if account: success, reason = account.sender.send_mail(mail) if success: @@ -379,14 +378,14 @@ class ComposeCommand(Command): def apply(self, ui): # TODO: fill with default header (per account) # get From header - accounts = get_accounts() + accounts = ui.accountman.get_accounts() if len(accounts) == 0: ui.notify('no accounts set') return elif len(accounts) == 1: a = accounts[0] else: - cmpl = AccountCompleter() + cmpl = AccountCompleter(ui.accountman) fromaddress = ui.prompt(prefix='From>', completer=cmpl, tab=1) validaddresses = [a.address for a in accounts] + [None] while fromaddress not in validaddresses: @@ -402,7 +401,7 @@ class ComposeCommand(Command): if 'To' not in self.headers: self.headers['To'] = ui.prompt(prefix='To>', completer=ContactsCompleter()) - if config.getboolean('general', 'ask_subject') and \ + if settings.config.getboolean('general', 'ask_subject') and \ not 'Subject' in self.headers: self.headers['Subject'] = ui.prompt(prefix='Subject>') diff --git a/alot/completion.py b/alot/completion.py index fcfc4d57..84335698 100644 --- a/alot/completion.py +++ b/alot/completion.py @@ -86,8 +86,11 @@ class ContactsCompleter(Completer): class AccountCompleter(Completer): """completes own mailaddresses""" + def __init__(self, accountman): + self.accountman = accountman + def complete(self, prefix): - valids = settings.get_account_addresses() + valids = self.accountman.get_account_addresses() return [a[len(prefix):] for a in valids if a.startswith(prefix)] class CommandCompleter(Completer): @@ -107,8 +110,9 @@ class CommandCompleter(Completer): class CommandLineCompleter(Completer): """completion for commandline""" - def __init__(self, dbman, mode): + def __init__(self, dbman, accoountman, mode): self.dbman = dbman + self.accountman = accountman self.mode = mode self._commandcompleter = CommandCompleter(dbman, mode) self._querycompleter = QueryCompleter(dbman) diff --git a/alot/init.py b/alot/init.py index 9217bfba..cb96c86a 100755 --- a/alot/init.py +++ b/alot/init.py @@ -21,6 +21,7 @@ import logging import os import settings +from settings import AccountManager from db import DBManager from ui import UI from urwid.command_map import command_map @@ -59,7 +60,11 @@ def main(): #read config file configfilename = os.path.expanduser(args.configfile) - settings.setup(configfilename) + settings.config.read(configfilename) + settings.hooks.setup(settings.config.get('general', 'hooksfile')) + + #accountman + aman = AccountManager(settings.config) # setup logging numeric_loglevel = getattr(logging, args.debug_level.upper(), None) @@ -69,8 +74,6 @@ def main(): # get ourselves a database manager dbman = DBManager(path=args.db_path, ro=args.read_only) - # read accounts - accounts = settings.get_accounts() # set up global urwid command maps command_map['j'] = 'cursor down' @@ -82,7 +85,7 @@ def main(): # set up and start interface ui = UI(dbman, logger, - accounts, + aman, args.query, args.colours, ) diff --git a/alot/settings.py b/alot/settings.py index 48485503..78a984f3 100644 --- a/alot/settings.py +++ b/alot/settings.py @@ -29,7 +29,6 @@ DEFAULTS = { 'general': { 'colourmode': '16', 'editor_cmd': "/usr/bin/vim -f -c 'set filetype=mail' +", - 'sendmail_cmd': 'msmtp --account=gmail -t', 'terminal_cmd': 'urxvt -T notmuch -e', 'spawn_editor': 'False', 'displayed_headers': 'From,To,Cc,Bcc,Subject', @@ -39,6 +38,7 @@ DEFAULTS = { 'show_notificationbar': 'False', 'show_statusbar': 'True', 'flush_retry_timeout': '5', + 'hooksfile': '~/.alot.py', }, 'normal-theme': { 'bufferlist_focus_bg': 'dark gray', @@ -212,43 +212,107 @@ class CustomConfigParser(SafeConfigParser): value = self.get(section, option, **kwargs) return [s.strip() for s in value.split(',')] + def read(self, *args): + SafeConfigParser.read(self, *args) + if self.has_option('general', 'hooksfile'): + hf = os.path.expanduser(config.get('general', 'hooksfile')) + if hf is not None: + try: + config.hooks = imp.load_source('hooks', hf) + except: + pass + + def get_palette(self): + p = list() + for attr in DEFAULTS['mono-theme'].keys(): + p.append(( + attr, + self.get('normal-theme', attr + '_fg'), + self.get('normal-theme', attr + '_bg'), + self.get('mono-theme', attr), + self.get('highcolour-theme', attr + '_fg'), + self.get('highcolour-theme', attr + '_bg'), + )) + return p + + +class HookManager: + def setup(self, hooksfile): + hf = os.path.expanduser(hooksfile) + if os.path.isfile(hf): + try: + self.module = imp.load_source('hooks', hf) + except: + self.module = None + else: + self.module = {} -config = CustomConfigParser(DEFAULTS) -mailcaps = mailcap.getcaps() + def get(self, key): + if self.module: + if key in self.module.__dict__: + return self.module.__dict__[key] + def f(*args, **kwargs): + msg = 'called undefined hook: %s with arguments' + logging.debug(msg % key) + return f -def setup(configfilename): - config.read(os.path.expanduser(configfilename)) - if config.has_option('general', 'hooksfile'): - hf = os.path.expanduser(config.get('general', 'hooksfile')) - if hf is not None: - try: - config.hooks = imp.load_source('hooks', hf) - except: + def call(self, hookname, *args, **kwargs): + hook = self.get_hook(hookname) + try: + hook(*args, **kwargs) + except: + msg = 'exception occured while calling hook: %s with arguments %s, %s' + logging.exception(msg % hookname, args, kwargs) + + +class AccountManager: + allowed = ['realname', + 'address', + 'gpg_key', + 'signature', + 'sender_type', + 'sendmail_command', + 'sent_mailbox'] + manditory = ['realname', 'address'] + accounts = [] + + def __init__(self, config): + sections = config.sections() + accountsections = filter(lambda s: s.startswith('account '), sections) + for s in accountsections: + options = filter(lambda x: x in self.allowed, config.options(s)) + args = {} + for o in options: + args[o] = config.get(s, o) + if o in self.manditory: + self.manditory.remove(o) + if not self.manditory: + logging.info(args) + self.accounts.append(Account(**args)) + else: pass + # log info + def get_accounts(self): + return self.accounts -def get_palette(): - p = list() - for attr in DEFAULTS['mono-theme'].keys(): - p.append(( - attr, - config.get('normal-theme', attr + '_fg'), - config.get('normal-theme', attr + '_bg'), - config.get('mono-theme', attr), - config.get('highcolour-theme', attr + '_fg'), - config.get('highcolour-theme', attr + '_bg'), - )) - return p + def get_account_by_address(self, address): + matched = [a for a in self.accounts if a.address == address] + if len(matched) == 1: + return matched.pop() + else: + return None + # log info + def get_account_addresses(self): + return [a.address for a in self.accounts] -def get_hook(hookname): - h = None - if config.hooks: - if config.hooks.__dict__: - if hookname in config.hooks.__dict__: - h = config.hooks.__dict__[hookname] - return h + +config = CustomConfigParser(DEFAULTS) +hooks = HookManager() +#accounts = AccountManager() +mailcaps = mailcap.getcaps() def get_mime_handler(mime_type, key, interactive=True): @@ -266,47 +330,6 @@ def get_mime_handler(mime_type, key, interactive=True): else: return None - -def get_accounts(): - allowed = ['realname', - 'address', - 'gpg_key', - 'signature', - 'sender_type', - 'sendmail_command', - 'sent_mailbox'] - manditory = ['realname', 'address'] - sections = config.sections() - accountsections = filter(lambda s: s.startswith('account '), sections) - accounts = [] - for s in accountsections: - options = filter(lambda x: x in allowed, config.options(s)) - args = {} - for o in options: - args[o] = config.get(s, o) - if o in manditory: - manditory.remove(o) - if not manditory: - logging.info(args) - accounts.append(Account(**args)) - else: - pass - # log info - return accounts - - -def get_account_by_address(address): - accounts = get_accounts() - matched = [a for a in accounts if a.address == address] - if len(matched) == 1: - return matched.pop() - else: - return None - - -def get_account_addresses(): - return [a.address for a in get_accounts()] - # maps mode to keybingins: for each one, # a key is mapped to a pair cmdline, helpstring. MAPPING = { diff --git a/alot/ui.py b/alot/ui.py index 8bd198ad..4cd35f76 100644 --- a/alot/ui.py +++ b/alot/ui.py @@ -21,7 +21,6 @@ import os from urwid.command_map import command_map from settings import config -from settings import get_palette from settings import get_mapping from buffer import BufferListBuffer from commandfactory import commandfactory @@ -34,18 +33,18 @@ class UI: buffers = [] current_buffer = None - def __init__(self, db, log, accounts, initialquery, colourmode): - self.dbman = db + def __init__(self, dbman, log, accountman, initialquery, colourmode): + self.dbman = dbman self.dbman.ui = self # register ui with dbman self.logger = log - self.accounts = accounts + self.accountman = accountman if not colourmode: colourmode = config.getint('general', 'colourmode') self.logger.info('setup gui in %d colours' % colourmode) self.mainframe = urwid.Frame(urwid.SolidFill(' ')) self.mainloop = urwid.MainLoop(self.mainframe, - get_palette(), + config.get_palette(), handle_mouse=False, unhandled_input=self.keypress) self.mainloop.screen.set_terminal_properties(colors=colourmode) @@ -111,7 +110,9 @@ class UI: mode = self.current_buffer.typename cmdline = self.prompt(prefix=':', text=startstring, - completer=CommandLineCompleter(self.dbman, mode)) + completer=CommandLineCompleter(self.dbman, + self.accountman, + mode)) if cmdline: cmd = interpret_commandline(cmdline, mode) if cmd: -- cgit v1.2.3