summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Trigaux <mat@openerp.com>2013-03-18 17:40:36 +0100
committerMartin Trigaux <mat@openerp.com>2013-03-18 17:40:36 +0100
commit4ef547fd34e13b78294a83fc2f2500021fe1ad6c (patch)
tree2f18c720b1a5bf1b8259e9b0c7e199106517522d
parent4f723dba7f99bd80f3f29eaba114f7238efd5349 (diff)
[IMP] use safe_eval for code execution
bzr revid: mat@openerp.com-20130318164036-dhsbs1e3m22iphfh
-rw-r--r--addons/gamification/__init__.py1
-rw-r--r--addons/gamification/badge.py46
-rw-r--r--addons/gamification/badge_execute.py16
3 files changed, 40 insertions, 23 deletions
diff --git a/addons/gamification/__init__.py b/addons/gamification/__init__.py
index b7f7efeac07..845af643db1 100644
--- a/addons/gamification/__init__.py
+++ b/addons/gamification/__init__.py
@@ -2,3 +2,4 @@ import goal
import plan
import res_users
import badge
+import badge_execute
diff --git a/addons/gamification/badge.py b/addons/gamification/badge.py
index a209eaf822d..c299cacd799 100644
--- a/addons/gamification/badge.py
+++ b/addons/gamification/badge.py
@@ -22,6 +22,7 @@
from openerp.osv import fields, osv
from openerp import tools
from openerp.tools.translate import _
+from openerp.tools.safe_eval import safe_eval
from templates import TemplateHelper
from datetime import date
@@ -146,8 +147,8 @@ class gamification_badge(osv.Model):
help="Can this badge be automatically rewarded",
required=True),
- 'compute_code': fields.text('Compute Code',
- help="The python code that will be executed to verify if a user can receive this badge."),
+ 'compute_code': fields.char('Compute Code',
+ help="The name of the python method that will be executed to verify if a user can receive this badge."),
'goal_type_ids': fields.many2many('gamification.goal.type',
string='Goals Linked',
help="The users that have succeeded theses goals will receive automatically the badge."),
@@ -179,12 +180,7 @@ class gamification_badge(osv.Model):
'stat_this_month': 0,
'rule_auth': 'everyone',
'rule_automatic': 'manual',
- 'compute_code': """# Example of python code to execute
-# Use the variable 'result' to store the list of ids that will receive the badge
-from openerp import pooler
-pool = pooler.get_pool(cr.dbname)
-# return the list of ALL users
-result = pool.get('res.users').search(cr, uid, domain=[], context=context)""",
+ 'compute_code': "self.nobody(cr, uid, context)",
}
def send_badge(self, cr, uid, badge_id, badge_user_ids, user_from=None, context=None):
@@ -232,15 +228,14 @@ result = pool.get('res.users').search(cr, uid, domain=[], context=context)""",
the one validating the condition.
:param ids: the list of id of the badges to check
- In case of python code to execute, the code has access to the local
- variables cr (database cursor), uid (current user id) and context.
- To access other objects of the database, use a code like :
- from openerp import pooler
- pool = pooler.get_pool(cr.dbname)
- pool.get('object.class.reference').action(...)
+ In case of python code to execute, the user should input the name of
+ the function that will be excuted through safe_eval. The globals
+ variables available are cr (database cursor), uid (current user id)
+ and context.
- The result should be a list of res.users ids (int) and stored in the
- local variable 'result' (read after the code execution). A badge_user
+ To create new functions in different modules, create a class extending
+ the 'gamification.badge.execute' class and implementing this method. The result
+ of the function should be a list of res.users ids (int). A badge_user
linked to this badge will be created for each of these users and a
notification will be send.
Beware that the case of user already having this badge is NOT checked
@@ -257,17 +252,22 @@ result = pool.get('res.users').search(cr, uid, domain=[], context=context)""",
for badge in self.browse(cr, uid, ids, context=context):
if badge.rule_automatic == 'python':
- code_obj = compile(badge.compute_code, '<string>', 'exec')
- code_globals = {}
- code_locals = {'cr': cr, 'uid': uid, 'context': context, 'result': []}
- exec code_obj in code_globals, code_locals
-
- if 'result' in code_locals and type(code_locals['result']) == list:
+ values = {'cr': cr, 'uid': uid, 'context': context, 'self': self.pool.get('gamification.badge.execute')}
+ result = safe_eval(badge.compute_code, values, {})
+
+ # code_obj = compile(badge.compute_code, '<string>', 'exec')
+ # code_globals = {}
+ # code_locals = {'cr': cr, 'uid': uid, 'context': context, 'result': []}
+ # exec code_obj in code_globals, code_locals
+ print(result)
+ if type(result) == list:
user_badge_ids = [
badge_user_obj.create(cr, uid, {'user_id': user_id, 'badge_id': badge.id}, context=context)
- for user_id in code_locals['result']
+ for user_id in result
]
self.send_badge(cr, uid, badge.id, user_badge_ids, context=context)
+ else:
+ raise osv.except_osv(_('Error!'), _('Unvalid return content from the evaluation of %s' % str(badge.compute_code)))
elif badge.rule_automatic == 'goals':
common_users = None
diff --git a/addons/gamification/badge_execute.py b/addons/gamification/badge_execute.py
new file mode 100644
index 00000000000..a851bfbb81a
--- /dev/null
+++ b/addons/gamification/badge_execute.py
@@ -0,0 +1,16 @@
+from openerp.osv import osv
+
+
+class gamification_badge_execute(osv.Model):
+ """Class that contains the methods to execute for badge granting"""
+
+ _name = 'gamification.badge.execute'
+ _description = 'Gamification Badge Execute'
+
+ def nobody(self, cr, uid, context):
+ """Return an empty list of users"""
+ return []
+
+ def everybody(self, cr, uid, context):
+ """Return the id of every user"""
+ return self.pool.get('res.users').search(cr, uid, [], context=context)