attachment.py 3.68 KB
Newer Older
François C. committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
# coding: utf-8
# @ 2015 Florian DA COSTA @ Akretion
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from openerp import models, fields, api, _
from openerp.exceptions import Warning as UserError
import openerp
import hashlib
from base64 import b64decode
import logging

_logger = logging.getLogger(__name__)


class IrAttachmentMetadata(models.Model):
    _name = 'ir.attachment.metadata'
    _inherits = {'ir.attachment': 'attachment_id'}
    _inherit = ['mail.thread']

    internal_hash = fields.Char(
        store=True, compute='_compute_hash',
        help="File hash computed with file data to be compared "
             "to external hash when provided.")
    external_hash = fields.Char(
        help="File hash comes from the external owner of the file.\n"
             "If provided allow to check than downloaded file "
             "is the exact copy of the original file.")
    attachment_id = fields.Many2one(
        'ir.attachment', required=True, ondelete='cascade',
        help="Link to ir.attachment model ")
    file_type = fields.Selection(
        selection=[],
        string="File type",
        help="The file type determines an import method to be used "
        "to parse and transform data before their import in ERP or an export")
    sync_date = fields.Datetime()
    state = fields.Selection([
        ('pending', 'Pending'),
        ('failed', 'Failed'),
        ('done', 'Done'),
        ], readonly=False, required=True, default='pending')
    state_message = fields.Text()

    @api.depends('datas', 'external_hash')
    def _compute_hash(self):
        for attachment in self:
            if attachment.datas:
                attachment.internal_hash = hashlib.md5(
                    b64decode(attachment.datas)).hexdigest()
            if attachment.external_hash and\
               attachment.internal_hash != attachment.external_hash:
                raise UserError(
                    _("File corrupted: Something was wrong with "
                      "the retrieved file, please relaunch the task."))

    @api.model
    def run_attachment_metadata_scheduler(self, domain=None):
        if domain is None:
            domain = []
        domain.append(('state', '=', 'pending'))
        attachments = self.search(domain)
        if attachments:
            return attachments.run()
        return True

    @api.multi
    def run(self):
        """
        Run the process for each attachment metadata
        """
        for attachment in self:
            with api.Environment.manage():
                with openerp.registry(self.env.cr.dbname).cursor() as new_cr:
                    new_env = api.Environment(
                        new_cr, self.env.uid, self.env.context)
                    attach = attachment.with_env(new_env)
                    try:
                        attach._run()
                    except Exception, e:
                        attach.env.cr.rollback()
                        _logger.exception(e)
                        attach.write(
                            {
                                'state': 'failed',
                                'state_message': e,
                            })
                        attach.env.cr.commit()
                    else:
                        attach.write({'state': 'done'})
                        attach.env.cr.commit()
        return True

    @api.multi
    def _run(self):
        self.ensure_one()
        _logger.info('Start to process attachment metadata id %s' % self.id)

    @api.multi
    def set_done(self):
        """
        Manually set to done
        """
        message = "Manually set to done by %s" % self.env.user.name
        self.write({'state_message': message, 'state': 'done'})