[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r5318 - trunk/gnue-common/src/apps
From: |
reinhard |
Subject: |
r5318 - trunk/gnue-common/src/apps |
Date: |
Sat, 13 Mar 2004 19:31:29 -0600 (CST) |
Author: reinhard
Date: 2004-03-13 19:31:27 -0600 (Sat, 13 Mar 2004)
New Revision: 5318
Added:
trunk/gnue-common/src/apps/plugin.py
Log:
Flexible plugin system. Not used yet, still to be adapted for McMillan.
Added: trunk/gnue-common/src/apps/plugin.py
===================================================================
--- trunk/gnue-common/src/apps/plugin.py 2004-03-13 13:38:02 UTC (rev
5317)
+++ trunk/gnue-common/src/apps/plugin.py 2004-03-14 01:31:27 UTC (rev
5318)
@@ -0,0 +1,205 @@
+# GNU Enterprise Common Library - Plugin support
+#
+# This file is part of GNU Enterprise.
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright 2001-2004 Free Software Foundation
+#
+# $Id$
+
+"""
+Functions to list and load avaliable plugins dynamically.
+"""
+from types import *
+
+import os
+
+from gnue.common.apps import GDebug
+
+# -----------------------------------------------------------------------------
+# List all available plugins
+# -----------------------------------------------------------------------------
+
+def list (base, identifier, test):
+ """
+ List all available plugins
+ """
+ checktype (base, [StringType, UnicodeType])
+ checktype (identifier, [StringType, UnicodeType])
+ checktype (test, FunctionType)
+
+ # Make sure everything is a string. Non-ASCII characters are not allowed in
+ # Python module names anyway.
+ _base = base.encode ()
+ _identifier = identifier.encode ()
+
+ # Now recursively list the plugins
+ return __list (_base, _identifier, test)
+
+# -----------------------------------------------------------------------------
+# Find a plugin
+# -----------------------------------------------------------------------------
+
+def find (name, base, identifier, test):
+ """
+ Find a plugin by name.
+ """
+ checktype (name, [StringType, UnicodeType])
+ checktype (base, [StringType, UnicodeType])
+ checktype (identifier, [StringType, UnicodeType])
+ checktype (test, FunctionType)
+
+ # Make sure everything is a string. Non-ASCII characters are not allowed in
+ # Python module names anyway.
+ _name = name.encode ()
+ _base = base.encode ()
+ _identifier = identifier.encode ()
+
+ # Now search the plugin
+ return __find (_base, name, _identifier, test)
+
+# -----------------------------------------------------------------------------
+# Find all modules and subpackages in a package
+# -----------------------------------------------------------------------------
+
+def __modules (package, want_packages):
+
+ (basedir, basefile) = os.path.split (package.__file__)
+ (basename, baseext) = os.path.splitext (basefile)
+
+ if basename != '__init__':
+ # This is not a package, so no need to go deeper
+ return []
+
+ # Find all submodules
+ result = []
+ for subfile in os.listdir (basedir):
+ (subname, subext) = os.path.splitext (subfile)
+ subpath = os.path.join (basedir, subfile)
+ # We are only interested in Python modules or packages
+ if (not want_packages and subext == '.py' and subfile != '__init__') or \
+ (os.path.isdir (subpath) and \
+ os.path.isfile (os.path.join (subpath, '__init__.py'))):
+ result = result + [subname]
+ return result
+
+# -----------------------------------------------------------------------------
+# Recursively list all plugins
+# -----------------------------------------------------------------------------
+
+def __list (base, identifier, test):
+
+ try:
+ m = __import__ (base, None, None, '*')
+ except:
+ return []
+
+ if hasattr (m, identifier):
+ # This is already a plugin, now test if it is loadable
+ try:
+ test (m)
+ return [m]
+ except Exception, message:
+ gDebug (1, _('Can\'t use module %(module)s: %(message)s') % \
+ {'module': m.__name__, 'message': message})
+ return []
+
+ # List all submodules
+ result = []
+ for sub in __modules (m, False):
+ result = result + __list (base + '.' + sub, identifier, test)
+ return result
+
+# -----------------------------------------------------------------------------
+# Recursively find first available plugin
+# -----------------------------------------------------------------------------
+
+def __first (base, identifier, test):
+
+ try:
+ m = __import__ (base, None, None, '*')
+ except:
+ return None
+
+ if hasattr (m, identifier):
+ # This is already a plugin, now test if it is loadable
+ try:
+ test (m)
+ return m
+ except message:
+ print 'Can\'t use module %s:', message
+ return None
+
+ # Search all submodules
+ for sub in __modules (m, False):
+ result = __first (base + '.' + sub, identifier, test)
+ if result:
+ return result
+ return None
+
+# -----------------------------------------------------------------------------
+# Recursively search for a plugin
+# -----------------------------------------------------------------------------
+
+def __find (base, name, identifier, test):
+
+ try:
+ m = __import__ (base, None, None, '*')
+ except:
+ return None
+
+ try:
+ m = __import__ (base + '.' + name, None, None, '*')
+ return __first (base + '.' + name, identifier, test)
+ except:
+ pass
+
+ # Search all submodules
+ for sub in __modules (m, True):
+ result = __find (base + '.' + sub, name, identifier, test)
+ if result:
+ return result
+ return None
+
+# =============================================================================
+# Self test code
+# =============================================================================
+
+if __name__ == '__main__':
+
+ def test (module):
+ module.Connection (None, None, {})
+
+ base = 'gnue.common.datasources.drivers'
+
+ for m in list (base, 'Connection', test):
+ print m.__name__
+
+ m = find ('postgresql.popy', base, 'Connection', test)
+ print 'find "postgresql.popy":', (m and m.__name__)
+
+ m = find ('pygresql', base, 'Connection', test)
+ print 'find "pygresql":', (m and m.__name__)
+
+ m = find ('mysql', base, 'Connection', test)
+ print 'find "mysql":', (m and m.__name__)
+
+ m = find ('oracle', base, 'Connection', test)
+ print 'find "oracle":', (m and m.__name__)
+
+ m = find ('nonexistent', base, 'Connection', test)
+ print 'find "nonexistent":', m
Property changes on: trunk/gnue-common/src/apps/plugin.py
___________________________________________________________________
Name: svn:keywords
+ Id
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r5318 - trunk/gnue-common/src/apps,
reinhard <=