Refactoring by validation with pylint

This commit is contained in:
Cédric Krier committed 2010-02-18 18:50:35 +01:00
1 parent 5a2baacef4
commit b5fb4d1ef3
34 files changed
+438 -416

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Refactoring by validation with pylint
* Modify ondelete attribute of Many2One according to required attribute value
* Refactor import_data of ModelStorage
* Raise exception when search function is missing on Function fields
+2 -2
View File
@@ -1,7 +1,8 @@
#!/usr/bin/env python
#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 sys, os
import sys
import os
DIR = os.path.abspath(os.path.normpath(os.path.join(__file__,
'..', '..', 'trytond')))
if os.path.isdir(DIR):
@@ -11,7 +12,6 @@ if '--profile' in sys.argv:
import profile
import pstats
import tempfile
import os
sys.argv.remove('--profile')
statfile = tempfile.mkstemp(".stat","trytond-")[1]
+1 -1
View File
@@ -23,7 +23,7 @@ class Field(object):
@staticmethod
def sql_type(field):
return None
raise NotImplementedError
class Boolean(Field):
+2 -2
View File
@@ -5,7 +5,7 @@ from trytond.backend.database import DatabaseInterface, CursorInterface
from trytond.config import CONFIG
from trytond.session import Session
from psycopg2.pool import ThreadedConnectionPool
from psycopg2.extensions import cursor
from psycopg2.extensions import cursor as PsycopgCursor
from psycopg2.extensions import ISOLATION_LEVEL_SERIALIZABLE
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
from psycopg2.extensions import register_type, register_adapter
@@ -238,7 +238,7 @@ class Database(DatabaseInterface):
(0, module_id, dependency))
class _Cursor(cursor):
class _Cursor(PsycopgCursor):
def __build_dict(self, row):
return dict((desc[0], row[i])
+13 -12
View File
@@ -2,7 +2,6 @@
#this repository contains the full copyright notices and license terms.
from trytond.backend.table import TableHandlerInterface
from trytond.backend.postgresql.fields import FIELDS
import logging
@@ -25,8 +24,8 @@ class TableHandler(TableHandlerInterface):
if not self.table_exist(self.cursor, self.table_name):
self.cursor.execute('CREATE TABLE "%s" ()' % self.table_name)
self.cursor.execute('COMMENT ON TABLE "%s" IS \'%s\'' % (self.table_name,
model._description.replace("'", "''")))
self.cursor.execute('COMMENT ON TABLE "%s" IS \'%s\'' %
(self.table_name, model._description.replace("'", "''")))
self._update_definitions()
if 'id' not in self._columns:
@@ -140,9 +139,10 @@ class TableHandler(TableHandlerInterface):
self.cursor.execute("SELECT co.contype, co.confdeltype, at.attname, "\
"cl2.relname, co.conname "\
"FROM pg_constraint co "\
"LEFT JOIN pg_class cl on (co.conrelid = cl.oid) "\
"LEFT JOIN pg_class cl2 on (co.confrelid = cl2.oid) "\
"LEFT JOIN pg_attribute at on (co.conkey[1] = at.attnum) "\
"LEFT JOIN pg_class cl ON (co.conrelid = cl.oid) "\
"LEFT JOIN pg_class cl2 ON (co.confrelid = cl2.oid) "\
"LEFT JOIN pg_attribute at ON " \
"(co.conkey[1] = at.attnum) "\
"WHERE cl.relname = %s AND at.attrelid = cl.oid",
(self.table_name,))
self._constraints = []
@@ -237,7 +237,6 @@ class TableHandler(TableHandlerInterface):
if field_size == None:
if self._columns[column_name]['size'] > 0:
self.alter_size(column_name, base_type)
pass
elif self._columns[column_name]['size'] == field_size:
pass
elif self._columns[column_name]['size'] > 0 and \
@@ -318,7 +317,7 @@ class TableHandler(TableHandlerInterface):
return
self.cursor.execute('CREATE INDEX "' + index_name + '" ' \
'ON "' + self.table_name + '" ( ' + \
','.join(['"' + x + '"' for x in column_name]) + \
','.join(['"' + x + '"' for x in column_name]) +\
')')
self._update_definitions()
elif action == 'remove':
@@ -354,9 +353,11 @@ class TableHandler(TableHandlerInterface):
'of table %s not null !\n'\
'Try to re-run: ' \
'trytond.py --update=module\n' \
'If it doesn\'t work, update records and execute manually:\n' \
'ALTER TABLE "%s" ALTER COLUMN "%s" SET NOT NULL' % \
(column_name, self.table_name, self.table_name, column_name))
'If it doesn\'t work, update records ' \
'and execute manually:\n' \
'ALTER TABLE "%s" ALTER COLUMN "%s" SET NOT NULL' %
(column_name, self.table_name, self.table_name,
column_name))
elif action == 'remove':
if not self._columns[column_name]['notnull']:
return
@@ -424,7 +425,7 @@ class TableHandler(TableHandlerInterface):
self._update_definitions()
@staticmethod
def dropTable(cursor, model, table, cascade=False):
def drop_table(cursor, model, table, cascade=False):
cursor.execute('DELETE from ir_model_data where '\
'model = \'%s\'' % model)
+12 -13
View File
@@ -4,7 +4,6 @@
from trytond.backend.database import DatabaseInterface, CursorInterface
from trytond.config import CONFIG
from trytond.session import Session
import logging
import os
import re
from decimal import Decimal
@@ -180,12 +179,12 @@ class Database(DatabaseInterface):
@staticmethod
def list(cursor):
res = []
for file in os.listdir(CONFIG['data_path']) + [':memory:']:
if file.endswith('.sqlite') or file == ':memory:':
if file == ':memory:':
for db_file in os.listdir(CONFIG['data_path']) + [':memory:']:
if db_file.endswith('.sqlite') or db_file == ':memory:':
if db_file == ':memory:':
db_name = ':memory:'
else:
db_name = file[:-7]
db_name = db_file[:-7]
try:
database = Database(db_name)
except:
@@ -270,12 +269,12 @@ class Cursor(CursorInterface):
def execute(self, sql, params=None):
buf = ""
for nq, q in QUOTE_SEPARATION.findall(sql+"''"):
nq = nq.replace('?', '??')
nq = nq.replace('%s', '?')
nq = nq.replace('ilike', 'like')
nq = re.sub(EXTRACT_PATTERN, r'EXTRACT("\1",', nq)
buf += nq + q
for nquote, quote in QUOTE_SEPARATION.findall(sql+"''"):
nquote = nquote.replace('?', '??')
nquote = nquote.replace('%s', '?')
nquote = nquote.replace('ilike', 'like')
nquote = re.sub(EXTRACT_PATTERN, r'EXTRACT("\1",', nquote)
buf += nquote + quote
sql = buf[:-2]
try:
if params:
@@ -345,8 +344,8 @@ class Cursor(CursorInterface):
return select
sqlite.register_converter('NUMERIC', lambda val: Decimal(str(val)))
sqlite.register_adapter(Decimal, lambda val: float(val))
sqlite.register_adapter(Session, lambda val: int(val))
sqlite.register_adapter(Decimal, float)
sqlite.register_adapter(Session, int)
def adapt_datetime(val):
return val.replace(tzinfo=None).isoformat(" ")
sqlite.register_adapter(datetime.datetime, adapt_datetime)
+1 -3
View File
@@ -2,7 +2,6 @@
#this repository contains the full copyright notices and license terms.
from trytond.backend.table import TableHandlerInterface
from trytond.backend.sqlite.fields import FIELDS
import logging
import re
@@ -160,7 +159,6 @@ class TableHandler(TableHandlerInterface):
if field_size == None:
if self._columns[column_name]['size'] > 0:
self.alter_size(column_name, base_type)
pass
elif self._columns[column_name]['size'] == field_size:
pass
elif self._columns[column_name]['size'] > 0 and \
@@ -268,7 +266,7 @@ class TableHandler(TableHandlerInterface):
(column_name, self.table_name))
@staticmethod
def dropTable(cursor, model, table, cascade=False):
def drop_table(cursor, model, table, cascade=False):
cursor.execute('DELETE from ir_model_data where '\
'model = \'%s\'' % model)
+1 -1
View File
@@ -206,7 +206,7 @@ class TableHandlerInterface(object):
raise
@staticmethod
def dropTable(cursor, model, table, cascade=False):
def drop_table(cursor, model, table, cascade=False):
'''
Remove a table and clean ir_model_data from the given model.
+3 -2
View File
@@ -1,7 +1,7 @@
#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 ConfigParser, optparse, os, sys
from version import VERSION
from trytond.version import VERSION
class ConfigManager(object):
@@ -52,6 +52,7 @@ class ConfigManager(object):
'init': {},
'update': {},
}
self.configfile = None
def parse(self):
parser = optparse.OptionParser(version=VERSION)
@@ -75,7 +76,7 @@ class ConfigManager(object):
parser.add_option("--logfile", dest="logfile",
help="file where the server log will be stored")
(opt, args) = parser.parse_args()
(opt, _) = parser.parse_args()
if opt.config:
self.configfile = opt.config
+8 -7
View File
@@ -16,7 +16,7 @@ class BrowseRecordList(list):
res = []
for record in self:
res2 = {}
for field_name, field in record._model._columns.iteritems():
for field_name, _ in record._model._columns.iteritems():
if not isinstance(record[field_name], BrowseRecordList):
res2[field_name] = record.get_eval(field_name)
res.append(res2)
@@ -68,7 +68,7 @@ class BrowseRecord(object):
self._data[record_id] = {'id': record_id}
self._cache = cache
if local_cache is None:
local_cache ={}
local_cache = {}
self._local_cache = local_cache
self._local_cache.setdefault(model._name, {})
self._local_cache.setdefault('_language_cache', {})
@@ -145,8 +145,8 @@ class BrowseRecord(object):
for data in datas:
for i, j in ffields:
model = None
if hasattr(j, 'model_name') \
and j.model_name in self._model.pool.object_name_list():
if hasattr(j, 'model_name') and \
j.model_name in self._model.pool.object_name_list():
model = self._model.pool.get(j.model_name)
elif hasattr(j, 'get_target'):
model = j.get_target(self._model.pool)
@@ -156,12 +156,13 @@ class BrowseRecord(object):
data[i] = BrowseRecordNull()
else:
ctx = self._context
if hasattr(j, 'datetime_field') and j.datetime_field:
if hasattr(j, 'datetime_field') and \
j.datetime_field:
ctx = self._context.copy()
ctx['_datetime'] = data[j.datetime_field]
data[i] = BrowseRecord(self._cursor, self._user,
data[i], model, local_cache=self._local_cache,
context=ctx)
data[i], model,
local_cache=self._local_cache, context=ctx)
elif model and j._type in ('one2many', 'many2many') \
and len(data[i]):
ctx = self._context
+1
View File
@@ -6,6 +6,7 @@ import time
class Cacheable(object):
_name = None
def __init__(self):
super(Cacheable, self).__init__()
+2 -1
View File
@@ -10,7 +10,8 @@ class Binary(Field):
'''
_type = 'binary'
def get(self, cursor, user, ids, model, name, values=None, context=None):
@staticmethod
def get(cursor, user, ids, model, name, values=None, context=None):
'''
Convert the binary value into ``str``
+20 -14
View File
@@ -13,9 +13,10 @@ class Property(Function):
def __init__(self, type='float', model_name=None, selection=None,
digits=None, relation=None, add_remove=None, string='', help='',
required=False, readonly=False, domain=None, states=None, priority=0,
change_default=False, translate=False, select=0, on_change=None,
on_change_with=None, depends=None, order_field=None, context=None):
required=False, readonly=False, domain=None, states=None,
priority=0, change_default=False, translate=False, select=0,
on_change=None, on_change_with=None, depends=None,
order_field=None, context=None):
'''
:param type: The type of the field.
:param fnct_search: The name of the search function.
@@ -69,8 +70,8 @@ class Property(Function):
'''
property_obj = model.pool.get('ir.property')
return property_obj.set(cursor, user, name, model._name, record_id,
(value and (self.model_name or '') + ',' + str(value)) or False,
context=context)
(value and (self.model_name or '') + ',' + str(value)) or
False, context=context)
def search(self, cursor, user, model, name, args, context=None):
@@ -106,16 +107,21 @@ class Property(Function):
#Fetch res ids that comply with the domain
cursor.execute(
'SELECT cast(split_part("' + property_obj._table + '".res,\',\',2) as integer), ' + \
'SELECT CAST(' \
'SPLIT_PART("' + property_obj._table + '".res,\',\',2) ' \
'AS INTEGER), '\
'"' + property_obj._table + '".id '\
'FROM "' + property_obj._table + '" '\
'JOIN "' + field_obj._table + '" on ("' + field_obj._table + '"'+ \
'.id = "' + property_obj._table + '".field) '\
'JOIN "' + model_obj._table +'" on ("' + model_obj._table + \
'".id = "' + field_obj._table + '".model) '\
'JOIN "' + field_obj._table + '" ON ' \
'("' + field_obj._table + '"'+ \
'.id = "' + property_obj._table + '".field) '\
'JOIN "' + model_obj._table +'" ON ' \
'("' + model_obj._table + \
'".id = "' + field_obj._table + '".model) '\
'WHERE '\
'CASE WHEN "' +\
model_obj._table + '".model = %s AND "' + field_obj._table + '".name = %s AND ' \
model_obj._table + '".model = %s ' \
'AND "' + field_obj._table + '".name = %s AND ' \
+ property_query + \
' THEN ' + \
conditions + \
@@ -126,9 +132,9 @@ class Property(Function):
props = cursor.fetchall()
default = None
for x in props:
if not x[0]:
default = x[1]
for prop in props:
if not prop[0]:
default = prop[1]
break
if not default:
+21 -14
View File
@@ -3,7 +3,7 @@
from trytond.model import fields
from trytond.pool import Pool
from trytond.pyson import PYSONEncoder, CONTEXT
from trytond.pyson import PYSONEncoder
import copy
@@ -20,6 +20,9 @@ class Model(object):
:_error_messages: a dictionary mapping keywords to an error message. Eg.:
``{'recursive_categories': 'You can not create recursive categories!'}``
:_rec_name: The name of the main field of the model.
By default the field ``name``.
:id: An Integer field for unique identifier.
"""
_name = None
_inherits = {}
@@ -28,6 +31,9 @@ class Model(object):
__columns = None
__xxx2many_targets = None
__defaults = None
_rec_name = 'name'
id = fields.Integer('ID', readonly=True)
def _reset_columns(self):
self.__columns = None
@@ -245,9 +251,9 @@ class Model(object):
'WHERE f.model = m.id ' \
'AND m.model = %s ',
(self._name,))
fields = {}
model_fields = {}
for field in cursor.dictfetchall():
fields[field['name']] = field
model_fields[field['name']] = field
# Prefetch field translations
if self._columns:
@@ -278,17 +284,17 @@ class Model(object):
relation = field.model_name
elif hasattr(field, 'relation_name'):
relation = field.relation_name
if field_name not in fields:
if field_name not in model_fields:
cursor.execute("INSERT INTO ir_model_field " \
"(model, name, field_description, ttype, " \
"relation, help, module) " \
"VALUES (%s, %s, %s, %s, %s, %s, %s)",
(model_id, field_name, field.string, field._type,
relation, field.help, module_name))
elif fields[field_name]['field_description'] != field.string \
or fields[field_name]['ttype'] != field._type \
or fields[field_name]['relation'] != relation \
or fields[field_name]['help'] != field.help:
elif model_fields[field_name]['field_description'] != field.string \
or model_fields[field_name]['ttype'] != field._type \
or model_fields[field_name]['relation'] != relation \
or model_fields[field_name]['help'] != field.help:
cursor.execute('UPDATE ir_model_field ' \
'SET field_description = %s, ' \
'ttype = %s, ' \
@@ -296,7 +302,7 @@ class Model(object):
'help = %s ' \
'WHERE id = %s ',
(field.string, field._type, relation,
field.help, fields[field_name]['id']))
field.help, model_fields[field_name]['id']))
trans_name = self._name + ',' + field_name
if trans_name not in trans_fields:
if field_name not in ('create_uid', 'create_date',
@@ -328,7 +334,7 @@ class Model(object):
and ((hasattr(field, 'translate_selection') \
and field.translate_selection)
or not hasattr(field, 'translate_selection')):
for (key, val) in field.selection:
for (_, val) in field.selection:
if trans_name not in trans_selection \
or val not in trans_selection[trans_name]:
cursor.execute('INSERT INTO ir_translation ' \
@@ -338,13 +344,14 @@ class Model(object):
(trans_name, 'en_US', 'selection', val, '',
module_name, False))
# Clean ir_model_field from field that are no more existing.
for field_name in fields:
if fields[field_name]['module'] == module_name \
for field_name in model_fields:
if model_fields[field_name]['module'] == module_name \
and field_name not in self._columns:
# XXX This delete field even when it is defined later in the module
#XXX This delete field even when it is defined later
# in the module
cursor.execute('DELETE FROM ir_model_field '\
'WHERE id = %s',
(fields[field_name]['id'],))
(model_fields[field_name]['id'],))
# Add error messages in ir_translation
cursor.execute('SELECT id, src FROM ir_translation ' \
+92 -55
View File
@@ -5,7 +5,6 @@ from trytond.model import ModelStorage
from trytond.model import fields
from trytond.backend import FIELDS, TableHandler
from trytond.backend import DatabaseIntegrityError, Database
from trytond.model.browse import BrowseRecord, BrowseRecordNull
from trytond.tools import reduce_ids
from trytond.const import OPERATORS
import datetime
@@ -62,7 +61,8 @@ class ModelSQL(ModelStorage):
# create/update table in the database
table = TableHandler(cursor, self, module_name)
if self._history:
history_table = TableHandler(cursor, self, module_name, history=True)
history_table = TableHandler(cursor, self, module_name,
history=True)
timestamp_field = FIELDS['timestamp']
integer_field = FIELDS['integer']
logs = (
@@ -168,7 +168,7 @@ class ModelSQL(ModelStorage):
and field.left and field.right:
self._rebuild_tree(cursor, 0, field_name, False, 0)
for ident, constraint, msg in self._sql_constraints:
for ident, constraint, _ in self._sql_constraints:
table.add_constraint(ident, constraint)
if self._history:
@@ -179,7 +179,8 @@ class ModelSQL(ModelStorage):
if not cursor.fetchone():
columns = ['"' + str(x) + '"' for x in self._columns
if not hasattr(self._columns[x], 'set')]
cursor.execute('INSERT INTO "' + self._table + '__history" '\
cursor.execute('INSERT ' \
'INTO "' + self._table + '__history" '\
'(' + ','.join(columns) + ') ' \
'SELECT ' + ','.join(columns) + \
' FROM "' + self._table + '"')
@@ -204,6 +205,24 @@ class ModelSQL(ModelStorage):
res.append(error)
return res
def default_sequence(self, cursor, user, context=None):
'''
Return the default value for sequence field.
'''
table = self._table
if 'sequence' not in self._columns:
for model in self._inherits:
model_obj = self.pool.get(model)
if 'sequence' in model_obj._columns:
table = model_obj._table
break
cursor.execute('SELECT MAX(sequence) ' \
'FROM "' + table + '"')
res = cursor.fetchone()
if res:
return res[0]
return 0
def table_query(self, context=None):
'''
Return None if the model is a real table in the database
@@ -269,7 +288,7 @@ class ModelSQL(ModelStorage):
for i in values.keys():
if i in self._inherit_fields:
(inherits, col, col_detail) = self._inherit_fields[i]
(inherits, _, _) = self._inherit_fields[i]
if i in self._columns:
continue
if inherits in tocreate:
@@ -388,8 +407,8 @@ class ModelSQL(ModelStorage):
upd_todo.sort(lambda x, y: self._columns[x].priority - \
self._columns[y].priority)
for field in upd_todo:
self._columns[field].set(cursor, user, id_new, self, field, values[field],
context=context)
self._columns[field].set(cursor, user, id_new, self, field,
values[field], context=context)
if self._history:
cursor.execute('INSERT INTO "' + self._table + '__history" ' \
@@ -406,7 +425,8 @@ class ModelSQL(ModelStorage):
if isinstance(field, fields.Many2One) \
and field.model_name == self._name \
and field.left and field.right:
self._update_tree(cursor, user, id_new, k, field.left, field.right)
self._update_tree(cursor, user, id_new, k, field.left,
field.right)
return id_new
@@ -502,7 +522,7 @@ class ModelSQL(ModelStorage):
else:
cursor.execute('SELECT ' + \
','.join(fields_pre2 + ['id']) + \
' FROM ' + table_query + '\"' + self._table + '\" ' \
' FROM ' + table_query + '\"' + self._table + '\" '\
'WHERE ' + red_sql + \
history_clause + history_order + history_limit,
table_args + red_ids + history_args)
@@ -647,8 +667,8 @@ class ModelSQL(ModelStorage):
record_id = record2['id']
del record2['id']
fields_related2values[field].setdefault(record_id, {})
fields_related2values[field][record_id][record['id']] = \
record2
fields_related2values[
field][record_id][record['id']] = record2
else:
for record in obj.read(cursor, user, [x[field] for x in res
if x[field]], fields_related[field], context=context):
@@ -876,9 +896,9 @@ class ModelSQL(ModelStorage):
.get(field.model_name, set())
if not ((model_obj.search(cursor2, 0, [
('id', '=', values[field_name]),
], order=[], context=context) \
or values[field_name] in create_records) \
and values[field_name] not in delete_records):
], order=[], context=context) or
values[field_name] in create_records) and
values[field_name] not in delete_records):
self.raise_user_error(cursor2,
'foreign_model_missing',
error_args=self._get_error_args(
@@ -948,8 +968,9 @@ class ModelSQL(ModelStorage):
and field.model_name == self._name \
and field.left and field.right:
if field.left in values or field.right in values:
raise Exception('ValidateError', 'You can not update fields: ' \
'"%s", "%s"' % (field.left, field.right))
raise Exception('ValidateError',
'You can not update fields: "%s", "%s"' %
(field.left, field.right))
if len(ids) == 1:
self._update_tree(cursor, user, ids[0], k,
field.left, field.right)
@@ -1104,10 +1125,12 @@ class ModelSQL(ModelStorage):
error_args = []
error_args.append(self._get_error_args(cursor2,
user, 'id', context=context)[1])
error_args.extend(list(model._get_error_args(cursor2,
user, field_name, context=context)))
self.raise_user_error(cursor2, 'foreign_model_exist',
error_args=tuple(error_args), context=context)
error_args.extend(list(model._get_error_args(
cursor2, user, field_name, context=context)))
self.raise_user_error(cursor2,
'foreign_model_exist',
error_args=tuple(error_args),
context=context)
for name, _, error in self._sql_constraints:
if name in exception[0]:
self.raise_user_error(cursor2, error,
@@ -1269,7 +1292,8 @@ class ModelSQL(ModelStorage):
return [x['id'] for x in datas]
def search_domain(self, cursor, user, domain, active_test=True, context=None):
def search_domain(self, cursor, user, domain, active_test=True,
context=None):
'''
Return SQL clause and arguments for the domain
@@ -1377,7 +1401,7 @@ class ModelSQL(ModelStorage):
self._inherits[itable._name])
if table_join not in tables:
tables.append(table_join)
tables_args += table_arg
tables_args.extend(table_arg)
field = table._columns.get(fargs[0], False)
if not field:
if not fargs[0] in self._inherit_fields:
@@ -1389,21 +1413,25 @@ class ModelSQL(ModelStorage):
if field._type == 'many2one':
if hasattr(field, 'search'):
domain.extend([(fargs[0], 'in',
self.pool.get(field.model_name).search(cursor, user,
[(fargs[1], domain[i][1], domain[i][2])],
order=[], context=context))])
self.pool.get(field.model_name).search(cursor,
user,[
(fargs[1], domain[i][1], domain[i][2]),
], order=[], context=context))])
domain.pop(i)
else:
domain[i] = (fargs[0], 'inselect',
self.pool.get(field.model_name).search(cursor, user,
[(fargs[1], domain[i][1], domain[i][2])],
order=[], context=context, query_string=True),
self.pool.get(field.model_name).search(cursor,
user, [
(fargs[1], domain[i][1], domain[i][2]),
], order=[], context=context,
query_string=True),
table)
i += 1
continue
else:
raise Exception('ValidateError', 'Clause on field "%s" ' \
'doesn\'t work on "%s"' % (domain[i][0], self._name))
'doesn\'t work on "%s"' %
(domain[i][0], self._name))
if hasattr(field, 'search'):
arg = [domain.pop(i)]
domain.extend(field.search(cursor, user, table,
@@ -1427,7 +1455,8 @@ class ModelSQL(ModelStorage):
if ids2 == True or ids2 == False:
query1 = 'SELECT "' + field.field + '" ' \
'FROM ' + table_query + '"' + field_obj._table + '" ' \
'FROM ' + table_query + \
'"' + field_obj._table + '" ' \
'WHERE "' + field.field + '" IS NOT NULL'
query2 = table_args
clause = 'inselect'
@@ -1440,7 +1469,8 @@ class ModelSQL(ModelStorage):
if len(ids2) < cursor.IN_MAX:
red_sql, red_ids = reduce_ids('id', ids2)
query1 = 'SELECT "' + field.field + '" ' \
'FROM ' + table_query + '"' + field_obj._table + '" ' \
'FROM ' + table_query + \
'"' + field_obj._table + '" ' \
'WHERE ' + red_sql
query2 = table_args + red_ids
domain[i] = ('id', 'inselect', (query1, query2))
@@ -1450,8 +1480,9 @@ class ModelSQL(ModelStorage):
sub_ids2 = ids2[i:i + cursor.IN_MAX]
red_sql, red_ids = reduce_ids('id', sub_ids2)
cursor.execute(
'SELECT "' + field.field + \
'" FROM ' + table_query + '"' + field_obj._table + '" ' \
'SELECT "' + field.field + '" ' \
'FROM ' + table_query + \
'"' + field_obj._table + '" ' \
'WHERE ' + red_sql,
table_args + red_ids)
@@ -1570,9 +1601,10 @@ class ModelSQL(ModelStorage):
raise Exception('Error', 'Programming error: ' \
'child_of on field "%s" is not allowed!' % \
(domain[i][0],))
ids2 = self.pool.get(field.model_name).search(cursor, user,
[(domain[i][3], 'child_of', ids2)], order=[],
context=context)
ids2 = self.pool.get(field.model_name).search(cursor,
user, [
(domain[i][3], 'child_of', ids2),
], order=[], context=context)
if domain[i][1] == 'child_of':
domain[i] = (domain[i][0], 'in', ids2, table)
else:
@@ -1667,7 +1699,8 @@ class ModelSQL(ModelStorage):
query1 = 'SELECT "' + table._table + '".id ' \
'FROM ' + table_query + '"' + table._table + '" ' \
+ table_join + ' ' \
'WHERE (' + trans_field + ' ' + domain[i][1] + ' %s)'
'WHERE ' \
'(' + trans_field + ' ' + domain[i][1] + ' %s)'
query2 = table_args + table_join_args + [domain[i][2]]
domain[i] = ('id', 'inselect', (query1, query2), table)
else:
@@ -1684,8 +1717,8 @@ class ModelSQL(ModelStorage):
clause = 'IN'
if arg[1] == 'notinselect':
clause = 'NOT IN'
qu1.append('("%s"."%s" %s (%s))' % (table._table, arg[0], clause,
arg[2][0]))
qu1.append('("%s"."%s" %s (%s))' % (table._table, arg[0],
clause, arg[2][0]))
qu2 += arg[2][1]
elif arg[1] in ('in', 'not in'):
if len(arg[2]) > 0:
@@ -1793,13 +1826,15 @@ class ModelSQL(ModelStorage):
add_null = True
else:
if arg[0] in table._columns:
qu2.append(FIELDS[table._columns[arg[0]]._type].\
sql_format(arg[2]))
qu2.append(FIELDS[
table._columns[arg[0]]._type
].sql_format(arg[2]))
qu1.append('("%s"."%s" %s %%s)' % (table._table,
arg[0], arg[1]))
if add_null:
qu1[-1] = '(' + qu1[-1] + ' OR ' + \
'"' + table._table + '".' + arg[0] +' IS NULL)'
qu1[-1] = '(' + qu1[-1] + ' OR ' \
'"' + table._table + '".' + arg[0] + \
' IS NULL)'
return qu1, qu2
@@ -1963,7 +1998,8 @@ class ModelSQL(ModelStorage):
FIELDS['boolean'].sql_format(False))
if table_join not in tables:
tables.append(table_join)
tables_args[table_join] = [context.get('language') or 'en_US']
tables_args[table_join] = [
context.get('language') or 'en_US']
order_by.append('COALESCE(NULLIF(' \
+ '"' + translation_table + '".value, \'\'), ' \
+ '"' + table_name + '".' + field_name + ') ' + otype)
@@ -1992,7 +2028,8 @@ class ModelSQL(ModelStorage):
'order': otype,
})
else:
order_by.append('"' + table_name + '".' + field_name + ' ' + otype)
order_by.append('"' + table_name + '".' + field_name + \
' ' + otype)
return order_by, tables, tables_args
if field in self._inherit_fields.keys():
@@ -2126,14 +2163,14 @@ class ModelSQL(ModelStorage):
], context={'active_test': False})
if brother_ids[-1] != object_id:
next_id = brother_ids[brother_ids.index(object_id) + 1]
cursor.execute('SELECT "' + left + '", "' + right + '" ' \
cursor.execute('SELECT "' + left + '" ' \
'FROM "' + self._table + '" ' \
'WHERE id = %s', (next_id,))
next_left, next_right = cursor.fetchone()
cursor.execute('SELECT "' + left + '", "' + right + '" '\
next_left = cursor.fetchone()[0]
cursor.execute('SELECT "' + left + '" '\
'FROM "' + self._table + '" ' \
'WHERE id = %s', (object_id,))
current_left, current_right = cursor.fetchone()
current_left = cursor.fetchone()[0]
cursor.execute('UPDATE "' + self._table + '" ' \
@@ -2157,9 +2194,9 @@ class ModelSQL(ModelStorage):
return
# Works only for a single transaction
for _, sql, error in self._sql_constraints:
m = _RE_UNIQUE.match(sql)
if m:
sql = m.group(1)
match = _RE_UNIQUE.match(sql)
if match:
sql = match.group(1)
sql_clause = ' AND '.join('%s = %%s' % \
i for i in sql.split(','))
sql_clause = '(id != %s AND ' + sql_clause + ')'
@@ -2182,9 +2219,9 @@ class ModelSQL(ModelStorage):
if cursor.fetchone():
self.raise_user_error(cursor, error, context=context)
continue
m = _RE_CHECK.match(sql)
if m:
sql = m.group(1)
match = _RE_CHECK.match(sql)
if match:
sql = match.group(1)
for i in range(0, len(ids), cursor.IN_MAX):
sub_ids = ids[i:i + cursor.IN_MAX]
red_sql, red_ids = reduce_ids('id', sub_ids)
+33 -57
View File
@@ -3,7 +3,8 @@
from trytond.model import Model
from trytond.model import fields
from trytond.model.browse import BrowseRecordList, BrowseRecord, BrowseRecordNull
from trytond.model.browse import BrowseRecordList, BrowseRecord, \
BrowseRecordNull
from trytond.model.browse import EvalEnvironment
from trytond.tools import safe_eval
from trytond.pyson import PYSONEncoder, PYSONDecoder, PYSON
@@ -15,7 +16,7 @@ import logging
from itertools import chain
try:
import cStringIO as StringIO
except ImprotError:
except ImportError:
import StringIO
import csv
@@ -24,9 +25,6 @@ class ModelStorage(Model):
"""
Define a model with storage capability in Tryton.
:_rec_name: The name of the main field of the model.
By default the field ``name``.
:id: An Integer field for unique identifier.
:create_uid: A Many2One that points to the
user who created the record.
:create_date: A Date field for date of creation of the record.
@@ -40,9 +38,7 @@ class ModelStorage(Model):
violated). ``error_keyword`` must be one of the key of
``_sql_error_messages``.
"""
_rec_name = 'name'
id = fields.Integer('ID', readonly=True)
create_uid = fields.Many2One('res.user', 'Create User', readonly=True)
create_date = fields.DateTime('Create Date', readonly=True)
write_uid = fields.Many2One('res.user', 'Write User', readonly=True)
@@ -74,24 +70,6 @@ class ModelStorage(Model):
"Default value for create_date field."
return datetime.datetime.today()
def default_sequence(self, cursor, user, context=None):
'''
Return the default value for sequence field.
'''
table = self._table
if 'sequence' not in self._columns:
for model in self._inherits:
model_obj = self.pool.get(model)
if 'sequence' in model_obj._columns:
table = model_obj._table
break
cursor.execute('SELECT MAX(sequence) ' \
'FROM "' + table + '"')
res = cursor.fetchone()
if res:
return res[0]
return 0
def __clean_xxx2many_cache(self, cursor, user, context=None):
# Clean cursor cache
to_clean = [(model._name, field_name)
@@ -157,8 +135,6 @@ class ModelStorage(Model):
:return: True if succeed
'''
model_access_obj = self.pool.get('ir.model.access')
rule_group_obj = self.pool.get('ir.rule.group')
rule_obj = self.pool.get('ir.rule')
model_access_obj.check(cursor, user, self._name, 'write',
context=context)
@@ -241,11 +217,11 @@ class ModelStorage(Model):
default['state'] = self._defaults['state'](cursor, user,
context)
def convert_data(fields, data):
def convert_data(field_defs, data):
data = data.copy()
data_o2m = {}
for field_name in fields:
ftype = fields[field_name]['type']
for field_name in field_defs:
ftype = field_defs[field_name]['type']
if field_name in (
'create_date',
@@ -280,21 +256,22 @@ class ModelStorage(Model):
fields_names = self._columns.keys()
datas = self.read(cursor, user, ids, fields_names=fields_names,
context=context)
fields = self.fields_get(cursor, user, fields_names=fields_names,
field_defs = self.fields_get(cursor, user, fields_names=fields_names,
context=context)
for data in datas:
data_id = data['id']
data, data_o2m = convert_data(fields, data)
data, data_o2m = convert_data(field_defs, data)
new_ids[data_id] = self.create(cursor, user, data, context=context)
for field_name in data_o2m:
relation_model = self.pool.get(fields[field_name]['relation'])
relation_field = fields[field_name]['relation_field']
relation_model = self.pool.get(
field_defs[field_name]['relation'])
relation_field = field_defs[field_name]['relation_field']
relation_model.copy(cursor, user, data_o2m[field_name],
default={relation_field: new_ids[data_id]},
context=context)
fields_translate = {}
for field_name, field in fields.iteritems():
for field_name, field in field_defs.iteritems():
if field_name in self._columns and \
self._columns[field_name].translate:
fields_translate[field_name] = field
@@ -317,7 +294,8 @@ class ModelStorage(Model):
for data in datas:
data_id = data['id']
data, _ = convert_data(fields_translate, data)
self.write(cursor, user, new_ids[data_id], data, context=ctx)
self.write(cursor, user, new_ids[data_id], data,
context=ctx)
if int_id:
return new_ids.values()[0]
return new_ids.values()
@@ -367,8 +345,8 @@ class ModelStorage(Model):
return len(res)
return res
def search_read(self, cursor, user, domain, offset=0, limit=None, order=None,
context=None, fields_names=None):
def search_read(self, cursor, user, domain, offset=0, limit=None,
order=None, context=None, fields_names=None):
'''
Call search and read functions at once.
Useful for the client to reduce the number of calls.
@@ -400,9 +378,9 @@ class ModelStorage(Model):
for model in self.browse(cursor, user, ids, context=context):
record = {}
for fields_name in set(fields_names):
fields = fields_name.split('.')
while fields:
field_name = fields.pop(0)
fields_split = fields_name.split('.')
while fields_split:
field_name = fields_split.pop(0)
if fields_name not in record:
record[fields_name] = model[field_name]
else:
@@ -602,7 +580,7 @@ class ModelStorage(Model):
if not isinstance(selection, (tuple, list)):
selection = getattr(self, selection)(cursor, user,
context=context)
for key, val in selection:
for key, _ in selection:
if str(key) == value:
res = key
break
@@ -673,11 +651,11 @@ class ModelStorage(Model):
if not value:
return False
relation = None
type = fields_def[field[-1][:-3]]['type']
if type == 'many2many':
ftype = fields_def[field[-1][:-3]]['type']
if ftype == 'many2many':
value = csv.reader(StringIO.StringIO(value), delimiter=',',
quoting=csv.QUOTE_NONE, escapechar='\\').next()
elif type == 'reference':
elif ftype == 'reference':
try:
relation, value = value.split(',', 1)
except:
@@ -696,9 +674,9 @@ class ModelStorage(Model):
db_id = ir_model_data_obj.get_id(cursor, user,
module, xml_id)
res_ids.append(db_id)
if type == 'many2many' and res_ids:
if ftype == 'many2many' and res_ids:
return [('set', res_ids)]
elif type == 'reference' and res_ids:
elif ftype == 'reference' and res_ids:
return '%s,%s' % (relation, str(res_ids[0]))
return res_ids and res_ids[0] or False
@@ -763,7 +741,7 @@ class ModelStorage(Model):
cursor, user, context=context)
res = process_lines(self, datas, prefix + [field], newfd,
position)
(newrow, max2, translate2) = res
(newrow, max2, _) = res
nbrmax = max(nbrmax, max2)
reduce(lambda x, y: x and y, newrow)
row[field] = (reduce(lambda x, y: x or y, newrow.values()) and
@@ -778,7 +756,7 @@ class ModelStorage(Model):
break
if not test:
break
(newrow, max2, translate2) = \
(newrow, max2, _) = \
process_lines(self, datas, prefix + [field], newfd,
position + i)
if reduce(lambda x, y: x or y, newrow.values()):
@@ -810,7 +788,7 @@ class ModelStorage(Model):
while len(datas):
res = {}
try:
(res, other, translate) = \
(res, _, translate) = \
process_lines(self, datas, [], fields_def)
warning = warning_stream.getvalue()
if warning:
@@ -909,12 +887,12 @@ class ModelStorage(Model):
walker = record[parent]
while walker:
if parent_type == 'many2many':
for w in walker:
walked.add(w.id)
if w.id == record.id:
for walk in walker:
walked.add(walk.id)
if walk.id == record.id:
return False
walker = list(chain(*(w[parent] for w in walker
if w.id not in visited)))
walker = list(chain(*(walk[parent] for walk in walker
if walk.id not in visited)))
else:
walked.add(walker.id)
if walker.id == record.id:
@@ -952,8 +930,6 @@ class ModelStorage(Model):
return self._validate(cursor, context['user'], ids, context=ctx)
context = context.copy()
field_error = []
field_err_str = []
for field in self._constraints:
if not getattr(self, field[0])(cursor, user, ids):
self.raise_user_error(cursor, field[1], context=context)
+6 -6
View File
@@ -30,10 +30,10 @@ def _inherit_apply(src, inherit):
pos = element2.get('position', 'inside')
if pos == 'replace':
parent = element.getparent()
next = element.getnext()
if next is not None:
enext = element.getnext()
if enext is not None:
for child in element2:
index = parent.index(next)
index = parent.index(enext)
parent.insert(index, child)
else:
parent.extend(element2.getchildren())
@@ -46,10 +46,10 @@ def _inherit_apply(src, inherit):
element.extend(element2.getchildren())
elif pos == 'after':
parent = element.getparent()
next = element.getnext()
if next is not None:
enext = element.getnext()
if enext is not None:
for child in element2:
index = parent.index(next)
index = parent.index(enext)
parent.insert(index, child)
else:
parent.extend(element2.getchildren())
+1 -1
View File
@@ -66,7 +66,7 @@ class ModelWorkflow(ModelStorage):
], context=context)
for res_id in ids:
for wkf_id in workflow_ids:
instance_id = instance_obj.create(cursor, user, {
instance_obj.create(cursor, user, {
'res_type': self._name,
'res_id': res_id,
'workflow': wkf_id,
+15 -17
View File
@@ -6,30 +6,28 @@ import subprocess
from threading import Lock
from trytond.modules import get_module_list
_lock = Lock()
_times = {}
_modules = None
_LOCK = Lock()
_TIMES = {}
_MODULES = None
def _modified(path):
global _times
global _lock
_lock.acquire()
_LOCK.acquire()
try:
try:
if not os.path.isfile(path):
return path in _times
return path in _TIMES
mtime = os.stat(path).st_mtime
if path not in _times:
_times[path] = mtime
if path not in _TIMES:
_TIMES[path] = mtime
if mtime != _times[path]:
_times[path] = mtime
if mtime != _TIMES[path]:
_TIMES[path] = mtime
return True
except:
return True
finally:
_lock.release()
_LOCK.release()
return False
def monitor():
@@ -38,7 +36,7 @@ def monitor():
:return: True if at least one file has changed
'''
global _modules
global _MODULES
modified = False
for module in sys.modules.keys():
if not module.startswith('trytond.'):
@@ -58,13 +56,13 @@ def monitor():
break
modified = True
modules = set(get_module_list())
if _modules is None:
_modules = modules
for module in modules.difference(_modules):
if _MODULES is None:
_MODULES = modules
for module in modules.difference(_MODULES):
if subprocess.call((sys.executable, '-c',
'import trytond.modules.%s' % module)):
modified = False
break
modified = True
_modules = modules
_MODULES = modules
return modified
+6 -4
View File
@@ -42,17 +42,19 @@ class Pool(object):
lock.release()
@staticmethod
def register(cls, type='model'):
def register(klass, type='model'):
'''
Register a class
:param cls: the class
:param klass: the class
:param type: the type
'''
for module in cls.__module__.split('.'):
module = None
for module in klass.__module__.split('.'):
if module != 'trytond' and module != 'modules':
break
Pool.classes[type].setdefault(module, []).append(cls)
if module:
Pool.classes[type].setdefault(module, []).append(klass)
@staticmethod
def start():
+4 -5
View File
@@ -3,8 +3,8 @@
#this repository contains the full copyright notices and license terms.
from trytond.pool import Pool
from trytond import security
from trytond.tools import Cache, find_language_context
from trytond.backend import Database, DatabaseIntegrityError
from trytond.tools import Cache
from trytond.backend import Database
from trytond.config import CONFIG
from trytond.version import VERSION
from trytond.monitor import monitor
@@ -39,7 +39,8 @@ def dispatch(host, port, protocol, database_name, user, session, object_type,
elif method == 'logout':
name = security.logout(database_name, user, session)
logger = logging.getLogger('dispatcher')
logger.info('logout \'%s\' from %s:%d using %s on database \'%s\'' % \
logger.info('logout \'%s\' from %s:%d ' \
'using %s on database \'%s\'' %
(name, host, port, protocol, database_name))
return True
elif method == 'version':
@@ -206,7 +207,6 @@ def create(database_name, password, lang, admin_password):
res = True
except:
logger.error('CREATE DB: %s failed' % (database_name,))
import traceback, sys
tb_s = reduce(lambda x, y: x+y,
traceback.format_exception(*sys.exc_info()))
logger.error('Exception in call: \n' + tb_s)
@@ -233,7 +233,6 @@ def drop(database_name, password):
cursor.commit()
except:
logger.error('DROP DB: %s failed' % (database_name,))
import traceback, sys
tb_s = reduce(lambda x, y: x+y,
traceback.format_exception(*sys.exc_info()))
logger.error('Exception in call: \n' + tb_s)
+9 -8
View File
@@ -6,7 +6,6 @@ from trytond.config import CONFIG
import SimpleXMLRPCServer
import SimpleHTTPServer
import SocketServer
from xmlrpclib import Fault
import threading
import traceback
import socket
@@ -56,7 +55,7 @@ class JSONEncoder(json.JSONEncoder):
}
elif isinstance(obj, Decimal):
return float(obj)
return json.JSONEncoder.default(self, obj)
return super(JSONEncoder, self).default(obj)
class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
@@ -80,11 +79,11 @@ class SimpleJSONRPCDispatcher(SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
"""
rawreq = json.loads(data, object_hook=object_hook)
id = rawreq.get('id', 0)
req_id = rawreq.get('id', 0)
method = rawreq['method']
params = rawreq.get('params', [])
response = {'id': id}
response = {'id': req_id}
try:
#generate response
@@ -210,8 +209,8 @@ class SimpleJSONRPCRequestHandler(GenericJSONRPCRequestHandler,
"""
# abandon query parameters
path = path.split('?',1)[0]
path = path.split('#',1)[0]
path = path.split('?', 1)[0]
path = path.split('#', 1)[0]
path = posixpath.normpath(urllib.unquote(path))
words = path.split('/')
words = filter(None, words)
@@ -252,12 +251,14 @@ class SimpleJSONRPCServer(SocketServer.TCPServer,
_send_traceback_header = False
def __init__(self, addr, requestHandler=SimpleJSONRPCRequestHandler,
logRequests=True, allow_none=False, encoding=None, bind_and_activate=True):
logRequests=True, allow_none=False, encoding=None,
bind_and_activate=True):
self.logRequests = logRequests
SimpleJSONRPCDispatcher.__init__(self, allow_none, encoding)
try:
SocketServer.TCPServer.__init__(self, addr, requestHandler, bind_and_activate)
SocketServer.TCPServer.__init__(self, addr, requestHandler,
bind_and_activate)
except TypeError:
SocketServer.TCPServer.__init__(self, addr, requestHandler)
+4 -3
View File
@@ -29,7 +29,7 @@ class NetRPCClientThread(threading.Thread):
return False
timeout = 0
while self.running:
(rlist, wlist, xlist) = select.select([self.sock], [], [], 1)
(rlist, _, _) = select.select([self.sock], [], [], 1)
if not rlist:
timeout += 1
if timeout > 600:
@@ -61,7 +61,8 @@ class NetRPCClientThread(threading.Thread):
tback = sys.exc_info()[2]
pdb.post_mortem(tback)
try:
pysocket.send(exception.args, exception=True, traceback=tb_s)
pysocket.send(exception.args, exception=True,
traceback=tb_s)
except:
pysocket.disconnect()
self.threads.remove(self)
@@ -101,7 +102,7 @@ class NetRPCServerThread(threading.Thread):
while self.running:
if not int(CONFIG['max_thread']) \
or len(self.threads) < int(CONFIG['max_thread']):
(clientsocket, address) = self.socket.accept()
(clientsocket, _) = self.socket.accept()
c_thread = NetRPCClientThread(clientsocket, self.threads,
self.secure)
self.threads.append(c_thread)
+12 -12
View File
@@ -14,11 +14,10 @@ import socket
import os
import BaseHTTPServer
import urlparse
import base64
import time
from DAV import AuthServer, WebDAVServer, iface
from DAV.errors import *
from DAV.constants import COLLECTION, OBJECT, DAV_VERSION_1, DAV_VERSION_2
from DAV.constants import COLLECTION, DAV_VERSION_1, DAV_VERSION_2
from DAV.utils import get_uriparentpath, get_urifilename, quote_uri
from DAV.davcmd import copyone, copytree, moveone, movetree, delone, deltree
import urllib
@@ -36,6 +35,7 @@ DAV_VERSION_2['version'] += ',access-control'
class LocalInt(local):
def __init__(self, value=0):
super(LocalInt, self).__init__()
self.value = value
def __int__(self):
@@ -153,7 +153,8 @@ class TrytonDAVInterface(iface.dav_interface):
protocol = 'https'
else:
protocol = 'http'
self.baseuri = '%s://%s:%s/' % (protocol, interface or socket.gethostname(), port)
self.baseuri = '%s://%s:%s/' % (protocol, interface or
socket.gethostname(), port)
self.verbose = False
def _log_exception(self, exception):
@@ -221,10 +222,12 @@ class TrytonDAVInterface(iface.dav_interface):
def get_data(self, uri):
dbname, dburi = self._get_dburi(uri)
if not dbname or (self.exists(uri) and self.is_collection(uri)):
res = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">'
res = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 '\
'Transitional//EN">'
res += '<html>'
res += '<head>'
res += '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'
res += '<meta http-equiv="Content-Type" content="text/html; '\
'charset=utf-8">'
res += '<title>%s - WebDAV - %s</title>' \
% (PACKAGE, dbname or 'root')
res += '</head>'
@@ -461,7 +464,8 @@ class TrytonDAVInterface(iface.dav_interface):
pool = Pool(DATABASE['dbname'])
collection_obj = pool.get('webdav.collection')
try:
res = collection_obj.exists(cursor, int(USER_ID), dburi, cache=CACHE)
res = collection_obj.exists(cursor, int(USER_ID), dburi,
cache=CACHE)
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
raise
@@ -542,15 +546,14 @@ class TrytonDAVInterface(iface.dav_interface):
privilege.appendChild(unbind)
return privilege
TrytonDAVInterface.PROPS['DAV:'] = tuple(list(TrytonDAVInterface.PROPS['DAV:']) \
+ ['current-user-privilege-set'])
TrytonDAVInterface.PROPS['DAV:'] = tuple(list(TrytonDAVInterface.PROPS['DAV:']
) + ['current-user-privilege-set'])
class WebDAVAuthRequestHandler(AuthServer.BufferedAuthRequestHandler,
WebDAVServer.DAVRequestHandler):
def finish(self):
global DATABASE
dbname = None
if 'dbname' in DATABASE:
dbname = DATABASE['dbname']
@@ -564,9 +567,6 @@ class WebDAVAuthRequestHandler(AuthServer.BufferedAuthRequestHandler,
Cache.resets(dbname)
def get_userinfo(self, user, password, command=''):
global USER_ID
global DATABASE
dbname = urllib.unquote_plus(self.path.split('/', 2)[1])
DATABASE['dbname'] = dbname
if not dbname:
+3 -2
View File
@@ -44,8 +44,9 @@ class GenericXMLRPCRequestHandler:
args = (host, port, 'XML-RPC', database_name, None, None,
object_type, None, method) + params
else:
args = (host, port, 'XML-RPC', database_name, params[0], params[1],
object_type, object_name, method) + params[2:]
args = (host, port, 'XML-RPC', database_name, params[0],
params[1], object_type, object_name, method) + \
params[2:]
res = dispatch(*args)
return res
except:
+13 -13
View File
@@ -79,10 +79,10 @@ class PySocket:
sock.settimeout(CONNECT_TIMEOUT)
sock.connect((host, int(port)))
if ssl:
ssl_sock = ssl.wrap_socket(sock)
ssl.wrap_socket(sock)
self.ssl = True
elif hasattr(socket, 'ssl'):
ssl_sock = socket.ssl(sock)
socket.ssl(sock)
self.ssl = True
except:
pass
@@ -131,12 +131,12 @@ class PySocket:
msg = cPickle.dumps([msg, traceback], protocol=2)
gzip_p = False
if len(msg) > GZIP_THRESHOLD:
buffer = StringIO.StringIO()
output = gzip.GzipFile(mode='wb', fileobj=buffer)
buf = StringIO.StringIO()
output = gzip.GzipFile(mode='wb', fileobj=buf)
output.write(msg)
output.close()
buffer.seek(0)
msg = buffer.getvalue()
buf.seek(0)
msg = buf.getvalue()
gzip_p = True
size = len(msg)
msg = str(size) + ' ' + (exception and "1" or "0") \
@@ -155,7 +155,7 @@ class PySocket:
def receive(self):
buf = self.buffer
L = []
buf_list = []
size_remaining = MAX_LENGHT
while size_remaining:
chunk_size = min(size_remaining, 4096)
@@ -165,13 +165,13 @@ class PySocket:
chunk = self.sock.recv(chunk_size)
if chunk == '':
raise RuntimeError, "socket connection broken"
L.append(chunk)
buf_list.append(chunk)
size_remaining -= len(chunk)
if ' ' in chunk:
break
if size_remaining < 0:
raise RuntimeError, "socket connection broken"
buf += ''.join(L)
buf += ''.join(buf_list)
size, msg = buf.split(' ', 1)
size = int(size)
if size > MAX_SIZE:
@@ -186,8 +186,8 @@ class PySocket:
raise RuntimeError, "socket connection broken"
exception = msg[0] != "0"
gzip_p = msg[1] != "0"
L = [msg[2:]]
size_remaining = size - len(L[0])
buf_list = [msg[2:]]
size_remaining = size - len(buf_list[0])
while size_remaining:
chunk_size = min(size_remaining, 4096)
if self.ssl:
@@ -196,9 +196,9 @@ class PySocket:
chunk = self.sock.recv(chunk_size)
if chunk == '':
raise RuntimeError, "socket connection broken"
L.append(chunk)
buf_list.append(chunk)
size_remaining -= len(chunk)
msg = ''.join(L)
msg = ''.join(buf_list)
if len(msg) > size:
self.buffer = msg[size:]
msg = msg[:size]
+22 -12
View File
@@ -11,31 +11,31 @@ import datetime
class PYSON(object):
def pyson(self):
raise
raise NotImplementedError
def types(self):
raise
raise NotImplementedError
@staticmethod
def eval(dct, context):
raise
raise NotImplementedError
class PYSONEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, PYSON):
return o.pyson()
return super(PYSONEncoder, self).default(o)
def default(self, obj):
if isinstance(obj, PYSON):
return obj.pyson()
return super(PYSONEncoder, self).default(obj)
class PYSONDecoder(json.JSONDecoder):
def __init__(self, context=None):
self.__context = context or {}
return super(PYSONDecoder, self).__init__(object_hook=self.object_hook)
super(PYSONDecoder, self).__init__(object_hook=self._object_hook)
def object_hook(self, dct):
def _object_hook(self, dct):
if '__class__' in dct:
klass = globals().get(dct['__class__'])
if klass and hasattr(klass, 'eval'):
@@ -46,6 +46,7 @@ class PYSONDecoder(json.JSONDecoder):
class Eval(PYSON):
def __init__(self, value, default=''):
super(Eval, self).__init__()
self._value = value
self._default = default
@@ -70,6 +71,7 @@ class Eval(PYSON):
class Not(PYSON):
def __init__(self, value):
super(Not, self).__init__()
if isinstance(value, PYSON):
assert value.types() == set([bool]), 'value must be boolean'
else:
@@ -93,6 +95,7 @@ class Not(PYSON):
class Bool(PYSON):
def __init__(self, value):
super(Bool, self).__init__()
self._value = value
def pyson(self):
@@ -112,6 +115,7 @@ class Bool(PYSON):
class And(PYSON):
def __init__(self, *statements):
super(And, self).__init__()
for statement in statements:
if isinstance(statement, PYSON):
assert statement.types() == set([bool]), \
@@ -151,6 +155,7 @@ class Or(And):
class Equal(PYSON):
def __init__(self, statement1, statement2):
super(Equal, self).__init__()
if isinstance(statement1, PYSON):
types1 = statement1.types()
else:
@@ -181,6 +186,7 @@ class Equal(PYSON):
class Greater(PYSON):
def __init__(self, statement1, statement2, equal=False):
super(Greater, self).__init__()
for i in (statement1, statement2):
if isinstance(i, PYSON):
assert i.types().issubset(set([int, long, float])), \
@@ -233,6 +239,7 @@ class Less(Greater):
class If(PYSON):
def __init__(self, condition, then_statement, else_statement=None):
super(If, self).__init__()
if isinstance(condition, PYSON):
assert condition.types() == set([bool]), 'condition must be boolean'
else:
@@ -276,6 +283,7 @@ class If(PYSON):
class Get(PYSON):
def __init__(self, obj, key, default=''):
super(Get, self).__init__()
if isinstance(obj, PYSON):
assert obj.types() == set([dict]), 'obj must be a dict'
else:
@@ -310,6 +318,7 @@ class Get(PYSON):
class In(PYSON):
def __init__(self, key, obj):
super(In, self).__init__()
if isinstance(key, PYSON):
assert key.types().issubset(set([str, int, long])), \
'key must be a string or an integer or a long'
@@ -347,6 +356,7 @@ class Date(PYSON):
def __init__(self, year=None, month=None, day=None,
delta_years=0, delta_months=0, delta_days=0):
super(Date, self).__init__()
for i in (year, month, day, delta_years, delta_months, delta_days):
if isinstance(i, PYSON):
assert i.types().issubset(set([int, long, type(None)])), \
@@ -388,8 +398,8 @@ class Date(PYSON):
date = date.replace(year=year)
if dct['dM']:
month = date.month + dct['dM']
year = date.year + month/12
month = month%12
year = date.year + month / 12
month = month % 12
date = date.replace(year=year, month=month)
if dct['dd']:
date += datetime.timedelta(days=dct['dd'])
@@ -450,7 +460,7 @@ class DateTime(Date):
if dct[i] is not None:
replace[j] = dct[i]
datetime_ = datetime_.replace(**replace)
delta={}
delta = {}
for i, j in (('dh', 'hours'), ('dm', 'minutes'), ('ds', 'seconds'),
('dms', 'microseconds')):
if dct[i]:
+3 -3
View File
@@ -3,7 +3,7 @@
from trytond.backend import Database
from trytond.session import Session
from trytond.pool import Pool
from config import CONFIG
from trytond.config import CONFIG
import time
@@ -59,7 +59,7 @@ def check_super(passwd):
def check(dbname, user, session):
if user == 0:
raise Exception('AccessDenied')
result = False
result = None
now = time.time()
timeout = int(CONFIG['session_timeout'])
if _USER_CACHE.get(dbname, {}).has_key(user):
@@ -82,7 +82,7 @@ def get_connections(dbname, user):
now = time.time()
timeout = int(CONFIG['session_timeout'])
if _USER_CACHE.get(dbname, {}).has_key(int(user)):
for i, session in enumerate(_USER_CACHE[dbname][int(user)]):
for _, session in enumerate(_USER_CACHE[dbname][int(user)]):
if abs(session.timestamp - now) < timeout:
res += 1
return res
+8 -8
View File
@@ -4,13 +4,13 @@
%prog [options]
"""
import logging
format='[%(asctime)s] %(levelname)s:%(name)s:%(message)s'
datefmt='%a %b %d %H:%M:%S %Y'
logging.basicConfig(level=logging.DEBUG, format=format, datefmt=datefmt)
FORMAT = '[%(asctime)s] %(levelname)s:%(name)s:%(message)s'
DATEFMT = '%a %b %d %H:%M:%S %Y'
logging.basicConfig(level=logging.DEBUG, format=FORMAT, datefmt=DATEFMT)
import logging.handlers
import sys, os, signal
import time
from config import CONFIG
from trytond.config import CONFIG
from getpass import getpass
try:
import hashlib
@@ -26,7 +26,6 @@ class TrytonServer(object):
def __init__(self):
CONFIG.parse()
from trytond.backend import Database
if CONFIG['logfile']:
logf = CONFIG['logfile']
@@ -39,10 +38,11 @@ class TrytonServer(object):
logf, 'D', 1, 30)
handler.rolloverAt -= diff
except Exception, exception:
sys.stderr.write("ERROR: couldn't create the logfile directory:" \
sys.stderr.write(\
"ERROR: couldn't create the logfile directory:" \
+ str(exception))
else:
formatter = logging.Formatter(format, datefmt)
formatter = logging.Formatter(FORMAT, DATEFMT)
# tell the handler to use this format
handler.setFormatter(formatter)
@@ -69,7 +69,7 @@ class TrytonServer(object):
def run(self):
"Run the server and never return"
from trytond.backend import Database
from pool import Pool
from trytond.pool import Pool
from trytond.monitor import monitor
update = False
+1 -1
View File
@@ -7,7 +7,7 @@ import time
class Session(int):
def __init__(self, x):
def __init__(self, value):
super(Session, self).__init__()
self.__data = {
'session': base64.b64encode(os.urandom(32)),
+45 -36
View File
@@ -2,19 +2,12 @@
#this repository contains the full copyright notices and license terms.
"Convert"
import re
try:
import cStringIO as StringIO
except ImportError:
import StringIO
import os.path
from trytond.config import CONFIG
from trytond.version import VERSION
from trytond.tools import safe_eval
import time
from xml import sax
from decimal import Decimal
import datetime
import time
import logging
import traceback
import sys
@@ -43,6 +36,7 @@ class MenuitemTagHandler:
"""Taghandler for the tag <record> """
def __init__(self, master_handler):
self.mh = master_handler
self.xml_id = None
def startElement(self, name, attributes):
@@ -72,7 +66,8 @@ class MenuitemTagHandler:
"LEFT JOIN ir_action_act_window act ON (a.id = act.action) " \
"LEFT JOIN ir_action_wizard wizard ON (a.id = wizard.action) " \
"LEFT JOIN ir_action_url url ON (a.id = url.action) " \
"LEFT JOIN ir_action_act_window_view wv on (act.id = wv.act_window) " \
"LEFT JOIN ir_action_act_window_view wv ON " \
"(act.id = wv.act_window) " \
"LEFT JOIN ir_ui_view v on (v.id = wv.view) " \
"WHERE report.id = %s " \
"OR act.id = %s " \
@@ -123,7 +118,7 @@ class MenuitemTagHandler:
if not values.get('name'):
if not action_name:
raise Exception("Please provide at least a 'name' attributes "
"or a 'action' attributes on the menuitem tags.")
"or a 'action' attributes on the menuitem tags.")
else:
values['name'] = action_name
@@ -138,8 +133,7 @@ class MenuitemTagHandler:
if name != "menuitem":
return self
else:
res = self.mh.import_record(
'ir.ui.menu', self.values, self.xml_id)
self.mh.import_record( 'ir.ui.menu', self.values, self.xml_id)
return None
def current_state(self):
@@ -158,6 +152,11 @@ class RecordTagHandler:
self.xml_ids = []
self.model = None
self.xml_id = None
self.update = None
self.values = None
self.current_field = None
self.cdata = None
self.start_cdata = None
def startElement(self, name, attributes):
@@ -209,7 +208,9 @@ class RecordTagHandler:
if not answer: return
if self.model._columns[field_name]._type == 'many2many':
self.values[field_name] = [('set', [x['id'] for x in answer])]
self.values[field_name] = [
('set', [x['id'] for x in answer]),
]
elif self.model._columns[field_name]._type == 'many2one':
self.values[field_name] = answer[0]['id']
@@ -226,7 +227,8 @@ class RecordTagHandler:
self.values[field_name] = safe_eval(eval_attr, context)
else:
raise Exception("Tags '%s' not supported inside tag record."% (name,))
raise Exception("Tags '%s' not supported inside tag record." %
(name,))
def characters(self, data):
@@ -255,7 +257,7 @@ class RecordTagHandler:
"current_field expected to be set.")
# Escape end cdata tag :
if self.cdata in ('inside', 'start'):
self.values[self.current_field] =\
self.values[self.current_field] = \
CDATA_END.sub('', self.values[self.current_field])
self.cdata = 'done'
@@ -272,8 +274,7 @@ class RecordTagHandler:
elif name == "record":
if self.xml_id in self.xml_ids and not self.update:
raise Exception('Duplicate id: "%s".' % (self.xml_id,))
res = self.mh.import_record(
self.model._name, self.values, self.xml_id)
self.mh.import_record(self.model._name, self.values, self.xml_id)
self.xml_ids.append(self.xml_id)
return None
else:
@@ -393,6 +394,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
def __init__(self, cursor, pool, module,):
"Register known taghandlers, and managed tags."
sax.handler.ContentHandler.__init__(self)
self.pool = pool
self.cursor = cursor
@@ -401,6 +403,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
self.modeldata_obj = pool.get('ir.model.data')
self.fs2db = Fs2bdAccessor(cursor, self.user, self.modeldata_obj, pool)
self.to_delete = self.populate_to_delete()
self.noupdate = None
# Tag handlders are used to delegate the processing
self.taghandlerlist = {
@@ -410,7 +413,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
self.taghandler = None
# Managed tags are handled by the current class
self.managedtags= ["data", "tryton"]
self.managedtags = ["data", "tryton"]
# Connect to the sax api:
self.sax_parser = sax.make_parser()
@@ -455,7 +458,8 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
pass
else:
logging.getLogger("convert").info("Tag "+ name + " not supported")
logging.getLogger("convert").info( "Tag %s not supported" %
name)
return
else:
self.taghandler.startElement(name, attributes)
@@ -597,7 +601,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
raise Exception("This record try to overwrite " \
"data with the wrong model: %s (module: %s)" % (fs_id, module))
#Re-create object if it was deleted
#Re-create record if it was deleted
if not self.fs2db.get_browserecord(module, object_ref._name, db_id):
db_id = object_ref.create(cursor, user, values,
context={'module': module})
@@ -605,9 +609,11 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
# reset_browsercord
self.fs2db.reset_browsercord(module, object_ref._name, db_id)
object = self.fs2db.get_browserecord(module, object_ref._name, db_id)
for table, field_name, field in object_ref._inherit_fields.values():
inherit_db_ids[table] = object[field_name].id
record = self.fs2db.get_browserecord(module, object_ref._name,
db_id)
for table, field_name, field in \
object_ref._inherit_fields.values():
inherit_db_ids[table] = record[field_name].id
#Add a translation record for field translatable
for field_name in object_ref._columns.keys() + \
@@ -677,7 +683,8 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
})
self.fs2db.get(module, fs_id)["db_id"] = db_id
db_val = self.fs2db.get_browserecord(module, object_ref._name, db_id)
db_val = self.fs2db.get_browserecord(module, object_ref._name,
db_id)
if not db_val:
db_val = object_ref.browse(cursor, user, db_id)
@@ -737,10 +744,10 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
if not inherit_db_ids:
object = object_ref.browse(cursor, user, db_id)
record = object_ref.browse(cursor, user, db_id)
for table, field_name, field in \
object_ref._inherit_fields.values():
inherit_db_ids[table] = object[field_name].id
inherit_db_ids[table] = record[field_name].id
if not inherit_mdata_ids:
for table in inherit_db_ids.keys():
data_id = self.modeldata_obj.search(cursor, user, [
@@ -779,7 +786,8 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
cursor.execute('UPDATE ir_translation ' \
'SET src = %s, module = %s ' \
'WHERE id = %s',
(to_update[field_name], module, trans_id))
(to_update[field_name], module,
trans_id))
elif values.get(field_name):
cursor.execute('INSERT INTO ir_translation ' \
'(name, lang, type, src, res_id, ' \
@@ -835,9 +843,9 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
context={'module': module})
inherit_db_ids = {}
object = object_ref.browse(cursor, user, db_id)
record = object_ref.browse(cursor, user, db_id)
for table, field_name, field in object_ref._inherit_fields.values():
inherit_db_ids[table] = object[field_name].id
inherit_db_ids[table] = record[field_name].id
#Add a translation record for field translatable
for field_name in object_ref._columns.keys() + \
@@ -985,17 +993,17 @@ def post_import(cursor, pool, module, to_delete):
model_obj.delete(cursor, user, db_id)
mdata_delete.append(mdata_id)
cursor.commit()
except Exception, exception:
except:
cursor.rollback()
tb_s = reduce(lambda x, y: x + y,
traceback.format_exception(*sys.exc_info()))
logging.getLogger("convert").error(
'Could not delete id: %d of model %s\n' \
'There should be some relation ' \
'that points to this resource\n' \
'You should manually fix this ' \
'and restart --update=module\n' \
'Exception: %s' % \
'Could not delete id: %d of model %s\n'
'There should be some relation '
'that points to this resource\n'
'You should manually fix this '
'and restart --update=module\n'
'Exception: %s' %
(db_id, model, tb_s.decode('utf-8', 'ignore')))
transition_obj = pool.get('workflow.transition')
@@ -1009,7 +1017,8 @@ def post_import(cursor, pool, module, to_delete):
except:
cursor.rollback()
logging.getLogger("convert").error(
'Could not delete id: %d of model workflow.transition'% (db_id,))
'Could not delete id: %d of model workflow.transition' %
(db_id,))
# Clean model_data:
if mdata_delete:
+12 -13
View File
@@ -3,13 +3,13 @@
#Copyright (c) 2002-2007 John D. Hunter; All Rights Reserved
import time
def datetime_strftime(dt, fmt):
def datetime_strftime(date, fmt):
'''
Allow datetime strftime formatting for years before 1900.
See http://bugs.python.org/issue1777412
'''
if dt.year > 1900:
return dt.strftime(fmt)
if date.year > 1900:
return date.strftime(fmt)
def _findall(text, substr):
# Also finds overlaps
@@ -23,7 +23,7 @@ def datetime_strftime(dt, fmt):
i = j + 1
return sites
year = dt.year
year = date.year
# For every non-leap year century, advance by
# 6 years to get into the 28-year repeat cycle
delta = 2000 - year
@@ -31,20 +31,19 @@ def datetime_strftime(dt, fmt):
year = year + off
# Move to around the year 2000
year = year + ((2000 - year) // 28) * 28
timetuple = dt.timetuple()
s1 = time.strftime(fmt, (year,) + timetuple[1:])
sites1 = _findall(s1, str(year))
timetuple = date.timetuple()
string1 = time.strftime(fmt, (year,) + timetuple[1:])
sites1 = _findall(string1, str(year))
s2 = time.strftime(fmt, (year + 28,) + timetuple[1:])
sites2 = _findall(s2, str(year + 28))
string2 = time.strftime(fmt, (year + 28,) + timetuple[1:])
sites2 = _findall(string2, str(year + 28))
sites = []
for site in sites1:
if site in sites2:
sites.append(site)
s = s1
syear = "%4d" % (dt.year,)
syear = "%4d" % (date.year,)
for site in sites:
s = s[:site] + syear + s[site+4:]
return s
string1 = string1[:site] + syear + string1[site+4:]
return string1
+56 -77
View File
@@ -4,15 +4,13 @@
"""
Miscelleanous tools used by tryton
"""
import os, time, sys
import os, time
import inspect
from trytond.config import CONFIG
import socket
import subprocess
import zipfile
from trytond.backend import Database
from threading import Lock, local
import logging
import smtplib
try:
import cStringIO as StringIO
@@ -20,11 +18,6 @@ except ImportError:
import StringIO
import dis
import datetime
try:
import hashlib
except ImportError:
hashlib = None
import md5
def find_in_path(name):
if os.name == "nt":
@@ -90,9 +83,9 @@ def file_open(name, mode="r", subdir='modules'):
if subdir == 'modules':
module_name = name.split(os.sep)[0]
if module_name in EGG_MODULES:
ep = EGG_MODULES[module_name]
mod_path = os.path.join(ep.dist.location,
*ep.module_name.split('.')[:-1])
epoint = EGG_MODULES[module_name]
mod_path = os.path.join(epoint.dist.location,
*epoint.module_name.split('.')[:-1])
name3 = os.path.join(mod_path, name)
if subdir:
@@ -155,20 +148,6 @@ def get_smtp_server():
return smtp_server
def sms_send(user, password, api_id, text, to):
"text must be latin-1 encoded"
import urllib
params = urllib.urlencode({
'user': user,
'password': password,
'api_id': api_id,
'text': text,
'to':to,
})
#urllib.urlopen("http://api.clickatell.com/http/sendmsg", params)
urllib.urlopen("http://196.7.150.220/http/sendmsg", params)
return True
def find_language_context(args, kargs=None):
if kargs is None:
kargs = {}
@@ -330,7 +309,8 @@ class Cache(object):
cursor.execute('UPDATE ir_cache SET "timestamp" = %s '\
'WHERE name = %s', (datetime.datetime.now(), name))
else:
cursor.execute('INSERT INTO ir_cache ("timestamp", "name") ' \
cursor.execute('INSERT INTO ir_cache ' \
'("timestamp", "name") ' \
'VALUES (%s, %s)', (datetime.datetime.now(), name))
Cache._resets[dbname].clear()
finally:
@@ -360,7 +340,7 @@ def memoize(maxsize):
"""
assert maxsize >= 4, "Memoize cannot work if maxsize is less than 4"
def wrap(f):
def wrap(fct):
cache = {}
keys = [None for i in xrange(maxsize)]
seg_size = maxsize // 4
@@ -375,15 +355,15 @@ def memoize(maxsize):
pos, res = res
keys[pos] = None
else:
res = f(*args)
res = fct(*args)
value = res
for segment, p in enumerate(pointers):
newkey = keys[p]
keys[p] = key
cache[key] = (p, value)
for segment, pointer in enumerate(pointers):
newkey = keys[pointer]
keys[pointer] = key
cache[key] = (pointer, value)
pointers[segment] = p + 1
pointers[segment] = pointer + 1
if pointers[segment] == max_pointers[segment]:
pointers[segment] = segment * seg_size
@@ -394,8 +374,8 @@ def memoize(maxsize):
return res
wrapper.__doc__ = f.__doc__
wrapper.__name__ = f.__name__
wrapper.__doc__ = fct.__doc__
wrapper.__name__ = fct.__name__
return wrapper
return wrap
@@ -419,103 +399,102 @@ def mod10r(number):
class LocalDict(local):
def __init__(self, dict=None):
if dict is None:
dict = {}
self.dict = dict
def __init__(self):
super(LocalDict, self).__init__()
self._dict = {}
def __str__(self):
return str(self.dict)
return str(self._dict)
def __repr__(self):
return str(self.dict)
return str(self._dict)
def clear(self):
return self.dict.clear()
return self._dict.clear()
def keys(self):
return self.dict.keys()
return self._dict.keys()
def __setitem__(self, i, y):
self.dict.__setitem__(i, y)
self._dict.__setitem__(i, y)
def __getitem__(self, i):
return self.dict.__getitem__(i)
return self._dict.__getitem__(i)
def copy(self):
return self.dict.copy()
return self._dict.copy()
def iteritems(self):
return self.dict.iteritems()
return self._dict.iteritems()
def iterkeys(self):
return self.dict.iterkeys()
return self._dict.iterkeys()
def itervalues(self):
return self.dict.itervalues()
return self._dict.itervalues()
def pop(self, k, d=None):
return self.dict.pop(k, d)
return self._dict.pop(k, d)
def popitem(self):
return self.dict.popitem()
return self._dict.popitem()
def setdefault(self, k, d=None):
return self.dict.setdefault(k, d)
return self._dict.setdefault(k, d)
def update(self, E, **F):
return self.dict.update(E, F)
return self._dict.update(E, F)
def values(self):
return self.dict.values()
return self._dict.values()
def get(self, k, d=None):
return self.dict.get(k, d)
return self._dict.get(k, d)
def has_key(self, k):
return self.dict.has_key(k)
return self._dict.has_key(k)
def items(self):
return self.dict.items()
return self._dict.items()
def __cmp__(self, y):
return self.dict.__cmp__(y)
return self._dict.__cmp__(y)
def __contains__(self, k):
return self.dict.__contains__(k)
return self._dict.__contains__(k)
def __delitem__(self, y):
return self.dict.__delitem__(y)
return self._dict.__delitem__(y)
def __eq__(self, y):
return self.dict.__eq__(y)
return self._dict.__eq__(y)
def __ge__(self, y):
return self.dict.__ge__(y)
return self._dict.__ge__(y)
def __getitem__(self, y):
return self.dict.__getitem__(y)
return self._dict.__getitem__(y)
def __gt__(self, y):
return self.dict.__gt__(y)
return self._dict.__gt__(y)
def __hash__(self):
return self.dict.__hash__()
return self._dict.__hash__()
def __iter__(self):
return self.dict.__iter__()
return self._dict.__iter__()
def __le__(self, y):
return self.dict.__le__(y)
return self._dict.__le__(y)
def __len__(self):
return self.dict.__len__()
return self._dict.__len__()
def __lt__(self, y):
return self.dict.__lt__(y)
return self._dict.__lt__(y)
def __ne__(self, y):
return self.dict.__ne__(y)
return self._dict.__ne__(y)
def reduce_ids(field, ids):
'''
@@ -577,12 +556,12 @@ _ALLOWED_CODES = set(dis.opmap[x] for x in [
@memoize(1000)
def _compile_source(source):
c = compile(source, '', 'eval')
comp = compile(source, '', 'eval')
codes = []
s = c.co_code
co_code = comp.co_code
i = 0
while i < len(s):
code = ord(s[i])
while i < len(co_code):
code = ord(co_code[i])
codes.append(code)
if code >= dis.HAVE_ARGUMENT:
i += 3
@@ -591,14 +570,14 @@ def _compile_source(source):
for code in codes:
if code not in _ALLOWED_CODES:
raise ValueError('opcode %s not allowed' % dis.opname[code])
return c
return comp
def safe_eval(source, data=None):
if '__subclasses__' in source:
raise ValueError('__subclasses__ not allowed')
c = _compile_source(source)
return eval(c, {'__builtins__': {
comp = _compile_source(source)
return eval(comp, {'__builtins__': {
'True': True,
'False': False,
'str': str,
+5 -11
View File
@@ -1,14 +1,7 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from trytond.pool import Pool
from trytond.model import ModelView
from trytond.config import CONFIG
from trytond.backend import DatabaseIntegrityError
import sys
import copy
from xml import dom
import traceback
import logging
from threading import Lock
from random import randint
from sys import maxint
@@ -17,6 +10,7 @@ from sys import maxint
class Wizard(object):
_name = ""
states = {}
pool = None
def __new__(cls):
Pool.register(cls, type='wizard')
@@ -35,8 +29,8 @@ class Wizard(object):
def init(self, cursor, module_name):
for state in self.states.keys():
if self.states[state]['result']['type'] == 'form':
for i, button in enumerate(
self.states[state]['result']['state']):
for button in \
self.states[state]['result']['state']:
button_name = button[0]
button_value = button[1]
cursor.execute('SELECT id, name, src ' \
@@ -50,8 +44,8 @@ class Wizard(object):
res = cursor.dictfetchall()
if not res:
cursor.execute('INSERT INTO ir_translation ' \
'(name, lang, type, src, value, module, fuzzy) ' \
'VALUES (%s, %s, %s, %s, %s, %s, %s)',
'(name, lang, type, src, value, module, fuzzy)'\
' VALUES (%s, %s, %s, %s, %s, %s, %s)',
(self._name + ',' + state + ',' + button_name,
'en_US', 'wizard_button', button_value,
'', module_name, False))