Sébastien BEAU - http://www.akretion.com has proposed merging lp:~akretion-team/server-env-tools/server-env-tools into lp:server-env-tools.
Requested reviews: Server Environment And Tools Core Editors (server-env-tools-core-editors) For more details, see: https://code.launchpad.net/~akretion-team/server-env-tools/server-env-tools/+merge/222291 Here is a proposal too add new fields for image and binary -- https://code.launchpad.net/~akretion-team/server-env-tools/server-env-tools/+merge/222291 Your team Server Environment And Tools Core Editors is requested to review the proposed merge of lp:~akretion-team/server-env-tools/server-env-tools into lp:server-env-tools.
=== added directory 'binary_field' === added file 'binary_field/__init__.py' --- binary_field/__init__.py 1970-01-01 00:00:00 +0000 +++ binary_field/__init__.py 2014-06-06 09:01:45 +0000 @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Module for OpenERP +# Copyright (C) 2013 Akretion (http://www.akretion.com). +# @author Sébastien BEAU <sebastien.b...@akretion.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################### + +from . import fields === added file 'binary_field/__openerp__.py' --- binary_field/__openerp__.py 1970-01-01 00:00:00 +0000 +++ binary_field/__openerp__.py 2014-06-06 09:01:45 +0000 @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Module for OpenERP +# Copyright (C) 2013 Akretion (http://www.akretion.com). +# @author Sébastien BEAU <sebastien.b...@akretion.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################### + +{'name': 'Binary Field', + 'version': '0.0.1', + 'author': 'Akretion', + 'website': 'www.akretion.com', + 'license': 'AGPL-3', + 'category': 'Framework', + 'description': """This module extend the fields class in order to add 3 new +type of fields +- BinaryStore +- ImageStore +- ImageRezise + +Now let's do it ;) + + """, + 'depends': [ + 'base', + ], + 'data': [ + 'data.xml', + ], + 'installable': True, + 'application': True, +} + + + + === added file 'binary_field/data.xml' --- binary_field/data.xml 1970-01-01 00:00:00 +0000 +++ binary_field/data.xml 2014-06-06 09:01:45 +0000 @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<openerp> + <data> + <record id="binary_storage_parameter" model="ir.config_parameter"> + <field name="key">binary.location</field> + <field name="value">file:///filestore</field> + </record> + </data> +</openerp> === added file 'binary_field/fields.py' --- binary_field/fields.py 1970-01-01 00:00:00 +0000 +++ binary_field/fields.py 2014-06-06 09:01:45 +0000 @@ -0,0 +1,249 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Module for OpenERP +# Copyright (C) 2014 Akretion (http://www.akretion.com). +# @author Sébastien BEAU <sebastien.b...@akretion.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################### + +from openerp.osv import fields, orm +from openerp.tools import image_resize_image +from openerp.tools.translate import _ +from openerp import tools +import os +import sys +import logging + +_logger = logging.getLogger(__name__) + + +class Storage(object): + + def __init__(self, cr, uid, record, field_name): + self.cr = cr + self.uid = uid + self.pool = record._model.pool + self.field_key = ("%s-%s" % (record._name, field_name)).replace('.', '') + base_location = self.pool.get('ir.config_parameter').\ + get_param(cr, uid, 'binary.location') + if not base_location: + raise orm.except_orm( + _('Configuration Error'), + _('The "binary.location" is empty, please fill it in' + 'Configuration > Parameters > System Parameters')) + self.base_location = base_location + self.location = (self.base_location, self.field_key) + + def add(self, value): + if not value: + return {} + file_size = sys.getsizeof(value.decode('base64')) + binary_uid = self.pool['ir.attachment'].\ + _file_write(self.cr, self.uid, self.location, value) + _logger.debug('Add binary %s/%s' % (self.field_key, binary_uid)) + return { + 'binary_uid': binary_uid, + 'file_size': file_size, + } + + def update(self, binary_uid, value): + _logger.debug('Delete binary %s/%s' % (self.field_key, binary_uid)) + self.pool['ir.attachment'].\ + _file_delete(self.cr, self.uid, self.location, binary_uid) + if not value: + return {} + return self.add(value) + + def get(self, binary_uid): + return self.pool['ir.attachment'].\ + _file_read(self.cr, self.uid, self.location, binary_uid) + + +class BinaryField(fields.function): + + def __init__(self, string, filters=None, get_storage=Storage, **kwargs): + new_kwargs = { + 'type': 'binary', + 'string': string, + 'fnct': self._fnct_read, + 'fnct_inv': self._fnct_write, + 'multi': False, + } + new_kwargs.update(kwargs) + self.filters = filters + self.get_storage = get_storage + super(BinaryField, self).__init__(**new_kwargs) + + #No postprocess are needed + #we already take care of bin_size option in the context + def postprocess(self, cr, uid, obj, field, value=None, context=None): + return value + + def _prepare_binary_meta(self, cr, uid, field_name, res, context=None): + return { + '%s_uid' % field_name: res.get('binary_uid'), + '%s_file_size' % field_name: res.get('file_size'), + } + + def _fnct_write(self, obj, cr, uid, ids, field_name, value, args, + context=None): + if not isinstance(ids, (list, tuple)): + ids = [ids] + for record in obj.browse(cr, uid, ids, context=context): + storage = self.get_storage(cr, uid, record, field_name) + binary_uid = record['%s_uid' % field_name] + if binary_uid: + res = storage.update(binary_uid, value) + else: + res = storage.add(value) + vals = self._prepare_binary_meta(cr, uid, field_name, res, context=context) + record.write(vals) + return True + + def _fnct_read(self, obj, cr, uid, ids, field_name, args, context=None): + result = {} + for record in obj.browse(cr, uid, ids, context=context): + storage = self.get_storage(cr, uid, record, field_name) + binary_uid = record['%s_uid' % field_name] + if binary_uid: + #Compatibility with existing binary field + if context.get('bin_size_%s' % field_name, context.get('bin_size')): + size = record['%s_file_size' % field_name] + result[record.id] = tools.human_size(long(size)) + else: + result[record.id] = storage.get(binary_uid) + else: + result[record.id] = None + return result + + +class ImageField(BinaryField): + + def __init__(self, string, filters=None, **kwargs): + self.filters = filters + super(ImageField, self).__init__( + string=string, + **kwargs) + + def _fnct_write(self, obj, cr, uid, ids, field_name, value, args, + context=None): + super(ImageField, self)._fnct_write( + obj, cr, uid, ids, field_name, value, args, context=context) + for name, field in obj._columns.items(): + if isinstance(field, ImageResizeField) \ + and field.related_field == field_name: + field._refresh_cache( + obj, cr, uid, ids, name, context=context) + return True + + +class ImageResizeField(ImageField): + + def __init__(self, string, related_field, height, width, + filters=None, **kwargs): + self.filters = filters + self.height = height + self.width = width + self.related_field = related_field + super(ImageResizeField, self).__init__( + string=string, + **kwargs) + + def _refresh_cache(self, obj, cr, uid, ids, field_name, context=None): + if not isinstance(ids, (list, tuple)): + ids = [ids] + for record_id in ids: + _logger.debug('Refreshing Image Cache from the field %s of object %s ' + 'id : %s' % (field_name, obj._name, record_id)) + field = obj._columns[field_name] + record = obj.browse(cr, uid, record_id, context=context) + original_image = record[field.related_field] + if original_image: + size = (field.height, field.width) + resized_image = image_resize_image(original_image, size) + else: + resized_image = None + ctx = context.copy() + ctx['refresh_image_cache'] = True + self._fnct_write(obj, cr, uid, [record_id], field_name, + resized_image, None, context=ctx) + + def _fnct_write(self, obj, cr, uid, ids, field_name, value, args, + context=None): + if context is not None and context.get('refresh_image_cache'): + field = field_name + else: + field = obj._columns[field_name].related_field + return super(ImageResizeField, self)._fnct_write( + obj, cr, uid, ids, field, value, args, context=context) + + +fields.BinaryField = BinaryField +fields.ImageField = ImageField +fields.ImageResizeField = ImageResizeField + + +original__init__ = orm.BaseModel.__init__ + + +def __init__(self, pool, cr): + original__init__(self, pool, cr) + if self.pool.get('binary.field.installed'): + additionnal_field = {} + for field in self._columns: + if isinstance(self._columns[field], BinaryField): + additionnal_field.update({ + '%s_uid' % field: + fields.char('%s UID' % self._columns[field].string), + '%s_file_size' % field: + fields.char('%s File Size' % self._columns[field].string), + }) + + #Inject the store invalidation function for ImageResize + if isinstance(self._columns[field], ImageResizeField): + self._columns[field].store = { + self._name: ( + lambda self, cr, uid, ids, c={}: ids, + [self._columns[field].related_field], + 10), + } + self._columns.update(additionnal_field) + + +orm.BaseModel.__init__ = __init__ + + +class IrAttachment(orm.Model): + _inherit = 'ir.attachment' + + def _full_path(self, cr, uid, location, path): + # Hack for passing the field_key in the full path + # For now I prefer to use this hack and to reuse + # the ir.attachment code + # An alternative way will to copy/paste and + # adapt the ir.attachment code + if isinstance(location, tuple): + base_location, field_key = location + path = os.path.join(field_key, path) + else: + base_location = location + return super(IrAttachment, self).\ + _full_path(cr, uid, base_location, path) + + +class BinaryFieldInstalled(orm.AbstractModel): + _name = 'binary.field.installed' === added directory 'binary_field_example' === added file 'binary_field_example/__init__.py' --- binary_field_example/__init__.py 1970-01-01 00:00:00 +0000 +++ binary_field_example/__init__.py 2014-06-06 09:01:45 +0000 @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Module for OpenERP +# Copyright (C) 2013 Akretion (http://www.akretion.com). +# @author Sébastien BEAU <sebastien.b...@akretion.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################### + +from . import res_company + === added file 'binary_field_example/__openerp__.py' --- binary_field_example/__openerp__.py 1970-01-01 00:00:00 +0000 +++ binary_field_example/__openerp__.py 2014-06-06 09:01:45 +0000 @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Module for OpenERP +# Copyright (C) 2013 Akretion (http://www.akretion.com). +# @author Sébastien BEAU <sebastien.b...@akretion.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################### + +{'name': 'binary field example', + 'version': '0.0.1', + 'author': 'Akretion', + 'website': 'www.akretion.com', + 'license': 'AGPL-3', + 'category': 'Generic Modules', + 'description': """Just an example + + """, + 'depends': [ + 'binary_field', + ], + 'data': [ + 'res_company_view.xml', + ], + 'installable': True, + 'application': True, +} + + + + === added file 'binary_field_example/res_company.py' --- binary_field_example/res_company.py 1970-01-01 00:00:00 +0000 +++ binary_field_example/res_company.py 2014-06-06 09:01:45 +0000 @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Module for OpenERP +# Copyright (C) 2013 Akretion (http://www.akretion.com). +# @author Sébastien BEAU <sebastien.b...@akretion.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################### + +from openerp.osv import fields, orm + + +class ResCompany(orm.Model): + _inherit = 'res.company' + + _columns = { + 'binary_test': fields.BinaryField('Test Binary'), + 'image_test': fields.ImageField('Test Image'), + 'image_test_resize': fields.ImageResizeField( + related_field='image_test', + string='Test Image small', + height=64, + width=64, + ), + } === added file 'binary_field_example/res_company_view.xml' --- binary_field_example/res_company_view.xml 1970-01-01 00:00:00 +0000 +++ binary_field_example/res_company_view.xml 2014-06-06 09:01:45 +0000 @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<openerp> + <data> + + <record id="view_res_company_form" model="ir.ui.view"> + <field name="model">res.company</field> + <field name="inherit_id" ref="base.view_company_form"/> + <field name="arch" type="xml"> + <field name="parent_id" position="after"> + <field name="binary_test"/> + <field name="image_test" widget='image'/> + <field name="image_test_resize" widget='image'/> + </field> + </field> + </record> + + </data> +</openerp>
-- Mailing list: https://launchpad.net/~openerp-community-reviewer Post to : openerp-community-reviewer@lists.launchpad.net Unsubscribe : https://launchpad.net/~openerp-community-reviewer More help : https://help.launchpad.net/ListHelp