Merge branch 'master' of /home/panos/tmp/tinyerp/openobject-server/ into mandriva

bzr revid: p_christ@hol.gr-20081006205715-p1hzrsvutwlozt5m
bzr revid: p_christ@hol.gr-20081008092006-9vq68ehp9ck1tnml
This commit is contained in:
P. Christeas 2008-10-08 12:20:06 +03:00
commit a73e9eb836
15 changed files with 281 additions and 108 deletions

View File

@ -12,7 +12,6 @@
</field>
<field name="field_parent">child_id</field>
</record>
<record id="action_menu_admin" model="ir.actions.act_window">
<field name="name">Menu</field>
<field name="usage">menu</field>
@ -22,13 +21,13 @@
<field name="view_type">tree</field>
<field eval="'[(\'parent_id\',\'=\',False)]'" name="domain"/>
</record>
<record id="lang_en" model="res.lang">
<field name="code">en_US</field>
<field name="name">English</field>
<field name="translatable">True</field>
<field name="name">English</field>
<field name="translatable">True</field>
</record>
<record id="ad" model="res.country">
<field name="name">Andorra, Principality of</field>
<field name="code">ad</field>

View File

@ -182,21 +182,32 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Configure User">
<separator col="4" colspan="4" string="Define a New User"/>
<separator string="Define New Users" colspan="4"/>
<field name="name" select="1"/>
<newline/>
<field name="active" select="1"/>
<field name="login" select="1"/>
<newline/>
<field name="password" required="1" password="True" />
<field colspan="4" name="signature"/>
<separator string="Assign Groups to Define Access Rights" colspan="4"/>
<field colspan="4" name="groups_id" nolabel="1"/>
<separator string="" colspan="4"/>
<label string="" colspan="1"/>
<group col="3" colspan="2">
<button icon='gtk-cancel' special="cancel" name="action_next" type='object' string='Skip &amp; Continue'/>
<button name='action_new' icon='gtk-ok' type='object' string='Add New User'/>
<button name='action_continue' icon='gtk-go-forward' type='object' string='Add &amp; Continue'/>
<field name="password" password="True"/>
<notebook colspan="4">
<page string="User">
<field name="address_id"/>
<field name="company_id" required="1"/>
<field name="action_id" required="True"/>
<field domain="[('usage','=','menu')]" name="menu_id" required="True"/>
<field name="context_lang"/>
<field name="context_tz"/>
<field colspan="4" name="signature"/>
</page>
<page string="Groups">
<field colspan="4" nolabel="1" name="groups_id"/>
</page>
<page string="Roles">
<field colspan="4" nolabel="1" name="roles_id"/>
</page>
</notebook>
<label string="" colspan="2"/>
<group col="2" colspan="2">
<button icon='gtk-cancel' special="cancel" name="action_next" type='object' string='Close'/>
<button name='action_new' icon='gtk-ok' type='object' string='Add User'/>
</group>
</form>
</field>

View File

@ -714,33 +714,36 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Fields">
<group colspan="4" col="6">
<group colspan="4" col="4">
<field name="name" select="1"/>
<field colspan="4" name="field_description" select="2"/>
<field name="model_id" readonly="1"/>
<field colspan="4" name="field_description" select="2"/>
</group>
<group colspan="2" col="2">
<separator string="Field Type" colspan="2"/>
<field name="ttype" select="2"/>
<field name="relation" select="2"/>
<field name="selection"/>
<field name="size"/>
<field name="state"/>
<field name="domain"/>
</group>
<notebook>
<page string="Properties">
<group colspan="2" col="2">
<field name="ttype" select="2"/>
<field name="relation" select="2"/>
<field name="selection"/>
<field name="size"/>
<field name="state"/>
<field name="domain"/>
</group>
<group colspan="2" col="2">
<separator string="Properties" colspan="2"/>
<field name="required" select="2"/>
<field name="readonly" select="2"/>
<field name="select_level"/>
<field name="translate"/>
<field name="relate"/>
<field name="on_delete"/>
</group>
<separator string="Security on Groups" colspan="4"/>
<field name="groups" colspan="4" nolabel="1"/>
<group colspan="2" col="2">
<field name="required" select="2"/>
<field name="readonly" select="2"/>
<field name="select_level"/>
<field name="translate"/>
<field name="relate"/>
<field name="on_delete"/>
</group>
</page>
<page string="Security on Groups" colspan="4">
<field name="groups" colspan="4" nolabel="1"/>
</page>
</notebook>
</form>
</field>
</record>
@ -1096,6 +1099,7 @@
<page string="Python Code" attrs="{'invisible':[('state','!=','python')]}">
<separator colspan="4" string="Python code"/>
<field name="code" colspan="4" nolabel="1" />
<button string="Create Action" name="%(wizard_server_action_create)d" type="action"/>
</page>
<page string="Trigger" attrs="{'invisible':[('state','!=','trigger')]}">

