1
# -*- encoding: utf-8 -*-
2
#########################################################################
3
# Copyright (C) 2009 Sharoon Thomas, Open Labs Business solutions #
4
# Copyright (C) 2011 Akretion Sébastien BEAU sebastien.beau@akretion.com#
6
#This program is free software: you can redistribute it and/or modify #
7
#it under the terms of the GNU General Public License as published by #
8
#the Free Software Foundation, either version 3 of the License, or #
9
#(at your option) any later version. #
11
#This program is distributed in the hope that it will be useful, #
12
#but WITHOUT ANY WARRANTY; without even the implied warranty of #
13
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14
#GNU General Public License for more details. #
16
#You should have received a copy of the GNU General Public License #
17
#along with this program. If not, see <http://www.gnu.org/licenses/>. #
18
#########################################################################
19
from osv import osv, fields
21
from tools.translate import _
25
_logger = logging.getLogger(__name__)
27
#TODO find a good solution in order to roll back changed done on file system
28
#TODO add the posibility to move from a store system to an other (example : moving existing image on database to file system)
30
class product_images(osv.osv):
31
"Products Image gallery"
32
_name = "product.images"
33
_description = __doc__
34
_table = "product_images"
36
def unlink(self, cr, uid, ids, context=None):
37
if isinstance(ids, (int, long)):
39
for image in self.browse(cr, uid, ids, context=context):
40
full_path = self._image_path(cr, uid, image, context=context)
42
os.path.isfile(full_path) and os.remove(full_path)
43
return super(product_images, self).unlink(cr, uid, ids, context=context)
45
def create(self, cr, uid, vals, context=None):
46
if vals.get('name', False) and not vals.get('extention', False):
47
vals['name'], vals['extention'] = os.path.splitext(vals['name'])
48
return super(product_images, self).create(cr, uid, vals, context=context)
50
def write(self, cr, uid, ids, vals, context=None):
51
if not isinstance(ids, list):
53
if vals.get('name', False) and not vals.get('extention', False):
54
vals['name'], vals['extention'] = os.path.splitext(vals['name'])
56
if vals.get('name', False) or vals.get('extention', False):
57
images = self.browse(cr, uid, upd_ids, context=context)
59
old_full_path = self._image_path(cr, uid, image, context=context)
62
# all the stuff below is there to manage the files on the filesystem
63
if vals.get('name', False) and (image.name != vals['name']) \
64
or vals.get('extention', False) and (image.extention != vals['extention']):
65
super(product_images, self).write(
66
cr, uid, image.id, vals, context=context)
67
upd_ids.remove(image.id)
69
# a new image have been loaded we should remove the old image
70
# TODO it's look like there is something wrong with function
71
# field in openerp indeed the preview is always added in the write :(
72
if os.path.isfile(old_full_path):
73
os.remove(old_full_path)
75
new_image = self.browse(cr, uid, image.id, context=context)
76
new_full_path = self._image_path(cr, uid, new_image, context=context)
77
#we have to rename the image on the file system
78
if os.path.isfile(old_full_path):
79
os.rename(old_full_path, new_full_path)
80
return super(product_images, self).write(cr, uid, upd_ids, vals, context=context)
82
def _image_path(self, cr, uid, image, context=None):
84
local_media_repository = self.pool.get('res.company').\
85
get_local_media_repository(cr, uid, context=context)
86
if local_media_repository:
87
full_path = os.path.join(
88
local_media_repository,
89
image.product_id.default_code,
90
'%s%s' % (image.name or '', image.extention or ''))
93
def get_image(self, cr, uid, id, context=None):
94
image = self.browse(cr, uid, id, context=context)
96
(filename, header) = urllib.urlretrieve(image.url)
97
with open(filename , 'rb') as f:
98
img = base64.b64encode(f.read())
101
if isinstance(image.product_id.default_code, bool):
102
_logger.debug('product not completely setup, no image available')
105
full_path = self._image_path(cr, uid, image, context=context)
107
_logger.error("Can not find the path for image %s: %s", id, e, exc_info=True)
110
if os.path.exists(full_path):
112
with open(full_path, 'rb') as f:
113
img = base64.b64encode(f.read())
115
_logger.error("Can not open the image %s, error : %s", full_path, e, exc_info=True)
118
_logger.error("The image %s doesn't exist ", full_path)
121
img = image.file_db_store
124
def _get_image(self, cr, uid, ids, field_name, arg, context=None):
127
res[each] = self.get_image(cr, uid, each, context=context)
130
def _check_filestore(self, image_filestore):
131
"""check if the filestore is created, if not it create it automatically"""
133
dir_path = os.path.dirname(image_filestore)
134
if not os.path.exists(dir_path):
135
os.makedirs(dir_path)
137
raise osv.except_osv(_('Error'), _('The image filestore can not be created, %s'%e))
140
def _save_file(self, path, b64_file):
141
"""Save a file encoded in base 64"""
142
self._check_filestore(path)
143
with open(path, 'w') as ofile:
144
ofile.write(base64.b64decode(b64_file))
147
def _set_image(self, cr, uid, id, name, value, arg, context=None):
148
image = self.browse(cr, uid, id, context=context)
149
full_path = self._image_path(cr, uid, image, context=context)
151
return self._save_file(full_path, value)
152
return self.write(cr, uid, id, {'file_db_store' : value}, context=context)
155
'name':fields.char('Image Title', size=100, required=True),
156
'extention': fields.char('file extention', size=6),
157
'link':fields.boolean('Link?', help="Images can be linked from files on your file system or remote (Preferred)"),
158
'file_db_store':fields.binary('Image stored in database'),
159
'file':fields.function(_get_image, fnct_inv=_set_image, type="binary", filters='*.png,*.jpg,*.gif'),
160
'url':fields.char('File Location', size=250),
161
'comments':fields.text('Comments'),
162
'product_id':fields.many2one('product.product', 'Product')
166
'link': lambda *a: False,
169
_sql_constraints = [('uniq_name_product_id', 'UNIQUE(product_id, name)',
170
_('A product can have only one image with the same name'))]