[XMLRpc Callbacks] add support for createLDAPUpdate XMLRPC callback

- XmlRpcCallback was renamed BatchJob and the XMLRPC action was
  extracted to another class called XmlRpcAction.

- The administration panel was improved.
This commit is contained in:
Benjamin Dauvergne 2010-07-28 12:22:07 +02:00
parent 6b6a29d2bf
commit 9c08234e13
5 changed files with 67 additions and 39 deletions

View File

@ -13,7 +13,7 @@ authentic.admin.root.register_page('afterjobs',
N_('Neogia registration jobs'))
def xmlrpc_resend(publisher):
for callback in modules.callback.XmlRpcCallback.values(ignore_errors = True):
for callback in modules.callback.BatchJob.values(ignore_errors = True):
callback.do()
get_publisher_class().register_cronjob(CronJob(xmlrpc_resend, minutes = range(0, 60, 1)))

View File

@ -21,12 +21,12 @@ from quixote import get_response, get_request, redirect
import qommon.errors as errors
from qommon import template
from callback import XmlRpcCallback
from callback import BatchJob
from qommon.admin.menu import html_top
class AfterJobStatusDirectory(Directory):
_q_exports = ['', 'run']
_q_exports = ['', 'run', 'delete']
def _q_traverse(self, path):
get_response().breadcrumb.append( ('afterjobs/', _('Neogia registration jobs')) )
@ -37,18 +37,34 @@ class AfterJobStatusDirectory(Directory):
id=get_request().form.get('id')
get_response().breadcrumb.append( ('run/', _('Run job %s') % id) )
if get_request().get_method() == 'POST':
callback = XmlRpcCallback.get(id, ignore_errors = True)
callback = BatchJob.get(id, ignore_errors = True)
if callback:
callback.do()
return redirect('.')
def delete [html] (self):
id=get_request().form.get('id')
if get_request().get_method() == 'POST' and id:
callback = BatchJob.get(id, ignore_errors = True)
if callback:
callback.remove_self()
return redirect('.')
def _q_index [html] (self):
html_top('afterjobs')
'<table width="100%">'
'<thead><tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr></thead>' % \
(_('Id'), _('Email'), _('Classification'), _('Error'))
for callback in XmlRpcCallback.values(ignore_errors = True):
'<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td><form method="post" action="run?id=%s"><input type="submit" value="Run"/></td></tr>' % \
(callback.id, callback.email, callback.classification, callback.error, callback.id)
'<thead><tr><td>%s</td><td>%s</td><td>%s</td></tr></thead>' % \
(_('Id'), _('Action'), _('Error'))
for callback in BatchJob.values(ignore_errors = True):
'''<tr>
<td>%(id)s</td>
<td>%(action)s</td>
<td>%(error)s</td>
<td>
<form method="post" action="run?id=%(id)s"><input type="submit" value="Run"/></form>
<form method="post" action="delete?id=%(id)s"><input type="submit" value="Delete"/></form>
</td>
</tr>''' % \
{ 'id': callback.id, 'action': str(callback.action), 'error': callback.error }
'</table>'

View File