View File

@ -369,7 +369,7 @@ class ir_model_data(osv.osv):
def _get_id(self,cr, uid, module, xml_id):
ids = self.search(cr, uid, [('module','=',module),('name','=', xml_id)])
assert len(ids)==1, '%d reference(s) to %s. You should have one and only one !' % (len(ids),xml_id)
assert len(ids)==1, '%d reference(s) to %s.%s. You should have one and only one !' % (len(ids), module, xml_id)
return ids[0]
_get_id = tools.cache()(_get_id)

View File

@ -28,6 +28,6 @@
#
##############################################################################
import wizard_menu
import create_action
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,92 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
#
# $Id$
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import wizard
import pooler
import time
action_type = '''<?xml version="1.0"?>
<form string="Select Action Type">
<field name="type"/>
</form>'''
action_type_fields = {
'type': {'string':"Start date",'type':'selection','required':True ,'selection':[('ir.actions.report.xml','Open Report')]},
}
report_action = '''<?xml version="1.0"?>
<form string="Select Report">
<field name="report" colspan="4"/>
</form>'''
report_action_fields = {
'report': {'string':"Select Report",'type':'many2one','relation':'ir.actions.report.xml', 'required':True},
}
class create_action(wizard.interface):
def _create_report_action(self, cr, uid, data, context={}):
pool = pooler.get_pool(cr.dbname)
reports = pool.get('ir.actions.report.xml')
form = data['form']
rpt = reports.browse(cr, uid, form['report'])
action = """
action = {
'type': 'ir.actions.report.xml',
'model':'%s',
'report_name': '%s',
'ids': context['active_ids'],
}""" % (rpt.model, rpt.report_name)
obj = pool.get('ir.actions.server')
obj.write(cr, uid, data['ids'], {'code':action})
return {}
states = {
'init': {
'actions': [],
'result': {'type':'form', 'arch':action_type,'fields':action_type_fields, 'state':[('step_1','Next'),('end','Close')]}
},
'step_1': {
'actions': [],
'result': {'type':'form', 'arch':report_action,'fields':report_action_fields, 'state':[('create','Create'),('end','Close')]}
},
'create': {
'actions': [_create_report_action],
'result': {'type':'state', 'state':'end'}
},
}
create_action('server.action.create')

View File

@ -28,6 +28,12 @@
</field>
</record>
<act_window context="{'model_id': active_id}" id="act_menu_create" name="Create Menu" res_model="wizard.ir.model.menu.create" target="new" view_mode="form"/>
<wizard
id="wizard_server_action_create"
model="ir.actions.server"
name="server.action.create"
string="Create Action"
menu="False"
/>
</data>
</openerp>

View File

