~openerp-commiter/openobject-addons/trunk-extra-addons

« back to all changes in this revision

Viewing changes to product_images_olbs/product_images.py

  • Committer: Cubic ERP
  • Date: 2012-11-28 00:54:54 UTC
  • mfrom: (5823.1.19 openobject-addons)
  • Revision ID: info@cubicerp.com-20121128005454-bbtsmufafj4hwady
[UPG]

Show diffs side-by-side

added added

removed removed

Lines of Context:
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#
5
 
#                                                                       #
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.                                    #
10
 
#                                                                       #
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.                           #
15
 
#                                                                       #
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
20
 
import base64, urllib
21
 
from tools.translate import _
22
 
import os
23
 
 
24
 
import logging
25
 
_logger = logging.getLogger(__name__)
26
 
 
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)
29
 
 
30
 
class product_images(osv.osv):
31
 
    "Products Image gallery"
32
 
    _name = "product.images"
33
 
    _description = __doc__
34
 
    _table = "product_images"
35
 
 
36
 
    def unlink(self, cr, uid, ids, context=None):
37
 
        if isinstance(ids, (int, long)):
38
 
            ids = [ids]
39
 
        for image in self.browse(cr, uid, ids, context=context):
40
 
            full_path = self._image_path(cr, uid, image, context=context)
41
 
            if full_path:
42
 
                os.path.isfile(full_path) and os.remove(full_path)
43
 
        return super(product_images, self).unlink(cr, uid, ids, context=context)
44
 
 
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)
49
 
 
50
 
    def write(self, cr, uid, ids, vals, context=None):
51
 
        if not isinstance(ids, list):
52
 
            ids = [ids]
53
 
        if vals.get('name', False) and not vals.get('extention', False):
54
 
            vals['name'], vals['extention'] = os.path.splitext(vals['name'])
55
 
        upd_ids = ids[:]
56
 
        if vals.get('name', False) or vals.get('extention', False):
57
 
            images = self.browse(cr, uid, upd_ids, context=context)
58
 
            for image in images:
59
 
                old_full_path = self._image_path(cr, uid, image, context=context)
60
 
                if not old_full_path:
61
 
                    continue
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)
68
 
                    if 'file' in vals:
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)
74
 
                    else:
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)
81
 
 
82
 
    def _image_path(self, cr, uid, image, context=None):
83
 
        full_path = False
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 ''))
91
 
        return full_path
92
 
 
93
 
    def get_image(self, cr, uid, id, context=None):
94
 
        image = self.browse(cr, uid, id, context=context)
95
 
        if image.link:
96
 
            (filename, header) = urllib.urlretrieve(image.url)
97
 
            with open(filename , 'rb') as f:
98
 
                img = base64.b64encode(f.read())
99
 
        else:
100
 
            try:
101
 
                if isinstance(image.product_id.default_code, bool):
102
 
                    _logger.debug('product not completely setup, no image available')
103
 
                    full_path = False
104
 
                else:
105
 
                    full_path = self._image_path(cr, uid, image, context=context)
106
 
            except Exception, e:
107
 
                _logger.error("Can not find the path for image %s: %s", id, e, exc_info=True)
108
 
                return False
109
 
            if full_path:
110
 
                if os.path.exists(full_path):
111
 
                    try:
112
 
                        with open(full_path, 'rb') as f:
113
 
                            img = base64.b64encode(f.read())
114
 
                    except Exception, e:
115
 
                        _logger.error("Can not open the image %s, error : %s", full_path, e, exc_info=True)
116
 
                        return False
117
 
                else:
118
 
                    _logger.error("The image %s doesn't exist ", full_path)
119
 
                    return False
120
 
            else:
121
 
                img = image.file_db_store
122
 
        return img
123
 
 
124
 
    def _get_image(self, cr, uid, ids, field_name, arg, context=None):
125
 
        res = {}
126
 
        for each in ids:
127
 
            res[each] = self.get_image(cr, uid, each, context=context)
128
 
        return res
129
 
 
130
 
    def _check_filestore(self, image_filestore):
131
 
        """check if the filestore is created, if not it create it automatically"""
132
 
        try:
133
 
            dir_path = os.path.dirname(image_filestore)
134
 
            if not os.path.exists(dir_path):
135
 
                os.makedirs(dir_path)
136
 
        except OSError, e:
137
 
            raise osv.except_osv(_('Error'), _('The image filestore can not be created, %s'%e))
138
 
        return True
139
 
 
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))
145
 
        return True
146
 
 
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)
150
 
        if full_path:
151
 
            return self._save_file(full_path, value)
152
 
        return self.write(cr, uid, id, {'file_db_store' : value}, context=context)
153
 
 
154
 
    _columns = {
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')
163
 
    }
164
 
 
165
 
    _defaults = {
166
 
        'link': lambda *a: False,
167
 
    }
168
 
 
169
 
    _sql_constraints = [('uniq_name_product_id', 'UNIQUE(product_id, name)',
170
 
                _('A product can have only one image with the same name'))]
171
 
 
172
 
product_images()