Re: [Repoze-dev] Folder event subscriber not called
On Wed, 2010-05-05 at 07:30 -0700, Sam Brauer wrote: From: Chris McDonough chr...@plope.com To: Sam Brauer sampbra...@yahoo.com Cc: repoze-dev@lists.repoze.org Sent: Tue, May 4, 2010 9:02:35 PM Subject: Re: [Repoze-dev] Folder event subscriber not called Hi Sam, Modify your run.py so that its app function calls hook_zca ala: def app(global_config, **settings): This function returns a WSGI application. It is usually called by the PasteDeploy framework during ``paster serve``. zodb_uri = settings.get('zodb_uri') zcml_file = settings.get('configure_zcml', 'configure.zcml') if zodb_uri is None: raise ValueError(No 'zodb_uri' in application configuration.) finder = PersistentApplicationFinder(zodb_uri, appmaker) def get_root(request): return finder(request.environ) config = Configurator(root_factory=get_root, settings=settings) config.begin() config.hook_zca() config.load_zcml(zcml_file) config.end() return config.make_wsgi_app() The repoze.folder code isn't dependent on BFG; it's actually general enough to be used in any ZODB application. Therefore it uses the global ZCA API to send events. When you call config.hook_zca(), this tells BFG to replace the normal lookup for a Zope global registry with a lookup which returns the ZCA registry that BFG uses. After I added this call, I tested your code, and saw your event sent to my console. See http://docs.repoze.org/bfg/1.2/narr/zca.html for more info. Chris, That call to hook_zca() was indeed the missing piece. Thank you! I think it would have taken me a very long time to have figured that out on my own, and I can imagine that this might stump other new users as well. Yes. May I suggest a couple of places in the documentation (which is extraordinary, btw) where this might be mentioned? It could be noted in the Using Events chapter of the docs (http://docs.repoze.org/bfg/1.2/narr/events.html). Also if you were to expand the example in the tutorial on using repoze.catalog (http://docs.repoze.org/bfg/1.2/tutorials/catalog/index.html) such that it included hooking up subscribers to index/unindex in response to folder add/remove events, that would be another good place to mention it. I'd rather make a r.b.folder implementation that used the BFG API when sending events and demonstrate using that in a tutorial. Explaining what hook_zca does in general is hard; in context it's mostly impossible. - C ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] Folder event subscriber not called
From: Chris McDonough chr...@plope.com To: Sam Brauer sampbra...@yahoo.com Cc: repoze-dev@lists.repoze.org Sent: Mon, May 3, 2010 11:37:15 PM Subject: Re: [Repoze-dev] Folder event subscriber not called On Mon, 2010-05-03 at 23:33 -0400, Chris McDonough wrote: Hi Sam, The events sent by repoze.folder are object events, which are events dispatched based on *two* interfaces (the context interface and the event interface). Here's an example from KARL: subscriber for=repoze.lemonade.interfaces.IContent repoze.folder.interfaces.IObjectAddedEvent handler=.subscribers.index_content/ Hopefully this helps, Sorry, I should have also provided the subscribers.index_content function so you could see its argument list: def index_content(obj, event): Index content (an IObjectAddedEvent subscriber) catalog = find_catalog(obj) if catalog is not None: for node in postorder(obj): if is_content(obj): path = model_path(node) docid = getattr(node, 'docid', None) if docid is None: docid = node.docid = catalog.document_map.add(path) else: catalog.document_map.add(path, docid) catalog.index_doc(docid, node) Chris, Thanks for clarifying the object event style of subscribers. I saw them in some example code and tried that approach too without success. If I modify my example such that my Content class implements an IContent interface and my subscriber_test function takes object and event arguments, models.py contains: --- import repoze.folder import persistent import zope.interface class IContent(zope.interface.Interface): pass class Content(persistent.Persistent): zope.interface.implements(IContent) class Site(repoze.folder.Folder): pass def appmaker(zodb_root): if not 'app_root' in zodb_root: app_root = Site() zodb_root['app_root'] = app_root import transaction transaction.commit() return zodb_root['app_root'] def subscriber_test(obj, event): print subscriber_test object=%s event=%s % (repr(obj), repr(event)) --- And configure.zcml contains: --- configure xmlns=http://namespaces.repoze.org/bfg; include package=repoze.bfg.includes / subscriber for=.models.IContent repoze.folder.interfaces.IObjectAddedEvent handler=.models.subscriber_test / /configure --- Then I run bfgshell and add a Content object to the app root like so: $ ../bin/paster --plugin=repoze.bfg bfgshell foo.ini zodb Python 2.5.4 (r254:67916, Jan 20 2010, 21:45:54) [GCC 4.3.3] on linux2 Type help for more information. root is the BFG app root object. import foo.models root['test'] = foo.models.Content() Nothing is printed to stdout, so it appears that again subscriber_test() isn't being called. I'm stumped. Maybe I'm missing some required code or configuration somewhere... I've been going in circles trying to figure it out. Thanks for your time, Sam ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] Folder event subscriber not called
On Mon, 2010-05-03 at 23:33 -0400, Chris McDonough wrote: On Mon, 2010-05-03 at 12:55 -0700, Sam Brauer wrote: Hi there! I'm a long-time Zope 2 user finally trying to do a demo project with Repoze.bfg. First off, congratulations to everyone developing Repoze! You've really cherry picked the best concepts from Zope and packaged them in a lean modern framework. My demo project was going along very well until I tried to wire up some subscribers for repoze.folder events; my subscriber callbacks don't seem to be firing. After trying a few days to figure out the problem, I think I need to ask for help. I've tried to come up with a small example to demonstrate the problem, and I'd be very grateful for any help. I feel like I'm missing something that should be obvious. Hi Sam, The events sent by repoze.folder are object events, which are events dispatched based on *two* interfaces (the context interface and the event interface). Here's an example from KARL: subscriber for=repoze.lemonade.interfaces.IContent repoze.folder.interfaces.IObjectAddedEvent handler=.subscribers.index_content/ Hopefully this helps, Sorry, I should have also provided the subscribers.index_content function so you could see its argument list: def index_content(obj, event): Index content (an IObjectAddedEvent subscriber) catalog = find_catalog(obj) if catalog is not None: for node in postorder(obj): if is_content(obj): path = model_path(node) docid = getattr(node, 'docid', None) if docid is None: docid = node.docid = catalog.document_map.add(path) else: catalog.document_map.add(path, docid) catalog.index_doc(docid, node) ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev