You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
3.8 KiB

  1. # coding: utf-8
  2. # @ 2015 Florian DA COSTA @ Akretion
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. from base64 import b64decode
  5. import hashlib
  6. import logging
  7. import odoo
  8. from odoo import _, api, fields, models
  9. from odoo.exceptions import UserError
  10. _logger = logging.getLogger(__name__)
  11. class IrAttachmentMetadata(models.Model):
  12. _name = 'ir.attachment.metadata'
  13. _inherits = {'ir.attachment': 'attachment_id'}
  14. _inherit = ['mail.thread']
  15. internal_hash = fields.Char(
  16. store=True, compute='_compute_hash',
  17. help="File hash computed with file data to be compared "
  18. "to external hash when provided.")
  19. external_hash = fields.Char(
  20. help="File hash comes from the external owner of the file.\n"
  21. "If provided allow to check than downloaded file "
  22. "is the exact copy of the original file.")
  23. attachment_id = fields.Many2one(
  24. 'ir.attachment', required=True, ondelete='cascade',
  25. help="Link to ir.attachment model ")
  26. file_type = fields.Selection(
  27. selection=[],
  28. string="File type",
  29. help="The file type determines an import method to be used "
  30. "to parse and transform data before their import in ERP or an export")
  31. sync_date = fields.Datetime()
  32. state = fields.Selection([
  33. ('pending', 'Pending'),
  34. ('failed', 'Failed'),
  35. ('done', 'Done'),
  36. ], readonly=False, required=True, default='pending')
  37. state_message = fields.Text()
  38. @api.depends('datas', 'external_hash')
  39. def _compute_hash(self):
  40. for attachment in self:
  41. if attachment.datas:
  42. attachment.internal_hash = hashlib.md5(
  43. b64decode(attachment.datas)).hexdigest()
  44. if attachment.external_hash and\
  45. attachment.internal_hash != attachment.external_hash:
  46. raise UserError(
  47. _("File corrupted: Something was wrong with "
  48. "the retrieved file, please relaunch the task."))
  49. @api.model
  50. def run_attachment_metadata_scheduler(self, domain=None):
  51. if domain is None:
  52. domain = [('state', '=', 'pending')]
  53. attachments = self.search(domain)
  54. if attachments:
  55. return attachments.run()
  56. return True
  57. @api.multi
  58. def run(self):
  59. """
  60. Run the process for each attachment metadata
  61. """
  62. for attachment in self:
  63. with api.Environment.manage():
  64. with odoo.registry(self.env.cr.dbname).cursor() as new_cr:
  65. new_env = api.Environment(
  66. new_cr, self.env.uid, self.env.context)
  67. attach = attachment.with_env(new_env)
  68. try:
  69. attach._run()
  70. except Exception, e:
  71. attach.env.cr.rollback()
  72. _logger.exception(e)
  73. attach.write(
  74. {
  75. 'state': 'failed',
  76. 'state_message': e,
  77. })
  78. attach.env.cr.commit()
  79. else:
  80. vals = {
  81. 'state': 'done',
  82. 'sync_date': fields.Datetime.now(),
  83. }
  84. attach.write(vals)
  85. attach.env.cr.commit()
  86. return True
  87. @api.multi
  88. def _run(self):
  89. self.ensure_one()
  90. _logger.info('Start to process attachment metadata id %s' % self.id)
  91. @api.multi
  92. def set_done(self):
  93. """
  94. Manually set to done
  95. """
  96. message = "Manually set to done by %s" % self.env.user.name
  97. self.write({'state_message': message, 'state': 'done'})