From a1d4e5af1a1e13d7260bb81ead46f28ced681f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 19 Mar 2012 14:19:45 +0100 Subject: [PATCH] Use RPCProgress almost everywhere Add management of exception inside RPCProgress Add RPCExecute to simplify the usage of RPCProgress review244004 --- CHANGELOG | 1 + tryton/action/main.py | 36 ++--- tryton/common/common.py | 52 ++++-- tryton/gui/main.py | 67 ++++---- tryton/gui/window/board.py | 11 +- tryton/gui/window/dbcreate.py | 2 +- tryton/gui/window/form.py | 46 ++---- tryton/gui/window/preference.py | 41 ++--- tryton/gui/window/view_board/action.py | 9 +- tryton/gui/window/view_form/model/field.py | 60 +++---- tryton/gui/window/view_form/model/group.py | 28 ++-- tryton/gui/window/view_form/model/record.py | 150 +++++++----------- tryton/gui/window/view_form/screen/screen.py | 71 ++++----- tryton/gui/window/view_form/view/form.py | 48 +++--- .../view_form/view/form_gtk/interface.py | 59 ++++--- .../view_form/view/form_gtk/many2many.py | 10 +- .../view_form/view/form_gtk/many2one.py | 42 +++-- .../view_form/view/form_gtk/one2many.py | 16 +- .../view_form/view/form_gtk/reference.py | 10 +- .../view_form/view/form_gtk/selection.py | 19 +-- tryton/gui/window/view_form/view/list.py | 31 ++-- .../window/view_form/view/list_gtk/parser.py | 121 ++++++-------- tryton/gui/window/win_export.py | 83 ++++------ tryton/gui/window/win_form.py | 13 +- tryton/gui/window/win_import.py | 16 +- tryton/gui/window/wizard.py | 34 ++-- 26 files changed, 459 insertions(+), 617 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b85b9e1d35..af80a94784 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Use RPCProgress almost everywhere * Add a simple search box * New domain parser using shlex * Better translation dialog box diff --git a/tryton/action/main.py b/tryton/action/main.py index aca6895e69..a73947c42a 100644 --- a/tryton/action/main.py +++ b/tryton/action/main.py @@ -4,12 +4,11 @@ import tryton.rpc as rpc from tryton.common import message, selection, file_open, mailto from tryton.gui.window import Window from tryton.pyson import PYSONDecoder -from tryton.exceptions import TrytonServerError import gettext import tempfile import os import webbrowser -import tryton.common as common +from tryton.common import RPCProgress, RPCExecute, RPCException _ = gettext.gettext @@ -30,11 +29,9 @@ class Action(object): ctx['email_print'] = email_print ctx['email'] = email args = ('report', name, 'execute', data.get('ids', []), data, ctx) - rpcprogress = common.RPCProgress('execute', args) try: - res = rpcprogress.run() - except TrytonServerError, exception: - common.process_exception(exception) + res = RPCProgress('execute', args).run() + except RPCException: return False if not res: return False @@ -57,26 +54,21 @@ class Action(object): @staticmethod def execute(act_id, data, action_type=None, context=None): - if context is None: - context = {} - ctx = rpc.CONTEXT.copy() - ctx.update(context) if not action_type: res = False try: - res = rpc.execute('model', 'ir.action', 'read', act_id, - ['type'], ctx) - except TrytonServerError, exception: - common.process_exception(exception) + res = RPCExecute('model', 'ir.action', 'read', act_id, + ['type'], context=context) + except RPCException: return if not res: raise Exception('ActionNotFound') action_type = res['type'] try: - res = rpc.execute('model', action_type, 'search_read', - [('action', '=', act_id)], 0, 1, None, None, ctx) - except TrytonServerError, exception: - common.process_exception(exception) + res = RPCExecute('model', action_type, 'search_read', + [('action', '=', act_id)], 0, 1, None, None, + context=context) + except RPCException: return Action._exec_action(res, data) @@ -163,11 +155,9 @@ class Action(object): if 'id' in data: model_id = data.get('id', False) try: - actions = rpc.execute('model', 'ir.action.keyword', - 'get_keyword', keyword, (data['model'], model_id), - rpc.CONTEXT) - except TrytonServerError, exception: - common.process_exception(exception) + actions = RPCExecute('model', 'ir.action.keyword', + 'get_keyword', keyword, (data['model'], model_id)) + except RPCException: return False keyact = {} diff --git a/tryton/common/common.py b/tryton/common/common.py index 6592c51657..b84b0c87bb 100644 --- a/tryton/common/common.py +++ b/tryton/common/common.py @@ -10,6 +10,8 @@ import os import subprocess import re import logging +from functools import wraps +from threading import Semaphore from tryton.config import CONFIG from tryton.config import TRYTON_ICON, PIXMAPS_DIR import time @@ -49,6 +51,7 @@ from tryton.exceptions import (TrytonServerError, TrytonError, _ = gettext.gettext + class TrytonIconFactory(gtk.IconFactory): batchnum = 10 @@ -1154,6 +1157,10 @@ class DBProgress(object): return False +class RPCException(Exception): + pass + + class RPCProgress(object): def __init__(self, method, args): @@ -1176,19 +1183,24 @@ class RPCProgress(object): self.error = True return True - def run(self): + def run(self, process_exception_p=True, main_iteration_p=True): thread.start_new_thread(self.start, ()) - watch = gtk.gdk.Cursor(gtk.gdk.WATCH) - self.parent.window.set_cursor(watch) + watch = None parent_sensitive = self.parent.props.sensitive - self.parent.props.sensitive = False i = 0 win = None progressbar = None while (not self.res) and (not self.error): i += 1 - if i > 10: + if i > 1: + watch = gtk.gdk.Cursor(gtk.gdk.WATCH) + self.parent.window.set_cursor(watch) + if main_iteration_p: + with gtk.gdk.lock: + while gtk.events_pending(): + gtk.main_iteration() + if i > 10 and main_iteration_p: if not win or not progressbar: win = gtk.Window(type=gtk.WINDOW_TOPLEVEL) win.set_position(gtk.WIN_POS_CENTER_ON_PARENT) @@ -1225,24 +1237,40 @@ class RPCProgress(object): win.set_modal(True) win.show_all() win.window.set_cursor(watch) + self.parent.props.sensitive = False with gtk.gdk.lock: progressbar.pulse() - if win: - with gtk.gdk.lock: - while gtk.events_pending(): - gtk.main_iteration() time.sleep(0.1) self.parent.props.sensitive = parent_sensitive self.parent.window.set_cursor(None) if win: win.destroy() - while gtk.events_pending(): - gtk.main_iteration() + with gtk.gdk.lock: + while gtk.events_pending(): + gtk.main_iteration() if self.exception: - raise self.exception + if process_exception_p: + if process_exception(self.exception): + self.res = None + self.error = False + self.exception = None + return self.run(process_exception_p) + raise RPCException() + else: + raise self.exception return self.res +def RPCExecute(*args, **kwargs): + rpc_context = rpc.CONTEXT.copy() + if kwargs.get('context'): + rpc_context.update(kwargs['context']) + args = args + (rpc_context,) + process_exception = kwargs.get('process_exception', True) + main_iteration = kwargs.get('main_iteration', True) + return RPCProgress('execute', args).run(process_exception, main_iteration) + + class Tooltips(object): _tooltips = None diff --git a/tryton/gui/main.py b/tryton/gui/main.py index 57d802436f..8d6c23c7de 100644 --- a/tryton/gui/main.py +++ b/tryton/gui/main.py @@ -15,6 +15,7 @@ except ImportError: import json import webbrowser import tryton.rpc as rpc +from tryton.common import RPCExecute, RPCException from tryton.config import CONFIG, TRYTON_ICON, get_config_dir import tryton.common as common from tryton.pyson import PYSONDecoder @@ -714,21 +715,20 @@ class Main(object): if not ids: return try: - values = rpc.execute('model', self.menu_screen.model_name, - 'read', ids, ['rec_name'], rpc.CONTEXT) - except TrytonServerError, exception: - common.process_exception(exception) + values = RPCExecute('model', self.menu_screen.model_name, + 'read', ids, ['rec_name']) + except RPCException: return try: for value in values: - rpc.execute('model', 'ir.ui.view_sc', 'create', { - 'name': value['rec_name'], - 'res_id': value['id'], - 'user_id': rpc._USER, - 'resource': self.menu_screen.model_name, - }, rpc.CONTEXT) - except TrytonServerError, exception: - common.process_exception(exception) + RPCExecute('model', 'ir.ui.view_sc', 'create', { + 'name': value['rec_name'], + 'res_id': value['id'], + 'user_id': rpc._USER, + 'resource': self.menu_screen.model_name, + }) + except RPCException: + pass self.shortcut_unset() def _manage_shortcut(widget): @@ -739,9 +739,9 @@ class Main(object): user = rpc._USER try: - shortcuts = rpc.execute('model', 'ir.ui.view_sc', 'get_sc', - user, 'ir.ui.menu', rpc.CONTEXT) - except TrytonServerError: + shortcuts = RPCExecute('model', 'ir.ui.view_sc', 'get_sc', + user, 'ir.ui.menu') + except RPCException: shortcuts = [] menu = self.menuitem_shortcut.get_submenu() if not menu: @@ -832,8 +832,11 @@ class Main(object): win = Preference(rpc._USER) if win.run(): rpc.context_reload() - prefs = rpc.execute('model', 'res.user', - 'get_preferences', False, rpc.CONTEXT) + try: + prefs = RPCExecute('model', 'res.user', 'get_preferences', + False) + except RPCException: + prefs = None if prefs and 'language_direction' in prefs: translate.set_language_direction(prefs['language_direction']) CONFIG['client.language_direction'] = \ @@ -883,14 +886,14 @@ class Main(object): if not rpc._USER: return if not exception: - res = rpc.execute('model', 'res.request', 'request_get', - rpc.CONTEXT) + res = RPCExecute('model', 'res.request', 'request_get', + process_exception=False) if not res: return ([], []) ids, ids2 = res else: - ids, ids2 = rpc.execute('model', 'res.request', 'request_get', - rpc.CONTEXT) + ids, ids2 = RPCExecute('model', 'res.request', 'request_get', + process_exception=False) message = _('Waiting requests: %s received - %s sent') % (len(ids), len(ids2)) self.sb_requests.set_text(message) @@ -921,9 +924,9 @@ class Main(object): self.refresh_ssl() if log_response > 0: try: - prefs = rpc.execute('model', 'res.user', 'get_preferences', - False, rpc.CONTEXT) - except TrytonServerError: + prefs = RPCExecute('model', 'res.user', 'get_preferences', + False) + except RPCException: prefs = None common.ICONFACTORY.load_icons() if prefs and 'language_direction' in prefs: @@ -1045,13 +1048,11 @@ class Main(object): from tryton.gui.window.view_form.screen import Screen if not prefs: - args = ('model', 'res.user', 'get_preferences', False, rpc.CONTEXT) try: - prefs = rpc.execute(*args) - except TrytonServerError, exception: - prefs = common.process_exception(exception, *args) - if not prefs: - return + prefs = RPCExecute('model', 'res.user', 'get_preferences', + False) + except RPCException: + return False if self.pane.get_child1(): self.pane.remove(self.pane.get_child1()) if self.pane.get_position(): @@ -1293,7 +1294,7 @@ class Main(object): rpcprogress = common.RPCProgress('db_exec', (host, int(port), 'drop', dbname, passwd)) try: - rpcprogress.run() + rpcprogress.run(False) except TrytonServerError, exception: self.refresh_ssl() if exception.faultCode == "AccessDenied": @@ -1324,7 +1325,7 @@ class Main(object): rpcprogress = common.RPCProgress('db_exec', (host, int(port), 'restore', dbname, passwd, buffer(data), update)) try: - res = rpcprogress.run() + res = rpcprogress.run(False) except TrytonServerError, exception: self.refresh_ssl() if exception.faultCode == \ @@ -1365,7 +1366,7 @@ class Main(object): rpcprogress = common.RPCProgress('db_exec', (host, int(port), 'dump', dbname, passwd)) try: - dump = rpcprogress.run() + dump = rpcprogress.run(False) except TrytonServerError, exception: if exception.faultCode == "Couldn't dump database with password": common.warning(_("It is not possible to dump a password " \ diff --git a/tryton/gui/window/board.py b/tryton/gui/window/board.py index 0516e9d2ea..e1ed1719ed 100644 --- a/tryton/gui/window/board.py +++ b/tryton/gui/window/board.py @@ -4,10 +4,8 @@ import gettext from tryton.signal_event import SignalEvent from tryton.gui import Main -import tryton.rpc as rpc from tryton.gui.window.view_board import ViewBoard -import tryton.common as common -from tryton.exceptions import TrytonServerError +from tryton.common import RPCExecute, RPCException from tabcontent import TabContent @@ -44,10 +42,9 @@ class Board(SignalEvent, TabContent): super(Board, self).__init__() try: - view = rpc.execute('model', 'ir.ui.view', 'read', - view_id, ['arch'], context) - except TrytonServerError, exception: - common.process_exception(exception) + view = RPCExecute('model', 'ir.ui.view', 'read', + view_id, ['arch'], context=context) + except RPCException: raise self.board = ViewBoard(view['arch'], context=context) diff --git a/tryton/gui/window/dbcreate.py b/tryton/gui/window/dbcreate.py index 817f7592a7..3fa5c1d217 100644 --- a/tryton/gui/window/dbcreate.py +++ b/tryton/gui/window/dbcreate.py @@ -371,7 +371,7 @@ class DBCreate(object): rpcprogress = common.RPCProgress('db_exec', (host, int(port), 'create', dbname, passwd, langreal, admin_passwd.get_text())) - rpcprogress.run() + rpcprogress.run(False) except TrytonServerError, exception: if str(exception.faultCode) == "AccessDenied": common.warning(_("Sorry, wrong password for " \ diff --git a/tryton/gui/window/form.py b/tryton/gui/window/form.py index 9c683779ae..adf3a814d3 100644 --- a/tryton/gui/window/form.py +++ b/tryton/gui/window/form.py @@ -5,7 +5,6 @@ import gettext import gtk import gobject import locale -import tryton.rpc as rpc from tryton.gui.window.view_form.screen import Screen from tryton.action import Action from tryton.gui import Main @@ -16,11 +15,11 @@ from tryton.gui.window.attachment import Attachment from tryton.signal_event import SignalEvent from tryton.common import (TRYTON_ICON, message, sur, sur_3b, COLOR_SCHEMES, timezoned_date) -from tryton.exceptions import TrytonServerError import tryton.common as common from tryton.translate import date_format from tryton.common import HM_FORMAT from tryton.pyson import PYSONEncoder +from tryton.common import RPCExecute, RPCException from tabcontent import TabContent @@ -147,16 +146,11 @@ class Form(SignalEvent, TabContent): gobject.timeout_add(int(auto_refresh) * 1000, self.sig_reload) def get_toolbars(self): - ctx = {} - ctx.update(rpc.CONTEXT) - ctx.update(self.context) - args = ('model', self.model, 'view_toolbar_get', ctx) try: - toolbars = rpc.execute(*args) - except TrytonServerError, exception: - toolbars = common.process_exception(exception, *args) - toolbars = toolbars if toolbars else {} - return toolbars + return RPCExecute('model', self.model, 'view_toolbar_get', + context=self.context) + except RPCException: + return {} def widget_get(self): return self.screen.widget @@ -282,16 +276,11 @@ class Form(SignalEvent, TabContent): ('write_date', _('Latest Modification Date:')), ] - ctx = self.context.copy() - ctx.update(rpc.CONTEXT) - args = ('model', self.model, 'read', [obj_id], [x[0] for x in fields], - ctx) try: - res = rpc.execute(*args) - except TrytonServerError, exception: - res = common.process_exception(exception, *args) - if not res: - return + res = RPCExecute('model', self.model, 'read', [obj_id], + [x[0] for x in fields], context=self.context) + except RPCException: + return message_str = '' for line in res: for (key, val) in fields: @@ -348,17 +337,14 @@ class Form(SignalEvent, TabContent): if not self.modified_save(): return res_ids = self.sel_ids_get() - ctx = self.context.copy() - ctx.update(rpc.CONTEXT) - args = ('model', self.model, 'copy', res_ids, {}, ctx) try: - new_ids = rpc.execute(*args) - except TrytonServerError, exception: - new_ids = common.process_exception(exception, *args) - if new_ids: - self.screen.load(new_ids) - self.message_info(_('Working now on the duplicated record(s)!'), - 'green') + new_ids = RPCExecute('model', self.model, 'copy', res_ids, {}, + context=self.context) + except RPCException: + return + self.screen.load(new_ids) + self.message_info(_('Working now on the duplicated record(s)!'), + 'green') def sig_save(self, widget=None): if self.screen.save_current(): diff --git a/tryton/gui/window/preference.py b/tryton/gui/window/preference.py index 0762060e4b..285337df0d 100644 --- a/tryton/gui/window/preference.py +++ b/tryton/gui/window/preference.py @@ -3,12 +3,11 @@ "Preference" import gettext import gtk -import tryton.rpc as rpc import copy from tryton.gui.window.view_form.screen import Screen from tryton.config import TRYTON_ICON -from tryton.exceptions import TrytonServerError import tryton.common as common +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -35,16 +34,13 @@ class Preference(object): self.win.set_default_response(gtk.RESPONSE_OK) - args = ('model', 'res.user', 'get_preferences_fields_view', - rpc.CONTEXT) try: - view = rpc.execute(*args) - except TrytonServerError, exception: - view = common.process_exception(exception, *args) - if not view: - self.win.destroy() - self.win = None - return + view = RPCExecute('model', 'res.user', + 'get_preferences_fields_view') + except RPCException: + self.win.destroy() + self.win = None + return title = gtk.Label(_('Edit User Preferences')) title.show() @@ -53,14 +49,13 @@ class Preference(object): self.screen.add_view(view) self.screen.new(default=False) - args = ('model', 'res.user', 'get_preferences', False, rpc.CONTEXT) try: - preferences = rpc.execute(*args) - except TrytonServerError, exception: - preferences = common.process_exception(exception, *args) - if not preferences: - self.win.destroy() - raise + preferences = RPCExecute('model', 'res.user', 'get_preferences', + False) + except RPCException: + self.win.destroy() + self.win = None + return self.screen.current_record.set(preferences) self.screen.current_record.validate(softvalidation=True) self.screen.screen_container.set(self.screen.current_view.widget) @@ -91,13 +86,11 @@ class Preference(object): break else: password = False - args = ('model', 'res.user', 'set_preferences', vals, - password, rpc.CONTEXT) try: - rpc.execute(*args) - except TrytonServerError, exception: - if not common.process_exception(exception, *args): - continue + RPCExecute('model', 'res.user', 'set_preferences', vals, + password) + except RPCException: + continue res = True break else: diff --git a/tryton/gui/window/view_board/action.py b/tryton/gui/window/view_board/action.py index a0e45070ef..017fbc3c4d 100644 --- a/tryton/gui/window/view_board/action.py +++ b/tryton/gui/window/view_board/action.py @@ -8,8 +8,8 @@ import tryton.common as common from tryton.pyson import PYSONDecoder import gettext from tryton.signal_event import SignalEvent -from tryton.exceptions import TrytonServerError from tryton.gui.window.win_form import WinForm +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -21,10 +21,9 @@ class Action(SignalEvent): self.context = context or {} try: - self.action = rpc.execute('model', 'ir.action.act_window', 'read', - self.act_id, False, rpc.CONTEXT) - except TrytonServerError, exception: - common.process_exception(exception) + self.action = RPCExecute('model', 'ir.action.act_window', 'read', + self.act_id, False) + except RPCException: raise view_ids = None diff --git a/tryton/gui/window/view_form/model/field.py b/tryton/gui/window/view_form/model/field.py index 63a4d16346..78fdf01303 100644 --- a/tryton/gui/window/view_form/model/field.py +++ b/tryton/gui/window/view_form/model/field.py @@ -3,16 +3,15 @@ import os import tempfile import locale -import tryton.rpc as rpc from tryton.common import datetime_strftime, HM_FORMAT, \ domain_inversion, eval_domain, localize_domain, unlocalize_domain, \ - merge, inverse_leaf, EvalEnvironment, RPCProgress + merge, inverse_leaf, EvalEnvironment import tryton.common as common import time import datetime from decimal import Decimal -from tryton.exceptions import TrytonServerError from tryton.translate import date_format +from tryton.common import RPCExecute, RPCException class Field(object): @@ -379,14 +378,11 @@ class M2OField(CharField): else: value = None if not rec_name and value >= 0: - args = ('model', self.attrs['relation'], 'read', value, - ['rec_name'], rpc.CONTEXT) try: - result = rpc.execute(*args) - except TrytonServerError, exception: - result = common.process_exception(exception, *args) - if not result: - return + result = RPCExecute('model', self.attrs['relation'], 'read', value, + ['rec_name']) + except RPCException: + return False rec_name = result['rec_name'] or '' record.value[self.name + '.rec_name'] = rec_name record.value[self.name] = value @@ -604,14 +600,11 @@ class O2MField(CharField): and fieldname not in fields): field_names.append(fieldname) if field_names: - args = ('model', self.attrs['relation'], 'fields_get', - field_names, context) try: - fields.update(rpc.execute(*args)) - except TrytonServerError, exception: - fields = common.process_exception(exception, *args) - if not fields: - return False + fields.update(RPCExecute('model', self.attrs['relation'], + 'fields_get', field_names, context=context)) + except RPCException: + return False parent_name = self.attrs.get('relation_field', '') group = Group(self.attrs['relation'], fields, @@ -647,14 +640,11 @@ class O2MField(CharField): for fieldname in val.keys(): if fieldname not in field_names: field_names.append(fieldname) - args = ('model', self.attrs['relation'], 'fields_get', - field_names, context) try: - fields = rpc.execute(*args) - except TrytonServerError, exception: - fields = common.process_exception(exception, *args) - if not fields: - return False + fields = RPCExecute('model', self.attrs['relation'], + 'fields_get', field_names, context=context) + except RPCException: + return False to_remove = [] for record2 in record.value[self.name]: @@ -813,14 +803,11 @@ class ReferenceField(CharField): rec_name = record.value.get(self.name + '.rec_name') or '' if ref_model and ref_id >= 0: if not rec_name and ref_id >= 0: - args = ('model', ref_model, 'read', ref_id, - ['rec_name'], rpc.CONTEXT) try: - result = rpc.execute(*args) - except TrytonServerError, exception: - result = common.process_exception(exception, *args) - if not result: - return + result = RPCExecute('model', ref_model, 'read', ref_id, + ['rec_name']) + except RPCException: + return rec_name = result['rec_name'] elif ref_model: rec_name = '' @@ -873,14 +860,11 @@ class BinaryField(CharField): if not isinstance(record.value.get(self.name), (basestring, buffer)): if record.id < 0: return '' - ctx = rpc.CONTEXT.copy() - ctx.update(record.context_get()) - rpcprogress = RPCProgress('execute', ('model', record.model_name, - 'read', record.id, [self.name], ctx)) + context = record.context_get() try: - values = rpcprogress.run() - except TrytonServerError, exception: - values = common.process_exception(exception) + values = RPCExecute('model', record.model_name, 'read', + record.id, [self.name], context=context) + except RPCException: return '' _, filename = tempfile.mkstemp(prefix='tryton_') with open(filename, 'wb') as fp: diff --git a/tryton/gui/window/view_form/model/group.py b/tryton/gui/window/view_form/model/group.py index bf19c3dc2d..a820ab8bca 100644 --- a/tryton/gui/window/view_form/model/group.py +++ b/tryton/gui/window/view_form/model/group.py @@ -1,12 +1,10 @@ #This file is part of Tryton. The COPYRIGHT file at the top level of #this repository contains the full copyright notices and license terms. -import tryton.rpc as rpc from record import Record from field import Field, O2MField from tryton.signal_event import SignalEvent -import tryton.common as common -from tryton.exceptions import TrytonServerError from tryton.common.domain_inversion import is_leaf +from tryton.common import RPCExecute, RPCException class Group(SignalEvent, list): @@ -178,14 +176,11 @@ class Group(SignalEvent, list): return [] res = [] for fnct in self.on_write: - args = ('model', self.model_name, fnct, ids, self.context) try: - res += rpc.execute(*args) - except TrytonServerError, exception: - res2 = common.process_exception(exception, *args) - if not res2: - return [] - res += res2 + res += RPCExecute('model', self.model_name, fnct, ids, + context=self.context) + except RPCException: + return [] return list({}.fromkeys(res)) def load(self, ids, display=True, modified=False, id2record=None): @@ -230,7 +225,7 @@ class Group(SignalEvent, list): return True def _get_context(self): - ctx = rpc.CONTEXT.copy() + ctx = self._context.copy() if self.parent: ctx.update(self.parent.context_get()) ctx.update(self._context) @@ -370,14 +365,11 @@ class Group(SignalEvent, list): if len(new) and len(to_add): ctx.update(self.context) - args = ('model', self.model_name, 'default_get', to_add.keys(), - ctx) try: - values = rpc.execute(*args) - except TrytonServerError, exception: - values = common.process_exception(exception, *args) - if not values: - return False + values = RPCExecute('model', self.model_name, 'default_get', + to_add.keys(), context=ctx) + except RPCException: + return False for name in to_add: if name not in values: values[name] = False diff --git a/tryton/gui/window/view_form/model/record.py b/tryton/gui/window/view_form/model/record.py index e22a64fbb3..592c762981 100644 --- a/tryton/gui/window/view_form/model/record.py +++ b/tryton/gui/window/view_form/model/record.py @@ -11,7 +11,7 @@ import tryton.common as common from tryton.pyson import PYSONDecoder import field as fields from functools import reduce -from tryton.exceptions import TrytonServerError +from tryton.common import RPCExecute, RPCException POOL = defaultdict(WeakSet) @@ -44,7 +44,7 @@ class Record(SignalEvent): self.destroyed = False POOL[model_name].add(self) - def __getitem__(self, name, raise_exception=False): + def __getitem__(self, name): if name not in self._loaded and self.id >= 0: id2record = { self.id: self, @@ -95,26 +95,20 @@ class Record(SignalEvent): if 'rec_name' not in fnames: fnames.append('rec_name') fnames.append('_timestamp') - ctx = rpc.CONTEXT.copy() - ctx.update(record_context) + ctx = record_context.copy() ctx.update(dict(('%s.%s' % (self.model_name, fname), 'size') for fname, field in self.group.fields.iteritems() if field.attrs['type'] == 'binary' and fname in fnames)) - args = ('model', self.model_name, 'read', id2record.keys(), fnames, - ctx) exception = None try: - values = rpc.execute(*args) - except TrytonServerError, exception: - if raise_exception: - raise - values = common.process_exception(exception, *args) - if not values: - values = [{'id': x} for x in id2record] - default_values = dict((f, False) for f in fnames) - for value in values: - value.update(default_values) - self.exception = True + values = RPCExecute('model', self.model_name, 'read', + id2record.keys(), fnames, context=ctx, main_iteration=False) + except RPCException, exception: + values = [{'id': x} for x in id2record] + default_values = dict((f, False) for f in fnames) + for value in values: + value.update(default_values) + self.exception = True id2value = dict((value['id'], value) for value in values) if len(id2record) > 1: for id, record in id2record.iteritems(): @@ -272,14 +266,11 @@ class Record(SignalEvent): if self.id < 0 or self.modified: if self.id < 0: value = self.get(get_readonly=True) - args = ('model', self.model_name, 'create', value, - self.context_get()) try: - res = rpc.execute(*args) - except TrytonServerError, exception: - res = common.process_exception(exception, *args) - if not res: - return False + res = RPCExecute('model', self.model_name, 'create', value, + context=self.context_get()) + except RPCException: + return False old_id = self.id self.id = res self.group.id_changed(old_id) @@ -291,15 +282,12 @@ class Record(SignalEvent): context = self.context_get() context = context.copy() context['_timestamp'] = self.get_timestamp() - args = ('model', self.model_name, 'write', [self.id], - value, context) try: - if not rpc.execute(*args): - return False - except TrytonServerError, exception: - res = common.process_exception(exception, *args) - if not res: + if not RPCExecute('model', self.model_name, 'write', + [self.id], value, context=context): return False + except RPCException: + return False self._loaded.clear() self.modified_fields = {} if force_reload: @@ -321,7 +309,6 @@ class Record(SignalEvent): assert all(r.group == group for r in records) records = [r for r in records if r.id >= 0] ctx = {} - ctx.update(rpc.CONTEXT) ctx.update(context or {}) ctx['_timestamp'] = {} for rec in records: @@ -330,26 +317,22 @@ class Record(SignalEvent): reload_ids = set(group.on_write_ids(list(record_ids))) reload_ids -= record_ids reload_ids = list(reload_ids) - args = ('model', record.model_name, 'delete', list(record_ids), ctx) try: - rpc.execute(*args) - except TrytonServerError, exception: - if not common.process_exception(exception, *args): - return False + RPCExecute('model', record.model_name, 'delete', list(record_ids), + context=ctx) + except RPCException: + return False if reload_ids: group.root_group.reload(reload_ids) return True def default_get(self, domain=None, context=None): if len(self.group.fields): - args = ('model', self.model_name, 'default_get', - self.group.fields.keys(), context) try: - vals = rpc.execute(*args) - except TrytonServerError, exception: - vals = common.process_exception(exception, *args) - if not vals: - return + vals = RPCExecute('model', self.model_name, 'default_get', + self.group.fields.keys(), context=context) + except RPCException: + return if (self.parent and self.parent_name in self.group.fields and (self.group.fields[self.parent_name].attrs['relation'] @@ -362,16 +345,11 @@ class Record(SignalEvent): self.do_autocomplete(fieldname) def rec_name(self): - ctx = rpc.CONTEXT.copy() - ctx.update(self.context_get()) - args = ('model', self.model_name, 'read', self.id, ['rec_name'], ctx) try: - res = rpc.execute(*args) - except TrytonServerError, exception: - res = common.process_exception(exception, *args) - if not res: - return '' - return res['rec_name'] + return RPCExecute('model', self.model_name, 'read', self.id, + ['rec_name'], context=self.context_get())['rec_name'] + except RPCException: + return '' def validate(self, fields=None, softvalidation=False): if isinstance(fields, list) and fields: @@ -469,10 +447,11 @@ class Record(SignalEvent): if check_load: self._check_load() ctx = rpc.CONTEXT.copy() + ctx['context'] = ctx for name, field in self.group.fields.items(): ctx[name] = field.get_eval(self, check_load=check_load) - ctx['context'] = self.context_get() + ctx['context'].update(self.context_get()) ctx['active_id'] = self.id ctx['_user'] = rpc._USER if self.parent and self.parent_name: @@ -498,15 +477,11 @@ class Record(SignalEvent): if isinstance(attr, basestring): attr = PYSONDecoder().decode(attr) args = self._get_on_change_args(attr) - ctx = rpc.CONTEXT.copy() - ctx.update(self.context_get()) - args = ('model', self.model_name, 'on_change_' + fieldname, args, ctx) try: - res = rpc.execute(*args) - except TrytonServerError, exception: - res = common.process_exception(exception, *args) - if not res: - return + res = RPCExecute('model', self.model_name, + 'on_change_' + fieldname, args, context=self.context_get()) + except RPCException: + return later = {} for fieldname, value in res.items(): if fieldname not in self.group.fields: @@ -547,29 +522,22 @@ class Record(SignalEvent): continue fieldnames.add(fieldname) values.update(self._get_on_change_args(on_change_with)) - ctx = rpc.CONTEXT.copy() - ctx.update(self.context_get()) if fieldnames: - args = ('model', self.model_name, 'on_change_with', - list(fieldnames), values, ctx) try: - result = rpc.execute(*args) - except TrytonServerError, exception: - result = common.process_exception(exception, *args) - if not result: - return + result = RPCExecute('model', self.model_name, 'on_change_with', + list(fieldnames), values, context=self.context_get()) + except RPCException: + return for fieldname, value in result.items(): self.group.fields[fieldname].set_on_change(self, value) for fieldname in later: values = self._get_on_change_args(on_change_with) - args = ('model', self.model_name, 'on_change_with_' + fieldname, - values, ctx) try: - result = rpc.execute(*args) - except TrytonServerError, exception: - result = common.process_exception(exception, *args) - if not result: - return + result = RPCExecute('model', self.model_name, + 'on_change_with_' + fieldname, values, + context=self.context_get()) + except RPCException: + return self.group.fields[fieldname].set_on_change(self, result) def autocomplete_with(self, field_name): @@ -583,29 +551,25 @@ class Record(SignalEvent): self.autocompletion[fieldname] = [] autocomplete = self.group.fields[fieldname].attrs['autocomplete'] args = self._get_on_change_args(autocomplete) - ctx = rpc.CONTEXT.copy() - ctx.update(self.context_get()) - args = ('model', self.model_name, 'autocomplete_' + fieldname, args, - ctx) try: - res = rpc.execute(*args) - except TrytonServerError, exception: - res = common.process_exception(exception, *args) - if not res: - # ensure res is a list - res = [] + res = RPCExecute('model', self.model_name, 'autocomplete_' + + fieldname, args, context=self.context_get()) + except RPCException: + # ensure res is a list + res = [] self.autocompletion[fieldname] = res def get_attachment_count(self, reload=False): if self.id < 0: return 0 if self.attachment_count < 0 or reload: - args = ('model', 'ir.attachment', 'search_count', [ - ('resource', '=', '%s,%s' % (self.model_name, self.id)), - ], rpc.CONTEXT) try: - self.attachment_count = rpc.execute(*args) - except TrytonServerError: + self.attachment_count = RPCExecute('model', 'ir.attachment', + 'search_count', [ + ('resource', '=', + '%s,%s' % (self.model_name, self.id)), + ]) + except RPCException: return 0 return self.attachment_count diff --git a/tryton/gui/window/view_form/screen/screen.py b/tryton/gui/window/view_form/screen/screen.py index 3a3c99538d..ffedd0a433 100644 --- a/tryton/gui/window/view_form/screen/screen.py +++ b/tryton/gui/window/view_form/screen/screen.py @@ -14,10 +14,10 @@ from tryton.gui.window.view_form.model.record import Record from tryton.gui.window.view_form.view.screen_container import ScreenContainer from tryton.signal_event import SignalEvent from tryton.config import CONFIG -import tryton.common as common from tryton.exceptions import TrytonServerError, TrytonServerUnavailable from tryton.jsonrpc import JSONEncoder from tryton.common.domain_parser import DomainParser +from tryton.common import RPCExecute, RPCException class Screen(SignalEvent): @@ -89,14 +89,11 @@ class Screen(SignalEvent): def search_active(self, active=True): if active and not self.parent: if not self.fields_view_tree: - ctx = {} - ctx.update(rpc.CONTEXT) - ctx.update(self.context) try: - self.fields_view_tree = rpc.execute('model', - self.model_name, 'fields_view_get', False, - 'tree', ctx) - except TrytonServerError: + self.fields_view_tree = RPCExecute('model', + self.model_name, 'fields_view_get', False, 'tree', + context=self.context) + except RPCException: return fields = self.fields_view_tree['fields'] @@ -117,10 +114,9 @@ class Screen(SignalEvent): def get_selection(self, props): try: - selection = rpc.execute('model', - self.model_name, props['selection'], rpc.CONTEXT) - except TrytonServerError, exception: - common.process_exception(exception, None) + selection = RPCExecute('model', self.model_name, + props['selection']) + except RPCException: selection = [] selection.sort(lambda x, y: cmp(x[1], y[1])) return selection @@ -148,29 +144,23 @@ class Screen(SignalEvent): else: domain = [('id', 'in', [x.id for x in self.group])] - ctx = {} - ctx.update(rpc.CONTEXT) - ctx.update(self.context) if domain: if self.domain: domain = ['AND', domain, self.domain] else: domain = self.domain - rpc_args = ('model', self.model_name, 'search', domain, self.offset, - self.limit, self.sort, ctx) try: - ids = rpc.execute(*rpc_args) - except TrytonServerError, exception: - ids = (common.process_exception(exception, *rpc_args) or []) + ids = RPCExecute('model', self.model_name, 'search', domain, + self.offset, self.limit, self.sort, context=self.context) + except RPCException: + ids = [] if not only_ids: if len(ids) == self.limit: - rpc_args = ('model', self.model_name, 'search_count', domain, - ctx) try: - self.search_count = rpc.execute(*rpc_args) - except TrytonServerError, exception: - self.search_count = (common.process_exception(exception, - *rpc_args) or 0) + self.search_count = RPCExecute('model', self.model_name, + 'search_count', domain, context=self.context) + except RPCException: + self.search_count = 0 else: self.search_count = len(ids) self.screen_container.but_prev.set_sensitive(bool(self.offset)) @@ -344,17 +334,11 @@ class Screen(SignalEvent): if view_type in self.views_preload: view = self.views_preload[view_type] else: - ctx = {} - ctx.update(rpc.CONTEXT) - ctx.update(self.context) - args = ('model', self.model_name, 'fields_view_get', - view_id, view_type, ctx) try: - view = rpc.execute(*args) - except TrytonServerError, exception: - view = common.process_exception(exception, *args) - if not view: - return + view = RPCExecute('model', self.model_name, 'fields_view_get', + view_id, view_type, context=self.context) + except RPCException: + return return self.add_view(view, display, context=context) def add_view(self, view, display=False, context=None): @@ -606,12 +590,12 @@ class Screen(SignalEvent): if expanded_nodes is None: json_domain = self.get_tree_domain(parent) try: - expanded_nodes = rpc.execute('model', + expanded_nodes = RPCExecute('model', 'ir.ui.view_tree_expanded_state', 'get_expanded', self.model_name, json_domain, - self.current_view.children_field, rpc.CONTEXT) + self.current_view.children_field) expanded_nodes = json.loads(expanded_nodes) - except TrytonServerError: + except RPCException: expanded_nodes = [] self.expanded_nodes[parent][view.children_field] = expanded_nodes view.expand_nodes(expanded_nodes) @@ -631,9 +615,10 @@ class Screen(SignalEvent): json_domain = self.get_tree_domain(parent) json_paths = json.dumps(paths) try: - rpc.execute('model', 'ir.ui.view_tree_expanded_state', + RPCExecute('model', 'ir.ui.view_tree_expanded_state', 'set_expanded', self.model_name, json_domain, - self.current_view.children_field, json_paths, rpc.CONTEXT) + self.current_view.children_field, json_paths, + process_exception=False) except (TrytonServerError, TrytonServerUnavailable): pass @@ -666,14 +651,14 @@ class Screen(SignalEvent): if self.current_view.view_type == 'calendar' and \ len(self.views) > 1: self.switch_view() + self.search_active(self.current_view.view_type \ + in ('tree', 'graph', 'calendar')) for view in self.views: view.display() self.current_view.widget.set_sensitive( bool(self.group \ or (self.current_view.view_type != 'form') \ or self.current_record)) - self.search_active(self.current_view.view_type \ - in ('tree', 'graph', 'calendar')) if set_cursor: self.set_cursor(reset_view=False) self.set_tree_state() diff --git a/tryton/gui/window/view_form/view/form.py b/tryton/gui/window/view_form/view/form.py index 6eb0c68b15..976e369a5b 100644 --- a/tryton/gui/window/view_form/view/form.py +++ b/tryton/gui/window/view_form/view/form.py @@ -4,11 +4,10 @@ import operator from functools import reduce import gtk import gettext -import tryton.rpc as rpc import tryton.common as common from interface import ParserView -from tryton.exceptions import TrytonServerError from tryton.action import Action +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -25,6 +24,16 @@ class ViewForm(ParserView): if isinstance(button, gtk.Button): button.connect('clicked', self.button_clicked) + # Force to display the first time it switches on a page + # This avoids glitch in position of widgets + display_done = {} + for notebook in notebooks: + def switch(notebook, page, page_num): + if page_num not in display_done.setdefault(notebook, []): + display_done[notebook].append(page_num) + self.display() + notebook.connect('switch-page', switch) + self.widgets = children for widgets in self.widgets.itervalues(): for widget in widgets: @@ -163,37 +172,34 @@ class ViewForm(ParserView): if not attrs.get('confirm', False) or \ common.sur(attrs['confirm']): button_type = attrs.get('type', 'workflow') - ctx = rpc.CONTEXT.copy() - ctx.update(record.context_get()) + context = record.context_get() if button_type == 'workflow': - args = ('model', self.screen.model_name, + try: + RPCExecute('model', self.screen.model_name, 'workflow_trigger_validate', record_id, - attrs['name'], ctx) - try: - rpc.execute(*args) - except TrytonServerError, exception: - common.process_exception(exception, *args) + attrs['name'], context=context) + except RPCException: + pass elif button_type == 'object': - args = ('model', self.screen.model_name, attrs['name'], - [record_id], ctx) try: - rpc.execute(*args) - except TrytonServerError, exception: - common.process_exception(exception, *args) + RPCExecute('model', self.screen.model_name, attrs['name'], + [record_id], context=context) + except RPCException: + pass elif button_type == 'action': action_id = None - args = ('model', 'ir.action', 'get_action_id', - int(attrs['name']), ctx) try: - action_id = rpc.execute(*args) - except TrytonServerError, exception: - action_id = common.process_exception(exception, *args) + action_id = RPCExecute('model', 'ir.action', + 'get_action_id', int(attrs['name']), + context=context) + except RPCException: + pass if action_id: Action.execute(action_id, { 'model': self.screen.model_name, 'id': record_id, 'ids': [record_id], - }, context=ctx) + }, context=context) else: raise Exception('Unallowed button type') self.screen.reload(written=True) diff --git a/tryton/gui/window/view_form/view/form_gtk/interface.py b/tryton/gui/window/view_form/view/form_gtk/interface.py index db0e9b0ead..33f1fae91d 100644 --- a/tryton/gui/window/view_form/view/form_gtk/interface.py +++ b/tryton/gui/window/view_form/view/form_gtk/interface.py @@ -6,10 +6,9 @@ import gettext from tryton.common import COLORS import tryton.common as common -import tryton.rpc as rpc -from tryton.exceptions import TrytonServerError from tryton.gui.window.nomodal import NoModal from tryton.common import TRYTON_ICON +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -202,24 +201,24 @@ class TranslateDialog(NoModal): label.set_alignment(1.0, 0.5) table.attach(label, 0, 1, i, i + 1, xoptions=gtk.FILL) - context = rpc.CONTEXT.copy() - context['language'] = language['code'] - context['fuzzy_translation'] = False + context = dict( + language=language['code'], + fuzzy_translation=False, + ) try: - value = rpc.execute('model', self.widget.record.model_name, + value = RPCExecute('model', self.widget.record.model_name, 'read', self.widget.record.id, [self.widget.field_name], - context)[self.widget.field_name] - except TrytonServerError, exception: - common.process_exception(exception) + context={'language': language['code']} + )[self.widget.field_name] + except RPCException: return context['fuzzy_translation'] = True try: - fuzzy_value = rpc.execute('model', + fuzzy_value = RPCExecute('model', self.widget.record.model_name, 'read', self.widget.record.id, [self.widget.field_name], - context)[self.widget.field_name] - except TrytonServerError, exception: - common.process_exception(exception) + context=context)[self.widget.field_name] + except RPCException: return widget = self.widget.translate_widget() self.widget.translate_widget_set(widget, fuzzy_value) @@ -267,17 +266,17 @@ class TranslateDialog(NoModal): if not editing.get_active(): continue value = self.widget.translate_widget_get(widget) - context = rpc.CONTEXT.copy() - context['language'] = code - context['fuzzy_translation'] = False - args = ('model', self.widget.record.model_name, 'write', - self.widget.record.id, { - self.widget.field_name: value, - }, context) + context = dict( + language=code, + fuzzy_translation=False, + ) try: - rpc.execute(*args) - except TrytonServerError, exception: - common.process_exception(exception, *args) + RPCExecute('model', self.widget.record.model_name, 'write', + self.widget.record.id, { + self.widget.field_name: value, + }, context=context) + except RPCException: + pass self.widget.record.cancel() self.widget.view.display() self.destroy() @@ -305,21 +304,19 @@ class TranslateMixin: return try: - lang_ids = rpc.execute('model', 'ir.lang', 'search', [ + lang_ids = RPCExecute('model', 'ir.lang', 'search', [ ('translatable', '=', True), - ], rpc.CONTEXT) - except TrytonServerError, exception: - common.process_exception(exception) + ]) + except RPCException: return if not lang_ids: common.message(_('No other language available!')) return try: - languages = rpc.execute('model', 'ir.lang', 'read', lang_ids, - ['code', 'name'], rpc.CONTEXT) - except TrytonServerError, exception: - common.process_exception(exception) + languages = RPCExecute('model', 'ir.lang', 'read', lang_ids, + ['code', 'name']) + except RPCException: return TranslateDialog(self, languages) diff --git a/tryton/gui/window/view_form/view/form_gtk/many2many.py b/tryton/gui/window/view_form/view/form_gtk/many2many.py index 5048b1435c..8cfdbc6723 100644 --- a/tryton/gui/window/view_form/view/form_gtk/many2many.py +++ b/tryton/gui/window/view_form/view/form_gtk/many2many.py @@ -3,13 +3,12 @@ import gtk from tryton.gui.window.view_form.screen import Screen from interface import WidgetInterface -import tryton.rpc as rpc from tryton.gui.window.win_search import WinSearch from tryton.gui.window.win_form import WinForm from tryton.config import CONFIG -from tryton.exceptions import TrytonServerError import tryton.common as common import gettext +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -133,10 +132,9 @@ class Many2Many(WidgetInterface): dom = [('rec_name', 'ilike', '%' + value + '%'), domain] else: dom = domain - ids = rpc.execute('model', self.attrs['relation'], 'search', - dom, 0, CONFIG['client.limit'], None, context) - except TrytonServerError, exception: - common.process_exception(exception) + ids = RPCExecute('model', self.attrs['relation'], 'search', + dom, 0, CONFIG['client.limit'], None, context=context) + except RPCException: self.focus_out = True return False diff --git a/tryton/gui/window/view_form/view/form_gtk/many2one.py b/tryton/gui/window/view_form/view/form_gtk/many2one.py index 0a6ee2378b..aa2721a393 100644 --- a/tryton/gui/window/view_form/view/form_gtk/many2one.py +++ b/tryton/gui/window/view_form/view/form_gtk/many2one.py @@ -1,17 +1,17 @@ #This file is part of Tryton. The COPYRIGHT file at the top level of #this repository contains the full copyright notices and license terms. import gtk +import gobject import gettext from interface import WidgetInterface import tryton.common as common from tryton.gui.window.view_form.screen import Screen from tryton.gui.window.win_search import WinSearch from tryton.gui.window.win_form import WinForm -import tryton.rpc as rpc from tryton.action import Action from tryton.config import CONFIG from tryton.pyson import PYSONEncoder -from tryton.exceptions import TrytonServerError +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -124,8 +124,7 @@ class Many2One(WidgetInterface): self.record)['required']) and key_press)): domain = self.field.domain_get(self.record) - context = rpc.CONTEXT.copy() - context.update(self.field.context_get(self.record)) + context = self.field.context_get(self.record) self.wid_text.grab_focus() try: @@ -135,11 +134,10 @@ class Many2One(WidgetInterface): domain] else: dom = domain - ids = rpc.execute('model', model, 'search', dom, 0, - CONFIG['client.limit'], None, context) - except TrytonServerError, exception: + ids = RPCExecute('model', model, 'search', dom, 0, + CONFIG['client.limit'], None, context=context) + except RPCException: self.focus_out = True - common.process_exception(exception) self.changed = True return if len(ids) == 1: @@ -216,8 +214,7 @@ class Many2One(WidgetInterface): return elif model and not self._readonly: domain = self.field.domain_get(self.record) - context = rpc.CONTEXT.copy() - context.update(self.field.context_get(self.record)) + context = self.field.context_get(self.record) self.wid_text.grab_focus() try: @@ -227,11 +224,10 @@ class Many2One(WidgetInterface): domain] else: dom = domain - ids = rpc.execute('model', model, 'search', dom, 0, - CONFIG['client.limit'], None, context) - except TrytonServerError, exception: + ids = RPCExecute('model', model, 'search', dom, 0, + CONFIG['client.limit'], None, context=context) + except RPCException: self.focus_out = True - common.process_exception(exception) self.changed = True return False if len(ids) == 1: @@ -276,8 +272,11 @@ class Many2One(WidgetInterface): return False value = self.field.get(self.record) if self.has_target(value): - self.field.set_client(self.record, self.value_from_id(None, '')) - self.display(self.record, self.field) + def clean(): + self.field.set_client(self.record, + self.value_from_id(None, '')) + self.display(self.record, self.field) + gobject.idle_add(clean) return False def set_value(self, record, field): @@ -311,14 +310,11 @@ class Many2One(WidgetInterface): def _populate_popup(self, widget, menu): value = self.field.get(self.record) - args = ('model', 'ir.action.keyword', 'get_keyword', - 'form_relate', (self.attrs['relation'], -1), rpc.CONTEXT) try: - relates = rpc.execute(*args) - except TrytonServerError, exception: - relates = common.process_exception(exception) - if not relates: - return False + relates = RPCExecute('model', 'ir.action.keyword', 'get_keyword', + 'form_relate', (self.attrs['relation'], -1)) + except RPCException: + return False menu_entries = [] menu_entries.append((None, None, None)) menu_entries.append((None, None, None)) diff --git a/tryton/gui/window/view_form/view/form_gtk/one2many.py b/tryton/gui/window/view_form/view/form_gtk/one2many.py index 2e7aaad018..3a4db78586 100644 --- a/tryton/gui/window/view_form/view/form_gtk/one2many.py +++ b/tryton/gui/window/view_form/view/form_gtk/one2many.py @@ -7,9 +7,8 @@ from tryton.gui.window.view_form.screen import Screen from tryton.gui.window.win_search import WinSearch from tryton.gui.window.win_form import WinForm from tryton.config import CONFIG -from tryton.exceptions import TrytonServerError import tryton.common as common -import tryton.rpc as rpc +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -302,11 +301,9 @@ class One2Many(WidgetInterface): def _sig_add(self, *args): self.view.set_value() domain = self.field.domain_get(self.record) - context = rpc.CONTEXT.copy() - context.update(self.field.context_get(self.record)) + context = self.field.context_get(self.record) domain = domain[:] - domain.extend(self.record.expr_eval(self.attrs.get('add_remove'), - context)) + domain.extend(self.record.expr_eval(self.attrs.get('add_remove'))) removed_ids = self.field.get_removed_ids(self.record) try: @@ -316,10 +313,9 @@ class One2Many(WidgetInterface): ['OR', domain, ('id', 'in', removed_ids)]] else: dom = ['OR', domain, ('id', 'in', removed_ids)] - ids = rpc.execute('model', self.attrs['relation'], 'search', dom, - 0, CONFIG['client.limit'], None, context) - except TrytonServerError, exception: - common.process_exception(exception) + ids = RPCExecute('model', self.attrs['relation'], 'search', dom, + 0, CONFIG['client.limit'], None, context=context) + except RPCException: return False def callback(result): diff --git a/tryton/gui/window/view_form/view/form_gtk/reference.py b/tryton/gui/window/view_form/view/form_gtk/reference.py index 1c9ff8aa84..a610486c5d 100644 --- a/tryton/gui/window/view_form/view/form_gtk/reference.py +++ b/tryton/gui/window/view_form/view/form_gtk/reference.py @@ -6,9 +6,7 @@ import gobject import gettext import math from many2one import Many2One -from tryton.exceptions import TrytonServerError -import tryton.rpc as rpc -import tryton.common as common +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -31,10 +29,8 @@ class Reference(Many2One): selection = attrs.get('selection', []) if not isinstance(selection, (list, tuple)): try: - selection = rpc.execute('model', - self.model_name, selection, rpc.CONTEXT) - except TrytonServerError, exception: - common.process_exception(exception) + selection = RPCExecute('model', self.model_name, selection) + except RPCException: selection = [] selection.sort(key=operator.itemgetter(1)) if selection: diff --git a/tryton/gui/window/view_form/view/form_gtk/selection.py b/tryton/gui/window/view_form/view/form_gtk/selection.py index df40cf86d9..27dc2d4f2b 100644 --- a/tryton/gui/window/view_form/view/form_gtk/selection.py +++ b/tryton/gui/window/view_form/view/form_gtk/selection.py @@ -5,9 +5,7 @@ import gtk import gobject import math from interface import WidgetInterface -import tryton.rpc as rpc -import tryton.common as common -from tryton.exceptions import TrytonServerError +from tryton.common import RPCExecute, RPCException class Selection(WidgetInterface): @@ -40,10 +38,8 @@ class Selection(WidgetInterface): selection = self.attrs.get('selection', [])[:] if not isinstance(selection, (list, tuple)): try: - selection = rpc.execute('model', - self.model_name, selection, rpc.CONTEXT) - except TrytonServerError, exception: - common.process_exception(exception) + selection = RPCExecute('model', self.model_name, selection) + except RPCException: selection = [] self.selection = selection[:] if self.attrs.get('sort', True): @@ -60,12 +56,11 @@ class Selection(WidgetInterface): if domain == self._last_domain: return - args = ('model', self.attrs['relation'], 'search_read', domain, 0, - None, None, ['rec_name'], rpc.CONTEXT) try: - result = rpc.execute(*args) - except TrytonServerError, exception: - result = common.process_exception(exception, args) + result = RPCExecute('model', self.attrs['relation'], 'search_read', + domain, 0, None, None, ['rec_name']) + except RPCException: + result = False if isinstance(result, list): selection = [(x['id'], x['rec_name']) for x in result] selection.append((False, '')) diff --git a/tryton/gui/window/view_form/view/list.py b/tryton/gui/window/view_form/view/list.py index 4309a5dfef..e73ed79aa1 100644 --- a/tryton/gui/window/view_form/view/list.py +++ b/tryton/gui/window/view_form/view/list.py @@ -7,20 +7,18 @@ try: import simplejson as json except ImportError: import json -import tryton.rpc as rpc import locale from interface import ParserView from tryton.action import Action from tryton.common import message import gettext -import tryton.common as common from tryton.config import CONFIG from tryton.common.cellrendererbutton import CellRendererButton from tryton.common.cellrenderertoggle import CellRendererToggle from tryton.common.cellrendererbinary import CellRendererBinary from tryton.pyson import PYSONEncoder from tryton.gui.window import Window -from tryton.exceptions import TrytonServerError +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -396,11 +394,10 @@ class ViewList(ParserView): while iter_: record = model.get_value(iter_, 0) if not record.get_loaded(fields): - try: - for field in fields: - record.__getitem__(field, True) - except TrytonServerError: - return True + for field in fields: + record[field] + if record.exception: + return True iter_ = model.iter_next(iter_) return False @@ -556,13 +553,13 @@ class ViewList(ParserView): menu_entries.append(('gtk-copy', lambda x: self.on_copy(), 1)) if hasattr(path[1], '_type') and path[1]._type == 'many2one': value = record[path[1].name].get(record) - args = ('model', 'ir.action.keyword', 'get_keyword', - 'form_relate', (self.screen.group.fields[ - path[1].name].attrs['relation'], -1), rpc.CONTEXT) try: - relates = rpc.execute(*args) - except TrytonServerError, exception: - relates = common.process_exception(exception, *args) + relates = RPCExecute('model', 'ir.action.keyword', + 'get_keyword', 'form_relate', + (self.screen.group.fields[ + path[1].name].attrs['relation'], -1)) + except RPCException: + relates = None if relates: menu_entries.append((None, None, None)) menu_entries.append((_('Actions'), @@ -662,9 +659,9 @@ class ViewList(ParserView): if fields and any(fields.itervalues()): try: - rpc.execute('model', 'ir.ui.view_tree_width', 'set_width', - self.screen.model_name, fields, rpc.CONTEXT) - except TrytonServerError: + RPCExecute('model', 'ir.ui.view_tree_width', 'set_width', + self.screen.model_name, fields) + except RPCException: pass def destroy(self): diff --git a/tryton/gui/window/view_form/view/list_gtk/parser.py b/tryton/gui/window/view_form/view/list_gtk/parser.py index e7ffb76bd6..4efe2a76ce 100644 --- a/tryton/gui/window/view_form/view/list_gtk/parser.py +++ b/tryton/gui/window/view_form/view/list_gtk/parser.py @@ -15,7 +15,6 @@ import tryton.rpc as rpc from tryton.common import COLORS, node_attributes, \ HM_FORMAT, file_selection, file_open import tryton.common as common -from tryton.exceptions import TrytonError, TrytonServerError from tryton.common.cellrendererbutton import CellRendererButton from tryton.common.cellrendererdate import CellRendererDate from tryton.common.cellrenderertext import CellRendererText @@ -26,6 +25,7 @@ from tryton.common.cellrendererfloat import CellRendererFloat from tryton.common.cellrendererbinary import CellRendererBinary from tryton.action import Action from tryton.translate import date_format +from tryton.common import RPCExecute, RPCException import gtk import locale import datetime @@ -581,17 +581,14 @@ class M2O(Char): domain] else: dom = domain - args = ('model', relation, 'search', dom, 0, None, None, - context) try: - ids = rpc.execute(*args) - except TrytonServerError, exception: - ids = common.process_exception(exception, *args) - if not ids: - field.set_client(record, '???') - if callback: - callback() - return + ids = RPCExecute('model', relation, 'search', dom, 0, None, None, + context=context) + except RPCException: + field.set_client(record, '???') + if callback: + callback() + return if len(ids) != 1: if callback: self.search_remote(record, relation, ids, domain=domain, @@ -617,16 +614,14 @@ class M2O(Char): dom = [('rec_name', 'ilike', '%' + text + '%'), domain] else: dom = domain - args = ('model', relation, 'search', dom, 0, None, None, context) try: - ids = rpc.execute(*args) - except TrytonServerError, exception: - ids = common.process_exception(exception, *args) - if not ids: - field.set_client(record, False) - if callback: - callback() - return + ids = RPCExecute('model', relation, 'search', dom, 0, None, + None, context=context) + except RPCException: + field.set_client(record, False) + if callback: + callback() + return if len(ids) == 1: field.set_client(record, ids[0]) if callback: @@ -738,17 +733,14 @@ class M2M(Char): domain] else: dom = domain - args = ('model', relation, 'search', dom, 0, CONFIG['client.limit'], - None, context) try: - ids = rpc.execute(*args) - except TrytonServerError, exception: - ids = common.process_exception(exception, *args) - if ids is False: - field.set_client(record, []) - if callback: - callback() - return + ids = RPCExecute('model', relation, 'search', dom, 0, + CONFIG['client.limit'], None, context=context) + except RPCException: + field.set_client(record, []) + if callback: + callback() + return if not callback: return @@ -773,15 +765,12 @@ class M2M(Char): if create: if text and len(text) and text[0] != '(': domain.append(('name', '=', text)) - args = ('model', relation, 'search', domain) try: - ids = rpc.execute(*args) - except TrytonServerError, exception: - ids = common.process_exception(exception, *args) - if ids is False: - field.set_client(record, False) - if callback: - callback() + ids = RPCExecute('model', relation, 'search', domain) + except RPCException: + field.set_client(record, False) + if callback: + callback() if ids and len(ids) == 1: field.set_client(record, ids) if callback: @@ -809,11 +798,10 @@ class Selection(Char): self._domain_cache = {} selection = self.attrs.get('selection', [])[:] if not isinstance(selection, (list, tuple)): - args = ('model', self.model_name, selection, rpc.CONTEXT) try: - selection = rpc.execute(*args) - except TrytonServerError, exception: - selection = (common.process_exception(exception, args) or []) + selection = RPCExecute('model', self.model_name, selection) + except RPCException: + selection = [] self.selection = selection[:] if self.attrs.get('sort', True): selection.sort(key=operator.itemgetter(1)) @@ -871,12 +859,11 @@ class Selection(Char): self.selection = self._domain_cache[str(domain)] self._last_domain = domain if domain != self._last_domain: - args = ('model', self.attrs['relation'], 'search_read', domain, - 0, None, None, ['rec_name'], rpc.CONTEXT) try: - result = rpc.execute(*args) - except TrytonServerError, exception: - result = common.process_exception(exception, *args) + result = RPCExecute('model', self.attrs['relation'], + 'search_read', domain, 0, None, None, ['rec_name']) + except RPCException: + result = None if isinstance(result, list): selection = [(x['id'], x['rec_name']) for x in result] @@ -900,10 +887,8 @@ class Reference(Char): selection = attrs.get('selection', []) if not isinstance(selection, (list, tuple)): try: - selection = rpc.execute('model', - model_name, selection, rpc.CONTEXT) - except TrytonServerError, exception: - common.process_exception(exception) + selection = RPCExecute('model', model_name, selection) + except RPCException: selection = [] selection.sort(key=operator.itemgetter(1)) for i, j in selection: @@ -1006,31 +991,27 @@ class Button(object): if not self.attrs.get('confirm', False) or \ common.sur(self.attrs['confirm']): button_type = self.attrs.get('type', 'workflow') - ctx = rpc.CONTEXT.copy() - ctx.update(record.context_get()) + ctx = record.context_get() if button_type == 'workflow': - args = ('model', self.screen.model_name, + try: + RPCExecute('model', self.screen.model_name, 'workflow_trigger_validate', obj_id, - self.attrs['name'], ctx) - try: - rpc.execute(*args) - except TrytonServerError, exception: - common.process_exception(exception, *args) + self.attrs['name'], context=ctx) + except RPCException: + pass elif button_type == 'object': - args = ('model', self.screen.model_name, - self.attrs['name'], [obj_id], ctx) try: - rpc.execute(*args) - except TrytonServerError, exception: - common.process_exception(exception, *args) + RPCExecute('model', self.screen.model_name, + self.attrs['name'], [obj_id], context=ctx) + except RPCException: + pass elif button_type == 'action': - action_id = None - args = ('model', 'ir.action', 'get_action_id', - int(self.attrs['name']), ctx) try: - action_id = rpc.execute(*args) - except TrytonServerError, exception: - action_id = common.process_exception(exception, *args) + action_id = RPCExecute('model', 'ir.action', + 'get_action_id', int(self.attrs['name']), + context=ctx) + except RPCException: + action_id = None if action_id: Action.execute(action_id, { 'model': self.screen.model_name, diff --git a/tryton/gui/window/win_export.py b/tryton/gui/window/win_export.py index e12e95a58d..1ea435db93 100644 --- a/tryton/gui/window/win_export.py +++ b/tryton/gui/window/win_export.py @@ -4,13 +4,12 @@ import gtk import gobject import gettext import tryton.common as common -import tryton.rpc as rpc -from tryton.exceptions import TrytonServerError import types from tryton.config import TRYTON_ICON import csv import tempfile import os +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -234,11 +233,10 @@ class WinExport(object): self.model1.insert(node, 0, [None, '', 'white']) def _get_fields(self, model): - args = ('model', model, 'fields_get', None, rpc.CONTEXT) try: - return rpc.execute(*args) - except TrytonServerError, exception: - return common.process_exception(exception, *args) + return RPCExecute('model', model, 'fields_get', None) + except RPCException: + return '' def on_row_expanded(self, treeview, iter, path): child = self.model1.iter_children(iter) @@ -271,30 +269,21 @@ class WinExport(object): self.model2.clear() def fill_predefwin(self): - args = ('model', 'ir.export', 'search', - [('resource', '=', self.model)], 0, None, None, rpc.CONTEXT) try: - export_ids = rpc.execute(*args) - except TrytonServerError, exception: - export_ids = common.process_exception(exception, *args) - if not export_ids: - return - args = ('model', 'ir.export', 'read', export_ids, None, rpc.CONTEXT) + export_ids = RPCExecute('model', 'ir.export', 'search', + [('resource', '=', self.model)], 0, None, None) + except RPCException: + return try: - exports = rpc.execute(*args) - except TrytonServerError, exception: - exports = common.process_exception(exception, *args) - if not exports: - return - args = ('model', 'ir.export.line', 'read', - sum((x['export_fields'] for x in exports), []), None, - rpc.CONTEXT) + exports = RPCExecute('model', 'ir.export', 'read', export_ids, + None) + except RPCException: + return try: - lines = rpc.execute(*args) - except TrytonServerError, exception: - lines = common.process_exception(exception, *args) - if not lines: - return + lines = RPCExecute('model', 'ir.export.line', 'read', + sum((x['export_fields'] for x in exports), []), None) + except RPCException: + return id2lines = {} for line in lines: id2lines.setdefault(line['export'], []).append(line) @@ -315,19 +304,16 @@ class WinExport(object): field_name = self.model2.get_value(iter, 1) fields.append(field_name) iter = self.model2.iter_next(iter) - args = ('model', 'ir.export', 'create', { - 'name': name, - 'resource': self.model, - 'export_fields': [('create', { - 'name': x, - }) for x in fields], - }, rpc.CONTEXT) try: - new_id = rpc.execute(*args) - except TrytonServerError, exception: - new_id = common.process_exception(exception, *args) - if not new_id: - return + new_id = RPCExecute('model', 'ir.export', 'create', { + 'name': name, + 'resource': self.model, + 'export_fields': [('create', { + 'name': x, + }) for x in fields], + }) + except RPCException: + return self.predef_model.append(( new_id, fields, @@ -342,12 +328,10 @@ class WinExport(object): if not i: return None export_id = model.get_value(i, 0) - args = ('model', 'ir.export', 'delete', export_id, rpc.CONTEXT) try: - rpc.execute(*args) - except TrytonServerError, exception: - if not common.process_exception(exception, *args): - return + RPCExecute('model', 'ir.export', 'delete', export_id) + except RPCException: + return for i in range(len(self.predef_model)): if self.predef_model[i][0] == export_id: del self.predef_model[i] @@ -437,14 +421,9 @@ class WinExport(object): return False def datas_read(self, ids, model, fields, context=None): - if context is None: - context = {} - ctx = context.copy() - ctx.update(rpc.CONTEXT) try: - datas = rpc.execute('model', model, - 'export_data', ids, fields, ctx) - except TrytonServerError, exception: - common.process_exception(exception) + datas = RPCExecute('model', model, 'export_data', ids, fields, + context=context) + except RPCException: return [] return datas diff --git a/tryton/gui/window/win_form.py b/tryton/gui/window/win_form.py index 95e85fcbbb..d9b4db72aa 100644 --- a/tryton/gui/window/win_form.py +++ b/tryton/gui/window/win_form.py @@ -6,9 +6,8 @@ from tryton.config import CONFIG import gtk import pango import gettext -from tryton.exceptions import TrytonServerError from tryton.gui.window.nomodal import NoModal -import tryton.rpc as rpc +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -255,7 +254,6 @@ class WinForm(NoModal): def _sig_add(self, *args): from tryton.gui.window.win_search import WinSearch domain = [] - context = rpc.CONTEXT.copy() model_name = self.screen.model_name try: @@ -264,10 +262,9 @@ class WinForm(NoModal): '%' + self.wid_text.get_text() + '%'), domain] else: dom = domain - ids = rpc.execute('model', model_name, 'search', dom, - 0, CONFIG['client.limit'], None, context) - except TrytonServerError, exception: - common.process_exception(exception) + ids = RPCExecute('model', model_name, 'search', dom, + 0, CONFIG['client.limit'], None) + except RPCException: return False def callback(result): @@ -281,7 +278,7 @@ class WinForm(NoModal): if len(ids) != 1: WinSearch(model_name, callback, sel_multi=True, - ids=ids, context=context, domain=domain, + ids=ids, domain=domain, view_ids=self.attrs.get('view_ids', '').split(','), views_preload=self.attrs.get('views', {})) else: diff --git a/tryton/gui/window/win_import.py b/tryton/gui/window/win_import.py index 6f8647cc48..620d5d33a9 100644 --- a/tryton/gui/window/win_import.py +++ b/tryton/gui/window/win_import.py @@ -4,10 +4,9 @@ import gtk import gobject import gettext import tryton.common as common -import tryton.rpc as rpc import csv from tryton.config import TRYTON_ICON, CONFIG -from tryton.exceptions import TrytonServerError +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -224,11 +223,10 @@ class WinImport(object): self.model1.insert(node, 0, [None, '', 'white']) def _get_fields(self, model): - args = ('model', model, 'fields_get', None, rpc.CONTEXT) try: - return rpc.execute(*args) - except TrytonServerError, exception: - return common.process_exception(exception, *args) + return RPCExecute('model', model, 'fields_get', None) + except RPCException: + return '' def on_row_expanded(self, treeview, iter, path): child = self.model1.iter_children(iter) @@ -346,10 +344,8 @@ class WinImport(object): datas.append([x.decode(csv_data['combo']).encode('utf-8') \ for x in line]) try: - res = rpc.execute('model', model, 'import_data', fields, datas, - rpc.CONTEXT) - except TrytonServerError, exception: - common.process_exception(exception) + res = RPCExecute('model', model, 'import_data', fields, datas) + except RPCException: return False if res[0] >= 0: if res[0] == 1: diff --git a/tryton/gui/window/wizard.py b/tryton/gui/window/wizard.py index 35383865e7..2b46036cee 100644 --- a/tryton/gui/window/wizard.py +++ b/tryton/gui/window/wizard.py @@ -11,6 +11,7 @@ from tryton.gui import Main from tryton.exceptions import TrytonServerError from tryton.gui.window.nomodal import NoModal from tryton.common.button import Button +from tryton.common import RPCExecute, RPCException _ = gettext.gettext @@ -50,13 +51,10 @@ class Wizard(object): self.email_print = email_print self.email = email self.context = context - args = ('wizard', action, 'create', rpc.CONTEXT) try: - result = rpc.execute(*args) - except TrytonServerError, exception: - result = common.process_exception(exception, *args) - if not result: - return + result = RPCExecute('wizard', action, 'create') + except RPCException: + return self.session_id, self.start_state, self.end_state = result self.state = self.start_state self.process() @@ -69,7 +67,6 @@ class Wizard(object): self.__processing = True while self.state != self.end_state: ctx = self.context.copy() - ctx.update(rpc.CONTEXT) ctx['active_id'] = self.id ctx['active_ids'] = self.ids ctx['active_model'] = self.model @@ -79,20 +76,11 @@ class Wizard(object): } else: data = {} - - def execute(): - rpcprogress = common.RPCProgress('execute', ('wizard', - self.action, 'execute', self.session_id, data, - self.state, ctx)) - try: - return rpcprogress.run() - except TrytonServerError, exception: - if common.process_exception(exception): - return execute() - else: - self.state = self.end_state - result = execute() - if self.state == self.end_state: + try: + result = RPCExecute('wizard', self.action, 'execute', + self.session_id, data, self.state, context=ctx) + except RPCException: + self.state = self.end_state break if 'view' in result: @@ -131,8 +119,8 @@ class Wizard(object): def end(self): try: - rpc.execute('wizard', self.action, 'delete', self.session_id, - rpc.CONTEXT) + RPCExecute('wizard', self.action, 'delete', self.session_id, + process_exception=False) if self.action == 'ir.module.module.config_wizard': rpc.context_reload() except TrytonServerError: