← Back to team overview

oerppy-hackers team mailing list archive

[Branch ~oerppy-hackers/oerppy/trunk] Rev 27: * Added a mechanism for tracking addons from any script, and the ability to add

 

------------------------------------------------------------
revno: 27
committer: duncan@xxxxxxxxxx
branch nick: trunk
timestamp: Thu 2011-06-02 09:16:11 -0600
message:
  * Added a mechanism for tracking addons from any script, and the ability to add
    them to this registry from any script, as long as the addons are somewhere in
    the PYTHONPATH.
  * Changed the export script to register the Canonical addon.
  * Removed the addon code from the client.
  * Added an addon method to Service (convenience wrapper for the registry).
  * Updated some docstrings.
added:
  oerppy/addons/tests/
  oerppy/addons/tests/__init__.py
  oerppy/addons/tests/test_canonical.py
  oerppy/reg.py
modified:
  bin/export_month_timesheets
  oerppy/addons/canonical.py
  oerppy/client.py
  oerppy/service.py


--
lp:oerppy
https://code.launchpad.net/~oerppy-hackers/oerppy/trunk

Your team oerppy Hackers is subscribed to branch lp:oerppy.
To unsubscribe from this branch go to https://code.launchpad.net/~oerppy-hackers/oerppy/trunk/+edit-subscription
=== modified file 'bin/export_month_timesheets'
--- bin/export_month_timesheets	2011-06-01 18:49:40 +0000
+++ bin/export_month_timesheets	2011-06-02 15:16:11 +0000
@@ -1,10 +1,15 @@
 #!/usr/bin/env python
+from oerppy.addons import canonical
 from oerppy.config import get_config_data
+from oerppy.reg import registry
 from oerppy.scripting import export
 
 
-# get configuration; option parsing is handled by the script class(es)
+# get configuration; note that option parsing is handled by the script
+# class(es)
 config_data = get_config_data()
+# setup any addons that we want
+registry.add("canonical", canonical.CanonicalAddOns)
 # run the exporter
 monthly_export = export.Monthly(config_data)
 monthly_export.run()

=== modified file 'oerppy/addons/canonical.py'
--- oerppy/addons/canonical.py	2011-06-01 22:52:15 +0000
+++ oerppy/addons/canonical.py	2011-06-02 15:16:11 +0000
@@ -50,7 +50,7 @@
         employees = self.client.searchfields(
             "hr.employee",
             [],
-            'name','department_id','resource_id','user_id'])
+            ['name','department_id','resource_id','user_id'])
 
         # Build dictionary of resource_id vs department
         user_dept = {}

=== added directory 'oerppy/addons/tests'
=== added file 'oerppy/addons/tests/__init__.py'
=== added file 'oerppy/addons/tests/test_canonical.py'
=== modified file 'oerppy/client.py'
--- oerppy/client.py	2011-06-01 16:42:38 +0000
+++ oerppy/client.py	2011-06-02 15:16:11 +0000
@@ -14,7 +14,6 @@
         self.endpoints = endpoints
         self.dbname = dbname
         self.credentials = creds
-        self.addons = []
         self.connect()
 
     def connect(self):
@@ -95,9 +94,3 @@
         # Return full dictionary i.e. result=base-64 content, format=file
         # extension
         return val
-
-    def update_addons(self, addon):
-        if isinstance(addon, list):
-            self.addons.extend(addon)
-        else:
-            self.addons.apped(addon)

=== added file 'oerppy/reg.py'
--- oerppy/reg.py	1970-01-01 00:00:00 +0000
+++ oerppy/reg.py	2011-06-02 15:16:11 +0000
@@ -0,0 +1,62 @@
+class Registry(object):
+    """
+    Registry instances will be most useful when made as singletons at the
+    module level or on long-lived objects.
+    """
+    def __init__(self, a_dict=None):
+        if not a_dict:
+            a_dict = {}
+        self._reg = a_dict
+
+    def update(self, a_dict):
+        self._reg.update(a_dict)
+
+    def add(self, key, value):
+        self._reg[key] = value
+
+    def remove(self, key):
+        del self._reg[key]
+
+    def get_value(self, key):
+        return self._reg[key]
+
+    def get_key(self, value):
+        for key, val in self._reg.items():
+            if val == value:
+                return key
+
+
+class AddOnRegistry(Registry):
+    """
+    This is specifically for keeping track of addons. This will enable any
+    script writer to import and incorporate addons from anywhere in the Python
+    path.
+    """
+    def __init__(self, *args, **kwargs):
+        super(AddOnRegistry, self).__init__(*args, **kwargs)
+        self._order = []
+
+    def add(self, name, instance):
+        super(AddOnRegistry, self).add(name, instance)
+        self._order.append(name)
+
+    def get_addon(self, name):
+        return self.get_value(name)
+
+    def remove_addon(self, name):
+        self.remove(name)
+
+    def get_addon_names(self):
+        return self._order
+
+    def get_addons(self):
+        addons = []
+        for name in self._order:
+            addons.append(self.get_value(name))
+        return addons
+
+
+# Default registry is for addons; we can change this later, if a general
+# registry is needed, and then make the addon registry a sub-reg of the general
+# one.
+registry = AddOnRegistry()

=== modified file 'oerppy/service.py'
--- oerppy/service.py	2011-06-01 22:33:25 +0000
+++ oerppy/service.py	2011-06-02 15:16:11 +0000
@@ -1,6 +1,6 @@
 import xmlrpclib
 
-from oerppy import client, util
+from oerppy import client, reg, util
 
 
 class Credentials(object):
@@ -178,7 +178,12 @@
               check the client; self.client.addons is returned
 
             * self.query isn't found on self or self.client, so each addon is
-            * checked; if CanonicalAddOns is loaded, it will find
+              checked (in the order that they were added to the registry, so
+              add your most important ones first)
+
+        If you have overlap between the addons methods, then you should call
+        the method directly on the addon. See the docstring for
+        Service.get_addon for more information.
         """
         try:
             attrib = super(Service, self).__getattr__(name)
@@ -186,7 +191,7 @@
             try:
                 attrib = getattr(self.client, name)
             except AttributeError:
-                for addon in self.client.addons:
+                for addon in registry.get_addons():
                     try:
                         attrib = getattr(addon, name)
                     except AttributeError:
@@ -195,3 +200,13 @@
             raise AttributeError(
                 "Attribute '%s' not found on Service, Client, "
                 "or any Addon." % (name))
+
+    def get_addon(self, name):
+        """
+        This method is a convenience wrapper around the registry method of the
+        same name. If you want to be very explicit about making calls on a
+        particular addon, rather than rely on the magic of __getattr__, then
+        this method is for you. Simply get the addon that you want, and call
+        methods on the returned object like usual.
+        """
+        return registry.get_addon(name)