Remove ir.values (bad modeling stuff)

- Add preference on res.user
- Fix language/timezone in context
This commit is contained in:
Cédric Krier committed 2008-01-27 17:36:59 +01:00
1 parent 1a554f0e55
commit 8f1a0a2a92
17 files changed
+101 -372

No files matched your search

-17
View File
@@ -9,23 +9,6 @@ CREATE TABLE inherit (
inst_id int not null
);
-------------------------------------------------------------------------
-- IR dictionary
-------------------------------------------------------------------------
create table ir_values
(
id serial,
name varchar(128) not null,
key varchar(128) not null,
key2 varchar(128) not null,
model varchar(128) not null,
value text,
meta text default NULL,
res_id integer default null,
primary key (id)
);
-------------------------------------------------------------------------
-- Modules Description
-------------------------------------------------------------------------
-1
View File
@@ -4,7 +4,6 @@ from actions import *
from model import *
from attachment import *
from cron import *
from values import *
from translation import *
from exports import *
from rule import *
-1
View File
@@ -11,7 +11,6 @@
'model.xml',
'attachment.xml',
'cron.xml',
'values.xml',
'translation.xml',
'exports.xml',
'rule.xml',
-12
View File
@@ -177,18 +177,6 @@ class UIMenu(OSV):
parent_path = ''
return parent_path + menu.name
def copy(self, cursor, user, obj_id, default=None, context=None):
ir_values_obj = self.pool.get('ir.values')
res = super(UIMenu, self).copy(cursor, user, obj_id, context=context)
ids = ir_values_obj.search(cursor, user, [
('model', '=', 'ir.ui.menu'),
('res_id', '=', obj_id),
])
for ir_value in ir_values_obj.browse(cursor, user, ids):
ir_values_obj.copy(cursor, user, ir_value.id,
default={'res_id': res}, context=context)
return res
def _action(self, cursor, user, ids, name, arg, context=None):
res = {}
for menu_id in ids:
-226
View File
@@ -1,226 +0,0 @@
"Values"
from trytond.osv import OSV, fields
import pickle
class Values(OSV):
"Values"
_name = 'ir.values'
_description = __doc__
def _value_unpickle(self, cursor, user, ids, name, arg, context=None):
res = {}
for report in self.browse(cursor, user, ids, context=context):
value = report[name[:-9]]
if not report.object and value:
try:
value = str(pickle.loads(value))
except:
pass
res[report.id] = value
return res
def _value_pickle(self, cursor, user, obj_id, name, value, arg,
context=None):
if context is None:
context = {}
ctx = context.copy()
if 'read_delta' in ctx:
del ctx['read_delta']
values = self.browse(cursor, user, obj_id, context=context)
if not values.object:
value = pickle.dumps(eval(value))
self.write(cursor, user, obj_id, {name[:-9]: value}, context=ctx)
_columns = {
'name': fields.char('Name', size=128),
'model': fields.char('Model', size=128),
'value': fields.text('Value'),
'value_unpickle': fields.function(_value_unpickle,
fnct_inv=_value_pickle, method=True, type='text', string='Value'),
'object': fields.boolean('Is Object'),
'key': fields.char('Type', size=128),
'key2': fields.char('Value', size=256),
'meta': fields.text('Meta Datas'),
'meta_unpickle': fields.function(_value_unpickle,
fnct_inv=_value_pickle, method=True, type='text',
string='Meta Datas'),
'res_id': fields.integer('Resource ID'),
'user_id': fields.many2one('res.user', 'User', ondelete='cascade'),
#TODO add in company module
#'company_id': fields.many2one('res.company', 'Company')
}
_defaults = {
'key': lambda *a: 'action',
'key2': lambda *a: 'tree_but_open',
#'company_id': lambda *a: False,
}
def _auto_init(self, cursor):
super(Values, self)._auto_init(cursor)
cursor.execute('SELECT indexname FROM pg_indexes ' \
'WHERE indexname = \'ir_values_key_model_key2_index\'')
if not cursor.fetchone():
cursor.execute('CREATE INDEX ir_values_key_model_key2_index ' \
'ON ir_values (key, model, key2)')
cursor.commit()
def set(self, cursor, user, key, key2, name, models, value, replace=True,
isobject=False, meta=False, preserve_user=False): #, company=False):
if type(value)==type(u''):
value = value.encode('utf8')
if not isobject:
value = pickle.dumps(value)
if meta:
meta = pickle.dumps(meta)
ids_res = []
for model in models:
if type(model)==type([]) or type(model)==type(()):
model, res_id = model
else:
res_id = False
if replace:
if key in ('meta', 'default'):
ids = self.search(cursor, user, [
('key', '=', key),
('key2', '=', key2),
('name', '=', name),
('model', '=', model),
('res_id', '=', res_id),
('user_id', '=', preserve_user and user)
])
else:
ids = self.search(cursor, user, [
('key', '=', key),
('key2', '=', key2),
('value', '=', value),
('model', '=', model),
('res_id', '=', res_id),
('user_id', '=', preserve_user and user)
])
self.unlink(cursor, user, ids)
vals = {
'name': name,
'value': value,
'model': model,
'object': isobject,
'key': key,
'key2': key2 and key2[:200],
'meta': meta,
'user_id': preserve_user and user,
}
# if company:
# cid = self.pool.get('res.user').browse(cursor, user, user,
# context={}).company_id.id
# vals['company_id'] = cid
if res_id:
vals['res_id'] = res_id
ids_res.append(self.create(cursor, user, vals))
return ids_res
def get(self, cursor, user, key, key2, models, meta=False, context=None,
res_id_req=False, without_user=True, key2_req=True):
result = []
for model in models:
if type(model)==type([]) or type(model)==type(()):
model, res_id = model
else:
res_id = False
where1 = ['key = %s', 'model = %s']
where2 = [key, str(model)]
where_opt = []
if key2:
where1.append('key2 = %s')
where2.append(key2[:200])
else:
dest = where1
if not key2_req or meta:
dest = where_opt
dest.append('key2 IS NULL')
if res_id_req and (models[-1][0]==model):
if res_id:
where1.append('res_id = %d' % (res_id,))
else:
where1.append('(res_id IS NULL)')
elif res_id:
if (models[-1][0]==model):
where1.append('(res_id = %d OR (res_id IS NULL))' % (res_id,))
where_opt.append('res_id = %d' % (res_id,))
else:
where1.append('res_id = %d' % (res_id,))
# if not without_user:
where_opt.append('user_id = %d' % (user,))
result = []
test = True
while test:
if not where_opt:
cursor.execute('SELECT id FROM ir_values ' \
'where ' + ' and '.join(where1) + ' ' \
'AND user_id IS NULL', where2)
else:
cursor.execute('select id FROM ir_values ' \
'where ' + ' and '.join(where1 + where_opt),
where2)
result.extend([x[0] for x in cursor.fetchall()])
if len(where_opt):
where_opt.pop()
else:
test = False
if result:
break
if not result:
return []
# cid = self.pool.get('res.user').browse(cursor, user, user,
# context={}).company_id.id
cursor.execute('SELECT id, name, value, object, meta, key ' \
'FROM ir_values ' \
'WHERE id IN (' + ','.join([str(x) for x in result])+') ' \
#'AND (company_id IS NULL OR company_id = %d) '\
'ORDER BY user_id')#, (cid,))
result = cursor.fetchall()
def _result_get(i, keys):
if i[1] in keys:
return False
keys.append(i[1])
if i[3]:
model, obj_id = i[2].split(',')
try:
obj_id = int(obj_id)
except:
return False
datas = self.pool.get(model).read(cursor, user, [obj_id], False,
context=context)
if not len(datas):
#ir_del(cursor, user, i[0])
return False
def clean(j):
for key in (
'report_sxw_content',
'report_rml_content',
'report_sxw', 'report_rml',
'report_sxw_content_data',
'report_rml_content_data',
):
if key in j:
del j[key]
return j
datas = clean(datas[0])
else:
datas = pickle.loads(i[2])
if meta:
meta2 = pickle.loads(i[4])
return (i[0], i[1], datas, meta2)
return (i[0], i[1], datas)
keys = []
res = filter(bool, map(lambda x: _result_get(x, keys), list(result)))
return res
Values()
-59
View File
@@ -1,59 +0,0 @@
<?xml version="1.0"?>
<tryton>
<data>
<record model="ir.ui.view" id="values_view_form">
<field name="model">ir.values</field>
<field name="type">form</field>
<field name="arch" type="xml">
<![CDATA[
<form string="Values">
<field name="name" select="1"/>
<field name="model" select="1"/>
<field name="key" select="1"/>
<field name="key2" select="2"/>
<field name="object" select="2"/>
<field name="res_id"/>
<field name="user_id" select="2"/>
<field name="value_unpickle"/>
<field name="meta_unpickle"/>
</form>
]]>
</field>
</record>
<record model="ir.ui.view" id="values_view_tree">
<field name="model">ir.values</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<![CDATA[
<tree string="Values">
<field name="name"/>
<field name="model"/>
<field name="key"/>
<field name="key2"/>
<field name="user_id"/>
</tree>
]]>
</field>
</record>
<record model="ir.action.act_window" id="act_values_form">
<field name="name">Values</field>
<field name="type">ir.action.act_window</field>
<field name="res_model">ir.values</field>
<field name="view_type">form</field>
</record>
<record model="ir.action.act_window.view"
id="act_values_form_view1">
<field name="sequence" eval="1"/>
<field name="view_id" ref="values_view_tree"/>
<field name="act_window_id" ref="act_values_form"/>
</record>
<record model="ir.action.act_window.view"
id="act_values_form_view2">
<field name="sequence" eval="2"/>
<field name="view_id" ref="values_view_form"/>
<field name="act_window_id" ref="act_values_form"/>
</record>
<menuitem parent_id="ir.menu_ir"
action="act_values_form" id="menu_values_form"/>
</data>
</tryton>
+12 -14
View File
@@ -958,7 +958,7 @@ class ORM(object):
mode=mode, noupdate=noupdate)
for lang in translate:
context2 = context.copy()
context2['lang'] = lang
context2['language'] = lang
self.write(cursor, user, [new_id], translate[lang],
context=context2)
except Exception, exp:
@@ -1042,7 +1042,7 @@ class ORM(object):
ids = [x['id'] for x in res]
res_trans = self.pool.get('ir.translation')._get_ids(cursor,
self._name + ',' + field, 'model',
context.get('lang', 'en_US'), ids)
context.get('language', 'en_US'), ids)
for i in res:
i[field] = res_trans.get(i['id'], False) or i[field]
@@ -1124,8 +1124,6 @@ class ORM(object):
# get the default values set by the user and override the default
# values defined in the object
#ir_values_obj = self.pool.get('ir.values')
#res = ir_values_obj.get(cursor, user, 'default', False, [self._name])
ir_default_obj = self.pool.get('ir.default')
defaults = ir_default_obj.get_default(cursor, user,
self._name, False, context=context)
@@ -1267,8 +1265,8 @@ class ORM(object):
upd_todo = []
updend = []
direct = []
totranslate = context.get('lang', False) \
and (context['lang'] != 'en_US')
totranslate = context.get('language', False) \
and (context['language'] != 'en_US')
for field in vals:
if field in self._columns:
if self._columns[field]._classic_write:
@@ -1348,7 +1346,7 @@ class ORM(object):
if self._columns[field].translate:
self.pool.get('ir.translation')._set_ids(cursor, user,
self._name + ',' + field, 'model',
context['lang'], ids, vals[field])
context['language'], ids, vals[field])
# call the 'set' method of fields which are not classic_write
upd_todo.sort(lambda x, y: self._columns[x].priority - \
@@ -1525,12 +1523,12 @@ class ORM(object):
# translate the field label
res_trans = translation_obj._get_source(cursor,
self._name + ',' + field, 'field',
context.get('lang', 'en_US'))
context.get('language', 'en_US'))
if res_trans:
res[field]['string'] = res_trans
help_trans = translation_obj._get_source(cursor,
self._name + ',' + field, 'help',
context.get('lang', 'en_US'))
context.get('language', 'en_US'))
if help_trans:
res[field]['help'] = help_trans
@@ -1542,7 +1540,7 @@ class ORM(object):
for (key, val) in sel:
val2 = translation_obj._get_source(cursor,
self._name + ',' + field, 'selection',
context.get('lang', 'en_US'), val)
context.get('language', 'en_US'), val)
sel2.append((key, val2 or val))
sel = sel2
res[field]['selection'] = sel
@@ -1619,16 +1617,16 @@ class ORM(object):
if node.nodeType == node.ELEMENT_NODE:
# translate view
translation_obj = self.pool.get('ir.translation')
if ('lang' in context) and not result:
if ('language' in context) and not result:
if node.hasAttribute('string') and node.getAttribute('string'):
trans = translation_obj._get_source(cursor,
self._name, 'view', context['lang'],
self._name, 'view', context['language'],
node.getAttribute('string').encode('utf8'))
if trans:
node.setAttribute('string', trans.decode('utf8'))
if node.hasAttribute('sum') and node.getAttribute('sum'):
trans = translation_obj._get_source(cursor,
self._name, 'view', context['lang'],
self._name, 'view', context['language'],
node.getAttribute('sum').encode('utf8'))
if trans:
node.setAttribute('sum', trans.decode('utf8'))
@@ -2007,7 +2005,7 @@ class ORM(object):
'AND type = %s ' \
'AND value ' + args[i][1] + ' %s',
(table._name + ',' + args[i][0],
context.get('lang', 'en_US'), 'model',
context.get('language', 'en_US'), 'model',
args[i][2]))
ids = [x[0] for x in cursor.fetchall()]
cursor.execute('SELECT id FROM "' + table._table + '" ' \
+7 -7
View File
@@ -213,8 +213,8 @@ class Report(object):
def _get_objects(self, cursor, user, ids, model, context):
model_obj = self.pool.get(model)
context = context.copy()
if 'lang' in context:
del context['lang']
if 'language' in context:
del context['language']
#TODO change list_class
return model_obj.browse(cursor, user, ids, context=context)
@@ -284,8 +284,8 @@ class Report(object):
node.nodeValue = res
node.parentNode.parentNode.replaceChild(node, node.parentNode)
return res
if 'lang' in localcontext:
lang = localcontext['lang']
if 'language' in localcontext:
lang = localcontext['language']
text = node.nodeValue
if lang and text and not text.isspace():
translation_obj = self.pool.get('ir.translation')
@@ -342,7 +342,7 @@ class Report(object):
return node
def set_lang(self, lang, localcontext):
localcontext['lang'] = lang
localcontext['language'] = lang
return None
def format_lang(self, value, digits=2, date=False, localcontext=None):
@@ -353,7 +353,7 @@ class Report(object):
encoding = 'UTF-8'
if encoding == 'cp1252':
encoding = '1252'
lang = localcontext.get('lang', False) or 'en_US'
lang = localcontext.get('language', False) or 'en_US'
try:
if os.name == 'nt':
locale.setlocale(locale.LC_ALL,
@@ -364,7 +364,7 @@ class Report(object):
Logger().notify_channel('web-service', LOG_ERROR,
'Report %s: unable to set locale "%s"' % \
(self._name,
localcontext.get('lang', False) or 'en_US'))
localcontext.get('language', False) or 'en_US'))
if date:
date = time.strptime(value, '%Y-%m-%d')
return time.strftime(locale.nl_langinfo(locale.D_FMT).\
+1 -1
View File
@@ -1,3 +1,3 @@
from user import *
from lang import *
from user import *
from request import *
+1 -1
View File
@@ -4,8 +4,8 @@
'depends': ['ir'],
'xml': [
'res.xml',
'users.xml',
'lang.xml',
'users.xml',
'request.xml',
]
}
+71
View File
@@ -1,4 +1,7 @@
"User"
import time
from xml import dom
from xml.dom import minidom
from trytond.osv import fields, OSV, ExceptOSV
#from trytond.tools import Cache
@@ -59,6 +62,23 @@ class User(OSV):
_name = "res.user"
_log_access = False
_description = __doc__
def _languages(self, cursor, user, context=None):
lang_obj = self.pool.get('res.lang')
lang_ids = lang_obj.search(cursor, user, [], context=context)
res = []
for lang in lang_obj.browse(cursor, user, lang_ids, context=context):
res.append([lang.code, lang.name])
return res
def _timezones(self, cursor, user, context=None):
try:
import pytz
res = [[x, x] for x in pytz.all_timezones]
except ImportError:
res = [[time.tzname[0], time.tzname[0]]]
return res
_columns = {
'name': fields.Char('Name', size=64, required=True, select=True),
'login': fields.Char('Login', size=64, required=True),
@@ -76,6 +96,8 @@ class User(OSV):
'rule_groups': fields.Many2Many('ir.rule.group', 'user_rule_group_rel',
'user_id', 'rule_group_id', 'Rules',
domain="[('global', '<>', True)]"),
'language': fields.Selection(_languages, 'Language'),
'timezone': fields.Selection(_timezones, 'Timezone'),
}
_sql_constraints = [
('login_key', 'UNIQUE (login)',
@@ -84,7 +106,18 @@ class User(OSV):
_defaults = {
'password' : lambda *a: '',
'active' : lambda *a: 1,
'language': lambda *a: 'en_US',
'timezone': lambda *a: time.tzname[0],
}
_preferences_fields = [
'name',
'password',
'signature',
]
_context_fields = [
'language',
'timezone',
]
# def company_get(self, cursor, user, uid2):
# company_id = self.pool.get('res.user').browse(cursor, user,
# user).company_id.id
@@ -143,6 +176,44 @@ class User(OSV):
default.update({'login': login+' (copy)'})
return super(User, self).copy(cursor, user, obj_id, default,
context=context)
def get_preferences(self, cursor, user, context_only=False, context=None):
res = {}
user = self.browse(cursor, user, user, context=context)
if context_only:
fields = self._context_fields
else:
fields = self._preferences_fields + self._context_fields
for field in fields:
res[field] = user[field]
return res
def set_preferences(self, cursor, user, values, context=None):
values = values.copy()
fields = self._preferences_fields + self._context_fields
for field in values:
if field not in fields:
del values[field]
self.write(cursor, 1, user, values, context=context)
def get_preferences_fields_view(self, cursor, user, context=None):
res = {}
fields = self.fields_get(cursor, user,
fields_names=self._preferences_fields, context=context)
xml = '<?xml version="1.0" encoding="utf-8"?>' \
'<form string="%s" colspan="2">' % (self._description,)
for field in fields:
#TODO remove newline when colspan on form is implemented
xml += '<field name="%s"/><newline/>' % (field,)
xml += '</form>'
doc = dom.minidom.parseString(xml)
arch, fields = self._view_look_dom_arch(cursor,
user, doc, context=context)
res['arch'] = arch
res['fields'] = fields
return res
User()
+4
View File
@@ -38,6 +38,10 @@
<field name="roles_id" colspan="4"/>
<field name="rule_groups" colspan="4"/>
</page>
<page string="Preferences">
<field name="language"/>
<field name="timezone"/>
</page>
</notebook>
</form>
]]>
-10
View File
@@ -196,16 +196,6 @@ class RecordTagHandler:
context['version'] = VERSION.rsplit('.', 1)[0]
context['ref'] = self.mh.get_id
context['obj'] = lambda *a: 1
try:
import pytz
except:
Logger().notify_channel("init", LOG_INFO,
'could not find pytz library')
class Pytz(object):
all_timezones = []
pytz = Pytz()
context['pytz'] = pytz
self.values[field_name] = eval(eval_attr, context)
else:
+3 -20
View File
@@ -32,7 +32,7 @@ def translate(cursor, user, name, source_type, lang, source=None):
return res
def translate_code(cursor, user, source, context):
lang = context.get('lang', False)
lang = context.get('language', False)
if lang:
return translate(cursor, user, None, 'code', lang, source)
else:
@@ -254,7 +254,6 @@ def trans_load_data(db_name, data, lang, strict=False, lang_name=None):
lang_obj = pool.get('res.lang')
trans_obj = pool.get('ir.translation')
model_data_obj = pool.get('ir.model.data')
values_obj = pool.get('ir.values')
try:
user = 1
cursor = pooler.get_db(db_name).cursor()
@@ -273,22 +272,6 @@ def trans_load_data(db_name, data, lang, strict=False, lang_name=None):
})
else:
lang_obj.write(cursor, user, ids, {'translatable':1})
lang_ids = lang_obj.search(cursor, user, [])
langs = lang_obj.read(cursor, user, lang_ids)
selection = [(x['code'], x['name']) for x in langs]
values_obj.set(cursor, user, 'meta', 'lang', 'lang',
[('res.user', False,)],
False, True, False, meta={
'type': 'selection',
'string': 'Language',
'selection': selection,
})
user_ids = pool.get('res.user').search(cursor, user, [])
for user_id in user_ids:
values_obj.set(cursor, user, 'meta', 'lang', 'lang',
[('res.user', user_id,)], lang, True, False)
reader = csv.reader(data)
# read the first line of the file (it contains columns titles)
@@ -306,9 +289,9 @@ def trans_load_data(db_name, data, lang, strict=False, lang_name=None):
continue
# dictionary which holds values for this line of the csv file
# {'lang': ..., 'type': ..., 'name': ..., 'res_id': ...,
# {'language': ..., 'type': ..., 'name': ..., 'res_id': ...,
# 'src': ..., 'value': ...}
dic = {'lang': lang}
dic = {'language': lang}
for i in range(len(first)):
dic[first[i]] = row[i]
-1
View File
@@ -86,7 +86,6 @@ class TrytonServer(object):
"FROM pg_class " \
"WHERE relkind = 'r' AND relname in (" \
"'inherit', "
"'ir_values', "
"'ir_model', "
"'ir_model_fields', "
"'ir_ui_view', "
+1 -1
View File
@@ -29,5 +29,5 @@ The whole source code is distributed under the terms of the
GNU Public Licence v2.
''' % (VERSION,)
def timezone_get(self):
def timezone_get(self, database, login, password):
return time.tzname[0]
+1 -1
View File
@@ -151,7 +151,7 @@ class Wizard(object):
res = copy.copy(result_def)
res['datas'] = actions_res
lang = context.get('lang', 'en_US')
lang = context.get('language', 'en_US')
if result_def['type'] == 'action':
res['action'] = result_def['action'](self, cursor, user, data,
context)