@ -11,28 +11,35 @@ class XmlRpcAction(object):
TYPE_ORGANISME = 'ORGANISME'
TYPE_PERSONNE = 'PERSONNE'
def __init__(self, action, *args):
def __init__(self, action, *args, **kwargs):
url = kwargs.get('url')
if url is None:
identity_configuration = configuration.get_configuration('identities')
url = identity_configuration.get('xmlrpc_registration_url')
self.url = url
self.action = action
self.args = args
@classmethod
def create_ldap_classification(email, classification):
return XmlRpcAction(ACTION_CREATE_LDAP_CLASSIFICATION, email, classification)
def create_ldap_classification(cls, email, classification, url = None):
return XmlRpcAction(XmlRpcAction.ACTION_CREATE_LDAP_CLASSIFICATION, email, classification, url = url)
@classmethod
def create_ldap_update(type, id):
return XmlRpcAction(ACTION_CREATE_LDAP_UPDATE, type, id)
def create_ldap_update(cls, type, id, url = None):
return XmlRpcAction(XmlRpcAction.ACTION_CREATE_LDAP_UPDATE, type, id, url = url)
def do(self):
identity_configuration = configuration.get_configuration('identities')
url = identity_configuration.get('xmlrpc_registration_url')
server = xmlrpclib.ServerProxy(url)
method = getattr(server, self.action)
def __call__(self):
server = xmlrpclib.ServerProxy(self.url)
method = getattr(server, self.action, None)
if method is None:
raise Exception('No action %s on XMLRPC endpoint %s' % (self.action, self.url))
method(*self.args)
get_logger().info('Neogia XmlRpc callback action:%r args:%r' % (self.action, self.args))
class XmlRpcCallback(StorableObject):
_names = 'neogia-callback'
def __str__(self):
return 'XMLRPC Call to url: %s method: %s arguments: %r' % (self.url, self.action, self.args)
class BatchJob(StorableObject):
_names = 'batchjobs'
def __init__(self, action):
self.action = action
@ -45,16 +52,20 @@ class XmlRpcCallback(StorableObject):
def do(self):
try:
self.action.do()
self.action()
except Exception, e:
self.error = repr(e)
self.store()
else:
self.remove_self()
get_logger().info('Batch job %s executed.' % self.action)
try:
self.remove_self()
except OSError:
# Never saved ? Ok
pass
def __call__(self):
try:
self.do()
except:
# Failure ? Finish later
self.store(async = True)
self.do()
def __str__(self):
return '<BatchJob id: %s error: %r action: %s>' % (getattr(self, 'id', None), self.error, self.action)

View File

@ -9,7 +9,7 @@ import authentic.publisher
import authentic.admin.configuration as configuration
import urllib2
import captcha
from callback import XmlRpcCallback, XmlRpcAction
from callback import BatchJob, XmlRpcAction
schema = (('PART_EMP', _('Particulier-employeur')),
(_('Salarie du Particulier-employeur'),
@ -186,7 +186,7 @@ href="conditions">conditions d'utilisation</a>''')),
classification = get_request().form['classification']
action = XmlRpcAction.create_ldap_classification(email, classification)
get_response().add_after_job('''Send registration to Neogia, email = %r,\
classification = %r''' % (email, classification), XmlRpcCallback(action))
classification = %r''' % (email, classification), BatchJob(action))
from qommon.publisher import get_publisher_class
get_publisher_class().root_directory_class = IfefRootDirectory

View File

@ -2,6 +2,7 @@ import authentic.identities
from authentic.identities import Field
from qommon.publisher import utf82sitecharset, sitecharset2utf8
from quixote import get_response
import callback
class IdentitiesStoreIFEF(authentic.identities.IdentitiesStoreLdap):
label = N_('IFEF Ldap Directory')
@ -59,18 +60,18 @@ class IdentitiesStoreIFEF(authentic.identities.IdentitiesStoreLdap):
self.alpha_request_str = '(&(uid=%%s*)(objectclass=%(oc)s))' % \
{ 'oc': self.ldap_object_class }
def save(self):
res = authentic.identities.IdentitiesStoreLdap.save(self)
def save(self, identity):
res = authentic.identities.IdentitiesStoreLdap.save(self, identity)
response = get_response()
try:
if response:
action = XmlRpcCallback.create_ldap_update(XmlRpcCallback.TYPE_PERSONNE, self.id)
id = identity.accounts[0].username
action = callback.XmlRpcAction.create_ldap_update(
callback.XmlRpcAction.TYPE_PERSONNE, id)
response.add_after_job('''Send use information update to Ofbix, \
id: %r''' % self.id, XmlRpcCallback(action))
except e:
pass
id: %r''' % id, callback.BatchJob(action))
except Exception, e:
raise
return res
authentic.identities.stores['ifef'] = IdentitiesStoreIFEF