@ -222,8 +222,8 @@ class module(osv.osv):
_columns = {
'name': fields.char("Name", size=128, readonly=True, required=True),
'category_id': fields.many2one('ir.module.category', 'Category', readonly=True),
'shortdesc': fields.char('Short description', size=256, readonly=True),
'description': fields.text("Description", readonly=True),
'shortdesc': fields.char('Short description', size=256, readonly=True, translate=True),
'description': fields.text("Description", readonly=True, translate=True),
'author': fields.char("Author", size=128, readonly=True),
'website': fields.char("Website", size=256, readonly=True),
'installed_version': fields.function(_get_installed_version, method=True,
@ -242,7 +242,7 @@ class module(osv.osv):
('to install','To be installed')
], string='State', readonly=True),
'demo': fields.boolean('Demo data'),
'license': fields.selection([('GPL-2', 'GPL-2'),
'license': fields.selection([('GPL-2', 'GPL-2'),('GPL-3', 'GPL-3'),
('Other proprietary', 'Other proprietary')], string='License',
readonly=True),
}

View File

@ -168,13 +168,31 @@
</field>
</record>
<record id="action_partner_title" model="ir.actions.act_window">
<field name="name">Partners Titles</field>
<field name="name">Titles</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner.title</field>
<field name="view_type">form</field>
</record>
<menuitem action="action_partner_title" id="menu_partner_title" parent="base.menu_base_config"/>
<record id="action_partner_title_partner" model="ir.actions.act_window">
<field name="name">Partners Titles</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner.title</field>
<field name="view_type">form</field>
<field name="domain">[('domain','=','partner')]</field>
</record>
<menuitem action="action_partner_title_partner" id="menu_partner_title_partner" parent="action_partner_title"/>
<record id="action_partner_title_contact" model="ir.actions.act_window">
<field name="name">Contacts Titles</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner.title</field>
<field name="view_type">form</field>
<field name="domain">[('domain','=','contact')]</field>
</record>
<menuitem action="action_partner_title_contact" id="menu_partner_title_contact" parent="action_partner_title"/>
<!--
=======================
Partner
@ -188,11 +206,10 @@
<field name="arch" type="xml">
<tree string="Partners">
<field name="name"/>
<field name="title"/>
<field name="ref"/>
<field name="city"/>
<field name="country"/>
<field name="title" string="Type"/>
<field name="ref"/>
<field name="address" string="# of Contacts"/>
<field name="lang"/>
</tree>
</field>

View File

@ -18,10 +18,6 @@
<field name="name">Employee</field>
</record>
<record model="res.groups" id="group_account_manager">
<field name="name">Account Manager</field>
</record>
<record model="res.groups" id="group_extended">
<field name="name">Useability / Extended View</field>
</record>

View File

@ -59,8 +59,8 @@ class expression(object):
doms = []
for o in table.browse(cr, uid, ids, context=context):
if doms:
doms.insert(0,'|')
doms += ['&',('parent_left','<',o.parent_right),('parent_left','>=',o.parent_left)]
doms.insert(0, '|')
doms += ['&', ('parent_left', '<', o.parent_right), ('parent_left', '>=', o.parent_left)]
if prefix:
return [(left, 'in', table.search(cr, uid, doms, context=context))]
return doms
@ -69,14 +69,14 @@ class expression(object):
if not ids:
return []
ids2 = table.search(cr, uid, [(parent, 'in', ids)], context=context)
return ids+rg(ids2, table, parent)
return ids + rg(ids2, table, parent)
return [(left, 'in', rg(ids, table, parent))]
self.__main_table = table
i = -1
while i+1<len(self.__exp):
i+=1
while i + 1<len(self.__exp):
i += 1
e = self.__exp[i]
if self._is_operator(e) or e == self.__DUMMY_LEAF:
continue
@ -114,19 +114,19 @@ class expression(object):
self.__exp[i] = self.__DUMMY_LEAF
else:
subexp = field.search(cr, uid, table, left, [self.__exp[i]])
# we assume that the expression is valid
# we assume that the expression is valid
# we create a dummy leaf for forcing the parsing of the resulting expression
self.__exp[i] = '&'
self.__exp.insert(i + 1, self.__DUMMY_LEAF)
for j, se in enumerate(subexp):
self.__exp.insert(i + 2 + j, se)
# else, the value of the field is store in the database, so we search on it
elif field._type == 'one2many':
if isinstance(right, basestring):
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator,limit=None)]
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator, limit=None)]
else:
ids2 = list(right)
if not ids2:
@ -138,7 +138,7 @@ class expression(object):
#FIXME
if operator == 'child_of':
if isinstance(right, basestring):
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], 'like',limit=None)]
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], 'like', limit=None)]
else:
ids2 = list(right)
@ -146,7 +146,7 @@ class expression(object):
if field_obj == table:
return ids
return self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, ids)
dom = _rec_get(ids2, field_obj, working_table._parent_name)
ids2 = field_obj.search(cr, uid, dom, context=context)
self.__exp[i] = ('id', 'in', _rec_convert(ids2))
@ -159,7 +159,7 @@ class expression(object):
elif field._type == 'many2one':
if operator == 'child_of':
if isinstance(right, basestring):
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], 'like',limit=None)]
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], 'like', limit=None)]
else:
ids2 = list(right)
@ -171,7 +171,7 @@ class expression(object):
self.__exp = self.__exp[:i] + dom + self.__exp[i+1:]
else:
if isinstance(right, basestring):
res_ids = field_obj.name_search(cr, uid, right, [], operator,limit=None)
res_ids = field_obj.name_search(cr, uid, right, [], operator, limit=None)
right = map(lambda x: x[0], res_ids)
self.__exp[i] = (left, 'in', right)
else:
@ -204,7 +204,7 @@ class expression(object):
def __leaf_to_sql(self, leaf, table):
if leaf == self.__DUMMY_LEAF:
return ('(1=1)',[])
return ('(1=1)', [])
left, operator, right = leaf
if operator == 'inselect':
@ -288,7 +288,7 @@ class expression(object):
q1 = stack.pop()
q2 = stack.pop()
stack.append('(%s %s %s)' % (q1, ops[e], q2,))
query = ' AND '.join(reversed(stack))
joins = ' AND '.join(map(lambda j: j[0], self.__joins))
if joins:

