diff --git a/CHANGELOG b/CHANGELOG
index 927821383f..b7af6e4913 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,4 @@
+* Add button on cron to run once
* Check all fields when writing a sequence of records, values (CVE-2015-0861)
* Add view_ids on tree view
* Add parent_of operator
diff --git a/trytond/ir/cron.py b/trytond/ir/cron.py
index 336def8e63..2cb992403d 100644
--- a/trytond/ir/cron.py
+++ b/trytond/ir/cron.py
@@ -9,7 +9,7 @@ from email.mime.text import MIMEText
from email.header import Header
from ast import literal_eval
-from ..model import ModelView, ModelSQL, fields
+from ..model import ModelView, ModelSQL, fields, dualmethod
from ..tools import get_smtp_server
from ..transaction import Transaction
from ..pool import Pool
@@ -69,6 +69,11 @@ class Cron(ModelSQL, ModelView):
'request_body': ("The following action failed to execute "
"properly: \"%s\"\n%s\n Traceback: \n\n%s\n")
})
+ cls._buttons.update({
+ 'run_once': {
+ 'icon': 'tryton-executable',
+ },
+ })
@classmethod
def __register__(cls, module_name):
@@ -125,52 +130,55 @@ class Cron(ModelSQL, ModelView):
'''
return _INTERVALTYPES[cron.interval_type](cron.interval_number)
- @classmethod
- def send_error_message(cls, cron):
- tb_s = ''.join(traceback.format_exception(*sys.exc_info()))
- tb_s = tb_s.decode('utf-8', 'ignore')
- subject = cls.raise_user_error('request_title',
- raise_exception=False)
- body = cls.raise_user_error('request_body',
- (cron.name, cron.__url__, tb_s),
- raise_exception=False)
-
- from_addr = config.get('email', 'from')
- to_addr = cron.request_user.email
-
- msg = MIMEText(body, _charset='utf-8')
- msg['To'] = to_addr
- msg['From'] = from_addr
- msg['Subject'] = Header(subject, 'utf-8')
- if not to_addr:
- logger.error(msg.as_string())
- else:
- try:
- server = get_smtp_server()
- server.sendmail(from_addr, to_addr, msg.as_string())
- server.quit()
- except Exception:
- logger.error('Unable to deliver email:\n %s',
- msg.as_string(), exc_info=True)
-
- @classmethod
- def _callback(cls, cron):
+ def send_error_message(self):
pool = Pool()
Config = pool.get('ir.configuration')
- try:
- args = (cron.args or []) and literal_eval(cron.args)
+
+ if self.request_user.language:
+ language = self.request_user.language.code
+ else:
+ language = Config.get_language()
+
+ with Transaction().set_user(self.user.id), \
+ Transaction().set_context(language=language):
+ tb_s = ''.join(traceback.format_exception(*sys.exc_info()))
+ tb_s = tb_s.decode('utf-8', 'ignore')
+ subject = self.raise_user_error('request_title',
+ raise_exception=False)
+ body = self.raise_user_error('request_body',
+ (self.name, self.__url__, tb_s),
+ raise_exception=False)
+
+ from_addr = config.get('email', 'from')
+ to_addr = self.request_user.email
+
+ msg = MIMEText(body, _charset='utf-8')
+ msg['To'] = to_addr
+ msg['From'] = from_addr
+ msg['Subject'] = Header(subject, 'utf-8')
+ if not to_addr:
+ logger.error(msg.as_string())
+ else:
+ try:
+ server = get_smtp_server()
+ server.sendmail(from_addr, to_addr, msg.as_string())
+ server.quit()
+ except Exception:
+ logger.error('Unable to deliver email:\n %s',
+ msg.as_string(), exc_info=True)
+
+ @dualmethod
+ @ModelView.button
+ def run_once(cls, crons):
+ pool = Pool()
+ for cron in crons:
+ if cron.args:
+ args = literal_eval(cron.args)
+ else:
+ args = []
Model = pool.get(cron.model)
with Transaction().set_user(cron.user.id):
getattr(Model, cron.function)(*args)
- except Exception:
- Transaction().cursor.rollback()
-
- req_user = cron.request_user
- language = (req_user.language.code if req_user.language
- else Config.get_language())
- with Transaction().set_user(cron.user.id), \
- Transaction().set_context(language=language):
- cls.send_error_message(cron)
@classmethod
def run(cls, db_name):
@@ -189,7 +197,11 @@ class Cron(ModelSQL, ModelView):
first = True
while next_call < now and number_calls != 0:
if first or cron.repeat_missed:
- cls._callback(cron)
+ try:
+ cron.run_once()
+ except Exception:
+ transaction.cursor.rollback()
+ cron.send_error_message()
next_call += cls.get_delta(cron)
if number_calls > 0:
number_calls -= 1
diff --git a/trytond/ir/view/cron_form.xml b/trytond/ir/view/cron_form.xml
index 7367844bcd..7f3355dfe4 100644
--- a/trytond/ir/view/cron_form.xml
+++ b/trytond/ir/view/cron_form.xml
@@ -20,6 +20,7 @@ this repository contains the full copyright notices and license terms. -->
+
diff --git a/trytond/ir/view/cron_list.xml b/trytond/ir/view/cron_list.xml
index b8a2e869c8..190fa4f6cc 100644
--- a/trytond/ir/view/cron_list.xml
+++ b/trytond/ir/view/cron_list.xml
@@ -11,4 +11,5 @@ this repository contains the full copyright notices and license terms. -->
+