From 35ed830de601197d098b1bc114be8d55621a1c2a Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Mon, 13 Apr 2009 09:16:57 +1000 Subject: [PATCH] Interface manager seems to be working; need some interface working now --- mitter | 22 +++--- mitterlib/__init__.py | 12 ++-- mitterlib/network/__init__.py | 4 +- mitterlib/ui/__init__.py | 131 +++++++++++++++++----------------- 4 files changed, 85 insertions(+), 84 deletions(-) diff --git a/mitter b/mitter index 9b3ded7..8f3ea21 100755 --- a/mitter +++ b/mitter @@ -53,21 +53,20 @@ def main(): metavar='INTERFACE', help='Interface to be used.') - # Ask networks to add their options + logging.basicConfig(level=logging.DEBUG) + # Start the network manager (which will add the network options) connection = Networks(options) - # Ask interfaces to add their options - - interfaces = Interfaces() - interfaces.options(options) + # Start the interface manager and make interfaces add their options to the + # command line + interfaces = Interfaces(options) + interfaces.options() # Parse the command line options and the config file - options() # start the logging service - if options['General']['debug']: logging.basicConfig(level=logging.DEBUG) else: @@ -87,14 +86,13 @@ def main(): preferred_interface = options.conflicts['interface'] log.debug('Command line interface: %s', preferred_interface) - interface = interfaces(preferred_interface) - - if interface is None: + # load the module with the selected interface (or pick one for the user if + # they don't chose anything.) + display = interface.load(connection, preferred_interface) + if display is None: log.error('Sorry, no interface could be found for your system') return - display = interface.Interface(connection, options) - # display the interface (the interface should take care of updating # itself) display() diff --git a/mitterlib/__init__.py b/mitterlib/__init__.py index ac89b0e..24e41ab 100644 --- a/mitterlib/__init__.py +++ b/mitterlib/__init__.py @@ -57,16 +57,14 @@ def module_search(source, ignore): base_dir = os.path.dirname(source) modules = glob.glob(os.path.join(base_dir, '*.py')) + # TODO: What if they only have the installed/compiled modules (*.pyc)? + # Shouldn't we add those to the glob list? for module in modules: module_name = os.path.basename(module) if module_name in ignore: # not a usable module continue - try: - module_name = _import_name(module_name) - yield module_name - except ImportError, exc: - _log.debug('Module %s is not "importable"', module_name) - _log.debug(str(exc)) - pass + # TODO: Maybe this is a good place to test if the module is + # "importable" + yield module_name diff --git a/mitterlib/network/__init__.py b/mitterlib/network/__init__.py index 36bf354..711aa9e 100644 --- a/mitterlib/network/__init__.py +++ b/mitterlib/network/__init__.py @@ -18,6 +18,7 @@ # along with this program. If not, see . import logging +import os.path from mitterlib.network.networkbase import NetworkData from mitterlib import module_search @@ -91,7 +92,8 @@ class Networks(object): return self._networks for module_name in module_search(__file__, SKIPPABLES): - module = __import__(module_name, fromlist=[module_name]) + import_name = _import_name(module_name) + module = __import__(import_name, fromlist=[import_name]) connection = module.Connection(self._options) self._networks[connection.SHORTCUT] = connection diff --git a/mitterlib/ui/__init__.py b/mitterlib/ui/__init__.py index 1f7da26..5597691 100644 --- a/mitterlib/ui/__init__.py +++ b/mitterlib/ui/__init__.py @@ -1,8 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/python2.5 # -*- coding: utf-8 -*- -# Mitter, a Maemo client for Twitter. -# Copyright (C) 2007, 2008 Julio Biason +# Mitter, a simple client for Twitter +# Copyright (C) 2007, 2008 The Mitter Contributors # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -18,64 +18,67 @@ # along with this program. If not, see . import logging - -_log = logging.getLogger('ui.__init__') - -interfaces = [ - 'pygtk', - 'cmd', - 'mh', - 'tty'] - - -def _import_name(interface): - """Return the name of the module for that interface.""" - return 'mitterlib.ui.ui_%s' % (interface) - - -def _interface_list(prefer=None): - """Return a list of UI modules.""" - if prefer: - if prefer in interfaces: - yield _import_name(prefer) - - for interface in interfaces: - module_name = _import_name(interface) - _log.debug('Module %s' % (module_name)) - yield module_name - - -def interface(prefer): - """Try to find an interface that works in the current user system.""" - _log.debug('Preferred interface: %s' % (prefer)) - interface = None - for module_name in _interface_list(prefer): - # try to import each using __import__ - try: - _log.debug('Trying to import %s' % (module_name)) - interface = __import__(module_name, fromlist=[module_name]) - break - except ImportError, exc: - _log.debug('Failed') - _log.debug(str(exc)) - pass - - return interface - - -def interface_options(options): - """Add options in the command line OptParser object for every - interface (yes, every interface, even the ones the user doesn't care).""" - - available_interfaces = [] - for module in _interface_list(): - try: - _log.debug('Importing %s for options' % (module)) - interface = __import__(module, fromlist=[module]) - - interface.options(options) - available_interfaces.append(module.split('_')[-1]) - except ImportError: - pass # so we don't care - - return +import os.path + +from mitterlib import module_search + +_log = logging.getLogger('mitterlib.ui.Interfaces') + +# List of files that are not networks +SKIPPABLES = ('__init__.py') + +#-------------------------------------------------------------------- +# Helper functions +#-------------------------------------------------------------------- + + +def _import_name(module): + """Based on the name of the module, return the proper "import" + statement.""" + (name, _) = os.path.splitext(module) + return 'mitterlib.ui.%s' % (name) + + +class Interfaces(object): + """Interface transparency layer: Check which interfaces are available and + tries to load the interface requested by the user.""" + + def __init__(self, options): + self._interfaces = [] + self._options = options + self.options() + return + + def options(self): + """Request all networks to add their options.""" + for module_name in module_search(__file__, SKIPPABLES): + import_name = _import_name(module_name) + + try: + _log.debug('Importing module %s', import_name) + module = __import__(import_name, fromlist=[import_name]) + interface_name = module.Interface.NAMESPACE + module.Interface.options(self._options) + self._interfaces.append(interface_name) + except ImportError, exc: + _log.debug('Cannot import module %s', import_name) + _log.debug(str(exc)) + + return + + def load(self, connection, prefer=None): + """Start the interface, using the prefered one.""" + if not self._interfaces: + return None + + if prefer and prefer in self._interfaces: + import_name = prefer + else: + # So we pick the one in the top of the list ('cause we know it's + # importable and the user didn't chose anything.) + # [we could be mean and use random.choice(self._interfaces)] + import_name = self._interfaces[0] + + module_name = _import_name(import_name) + module = __import__(module_name, fromlist[module_name]) + return module.Interface(connection, self._options)