From 82f780e948444cd9938613e99b3a77f32056f3ba Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Thu, 19 Jan 2012 20:16:54 +0100 Subject: [PATCH 0001/1390] [REM] unused imports. bzr revid: florent.xicluna@gmail.com-20120119191654-scm8c3o07icyz5b1 --- openerp/osv/fields.py | 3 --- openerp/tests/common.py | 1 - openerp/tests/test_orm.py | 1 - openerp/tiny_socket.py | 1 - 4 files changed, 6 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 871fc32f884..ff02a8c89f9 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -35,14 +35,11 @@ import base64 import datetime as DT import re -import string -import sys import warnings import xmlrpclib from psycopg2 import Binary import openerp -import openerp.netsvc as netsvc import openerp.tools as tools from openerp.tools.translate import _ from openerp.tools import float_round, float_repr diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 44696384ce7..93e5f6d5bc2 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -import os import time import xmlrpclib diff --git a/openerp/tests/test_orm.py b/openerp/tests/test_orm.py index c11d4cd19d2..cf880933fe5 100644 --- a/openerp/tests/test_orm.py +++ b/openerp/tests/test_orm.py @@ -1,4 +1,3 @@ -import os import unittest2 import openerp diff --git a/openerp/tiny_socket.py b/openerp/tiny_socket.py index b4bed83a4c0..f86797f0f67 100644 --- a/openerp/tiny_socket.py +++ b/openerp/tiny_socket.py @@ -22,7 +22,6 @@ import socket import cPickle import cStringIO -import marshal import netsvc From e7838dfbc44472a444b1f58dd7869febbc5984b7 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Thu, 19 Jan 2012 20:17:56 +0100 Subject: [PATCH 0002/1390] [REF] fix weird indentation, not multiple of four. bzr revid: florent.xicluna@gmail.com-20120119191756-niny262vp1nvmpp8 --- openerp/netsvc.py | 16 ++++++++-------- openerp/osv/orm.py | 12 ++++++------ openerp/service/netrpc_server.py | 6 +++--- openerp/service/web_services.py | 10 +++++----- openerp/tests/test_xmlrpc.py | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/openerp/netsvc.py b/openerp/netsvc.py index ca08a362771..53750ed84da 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -84,12 +84,12 @@ class Service(object): cls._services.pop(name) def LocalService(name): - # Special case for addons support, will be removed in a few days when addons - # are updated to directly use openerp.osv.osv.service. - if name == 'object_proxy': - return openerp.osv.osv.service + # Special case for addons support, will be removed in a few days when addons + # are updated to directly use openerp.osv.osv.service. + if name == 'object_proxy': + return openerp.osv.osv.service - return Service._services[name] + return Service._services[name] class ExportService(object): """ Proxy for exported services. @@ -198,9 +198,9 @@ def init_logger(): # server intended to test it. def init_alternative_logger(): class H(logging.Handler): - def emit(self, record): - if record.levelno > 20: - print record.levelno, record.pathname, record.msg + def emit(self, record): + if record.levelno > 20: + print record.levelno, record.pathname, record.msg handler = H() logger = logging.getLogger() logger.handlers = [] diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 1c12fab27c9..f2686708436 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -98,10 +98,10 @@ def transfer_node_to_modifiers(node, modifiers, context=None, in_tree_view=False if node.get('states'): if 'invisible' in modifiers and isinstance(modifiers['invisible'], list): - # TODO combine with AND or OR, use implicit AND for now. - modifiers['invisible'].append(('state', 'not in', node.get('states').split(','))) + # TODO combine with AND or OR, use implicit AND for now. + modifiers['invisible'].append(('state', 'not in', node.get('states').split(','))) else: - modifiers['invisible'] = [('state', 'not in', node.get('states').split(','))] + modifiers['invisible'] = [('state', 'not in', node.get('states').split(','))] for a in ('invisible', 'readonly', 'required'): if node.get(a): @@ -894,8 +894,8 @@ class BaseModel(object): for c in cls.__dict__.get(s, []): exist = False for c2 in range(len(new)): - #For _constraints, we should check field and methods as well - if new[c2][2]==c[2] and (new[c2][0] == c[0] \ + #For _constraints, we should check field and methods as well + if new[c2][2]==c[2] and (new[c2][0] == c[0] \ or getattr(new[c2][0],'__name__', True) == \ getattr(c[0],'__name__', False)): # If new class defines a constraint with @@ -2690,7 +2690,7 @@ class BaseModel(object): elif val in dict(self._columns[field].selection(self, cr, uid, context=context)): return raise except_orm(_('ValidateError'), - _('The value "%s" for the field "%s.%s" is not in the selection') % (value, self._table, field)) + _('The value "%s" for the field "%s.%s" is not in the selection') % (value, self._table, field)) def _check_removed_columns(self, cr, log=False): # iterate on the database columns to drop the NOT NULL constraints diff --git a/openerp/service/netrpc_server.py b/openerp/service/netrpc_server.py index f86d6d21273..efe26906720 100644 --- a/openerp/service/netrpc_server.py +++ b/openerp/service/netrpc_server.py @@ -125,9 +125,9 @@ class TinySocketServerThread(threading.Thread,netsvc.Server): ct.start() lt = len(self.threads) if (lt > 10) and (lt % 10 == 0): - # Not many threads should be serving at the same time, so log - # their abuse. - netsvc.Logger().notifyChannel("web-services", netsvc.LOG_DEBUG, + # Not many threads should be serving at the same time, so log + # their abuse. + netsvc.Logger().notifyChannel("web-services", netsvc.LOG_DEBUG, "Netrpc: %d threads" % len(self.threads)) self.socket.close() except Exception, e: diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 1bda0230c89..8c3db0e88af 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -521,11 +521,11 @@ GNU Public Licence. 'OS Name : %s\n' \ %(platform.platform(), platform.os.name) if os.name == 'posix': - if platform.system() == 'Linux': - lsbinfo = os.popen('lsb_release -a').read() - environment += '%s'%(lsbinfo) - else: - environment += 'Your System is not lsb compliant\n' + if platform.system() == 'Linux': + lsbinfo = os.popen('lsb_release -a').read() + environment += '%s'%(lsbinfo) + else: + environment += 'Your System is not lsb compliant\n' environment += 'Operating System Release : %s\n' \ 'Operating System Version : %s\n' \ 'Operating System Architecture : %s\n' \ diff --git a/openerp/tests/test_xmlrpc.py b/openerp/tests/test_xmlrpc.py index 954d3447360..ca0ae454437 100644 --- a/openerp/tests/test_xmlrpc.py +++ b/openerp/tests/test_xmlrpc.py @@ -19,8 +19,8 @@ ADMIN_USER_ID = common.ADMIN_USER_ID ADMIN_PASSWORD = common.ADMIN_PASSWORD def setUpModule(): - common.start_openerp() - common.create_xmlrpc_proxies() + common.start_openerp() + common.create_xmlrpc_proxies() tearDownModule = common.tearDownModule From efef81654b90e70a24d1a330c0ef8d9942e05444 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Thu, 19 Jan 2012 20:18:38 +0100 Subject: [PATCH 0003/1390] [REF] replace deprecated <> symbol. bzr revid: florent.xicluna@gmail.com-20120119191838-r07oybyiqbkfehsz --- openerp/osv/orm.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index f2686708436..dceb14a2710 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -1303,7 +1303,7 @@ class BaseModel(object): if not line[i]: continue - if field[:len(prefix)] <> prefix: + if field[:len(prefix)] != prefix: if line[i] and skip: return False continue @@ -2666,7 +2666,7 @@ class BaseModel(object): # if val is a many2one, just write the ID if type(val) == tuple: val = val[0] - if (val<>False) or (type(val)<>bool): + if val is not False: cr.execute(update_query, (ss[1](val), key)) def _check_selection_field_value(self, cr, uid, field, value, context=None): From c749cd8fcc864e6103f55bcf7b12e0910f2ffa14 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Mon, 23 Jan 2012 15:29:32 +0100 Subject: [PATCH 0004/1390] =?UTF-8?q?[IMP]=C2=A0upgrade=20the=20Pickle=20p?= =?UTF-8?q?rotocol=20to=20consume=20less=20bandwidth.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bzr revid: florent.xicluna@gmail.com-20120123142932-idcqz4p46gvbvhfh --- openerp/tiny_socket.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openerp/tiny_socket.py b/openerp/tiny_socket.py index b4bed83a4c0..c3960afd054 100644 --- a/openerp/tiny_socket.py +++ b/openerp/tiny_socket.py @@ -28,6 +28,10 @@ import netsvc #.apidoc title: Net-RPC classes +# Pickle protocol version 2 is optimized compared to default (version 0) +PICKLE_PROTOCOL = 2 + + class Myexception(Exception): """ custom exception object store @@ -63,8 +67,8 @@ class mysocket: netsvc.close_socket(self.sock) def mysend(self, msg, exception=False, traceback=None): - msg = cPickle.dumps([msg,traceback]) - self.sock.sendall('%8d%s%s' % (len(msg), exception and "1" or "0", msg)) + msg = cPickle.dumps([msg, traceback], PICKLE_PROTOCOL) + self.sock.sendall('%8d%d%s' % (len(msg), bool(exception), msg)) def myreceive(self): buf='' From bac1a957193c5b76fc944d268d2b711809e34d19 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Mon, 23 Jan 2012 15:30:15 +0100 Subject: [PATCH 0005/1390] =?UTF-8?q?[IMP]=C2=A0merge=20two=20socket.recv?= =?UTF-8?q?=20into=20one.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bzr revid: florent.xicluna@gmail.com-20120123143015-gz22l5qre6ria8f4 --- openerp/tiny_socket.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/openerp/tiny_socket.py b/openerp/tiny_socket.py index c3960afd054..87db82f6d91 100644 --- a/openerp/tiny_socket.py +++ b/openerp/tiny_socket.py @@ -72,15 +72,14 @@ class mysocket: def myreceive(self): buf='' - while len(buf) < 8: - chunk = self.sock.recv(8 - len(buf)) + while len(buf) < 9: + chunk = self.sock.recv(9 - len(buf)) if not chunk: raise socket.timeout buf += chunk - size = int(buf) - buf = self.sock.recv(1) - if buf != "0": - exception = buf + size = int(buf[:8]) + if buf[8] != "0": + exception = buf[8] else: exception = False msg = '' From 111d8b76f7e384a3b1a77d802b52eedbb7ae04c7 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Wed, 1 Feb 2012 13:33:11 +0100 Subject: [PATCH 0006/1390] [REF] one unused import and one redundant import. bzr revid: florent.xicluna@gmail.com-20120201123311-yvljvcj0luly77qt --- openerp-server | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/openerp-server b/openerp-server index 334c1790526..5868b4f33d5 100755 --- a/openerp-server +++ b/openerp-server @@ -42,9 +42,6 @@ import openerp __author__ = openerp.release.author __version__ = openerp.release.version -import sys -import imp - def check_root_user(): """ Exit if the process's user is 'root' (on POSIX system).""" if os.name == 'posix': @@ -200,7 +197,7 @@ def quit_on_signals(): try: while quit_signals_received == 0: time.sleep(60) - except KeyboardInterrupt, e: + except KeyboardInterrupt: pass if config['pidfile']: From 1ef81548ba5dd463adaf20433b7bc4b39ebb8e78 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Wed, 8 Feb 2012 15:22:48 +0100 Subject: [PATCH 0007/1390] [REF] additional cleanup after vmt's logging refactoring. bzr revid: florent.xicluna@gmail.com-20120208142248-p63odfqo673yqqml --- openerp/service/netrpc_server.py | 2 +- openerp/service/web_services.py | 17 ++++++++--------- openerp/wizard/__init__.py | 6 +----- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/openerp/service/netrpc_server.py b/openerp/service/netrpc_server.py index 327ebc5bbdc..fcbfaf0ba82 100644 --- a/openerp/service/netrpc_server.py +++ b/openerp/service/netrpc_server.py @@ -131,7 +131,7 @@ class TinySocketServerThread(threading.Thread,netsvc.Server): _logger.debug("Netrpc: %d threads", len(self.threads)) self.socket.close() except Exception, e: - _logger.warning("Netrpc: closing because of exception %s" % str(e)) + _logger.warning("Netrpc: closing because of exception %s", e) self.socket.close() return False diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 43f4d1af639..661b74a6995 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -224,9 +224,9 @@ class db(netsvc.ExportService): if not data or res: _logger.error( - 'DUMP DB: %s failed! Please verify the configuration of the database password on the server. '\ - 'It should be provided as a -w command-line option, or as `db_password` in the '\ - 'server configuration file.\n %s' % (db_name, data)) + 'DUMP DB: %s failed! Please verify the configuration of the database password on the server. ' + 'It should be provided as a -w command-line option, or as `db_password` in the ' + 'server configuration file.\n %s', db_name, data) raise Exception, "Couldn't dump database" _logger.info('DUMP DB successful: %s', db_name) @@ -239,7 +239,7 @@ class db(netsvc.ExportService): self._set_pg_psw_env_var() if self.exp_db_exist(db_name): - _logger.warning('RESTORE DB: %s already exists' % (db_name,)) + _logger.warning('RESTORE DB: %s already exists', db_name) raise Exception, "Database already exists" self._create_empty_database(db_name) @@ -268,7 +268,7 @@ class db(netsvc.ExportService): res = stdout.close() if res: raise Exception, "Couldn't restore database" - _logger.info('RESTORE DB: %s' % (db_name)) + _logger.info('RESTORE DB: %s', db_name) return True finally: @@ -451,8 +451,7 @@ GNU Public Licence. backup_directory = os.path.join(tools.config['root_path'], 'backup', time.strftime('%Y-%m-%d-%H-%M')) if zips and not os.path.isdir(backup_directory): - _logger.info('create a new backup directory to \ - store the old modules: %s', backup_directory) + _logger.info('create a new backup directory to store the old modules: %s', backup_directory) os.makedirs(backup_directory) for module in zips: @@ -678,7 +677,7 @@ class report_spool(netsvc.ExportService): self._reports[id]['state'] = True except Exception, exception: - _logger.exception('Exception: %s\n', str(exception)) + _logger.exception('Exception: %s\n', exception) if hasattr(exception, 'name') and hasattr(exception, 'value'): self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value)) else: @@ -715,7 +714,7 @@ class report_spool(netsvc.ExportService): self._reports[id]['format'] = format self._reports[id]['state'] = True except Exception, exception: - _logger.exception('Exception: %s\n', str(exception)) + _logger.exception('Exception: %s\n', exception) if hasattr(exception, 'name') and hasattr(exception, 'value'): self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value)) else: diff --git a/openerp/wizard/__init__.py b/openerp/wizard/__init__.py index 7354a43498d..debf0f1e74f 100644 --- a/openerp/wizard/__init__.py +++ b/openerp/wizard/__init__.py @@ -31,7 +31,6 @@ import openerp.pooler as pooler from openerp.osv.osv import except_osv from openerp.osv.orm import except_orm -import sys _logger = logging.getLogger(__name__) @@ -168,10 +167,7 @@ class interface(netsvc.Service): or isinstance(e, except_orm): netsvc.abort_response(2, e.name, 'warning', e.value) else: - import traceback - tb_s = reduce(lambda x, y: x+y, traceback.format_exception( - sys.exc_type, sys.exc_value, sys.exc_traceback)) - _logger.error('Exception in call: ' + tb_s) + _logger.exception('Exception in call:') raise return res From 01f3d0fc985fe4f98d10c88921f33676c84c4757 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Wed, 8 Feb 2012 16:08:15 +0100 Subject: [PATCH 0008/1390] =?UTF-8?q?[FIX]=C2=A0the=20embedded=20pychart?= =?UTF-8?q?=20library=20is=20not=20used.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bzr revid: florent.xicluna@gmail.com-20120208150815-8th86hvpp11yiv4x --- openerp/__init__.py | 1 - openerp/report/__init__.py | 1 - setup.py | 8 ++------ 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/openerp/__init__.py b/openerp/__init__.py index 7e723c41f9d..5827b744cf8 100644 --- a/openerp/__init__.py +++ b/openerp/__init__.py @@ -32,7 +32,6 @@ import modules import netsvc import osv import pooler -import pychart import release import report import run_tests diff --git a/openerp/report/__init__.py b/openerp/report/__init__.py index 646967f00d1..48b654fdd86 100644 --- a/openerp/report/__init__.py +++ b/openerp/report/__init__.py @@ -24,7 +24,6 @@ import print_xml import print_fnc import custom import render -import openerp.pychart import int_to_text import report_sxw diff --git a/setup.py b/setup.py index 6e1adadde82..037d288d7e5 100755 --- a/setup.py +++ b/setup.py @@ -87,14 +87,10 @@ setuptools.setup( scripts = ['openerp-server'], data_files = data(), packages = setuptools.find_packages(), + dependency_links = ['http://download.gna.org/pychart/'], #include_package_data = True, install_requires = [ - # TODO the pychart package we include in openerp corresponds to PyChart 1.37. - # It seems there is a single difference, which is a spurious print in generate_docs.py. - # It is probably safe to move to PyChart 1.39 (the latest one). - # (Let setup.py choose the latest one, and we should check we can remove pychart from - # our tree.) http://download.gna.org/pychart/ - # TODO 'pychart', + 'pychart', 'babel', 'feedparser', 'gdata', From 44e02f756b0066f61e1bbea648f92ea23a0aac02 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Wed, 8 Feb 2012 16:33:04 +0100 Subject: [PATCH 0009/1390] =?UTF-8?q?[FIX]=C2=A0file=5Fopen=20should=20not?= =?UTF-8?q?=20search=20zip=20files=20outside=20its=20root=20directory.=20?= =?UTF-8?q?=20Fix=20the=20returned=20value=20with=20pathinfo=3DTrue.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit lp bug: https://launchpad.net/bugs/928507 fixed lp bug: https://launchpad.net/bugs/928376 fixed bzr revid: florent.xicluna@gmail.com-20120208153304-9443zx2z09bws10x --- openerp/tools/misc.py | 89 ++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index a5c72900fc7..3c9210214b1 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -134,7 +134,7 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False): @param name name of the file @param mode file open mode @param subdir subdirectory - @param pathinfo if True returns tupple (fileobject, filepath) + @param pathinfo if True returns tuple (fileobject, filepath) @return fileobject if pathinfo is False else (fileobject, filepath) """ @@ -142,44 +142,51 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False): adps = addons.module.ad_paths rtp = os.path.normcase(os.path.abspath(config['root_path'])) - if name.replace(os.path.sep, '/').startswith('addons/'): + if os.path.isabs(name): + # It is an absolute path + # Is it below 'addons_path' or 'root_path'? + name = os.path.normcase(os.path.normpath(name)) + for root in adps + [rtp]: + if name.startswith(root): + base = root.rstrip(os.sep) + name = name[len(base) + 1:] + break + else: + # It is outside the OpenERP root: skip zipfile lookup. + base, name = os.path.split(name) + return _fileopen(name, mode=mode, basedir=base, pathinfo=pathinfo) + + if name.replace(os.sep, '/').startswith('addons/'): subdir = 'addons' - name = name[7:] + name2 = name[7:] + elif subdir: + name = os.path.join(subdir, name) + if name.replace(os.sep, '/').startswith('addons/'): + subdir = 'addons' + name2 = name[7:] + else: + name2 = name - # First try to locate in addons_path + # First, try to locate in addons_path if subdir: - subdir2 = subdir - if subdir2.replace(os.path.sep, '/').startswith('addons/'): - subdir2 = subdir2[7:] - - subdir2 = (subdir2 != 'addons' or None) and subdir2 - for adp in adps: try: - if subdir2: - fn = os.path.join(adp, subdir2, name) - else: - fn = os.path.join(adp, name) - fn = os.path.normpath(fn) - fo = file_open(fn, mode=mode, subdir=None, pathinfo=pathinfo) - if pathinfo: - return fo, fn - return fo + return _fileopen(name2, mode=mode, basedir=adp, + pathinfo=pathinfo) except IOError: pass - if subdir: - name = os.path.join(rtp, subdir, name) - else: - name = os.path.join(rtp, name) + # Second, try to locate in root_path + return _fileopen(name, mode=mode, basedir=rtp, pathinfo=pathinfo) - name = os.path.normpath(name) - # Check for a zipfile in the path - head = name - zipname = False +def _fileopen(path, mode, basedir, pathinfo): + head = os.path.normpath(path) + name = os.path.normpath(os.path.join(basedir, path)) name2 = False - while True: + zipname = False + # Check for a zipfile in the path, but stop at the 'basedir' level + while os.sep in head: head, tail = os.path.split(head) if not tail: break @@ -187,9 +194,10 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False): zipname = os.path.join(tail, zipname) else: zipname = tail - if zipfile.is_zipfile(head+'.zip'): + zpath = os.path.join(basedir, head + '.zip') + if zipfile.is_zipfile(zpath): from cStringIO import StringIO - zfile = zipfile.ZipFile(head+'.zip') + zfile = zipfile.ZipFile(zpath) try: fo = StringIO() fo.write(zfile.read(os.path.join( @@ -197,20 +205,21 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False): os.sep, '/'))) fo.seek(0) if pathinfo: - return fo, name + return (fo, name) return fo except Exception: - name2 = os.path.normpath(os.path.join(head + '.zip', zipname)) - pass - for i in (name2, name): - if i and os.path.isfile(i): - fo = file(i, mode) + name2 = os.path.normpath(os.path.join(zpath, zipname)) + # Look for a normal file + for fname in (name2, name): + if fname and os.path.isfile(fname): + fo = open(fname, mode) if pathinfo: - return fo, i + return (fo, fname) return fo - if os.path.splitext(name)[1] == '.rml': - raise IOError, 'Report %s doesn\'t exist or deleted : ' %str(name) - raise IOError, 'File not found : %s' % name + # Not found + if name.endswith('.rml'): + raise IOError('Report %r doesn\'t exist or deleted' % name) + raise IOError('File not found: %s' % name) #---------------------------------------------------------- From 57ca8e47975101c57991cf89efe86c033ff8a6de Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Wed, 8 Feb 2012 18:00:34 +0100 Subject: [PATCH 0010/1390] [REF] openerp.report: better use of isinstance. bzr revid: florent.xicluna@gmail.com-20120208170034-2w8szxy350qpwas6 --- openerp/report/custom.py | 2 +- openerp/report/render/rml2txt/utils.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openerp/report/custom.py b/openerp/report/custom.py index 051d1f29862..d06f2d721f7 100644 --- a/openerp/report/custom.py +++ b/openerp/report/custom.py @@ -108,7 +108,7 @@ class report_custom(report_int): key = levels.keys() for l in key: objs = eval('obj.'+l,{'obj': obj}) - if not isinstance(objs, browse_record_list) and type(objs) <> type([]): + if not isinstance(objs, (browse_record_list, list)): objs = [objs] field_new = [] cond_new = [] diff --git a/openerp/report/render/rml2txt/utils.py b/openerp/report/render/rml2txt/utils.py index 122411afb2d..c08210ecc79 100644 --- a/openerp/report/render/rml2txt/utils.py +++ b/openerp/report/render/rml2txt/utils.py @@ -75,9 +75,9 @@ def _process_text(self, txt): txt2 = eval(sps.pop(0),self.localcontext) except: txt2 = '' - if type(txt2) == type(0) or type(txt2) == type(0.0): + if isinstance(txt2, (int, float)): txt2 = str(txt2) - if type(txt2)==type('') or type(txt2)==type(u''): + if isinstance(txt2, basestring): result += txt2 return result From b5fa51f4a691b840e588bc33e4e960958860fd12 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Wed, 8 Feb 2012 18:02:17 +0100 Subject: [PATCH 0011/1390] =?UTF-8?q?[REF]=C2=A0openerp.report:=20use=20th?= =?UTF-8?q?e=20recommended=20syntax=20to=20raise=20error=20and=20never=20u?= =?UTF-8?q?se=20empty=20except:.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bzr revid: florent.xicluna@gmail.com-20120208170217-xsa5odzlhite0nda --- openerp/report/custom.py | 2 +- openerp/report/interface.py | 4 ++-- openerp/report/preprocess.py | 2 +- openerp/report/printscreen/ps_list.py | 2 +- openerp/report/render/rml2html/rml2html.py | 2 +- openerp/report/render/rml2pdf/trml2pdf.py | 2 +- openerp/report/render/rml2txt/utils.py | 8 ++++---- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/openerp/report/custom.py b/openerp/report/custom.py index d06f2d721f7..a03ae0b8a53 100644 --- a/openerp/report/custom.py +++ b/openerp/report/custom.py @@ -267,7 +267,7 @@ class report_custom(report_int): else: try: row.append(float(r[j])) - except: + except Exception: row.append(r[j]) results2.append(row) if report['type']=='pie': diff --git a/openerp/report/interface.py b/openerp/report/interface.py index 9a97c445671..69474a18433 100644 --- a/openerp/report/interface.py +++ b/openerp/report/interface.py @@ -44,8 +44,8 @@ class report_int(netsvc.Service): def __init__(self, name): assert not self.exists(name), 'The report "%s" already exists!' % name super(report_int, self).__init__(name) - if name[0:7]<>'report.': - raise Exception, 'ConceptionError, bad report name, should start with "report."' + if not name.startswith('report.'): + raise Exception('ConceptionError, bad report name, should start with "report."') self.name = name self.id = 0 self.name2 = '.'.join(name.split('.')[1:]) diff --git a/openerp/report/preprocess.py b/openerp/report/preprocess.py index e681860d7a2..93b6b4d1bc9 100644 --- a/openerp/report/preprocess.py +++ b/openerp/report/preprocess.py @@ -48,7 +48,7 @@ class report(object): try: while n.tag != txt.group(3): n = n.getparent() - except: + except Exception: n = node else: n = node.getparent() diff --git a/openerp/report/printscreen/ps_list.py b/openerp/report/printscreen/ps_list.py index dc280a53e3e..8f0629462f8 100644 --- a/openerp/report/printscreen/ps_list.py +++ b/openerp/report/printscreen/ps_list.py @@ -56,7 +56,7 @@ class report_printscreen_list(report_int): def _parse_string(self, view): try: dom = etree.XML(view.encode('utf-8')) - except: + except Exception: dom = etree.XML(view) return self._parse_node(dom) diff --git a/openerp/report/render/rml2html/rml2html.py b/openerp/report/render/rml2html/rml2html.py index 504492772df..a26f6eadaa6 100644 --- a/openerp/report/render/rml2html/rml2html.py +++ b/openerp/report/render/rml2html/rml2html.py @@ -98,7 +98,7 @@ class _flowable(object): try: if new_child.get('style').find('terp_tblheader')!= -1: new_node.tag = 'th' - except: + except Exception: pass process(node,new_node) if new_node.get('colWidths',False): diff --git a/openerp/report/render/rml2pdf/trml2pdf.py b/openerp/report/render/rml2pdf/trml2pdf.py index 96287166074..58457993142 100644 --- a/openerp/report/render/rml2pdf/trml2pdf.py +++ b/openerp/report/render/rml2pdf/trml2pdf.py @@ -424,7 +424,7 @@ class _rml_canvas(object): flow.drawOn(self.canvas,infos['x'],infos['y']) infos['height']-=h else: - raise ValueError, "Not enough space" + raise ValueError("Not enough space") def _line_mode(self, node): ljoin = {'round':1, 'mitered':0, 'bevelled':2} diff --git a/openerp/report/render/rml2txt/utils.py b/openerp/report/render/rml2txt/utils.py index c08210ecc79..95e99c32ce1 100644 --- a/openerp/report/render/rml2txt/utils.py +++ b/openerp/report/render/rml2txt/utils.py @@ -37,7 +37,7 @@ def _child_get(node, self=None, tagname=None): if n.get('rml_except', False): try: eval(n.get('rml_except'), {}, self.localcontext) - except: + except Exception: continue if n.get('rml_tag'): try: @@ -46,7 +46,7 @@ def _child_get(node, self=None, tagname=None): n2.tag = tag n2.attrib.update(attr) yield n2 - except: + except Exception: yield n else: yield n @@ -55,7 +55,7 @@ def _child_get(node, self=None, tagname=None): if self and self.localcontext and n.get('rml_except', False): try: eval(n.get('rml_except'), {}, self.localcontext) - except: + except Exception: continue if (tagname is None) or (n.tag==tagname): yield n @@ -73,7 +73,7 @@ def _process_text(self, txt): if sps: try: txt2 = eval(sps.pop(0),self.localcontext) - except: + except Exception: txt2 = '' if isinstance(txt2, (int, float)): txt2 = str(txt2) From 9621008df12a65730a123e389d84ef8b21e5941d Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Wed, 8 Feb 2012 18:03:51 +0100 Subject: [PATCH 0012/1390] =?UTF-8?q?[REF]=C2=A0openerp.report:=20replace?= =?UTF-8?q?=20deprecated=20has=5Fkey.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bzr revid: florent.xicluna@gmail.com-20120208170351-1vmewmuufmxn7x52 --- openerp/report/custom.py | 14 +++++++------- openerp/report/print_xml.py | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openerp/report/custom.py b/openerp/report/custom.py index a03ae0b8a53..b33065fcdee 100644 --- a/openerp/report/custom.py +++ b/openerp/report/custom.py @@ -221,7 +221,7 @@ class report_custom(report_int): res_dic[prev].append(line) else: prev = line[groupby] - if res_dic.has_key(line[groupby]): + if line[groupby] in res_dic: res_dic[line[groupby]].append(line) else: res_dic[line[groupby]] = [] @@ -389,7 +389,7 @@ class report_custom(report_int): if date_idx != None: for r in results: key = process_date['Y'](r[date_idx]) - if not data_by_year.has_key(key): + if key not in data_by_year: data_by_year[key] = [] for i in range(len(r)): r[i] = fct[i](r[i]) @@ -407,14 +407,14 @@ class report_custom(report_int): for d in data_by_year[line]: for idx in range(len(fields)-1): fields_bar.append({}) - if fields_bar[idx].has_key(d[0]): + if d[0] in fields_bar[idx]: fields_bar[idx][d[0]] += d[idx+1] else: fields_bar[idx][d[0]] = d[idx+1] for idx in range(len(fields)-1): data = {} for k in fields_bar[idx].keys(): - if data.has_key(k): + if k in data: data[k] += fields_bar[idx][k] else: data[k] = fields_bar[idx][k] @@ -488,7 +488,7 @@ class report_custom(report_int): if date_idx != None: for r in results: key = process_date['Y'](r[date_idx]) - if not data_by_year.has_key(key): + if key not in data_by_year: data_by_year[key] = [] for i in range(len(r)): r[i] = fct[i](r[i]) @@ -507,14 +507,14 @@ class report_custom(report_int): for d in data_by_year[line]: for idx in range(len(fields)-1): fields_bar.append({}) - if fields_bar[idx].has_key(d[0]): + if d[0] in fields_bar[idx]: fields_bar[idx][d[0]] += d[idx+1] else: fields_bar[idx][d[0]] = d[idx+1] for idx in range(len(fields)-1): data = {} for k in fields_bar[idx].keys(): - if data.has_key(k): + if k in data: data[k] += fields_bar[idx][k] else: data[k] = fields_bar[idx][k] diff --git a/openerp/report/print_xml.py b/openerp/report/print_xml.py index ee1b9a316b3..2137eabee79 100644 --- a/openerp/report/print_xml.py +++ b/openerp/report/print_xml.py @@ -200,7 +200,7 @@ class document(object): else: args = [] # get the object - if attrs.has_key('model'): + if 'model' in attrs: obj = self.pool.get(attrs['model']) else: if isinstance(browser, list): @@ -209,7 +209,7 @@ class document(object): obj = browser._table # get the ids - if attrs.has_key('ids'): + if 'ids' in attrs: ids = self.eval(browser, attrs['ids']) else: if isinstance(browser, list): From 7675d45c2c10e833bc5d5f0b3f905f1cca652a3d Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Wed, 8 Feb 2012 18:04:56 +0100 Subject: [PATCH 0013/1390] [REF] openerp.report: fix weird indentation, not multiple of four. bzr revid: florent.xicluna@gmail.com-20120208170456-ak1ykpy6yel71ylc --- openerp/report/interface.py | 2 +- openerp/report/print_xml.py | 2 +- openerp/report/printscreen/ps_form.py | 2 +- openerp/report/render/rml2html/rml2html.py | 16 ++++++++-------- openerp/report/render/rml2pdf/trml2pdf.py | 2 +- openerp/report/render/rml2txt/rml2txt.py | 4 ++-- openerp/report/render/simple.py | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/openerp/report/interface.py b/openerp/report/interface.py index 69474a18433..17dc0973d7e 100644 --- a/openerp/report/interface.py +++ b/openerp/report/interface.py @@ -181,7 +181,7 @@ class report_rml(report_int): def create_pdf(self, rml, localcontext = None, logo=None, title=None): if not localcontext: - localcontext={} + localcontext = {} localcontext.update({'internal_header':self.internal_header}) if logo: self.bin_datas['logo'] = logo diff --git a/openerp/report/print_xml.py b/openerp/report/print_xml.py index 2137eabee79..c2af0984c2e 100644 --- a/openerp/report/print_xml.py +++ b/openerp/report/print_xml.py @@ -228,7 +228,7 @@ class document(object): if not isinstance(datas[atr['value']], (str, unicode)): txt = str(datas[atr['value']]) else: - txt = datas[atr['value']] + txt = datas[atr['value']] el.text = txt else: for el_cld in node: diff --git a/openerp/report/printscreen/ps_form.py b/openerp/report/printscreen/ps_form.py index 8e3823e6b03..cf6d77cbe26 100644 --- a/openerp/report/printscreen/ps_form.py +++ b/openerp/report/printscreen/ps_form.py @@ -120,7 +120,7 @@ class report_printscreen_list(report_int): line[f]=round(line[f],precision) col = etree.SubElement(node_line, 'col', tree='no') if line[f] != None: - col.text = tools.ustr(line[f] or '') + col.text = tools.ustr(line[f] or '') else: col.text = '/' diff --git a/openerp/report/render/rml2html/rml2html.py b/openerp/report/render/rml2html/rml2html.py index a26f6eadaa6..17ed2e3103e 100644 --- a/openerp/report/render/rml2html/rml2html.py +++ b/openerp/report/render/rml2html/rml2html.py @@ -232,7 +232,7 @@ class _rml_stylesheet(object): attr = {} attrs = ps.attrib for key, val in attrs.items(): - attr[key] = val + attr[key] = val attrs = [] for a in attr: if a in self._tags: @@ -296,13 +296,13 @@ class _rml_template(object): frames[(posy,posx,tmpl.get('id'))] = _rml_tmpl_frame(posx, utils.unit_get(tmpl.get('width'))) for tmpl in pt.findall('pageGraphics'): for n in tmpl: - if n.tag == 'image': - self.data = rc + utils._process_text(self, n.text) - if n.tag in self._tags: - t = self._tags[n.tag](n, self.style,self.localcontext) - frames[(t.posy,t.posx,n.tag)] = t - else: - self.style.update(n) + if n.tag == 'image': + self.data = rc + utils._process_text(self, n.text) + if n.tag in self._tags: + t = self._tags[n.tag](n, self.style,self.localcontext) + frames[(t.posy,t.posx,n.tag)] = t + else: + self.style.update(n) keys = frames.keys() keys.sort() keys.reverse() diff --git a/openerp/report/render/rml2pdf/trml2pdf.py b/openerp/report/render/rml2pdf/trml2pdf.py index 58457993142..a17c03b40cb 100644 --- a/openerp/report/render/rml2pdf/trml2pdf.py +++ b/openerp/report/render/rml2pdf/trml2pdf.py @@ -82,7 +82,7 @@ class NumberedCanvas(canvas.Canvas): def showPage(self): self._currentPage +=1 if not self._flag: - self._pageCount += 1 + self._pageCount += 1 else: self.pages.update({self._currentPage:self._pageCount}) self._codes.append({'code': self._code, 'stack': self._codeStack}) diff --git a/openerp/report/render/rml2txt/rml2txt.py b/openerp/report/render/rml2txt/rml2txt.py index 4a30e0d2345..8a8c1b7f3c7 100755 --- a/openerp/report/render/rml2txt/rml2txt.py +++ b/openerp/report/render/rml2txt/rml2txt.py @@ -336,8 +336,8 @@ class _rml_stylesheet(object): attr = {} attrs = ps.attributes for i in range(attrs.length): - name = attrs.item(i).localName - attr[name] = ps.get(name) + name = attrs.item(i).localName + attr[name] = ps.get(name) attrs = [] for a in attr: if a in self._tags: diff --git a/openerp/report/render/simple.py b/openerp/report/render/simple.py index 4ce10991924..49d1adf148e 100644 --- a/openerp/report/render/simple.py +++ b/openerp/report/render/simple.py @@ -82,7 +82,7 @@ if __name__=='__main__': ''' if s.render(): - print s.get() + print s.get() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 6312fd9426d6ccdbbfdada88763961f4b29d5c06 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Wed, 8 Feb 2012 18:07:00 +0100 Subject: [PATCH 0014/1390] [REF] openerp.report: remove unused imports and vars, simplify logging. bzr revid: florent.xicluna@gmail.com-20120208170700-csx9jb3nwmvq3dzj --- openerp/report/custom.py | 3 --- openerp/report/render/html2html/html2html.py | 2 -- openerp/report/render/makohtml2html/makohtml2html.py | 8 +++----- openerp/report/render/odt2odt/odt2odt.py | 1 - openerp/report/render/rml2html/rml2html.py | 2 +- openerp/report/render/rml2txt/rml2txt.py | 2 -- openerp/report/render/rml2txt/utils.py | 1 - openerp/report/render/simple.py | 1 - 8 files changed, 4 insertions(+), 16 deletions(-) diff --git a/openerp/report/custom.py b/openerp/report/custom.py index b33065fcdee..80dd9462175 100644 --- a/openerp/report/custom.py +++ b/openerp/report/custom.py @@ -21,7 +21,6 @@ import os import time -import openerp.netsvc as netsvc import openerp.tools as tools from openerp.tools.safe_eval import safe_eval as eval @@ -67,7 +66,6 @@ class report_custom(report_int): # def _row_get(self, cr, uid, objs, fields, conditions, row_canvas=None, group_by=None): result = [] - tmp = [] for obj in objs: tobreak = False for cond in conditions: @@ -365,7 +363,6 @@ class report_custom(report_int): order_date['Y'] = lambda x : x abscissa = [] - tmp = {} idx = 0 date_idx = None diff --git a/openerp/report/render/html2html/html2html.py b/openerp/report/render/html2html/html2html.py index 181c7f7ba67..09d7ad5e825 100644 --- a/openerp/report/render/html2html/html2html.py +++ b/openerp/report/render/html2html/html2html.py @@ -20,9 +20,7 @@ ############################################################################## from openerp.report.render.rml2pdf import utils -from lxml import etree import copy -import openerp.pooler as pooler import base64 import cStringIO import re diff --git a/openerp/report/render/makohtml2html/makohtml2html.py b/openerp/report/render/makohtml2html/makohtml2html.py index 57e57bd8d63..dbb3327a105 100644 --- a/openerp/report/render/makohtml2html/makohtml2html.py +++ b/openerp/report/render/makohtml2html/makohtml2html.py @@ -23,8 +23,7 @@ import mako from lxml import etree from mako.template import Template from mako.lookup import TemplateLookup -import openerp.netsvc as netsvc -import traceback, sys, os +import os _logger = logging.getLogger(__name__) @@ -126,9 +125,8 @@ class makohtml2html(object): final_html += self.format_header(etree_obj) final_html += self.format_body(etree_obj) return final_html - except Exception,e: - tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) - _logger.error('report :\n%s\n%s\n', tb_s, str(e)) + except Exception: + _logger.exception('report :') def parseNode(html, localcontext = {}): r = makohtml2html(html, localcontext) diff --git a/openerp/report/render/odt2odt/odt2odt.py b/openerp/report/render/odt2odt/odt2odt.py index d077207f4d7..b9713943dc8 100644 --- a/openerp/report/render/odt2odt/odt2odt.py +++ b/openerp/report/render/odt2odt/odt2odt.py @@ -20,7 +20,6 @@ ############################################################################## from openerp.report.render.rml2pdf import utils -from lxml import etree import copy class odt2odt(object): diff --git a/openerp/report/render/rml2html/rml2html.py b/openerp/report/render/rml2html/rml2html.py index 17ed2e3103e..90bd58af99a 100644 --- a/openerp/report/render/rml2html/rml2html.py +++ b/openerp/report/render/rml2html/rml2html.py @@ -39,7 +39,7 @@ import sys import cStringIO from lxml import etree import copy -import utils + from openerp.report.render.rml2pdf import utils class _flowable(object): diff --git a/openerp/report/render/rml2txt/rml2txt.py b/openerp/report/render/rml2txt/rml2txt.py index 8a8c1b7f3c7..ab1930d81ba 100755 --- a/openerp/report/render/rml2txt/rml2txt.py +++ b/openerp/report/render/rml2txt/rml2txt.py @@ -22,9 +22,7 @@ import sys import StringIO -import copy from lxml import etree -import base64 import utils diff --git a/openerp/report/render/rml2txt/utils.py b/openerp/report/render/rml2txt/utils.py index 95e99c32ce1..2bf66925527 100644 --- a/openerp/report/render/rml2txt/utils.py +++ b/openerp/report/render/rml2txt/utils.py @@ -22,7 +22,6 @@ import re import reportlab import reportlab.lib.units -from lxml import etree from openerp.tools.safe_eval import safe_eval as eval _regex = re.compile('\[\[(.+?)\]\]') diff --git a/openerp/report/render/simple.py b/openerp/report/render/simple.py index 49d1adf148e..cb3831c141f 100644 --- a/openerp/report/render/simple.py +++ b/openerp/report/render/simple.py @@ -66,7 +66,6 @@ class simple(render.render): return self.result.getvalue() if __name__=='__main__': - import time s = simple() s.xml = ''' From 69a5eca5b48740c44e35ac5b0285e22a17c5dd8d Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 8 Feb 2012 18:39:32 +0100 Subject: [PATCH 0015/1390] [IMP] Give precedence to module directories instead of zips while locating resources The previous behavior gave the precedence to zipped modules, without any apparent reason, and this is sub-optimal for several reasons: 1. The default is to have regular modules, not zipped modules, so looking first for a regular module is more efficient. 2. Keeping a zipped module next to a regular module with the same name is not a documented or supported feature. 3. Even if you were relying on this behavior having the extracted module take precedence is more practical: you could simply extract the zipped module to test a quick fix. We have another issue related to this feature because the code looking for zipped modules escapes the addons paths chroot and goes up to the filesystem root looking for a zip module at each step. This is described in bug 928376 and a fix for it should follow. lp bug: https://launchpad.net/bugs/928376 fixed bzr revid: odo@openerp.com-20120208173932-pwhz53vxxdzbo8ja --- openerp/modules/module.py | 25 ++++++++++++++----------- openerp/tools/misc.py | 24 +++++++++++++++--------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/openerp/modules/module.py b/openerp/modules/module.py index 58a4547ff07..3d3bc0d9adf 100644 --- a/openerp/modules/module.py +++ b/openerp/modules/module.py @@ -280,25 +280,28 @@ def get_module_as_zip(modulename, b64enc=True, src=True): def get_module_resource(module, *args): """Return the full path of a resource of the given module. - @param module: the module - @param args: the resource path components + :param module: module name + :param list(str) args: resource path components within module - @return: absolute path to the resource + :rtype: str + :return: absolute path to the resource TODO name it get_resource_path TODO make it available inside on osv object (self.get_resource_path) """ - a = get_module_path(module) - if not a: return False - resource_path = opj(a, *args) - if zipfile.is_zipfile( a +'.zip') : - zip = zipfile.ZipFile( a + ".zip") + mod_path = get_module_path(module) + if not mod_path: return False + resource_path = opj(mod_path, *args) + if os.path.isdir(mod_path): + # the module is a directory - ignore zip behavior + if os.path.exists(resource_path): + return resource_path + elif zipfile.is_zipfile(mod_path + '.zip'): + zip = zipfile.ZipFile( mod_path + ".zip") files = ['/'.join(f.split('/')[1:]) for f in zip.namelist()] resource_path = '/'.join(args) if resource_path in files: - return opj(a, resource_path) - elif os.path.exists(resource_path): - return resource_path + return opj(mod_path, resource_path) return False def get_module_icon(module): diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index a5c72900fc7..e0be5ffaef9 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -175,10 +175,22 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False): name = os.path.normpath(name) - # Check for a zipfile in the path + # Give higher priority to module directories, which is + # a more common case than zipped modules. + if os.path.isfile(name): + fo = file(name, mode) + if pathinfo: + return fo, name + return fo + + # Support for loading modules in zipped form. + # This will not work for zipped modules that are sitting + # outside of known addons paths. head = name zipname = False - name2 = False + # FIXME: implement chrooting inside addons paths and fix + # for incorrect path_info behavior. Work in progress by + # Florent X linked to bug 928376 while True: head, tail = os.path.split(head) if not tail: @@ -200,14 +212,8 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False): return fo, name return fo except Exception: - name2 = os.path.normpath(os.path.join(head + '.zip', zipname)) pass - for i in (name2, name): - if i and os.path.isfile(i): - fo = file(i, mode) - if pathinfo: - return fo, i - return fo + if os.path.splitext(name)[1] == '.rml': raise IOError, 'Report %s doesn\'t exist or deleted : ' %str(name) raise IOError, 'File not found : %s' % name From ab9db3f6227789fabf3fdfcd2eda016b996bfd28 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Wed, 8 Feb 2012 22:33:13 +0100 Subject: [PATCH 0016/1390] [REM] more unused imports. bzr revid: florent.xicluna@gmail.com-20120208213313-1v0dugc59ch1fnnu --- openerp/service/http_server.py | 2 -- openerp/tests/addons/test_limits/models.py | 1 - 2 files changed, 3 deletions(-) diff --git a/openerp/service/http_server.py b/openerp/service/http_server.py index 07e31ea9c7d..63e0d08fc92 100644 --- a/openerp/service/http_server.py +++ b/openerp/service/http_server.py @@ -44,10 +44,8 @@ import posixpath import urllib import os import logging -from SimpleXMLRPCServer import SimpleXMLRPCDispatcher from websrv_lib import * -import openerp.netsvc as netsvc import openerp.tools as tools try: diff --git a/openerp/tests/addons/test_limits/models.py b/openerp/tests/addons/test_limits/models.py index 5240acd23ab..32e2a9a16f4 100644 --- a/openerp/tests/addons/test_limits/models.py +++ b/openerp/tests/addons/test_limits/models.py @@ -27,7 +27,6 @@ class m(openerp.osv.osv.Model): return True def consume_cpu_time(self, cr, uid, seconds, context=None): - import os t0 = time.clock() t1 = time.clock() while t1 - t0 < seconds: From 55e7b8167e9705ddaabf388e8c95d15666a81827 Mon Sep 17 00:00:00 2001 From: "Vaibhav (OpenERP)" Date: Fri, 6 Apr 2012 11:43:30 +0530 Subject: [PATCH 0017/1390] [IMP] Web addon for SignIn/Out. bzr revid: vda@tinyerp.com-20120406061330-n80vyxgkr309ykba --- addons/hr_attendance/__openerp__.py | 4 + .../static/src/img/emp-in-disable.png | Bin 0 -> 1135 bytes .../hr_attendance/static/src/img/emp-in.png | Bin 0 -> 2153 bytes .../static/src/img/emp-out-disable.png | Bin 0 -> 1110 bytes .../hr_attendance/static/src/img/emp-out.png | Bin 0 -> 2062 bytes addons/hr_attendance/static/src/img/icon.png | Bin 0 -> 5938 bytes .../static/src/js/sign_in_out.js | 82 ++++++++++++++++++ .../static/src/xml/sign_in_out.xml | 28 ++++++ .../wizard/hr_attendance_sign_in_out.py | 1 + .../wizard/hr_attendance_sign_in_out_view.xml | 11 +-- 10 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 addons/hr_attendance/static/src/img/emp-in-disable.png create mode 100644 addons/hr_attendance/static/src/img/emp-in.png create mode 100644 addons/hr_attendance/static/src/img/emp-out-disable.png create mode 100644 addons/hr_attendance/static/src/img/emp-out.png create mode 100644 addons/hr_attendance/static/src/img/icon.png create mode 100644 addons/hr_attendance/static/src/js/sign_in_out.js create mode 100644 addons/hr_attendance/static/src/xml/sign_in_out.xml diff --git a/addons/hr_attendance/__openerp__.py b/addons/hr_attendance/__openerp__.py index c903a87abc4..b25047638c8 100644 --- a/addons/hr_attendance/__openerp__.py +++ b/addons/hr_attendance/__openerp__.py @@ -54,5 +54,9 @@ actions(Sign in/Sign out) performed by them. 'installable': True, 'auto_install': False, 'certificate': '0063495605613', + + #web + "js": ["static/src/js/sign_in_out.js"], + 'qweb' : ["static/src/xml/sign_in_out.xml"], } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_attendance/static/src/img/emp-in-disable.png b/addons/hr_attendance/static/src/img/emp-in-disable.png new file mode 100644 index 0000000000000000000000000000000000000000..1968e0de46434949ddb12393f4f21895270a334c GIT binary patch literal 1135 zcmV-#1d#iQP)kdg00001b5ch_0Itp) z=>Px#0%A)?L;(MXkIcUS000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyb&2sa_Q z3&GR?00Z+$L_t(Y$BmR*Y*b|s$A5Fq>Dk@ZQkF#u6eyrrg9t^agh&iZ;K55`)F3_( zUwsf`AjlK77^_l~#=GH35^rGS#XuiSj3(Zt2oDqqAxgypEiK({yW8Ef=ljNoJ-yh{ zmYJO7!vitH6I{_{Z0XG;RM}XoG zqXLHvedJKJl0I2zEPl7Y@GM`9HSv44eXyfpI1-OfCFPV;Nfk+wWVuK;Llg)kz^(C~ zh*hsXc_>#l{t9inUX8dojC`Pga*1|=(l%fL2gR}G^Q*fKrXvPlvhwLI+Ytw_xCkH! z4nmrCvXMGd)MFUHQ5sry#e=M40ftZv)^m57 zg`-lA&k<3s<70493?LW+x+C&Q9$+!;v@wK>i=*CM+&>DC@3lDm!&(%J0~iD$OBThD zU=vFTFl@#nPX~R1_@z^*C4p0tz@1%o+jkT7TL| zEh!9cB;gVRmpm7^M#%4Mz;cRS;)D#4#A>F0L4f@}AN4GM0_FCn#`XyC_=%|A*$OVKrAy=tl5y~*LsnmoN{Xo(e+r}0} zNYuoibgE;TkP5AmBq>cvMR4ieLro{L#RZAZ;Jo`002ovPDHLkV1o9X B3oQTu literal 0 HcmV?d00001 diff --git a/addons/hr_attendance/static/src/img/emp-in.png b/addons/hr_attendance/static/src/img/emp-in.png new file mode 100644 index 0000000000000000000000000000000000000000..26e3c01556b290949b104240e73fe43dc27b1229 GIT binary patch literal 2153 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 literal 0 HcmV?d00001 diff --git a/addons/hr_attendance/static/src/img/emp-out.png b/addons/hr_attendance/static/src/img/emp-out.png new file mode 100644 index 0000000000000000000000000000000000000000..d2a6cbb50137c404d3f188151bb64024c082b75a GIT binary patch literal 2062 zcmV+p2=VucP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyb& z2ssF4I&?Mw00)jqL_t(o!?l)aY+c0_$A2^T-nTjNvtws-UhLR01rq`#aY8|rT1WsD zXe*J3N=T?dNG+9sR?rj?NaL6Uw?wj9K2+ip5fBz*q^c4~h`nMfS#U+-gecD9=LF(4 zes_t}ntkOg(5(Y+eYob#XmIsbD8E^usV-!l2X^~u&nk8j=Fy!EeJ>nGOQ z+S)G2o_(PJ>>!xCdCSJXU()!4U(K$XO(L13Saf;u8VV z70oLIl#0b1Y}>(cqOXV$1U^CF<9R+{WY_LpYWHV*uFZ{&e)5+s+so<~2 zCbu^)Z^rk1rIa8NO=AROLPShyEjkkfp<2GInHgne+rP{Cd4*u>6RizRO-tIUtExq7 zrIgY{Q=ybXL>2A?pdym$s4ZEf}U?%n&05m6$BFr2!%?+0fj;dB<1LUkY5w`0Q}AIpF5N?5;W zQ6XPEeb*IBmg4)~WDO9RP{q^~5mKo#-gxs3o_&7Ds{XI~^WUoyZrt?9udi8o?e_AS zY3bhoxw>)nO?aMHqM6BB0HC!d7K`)tJ8v<6-U8X%{rSGSnX|9Tjt!ZIAKq}`0RFsb z!~M74zV@m5MGa)LS&kp?W8eOLT;6mUjf)#6dH`B$j4|{a?qUCd{VcuWDi+q)OV#W- zY=7>V;}8ArfrS^$z{ZvhxBTL^U%uA3xKYB;DBt(#@9$@1WQ1&AmVtqjIF5}Ii{pD9 zz8^4W-hAdbacYhnq59Av;zy4NMVEtPxxVC)qxW7pGV=O40kpKVPzcAJmCLRvuDX7; z_B0x<815SB4*fuy0%C=FKg$5M_0YimCgRS+hPaNlG-&qHiEn9xC>lS2!p(w{9om-Yg zMMVV_6_ru)X~obBFS0NQU}y-H&x7lN)<{zm96N>pCNic@dY(>e{m*@gMD46%@#HiB z9UUF)>;CWBOE0|)*Y%WbTP1l3T014#sZu8dtrfWwUo!X8Pmy#wD$ApzFf;@=-;BEJ zE())|j=OFhp$H)$pbi@oTjIL^m=9~Fh2V}m?jSJX)w3$A1O%lNCr|bh0TGO0Qu|>T zB0%ugo5cG1P=^mgPY?9=A_D`^*@*-J$vf{P@yaU%O5p>3$=3<3Z~q{jPJbf@l8MAD zrBEWmz`!7}m_rzbr4X3OPA6grL~uU-7>*o4CT0+z90yY@;@x*202OQ2Fu$XNLJ5Qb z*DYR5CX;FY27qGG9h}g1Z*MQ@bb7MJPrQ64TCQ(GVuyN=zCP5kW5_MHpk8|odH;R% z?%l*YI}xqH7^>Hs0q8%dbY=l2c_4lKH%q#ji`7WEQ`PxSA9!&ocBuS zOWC^GMO0Q+5Rb>PEDNPnq<5u(C<&G0P`v*E{O5OIl_V1Y9^eAA)~_e?+ zojZ|O3}xF$c{%&P{POCrH=`I(W7%5$^e5M^C@V{eh^VOEPe_qc6ai!K%2H(Zd`4>K zOcLodGty~hRaP?ho_na+wr!eoY#Ze`h-HbJOb*s`bv^X;91y^~^g_qKp5O88hpy+V z88c>1zJj9I2h*lnxsub18;Cm&sbrE=B0=1?(P4-T4`e^x?<5`i^H$g(kd2L=r{}w&UP?0e%qRdp@ok_5Q(zdaD2PDQbLN6es~ycQ@+k zr%_*h6*+dC2t*>mIDA;ObLVe2ouwHifH}ZiAO(1JbqnVL%#eB6l=M1j_kQ>_u(7L`h=F=IYDc;LY5dBtKOQz)FZ8#+L;loRTF-VG>a zev?kmYt3ZZDsB6=SV?}^HWG_bwC%x>@$n}X?Ai0TV~K>+6^rNhAi0?F9Hf8T)YM#_ sOxA?p4h|0=y!`0VE`UwI<}>#G5B|MNh_viC#{d8T07*qoM6N<$f(9txod5s; literal 0 HcmV?d00001 diff --git a/addons/hr_attendance/static/src/img/icon.png b/addons/hr_attendance/static/src/img/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..297dc71c85c5fdd8deafabfbb46093e04adc32d1 GIT binary patch literal 5938 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 HxC&%52rYWz659b%5VwO|`_ zaaQ#=6u&oY2zu6@mqcZA?3^$LLA1@GkSu(6^PPQWZZY;7F6YC8a_lpM(DkSGftGO% z_um`BHhClkx;H`JSk~Ttd5GY({L&1e?@ro;X?i4Ydl);F;wRVRx9Bn&kc!o)Sl~z_ z5CQ#86V0KQ-(9hBGUwud@rXduz%Mk|H{?8!wKzZ-O|LnpQ?+E;o^A!~V>^k6D6xnd zIH(qQ2<1O5{oVuI+Z|4ljOkl$8fWCQoRVkuv)in~o164Wzg-7S+U)G*09}+29bg-k z6|fFK0<%QNWb+Fb+3iD13oqZpvlsX3_mojiiInYFH`6Hf7)O~;ahL_4ubvp9`%UGp z$4M(6d~&)2-lA0-nLOpnwZuxjB`(iIufhdS;V%yiTBR5ca;J7Iwk%4mY5;+dFI7V; zz7^=|Q!NMo{@GM4@(t6Bw4yNg>M1as7 z(YKyLW4AaK(X=h#HMD}7BWG+}9EgNBfcL11b-Jw{g-ZnBAypD%V{C=a_RP9+%&mXv zYA!=`cuYK?S`G+ECwenaSJ^Yf?T3E1pL`42z?_cH$B1^Uy`R%FUR#geTc;oQU4v5O zDWGtLejeaw9f<(a^=oi+1*;)Np4onst25!+{sHy+FbRRd zPn{b1<`{#;i4{Pd-v>#1N^|3=j~2yNm1MJzAOMP%14VIuUuBixf~dO?jso!wj36qN#&u}7i( z(&mmB*QfBxJUKMh_Wbz~@Oh@10!Aik%d(Qjwj{icpZ#2S^1pDcuy{pM!1qsjWuJci zcS>gZplI~L&iaGBn5~cfKOpe&@Q8B$d%XO5yaHmp{9-&j>^yw`@*g!m+W*Jk?rG=j z5cK~yWRfPA{WFmNH$m6a;X{D6k3B*_KmeDshpVrxwU<4Yr;lU)xdg?(CInSQ4TVNI HtLXm&e3x`` literal 0 HcmV?d00001 diff --git a/addons/hr_attendance/static/src/js/sign_in_out.js b/addons/hr_attendance/static/src/js/sign_in_out.js new file mode 100644 index 00000000000..0a0174d0a89 --- /dev/null +++ b/addons/hr_attendance/static/src/js/sign_in_out.js @@ -0,0 +1,82 @@ +openerp.hr_attendance = function(openerp) { + + openerp.hr_attendance.SignIn = openerp.web.Widget.extend({ + template: 'SignInNotifier', + start: function() { + this.$element.on('click', '.sign_in', this.getParent().on_sign_in_out); + } + }); + + openerp.hr_attendance.SignOut = openerp.web.Widget.extend({ + template: 'SignOutNotifier', + + start: function() { + this.$element.on('click', '.sign_out', this.getParent().on_sign_in_out); + } + }); + + openerp.hr_attendance.SignInOut = openerp.web.Widget.extend({ + template: "SignInOutNotifier", + init: function() { + this._super.apply(this, arguments); + this.dataset = new openerp.web.DataSetSearch( + this, + 'hr.employee', + this.session.user_context, + [['user_id','=', this.session.uid]]); + }, + + start: function() { + return this.dataset.read_slice(['state']).done(this.do_sign_in_out); + }, + + do_sign_in_out: function(user) { + if(_.isEmpty(user)) return; + if(user[0]['state'] === 'present') { + this.sign_out = new openerp.hr_attendance.SignOut(this); + this.sign_out.appendTo(this.$element); + } else { + this.sign_in = new openerp.hr_attendance.SignIn(this); + this.sign_in.appendTo(this.$element); + } + }, + + on_sign_in_out: function(evt) { + var self = this; + new openerp.web.DataSetSearch( + this, + 'ir.actions.act_window', + {}, + [['res_model', '=', 'hr.sign.in.out']]) + .read_slice().done(function(action) { + action = action[0]; + action.context = JSON.parse(action.context); + var action_manager = new openerp.web.ActionManager(self); + action_manager.do_action(action, self.on_close); + }); + }, + + on_close: function() { + if(this.sign_in) { + this.sign_in.destroy(); + this.sign_out = new openerp.hr_attendance.SignOut(this); + this.sign_out.appendTo(this.$element); + } else if(this.sign_out) { + this.sign_out.destroy(); + this.sign_in = new openerp.hr_attendance.SignIn(this); + this.sign_in.appendTo(this.$element); + } + } + }); + + openerp.web.UserMenu.include({ + do_update: function() { + var self = this; + this._super(); + this.update_promise.then(function() { + self.hr_sign_in_out = new openerp.hr_attendance.SignInOut(self); + self.hr_sign_in_out.appendTo(openerp.webclient.$element.find('.oe_systray')) + }); + } + }); +} diff --git a/addons/hr_attendance/static/src/xml/sign_in_out.xml b/addons/hr_attendance/static/src/xml/sign_in_out.xml new file mode 100644 index 00000000000..e28b93dfa6c --- /dev/null +++ b/addons/hr_attendance/static/src/xml/sign_in_out.xml @@ -0,0 +1,28 @@ + \ No newline at end of file diff --git a/addons/hr_attendance/wizard/hr_attendance_sign_in_out.py b/addons/hr_attendance/wizard/hr_attendance_sign_in_out.py index 55edb1406e8..15e8783d660 100644 --- a/addons/hr_attendance/wizard/hr_attendance_sign_in_out.py +++ b/addons/hr_attendance/wizard/hr_attendance_sign_in_out.py @@ -69,6 +69,7 @@ class hr_sign_in_out(osv.osv_memory): _columns = { 'name': fields.char('Employees name', size=32, required=True, readonly=True), 'state': fields.char('Current state', size=32, required=True, readonly=True), + 'date': fields.datetime('Date'), 'emp_id': fields.many2one('hr.employee', 'Empoyee ID', readonly=True), } diff --git a/addons/hr_attendance/wizard/hr_attendance_sign_in_out_view.xml b/addons/hr_attendance/wizard/hr_attendance_sign_in_out_view.xml index 5121a2d18a0..b729dd85e5b 100644 --- a/addons/hr_attendance/wizard/hr_attendance_sign_in_out_view.xml +++ b/addons/hr_attendance/wizard/hr_attendance_sign_in_out_view.xml @@ -10,15 +10,16 @@