[Zope] Running scripts after zope startup

Josef Meile jmeile at hotmail.com
Wed Oct 25 12:26:24 EDT 2006


Hi,

I'm working in a configuration module for other products I'm developing. 
The idea is that the user first has to make an instance from this 
product, then define there where the other products instances will be 
created, what header, footer, and style sheets they will use, etc..

The configuration product has to detect which of my products are 
installed, then load some xml Formulator forms. I just created a 
registry class that to do the detection process:

import Products

JM_PRODUCTS = ['JMConfigurator','JMPlace','JMPerson']
class JMRegistry:
   def __init__(self):
     availableJMProducts = {}

     for productName in JM_PRODUCTS:
       productModule = getattr(Products,productName,None)
       if productModule is not None:
         availableJMProducts[productName] = productModule
     self._AvailableJMProducts = availableJMProducts

   """More methods come here
      ...
   """

JM_Registry = JMRegistry()

The problem here is that if I import this in the initialize method of my 
configuration product, the _AvailableJMProducts dictionary is empty 
because at this point the other products hasn't been jet registered by zope.

I just thaught about something like the StartupScripts products does: 
running this after zope starts. This is achieved as follows:

__init__.py from my product:

from Products.JMUtils import JMRegistry
def initialize(context):
   #Some registration code comes here
   #...

   import ThreadedAsync.LoopCallback
   ThreadedAsync.LoopCallback.register_loop_callback(
    JMRegistry.createRegistry)

JMRegistry.py:
JM_PRODUCTS = ['JMConfigurator','JMPlace','JMPerson']
class JMRegistry:
   #Class definition is the same as above
   #...

JM_Registry = None
def createRegistry(args *):
   JM_Registry = JMRegistry()

Unfortunatelly, after seeing the zope source code, I saw that the 
ThreadedAsync is only used by ZEO, which I'm not using.

My workaround was to call this in the __setstate__ method of my 
configuration product as follows:

from Products.JMUtils import JMRegistry

class JMConfigurator(ZCatalog):
   #__init__ and other methods come here
   #...

   def __setstate__(self, state):
     ZCatalog.__setstate__(self,state)

     if JMRegistry.JM_REGISTRY is None:
       JMRegistry.JM_REGISTRY = JMRegistry.JMRegistry()

       #After having initialized the registry, I can call the methods to
       #load the Formulator forms
       self.LoadFormulatorForms()

This works well, but I think it is not the better place to define this 
kind of things. Is there any better way of achieving the task?

Regards
Josef


More information about the Zope mailing list