commit-gnue
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]