[ADD] deduplication of website images being uploaded

There is a deduplication in ir.attachment, but it's only for FS-stored content
*and* it only deduplicates storage not models (as there are access rights
issues involved).
  
The goal here is to always return the same attachment when a user uploads the
exact same image multiple times (because it's simpler or whatever).
  
Initially tried to use a binary field & digest(), but search() blows up
because it tries to utf-8 encode raw binary data. So use char & hexdigest
instead.
  
_compute_checksum returns None if the provided attachment data does not look
like a website image attachment.
  
Unhandled: multiple existing matches, maybe a UNIQUE constraint on the
checksum field would be a good idea just in case.

cherrypicked from saas-3's xmo@openerp.com-20140303153855-5f2l8v0jq2mgb26f
which had to be backed out (as the patch adds a new stored field)

bzr revid: xmo@openerp.com-20140304133117-r88p9zl2tc9tsh75
This commit is contained in:
Xavier Morel 2014-03-04 14:31:17 +01:00
parent 4641a23d14
commit 8ab5f3979b
1 changed files with 28 additions and 0 deletions

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import hashlib
import inspect
import itertools
import logging
@ -562,10 +563,37 @@ class ir_attachment(osv.osv):
'max_height': 768,
})
return result
def _datas_checksum(self, cr, uid, ids, name, arg, context=None):
return dict(
(attach['id'], self._compute_checksum(attach))
for attach in self.read(
cr, uid, ids, ['res_model', 'res_id', 'type', 'datas'],
context=context)
)
def _compute_checksum(self, attachment_dict):
if attachment_dict.get('res_model') == 'ir.ui.view'\
and not attachment_dict.get('res_id')\
and attachment_dict.get('type', 'binary') == 'binary'\
and attachment_dict.get('datas'):
return hashlib.new('sha1', attachment_dict['datas']).hexdigest()
return None
_columns = {
'datas_checksum': fields.function(_datas_checksum, size=40,
string="Datas checksum", type='char', store=True, select=True),
'website_url': fields.function(_website_url_get, string="Attachment URL", type='char')
}
def create(self, cr, uid, values, context=None):
chk = self._compute_checksum(values)
if chk:
match = self.search(cr, uid, [('datas_checksum', '=', chk)], context=context)
if match:
return match[0]
return super(ir_attachment, self).create(
cr, uid, values, context=context)
class res_partner(osv.osv):
_inherit = "res.partner"