View File

@ -230,6 +230,7 @@ class binary(_column):
get = get_memory
class selection(_column):
_type = 'selection'
@ -331,7 +332,7 @@ class many2one(_column):
context = {}
obj = obj_src.pool.get(self._obj)
self._table = obj_src.pool.get(self._obj)._table
if type(values)==type([]):
if type(values) == type([]):
for act in values:
if act[0] == 0:
id_new = obj.create(cr, act[2])
@ -495,7 +496,7 @@ class many2many(_column):
d1, d2 = obj.pool.get('ir.rule').domain_get(cr, user, obj._name)
if d1:
d1 = ' and '+d1
d1 = ' and ' + d1
cr.execute('SELECT '+self._rel+'.'+self._id2+','+self._rel+'.'+self._id1+' \
FROM '+self._rel+' , '+obj._table+' \
@ -531,7 +532,7 @@ class many2many(_column):
d1, d2 = obj.pool.get('ir.rule').domain_get(cr, user, obj._name)
if d1:
d1 = ' and '+d1
d1 = ' and ' + d1
cr.execute('delete from '+self._rel+' where '+self._id1+'=%d AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+obj._table+' WHERE '+self._rel+'.'+self._id1+'=%d AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2)
for act_nbr in act[2]:
@ -638,54 +639,93 @@ class function(_column):
class related(function):
def _fnct_search(self, tobj, cr, uid, obj=None, name=None, context=None):
raise 'Not Implemented Yet'
# field_detail=self._field_get(cr,uid,obj,obj._name,name)
# print field_detail
# if field_detail[1] in ('many2one'):
# ids=obj.pool.get(field_detail[0] or obj._name).search(cr,uid,[('name','ilike',context[0][2])])
# print ids
# return [('id','in',[5,6,7])]
# return True
where_flag = 0
where = " where"
query = "select %s.id from %s" % (obj._table, obj._table)
relation_child = obj._name
relation = obj._name
for i in range(len(self._arg)):
field_detail = self._field_get(cr, uid, obj, relation, self._arg[i])
relation = field_detail[0]
if field_detail[1] in ('one2many', 'many2many'):
obj_child = obj.pool.get(field_detail[2][self._arg[i]]['relation'])
field_detail_child = obj_child.fields_get(cr, uid,)
fields_filter = dict(filter(lambda x: x[1].get('relation', False)
and x[1].get('relation') == relation_child
and x[1].get('type')=='many2one', field_detail_child.items()))
query += " inner join %s on %s.id = %s.%s" % (obj_child._table, obj._table, obj_child._table, fields_filter.keys()[0])
relation_child = relation
elif field_detail[1] in ('many2one'):
obj_child = obj.pool.get(field_detail[2][self._arg[i]]['relation'])
obj_child2 = obj.pool.get(relation_child)
if obj_child._name == obj_child2._name:
# select res_partner.id from res_partner where res_partner.parent_id in(select id from res_partner where res_partner.date >= '2008-10-01');
# where +=" %s.id = %s.%s in (select id from %s where %s.%s %s %s"%(obj_child._table,obj_child2._table,self._arg[i])
pass
else:
query += " inner join %s on %s.id = %s.%s" % (obj_child._table, obj_child._table, obj_child2._table, self._arg[i])
relation_child = field_detail[0]
if i == (len(self._arg)-1):
if obj_child._inherits:
obj_child_inherits = obj.pool.get(obj_child._inherits.keys()[0])
query += " inner join %s on %s.id = %s.%s" % (obj_child_inherits._table, obj_child_inherits._table, obj_child._table, obj_child._inherits.values()[0])
obj_child = obj_child_inherits
where += " %s.%s %s '%%%s%%' and" % (obj_child._table, obj_child._rec_name, context[0][1], context[0][2])
else:
obj_child = obj.pool.get(relation_child)
if field_detail[1] in ('char'):
where += " %s.%s %s '%%%s%%' and" % (obj_child._table, self._arg[i], context[0][1], context[0][2])
if field_detail[1] in ('date'):
where += " %s.%s %s '%s' and" % (obj_child._table, self._arg[i], context[0][1], context[0][2])
if field_detail[1] in ['integer', 'long', 'float']:
where += " %s.%s %s '%d' and" % (obj_child._table, self._arg[i], context[0][1], context[0][2])
query += where.rstrip('and')
cr.execute(query)
ids = []
for id in cr.fetchall():
ids.append(id[0])
return [('id', 'in', ids)]
# def _fnct_write(self,obj,cr, uid, ids,values, field_name, args, context=None):
# raise 'Not Implemented Yet'
def _fnct_read(self,obj,cr, uid, ids, field_name, args, context=None):
def _fnct_read(self, obj, cr, uid, ids, field_name, args, context=None):
if not ids: return {}
relation=obj._name
res={}
objlst = obj.browse(cr,uid,ids)
relation = obj._name
res = {}
objlst = obj.browse(cr, uid, ids)
for data in objlst:
t_data=data
relation=obj._name
t_data = data
relation = obj._name
for i in range(len(self.arg)):
field_detail=self._field_get(cr,uid,obj,relation,self.arg[i])
relation=field_detail[0]
field_detail = self._field_get(cr, uid, obj, relation, self.arg[i])
relation = field_detail[0]
if not t_data[self.arg[i]]:
t_data = False
break
if field_detail[1] in ('one2many','many2many'):
t_data=t_data[self.arg[i]][0]
if field_detail[1] in ('one2many', 'many2many'):
t_data = t_data[self.arg[i]][0]
else:
t_data=t_data[self.arg[i]]
t_data = t_data[self.arg[i]]
if type(t_data) == type(objlst[0]):
res[data.id]=t_data.id
res[data.id] = t_data.id
else:
res[data.id]=t_data
res[data.id] = t_data
return res
def __init__(self,*arg,**args):
def __init__(self, *arg, **args):
self.arg = arg
super(related, self).__init__(self._fnct_read, arg, fnct_inv_arg=arg,method=True, fnct_search=self._fnct_search,**args)
super(related, self).__init__(self._fnct_read, arg, fnct_inv_arg=arg, method=True, fnct_search=self._fnct_search, **args)
# TODO: call field_get on the object, not in the DB
def _field_get(self, cr, uid, obj, model_name, prop):
fields=obj.pool.get(model_name).fields_get(cr,uid,[prop])
if fields.get(prop,False):
return(fields[prop].get('relation',False),fields[prop].get('type',False))
fields = obj.pool.get(model_name).fields_get(cr, uid,)
if fields.get(prop, False):
return(fields[prop].get('relation', False), fields[prop].get('type', False), fields)
else:
raise 'Fields %s not exist in %s'%(prop,model_name)
raise 'Field %s not exist in %s' % (prop, model_name)
# ---------------------------------------------------------
# Serialized fields

View File

@ -45,12 +45,14 @@ module_list = []
module_class_list = {}
class_pool = {}
class except_osv(Exception):
def __init__(self, name, value, exc_type='warning'):
self.name = name
self.exc_type = exc_type
self.value = value
self.args = (exc_type,name)
self.args = (exc_type, name)
class osv_pool(netsvc.Service):
@ -71,9 +73,9 @@ class osv_pool(netsvc.Service):
self.exportMethod(self.execute_cr)
def init_set(self, cr, mode):
if mode<>self._init:
if mode <> self._init:
if mode:
self._init_parent={}
self._init_parent = {}
if not mode:
for o in self._init_parent:
self.get(o)._parent_store_compute(cr)
@ -87,7 +89,7 @@ class osv_pool(netsvc.Service):
if not object:
self.abortResponse(1, 'Object Error', 'warning',
'Object %s doesn\'t exist' % str(obj))
return getattr(object,method)(cr, uid, *args, **kw)
return getattr(object, method)(cr, uid, *args, **kw)
except orm.except_orm, inst:
self.abortResponse(1, inst.name, 'warning', inst.value)
except except_osv, inst:
@ -147,7 +149,7 @@ class osv_pool(netsvc.Service):
# adds a new object instance to the object pool.
# if it already existed, the instance is replaced
def add(self, name, obj_inst):
if self.obj_pool.has_key(name):
if name in self.obj_pool:
del self.obj_pool[name]
self.obj_pool[name] = obj_inst
@ -171,6 +173,7 @@ class osv_pool(netsvc.Service):
res.append(klass.createInstance(self, module, cr))
return res
class osv_memory(orm.orm_memory):
#__metaclass__ = inheritor
def __new__(cls):
@ -190,7 +193,7 @@ class osv_memory(orm.orm_memory):
# put objects in the pool var
#
def createInstance(cls, pool, module, cr):
name = hasattr(cls,'_name') and cls._name or cls._inherit
name = hasattr(cls, '_name') and cls._name or cls._inherit
parent_name = hasattr(cls, '_inherit') and cls._inherit
if parent_name:
print 'Inherit not supported in osv_memory object !'
@ -237,7 +240,7 @@ class osv(orm.orm):
else:
new.extend(cls.__dict__.get(s, []))
nattr[s] = new
name = hasattr(cls,'_name') and cls._name or cls._inherit
name = hasattr(cls, '_name') and cls._name or cls._inherit
cls = type(name, (cls, parent_class), nattr)
obj = object.__new__(cls)
obj.__init__(pool, cr)
@ -249,6 +252,7 @@ class osv(orm.orm):
self.pool = pool
orm.orm.__init__(self, cr)
class Cacheable(object):
_cache = UpdateableDict()
@ -270,6 +274,7 @@ class Cacheable(object):
self._cache.clear()
self._items = []
def filter_dict(d, fields):
res = {}
for f in fields + ['id']:
@ -277,6 +282,7 @@ def filter_dict(d, fields):
res[f] = d[f]
return res
class cacheable_osv(osv, Cacheable):
_relevant = ['lang']
@ -286,9 +292,9 @@ class cacheable_osv(osv, Cacheable):
def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):
if not fields:
fields=[]
fields = []
if not context:
context={}
context = {}
fields = fields or self._columns.keys()
ctx = [context.get(x, False) for x in self._relevant]
result, tofetch = [], []
@ -330,7 +336,7 @@ class cacheable_osv(osv, Cacheable):
def write(self, cr, user, ids, values, context=None):
if not context:
context={}
context = {}
for id in ids:
self.invalidate((self._name, id))
return super(cacheable_osv, self).write(cr, user, ids, values, context)

View File

@ -79,6 +79,7 @@ class TinyPoFile(object):
def __iter__(self):
self.buffer.seek(0)
self.lines = self.buffer.readlines()
self.lines.append('') # ensure that the file ends with at least an empty line
self.first = True
self.tnrs= []
return self

1
setup.py Executable file → Normal file
View File

@ -1,5 +1,6 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2004-2008 Tiny SPRL (http://tiny.be) All Rights Reserved.