[Checkins] SVN: lovely.remotetask/branches/port-for-zope210/ Added
example application. This aplication is copied from the 2.9
branch (thanks timte!) and slightly modified.
Radim Novotny
novotny.radim at gmail.com
Thu May 15 11:32:16 EDT 2008
Log message for revision 86777:
Added example application. This aplication is copied from the 2.9 branch (thanks timte!) and slightly modified.
It shows the basic usage of lovely.remotetask. Some description is in configure.zcml.
Changed:
U lovely.remotetask/branches/port-for-zope210/TODO.txt
A lovely.remotetask/branches/port-for-zope210/remotetaskexample/
A lovely.remotetask/branches/port-for-zope210/remotetaskexample/__init__.py
A lovely.remotetask/branches/port-for-zope210/remotetaskexample/browser.py
A lovely.remotetask/branches/port-for-zope210/remotetaskexample/configure.zcml
A lovely.remotetask/branches/port-for-zope210/remotetaskexample/interfaces.py
A lovely.remotetask/branches/port-for-zope210/remotetaskexample/service.py
A lovely.remotetask/branches/port-for-zope210/remotetaskexample/task.py
U lovely.remotetask/branches/port-for-zope210/src/lovely/remotetask/README.txt
-=-
Modified: lovely.remotetask/branches/port-for-zope210/TODO.txt
===================================================================
--- lovely.remotetask/branches/port-for-zope210/TODO.txt 2008-05-15 14:57:40 UTC (rev 86776)
+++ lovely.remotetask/branches/port-for-zope210/TODO.txt 2008-05-15 15:32:15 UTC (rev 86777)
@@ -3,3 +3,10 @@
=============================
- remove zope.app.session dependency
+
+
+2.10 compatibility:
+
+- try cron jobs (not tested yet)
+- MultiProcessor does not work yet
+
Added: lovely.remotetask/branches/port-for-zope210/remotetaskexample/__init__.py
===================================================================
--- lovely.remotetask/branches/port-for-zope210/remotetaskexample/__init__.py (rev 0)
+++ lovely.remotetask/branches/port-for-zope210/remotetaskexample/__init__.py 2008-05-15 15:32:15 UTC (rev 86777)
@@ -0,0 +1,2 @@
+
+
Added: lovely.remotetask/branches/port-for-zope210/remotetaskexample/browser.py
===================================================================
--- lovely.remotetask/branches/port-for-zope210/remotetaskexample/browser.py (rev 0)
+++ lovely.remotetask/branches/port-for-zope210/remotetaskexample/browser.py 2008-05-15 15:32:15 UTC (rev 86777)
@@ -0,0 +1,91 @@
+from Products.CMFCore.utils import getToolByName
+from zope.component import getUtility, getUtilitiesFor
+from AccessControl import getSecurityManager
+from lovely.remotetask.interfaces import ITaskService
+from remotetaskexample.service import ExampleService
+import transaction
+
+# see configure.zcml for the description
+
+class Example(object):
+ """ Some docis """
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def __call__(self):
+ portal_url = getToolByName(self.context, 'portal_url')
+ site = portal_url.getPortalObject()
+
+ service = getUtility(ITaskService, name='ExampleService',
+ context=site)
+ service.startProcessing()
+ return "successfully started service"
+
+class JobStatus(object):
+ """ Some docis """
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def __call__(self):
+ jobid = self.request.get('job', -1)
+ if jobid == -1:
+ return
+ else:
+ service = getUtility(ITaskService, name='ExampleService')
+ return "%s - %s" % (service.getStatus(jobid) , service.getResult(jobid))
+
+
+class RunTask(object):
+ """ Some docis """
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def __call__(self):
+ service = getUtility(ITaskService, name='ExampleService')
+ # we want to pass current context path, current member ID and user storage
+ # anyway, the parameters are not required
+ path = '/'.join(self.context.getPhysicalPath())
+ # if Anonymous, user_id will be None
+ user = getSecurityManager().getUser()
+ user_id = user.getId()
+ user_container = '/'.join(user.aq_parent.getPhysicalPath())
+ # look to task.py how parameters are processed
+ jobid = service.add(u'exampletask', dict(path=path, user_id=user_id, user_container=user_container))
+ return "exampletask added. Job ID: %d." % jobid
+
+class AddExampleService(object):
+ """ Adds a service to the site. """
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def __call__(self):
+ portal_url = getToolByName(self.context, 'portal_url')
+ site = portal_url.getPortalObject()
+ # service will be persistently stored
+ sm = site.getSiteManager()
+ service = sm.queryUtility(ITaskService, 'ExampleService')
+ if service is None:
+ service = ExampleService()
+ service.__parent__ = site
+ service.id = 'ITaskService-ExampleService'
+ service.__name__ = service.getId()
+ site._setOb(service.id, service)
+ sm.registerUtility(service, ITaskService, 'ExampleService')
+ msg = "service successfully added and started"
+ else:
+ msg = "service successfully started"
+
+ # startProcessing needs the utility to have a _p_jar so we need
+ # to use a savepoint here
+ transaction.savepoint()
+ service.startProcessing()
+
+ return msg
Added: lovely.remotetask/branches/port-for-zope210/remotetaskexample/configure.zcml
===================================================================
--- lovely.remotetask/branches/port-for-zope210/remotetaskexample/configure.zcml (rev 0)
+++ lovely.remotetask/branches/port-for-zope210/remotetaskexample/configure.zcml 2008-05-15 15:32:15 UTC (rev 86777)
@@ -0,0 +1,62 @@
+<configure
+ xmlns:browser="http://namespaces.zope.org/browser"
+ xmlns:five="http://namespaces.zope.org/five"
+ xmlns="http://namespaces.zope.org/zope">
+
+ <class class=".service.ExampleService">
+ <implements
+ interface="zope.app.annotation.interfaces.IAttributeAnnotatable" />
+ <require
+ permission="zope.Public"
+ interface="lovely.remotetask.interfaces.ITaskService" />
+ </class>
+
+ <utility
+ factory=".task.ExampleTask"
+ name="exampletask" />
+
+ <!-- add new service and start it. This has to be called at least one time to be able to add tasks to the service
+ Service is added persistently -->
+ <browser:page
+ for="*"
+ name="addservice"
+ class=".browser.AddExampleService"
+ permission="cmf.ManagePortal"
+ />
+
+ <!-- add new task. If service is running, task will be processed soon
+ This task adds Folder with id SomeFolder to your site root-->
+ <browser:page
+ for="*"
+ name="addexamplejob"
+ class=".browser.RunTask"
+ permission="zope.Public"
+ />
+
+ <!-- return status of job. requires 'job' parameter in request with job id number
+ Example: .../jobstatus?job:int=47 -->
+ <browser:page
+ for="*"
+ name="jobstatus"
+ class=".browser.JobStatus"
+ permission="zope.Public"
+ />
+
+ <!-- start already existing ExampleService (added by addservice)
+ Has to be called after each Zope restart if service is not auto-started
+ autostarted service has to be declared in zope.conf as:
+ <product-config lovely.remotetask>
+ autostart portal at ExampleService
+ </product-config>
+ where 'portal' is site name and
+ ExampleService is service name (name, under service is registered - see service.py/AddExampleService
+ -->
+ <browser:page
+ for="*"
+ name="startexample"
+ class=".browser.Example"
+ permission="zope.Public"
+ />
+
+
+</configure>
Added: lovely.remotetask/branches/port-for-zope210/remotetaskexample/interfaces.py
===================================================================
--- lovely.remotetask/branches/port-for-zope210/remotetaskexample/interfaces.py (rev 0)
+++ lovely.remotetask/branches/port-for-zope210/remotetaskexample/interfaces.py 2008-05-15 15:32:15 UTC (rev 86777)
@@ -0,0 +1,4 @@
+from lovely.remotetask.interfaces import ITask
+
+class IExampleTask(ITask):
+ """ Identifying this task as a task for the ExampleTask service. """
Added: lovely.remotetask/branches/port-for-zope210/remotetaskexample/service.py
===================================================================
--- lovely.remotetask/branches/port-for-zope210/remotetaskexample/service.py (rev 0)
+++ lovely.remotetask/branches/port-for-zope210/remotetaskexample/service.py 2008-05-15 15:32:15 UTC (rev 86777)
@@ -0,0 +1,12 @@
+from remotetaskexample.interfaces import IExampleTask
+from lovely.remotetask.service import TaskService
+from OFS.SimpleItem import SimpleItem
+
+class ExampleService(TaskService, SimpleItem):
+ taskInterface = IExampleTask
+
+ def __init__(self):
+ super(ExampleService, self).__init__()
+ parent = getattr(self, '__parent__', None)
+ if parent:
+ self.startProcessing()
Added: lovely.remotetask/branches/port-for-zope210/remotetaskexample/task.py
===================================================================
--- lovely.remotetask/branches/port-for-zope210/remotetaskexample/task.py (rev 0)
+++ lovely.remotetask/branches/port-for-zope210/remotetaskexample/task.py 2008-05-15 15:32:15 UTC (rev 86777)
@@ -0,0 +1,41 @@
+from remotetaskexample.interfaces import IExampleTask
+from zope.interface import implements
+from zope.app.publication.zopepublication import ZopePublication
+from AccessControl.SecurityManagement import newSecurityManager
+from AccessControl.SecurityManagement import setSecurityManager
+from AccessControl import getSecurityManager
+
+FOLDER_ID = 'SomeFolder'
+
+class ExampleTask(object):
+ """ This example task shows how to create Folder from the service """
+ implements(IExampleTask)
+
+ def __call__(self, service, jobid, input):
+ print "Creating folder in context of %s" % input
+
+ # get application object
+ app = service._p_jar.root()[ZopePublication.root_name]
+ # get context object
+ context = app.unrestrictedTraverse(input['path'])
+ # get user
+ acl_users = app.unrestrictedTraverse(input['user_container'])
+ if acl_users is not None:
+ user = acl_users.getUser(input['user_id'])
+ else:
+ user = None
+ sm = getSecurityManager()
+ try:
+ # force user
+ newSecurityManager(None, user)
+
+ if getattr(context, FOLDER_ID, None) is None:
+ id = context.invokeFactory('Folder', FOLDER_ID)
+ folder = getattr(context, id)
+ print "Folder %s created" % folder
+ return "Folder %s created" % folder
+ else:
+ print "Folder %s already exists" % FOLDER_ID
+ return "Folder %s already exists" % FOLDER_ID
+ finally:
+ setSecurityManager(sm)
Modified: lovely.remotetask/branches/port-for-zope210/src/lovely/remotetask/README.txt
===================================================================
--- lovely.remotetask/branches/port-for-zope210/src/lovely/remotetask/README.txt 2008-05-15 14:57:40 UTC (rev 86776)
+++ lovely.remotetask/branches/port-for-zope210/src/lovely/remotetask/README.txt 2008-05-15 15:32:15 UTC (rev 86777)
@@ -15,6 +15,17 @@
2. They also allow to move expensive operations to other servers. This is
valuable, for example, when converting videos on high-traffic sites.
+Notes for Zope 2.10 users
+-------------------------
+
+If you are using buildout, don't forget to add fakezope2eggs to the buildout.cfg
+
+[fakezope2eggs]
+recipe = affinitic.recipe.fakezope2eggs
+additional-fake-eggs = ZODB3
+
+Please note, Zope 2.10 compatibility is written with intention to get at least something working.
+
Installation
------------
More information about the Checkins
mailing list