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.

158 lines
6.1 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2016 Antiun Ingeniería S.L. - Jairo Llopis
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. from odoo import api, SUPERUSER_ID
  5. import logging
  6. _logger = logging.getLogger(__name__)
  7. def pre_init_hook_for_submodules(cr, model, field):
  8. """Moves images from single to multi mode.
  9. Feel free to use this as a ``pre_init_hook`` for submodules.
  10. :param str model:
  11. Model name, like ``product.template``.
  12. :param str field:
  13. Binary field that had the images in that :param:`model`, like
  14. ``image``.
  15. """
  16. env = api.Environment(cr, SUPERUSER_ID, {})
  17. with cr.savepoint():
  18. table = env[model]._table
  19. column_exists = table_has_column(cr, table, field)
  20. # fields.Binary(), extract the binary content directly from the table
  21. if column_exists:
  22. extract_query = """
  23. SELECT id, '%(model)s', '%(model)s,' || id, 'db', %(field)s
  24. FROM %(table)s
  25. WHERE %(field)s IS NOT NULL
  26. """ % {
  27. "table": table,
  28. "field": field,
  29. "model": model,
  30. }
  31. image_field = 'file_db_store'
  32. # fields.Binary(attachment=True), get the ir_attachment record ID
  33. else:
  34. extract_query = """
  35. SELECT
  36. res_id,
  37. res_model,
  38. CONCAT_WS(',', res_model, res_id),
  39. 'filestore',
  40. id
  41. FROM ir_attachment
  42. WHERE res_field='%(field)s' AND res_model='%(model)s'
  43. """ % {"model": model, "field": field}
  44. image_field = 'attachment_id'
  45. cr.execute(
  46. """
  47. INSERT INTO base_multi_image_image (
  48. owner_id,
  49. owner_model,
  50. owner_ref_id,
  51. storage,
  52. %s
  53. )
  54. %s
  55. """ % (image_field, extract_query)
  56. )
  57. def uninstall_hook_for_submodules(cr, registry, model, field=None,
  58. field_medium=None, field_small=None):
  59. """Moves images from multi to single mode and remove multi-images for a
  60. given model.
  61. :param odoo.sql_db.Cursor cr:
  62. Database cursor.
  63. :param odoo.modules.registry.RegistryManager registry:
  64. Database registry, using v7 api.
  65. :param str model:
  66. Model technical name, like "res.partner". All multi-images for that
  67. model will be deleted
  68. :param str field:
  69. Binary field that had the images in that :param:`model`, like
  70. ``image``.
  71. :param str field_medium:
  72. Binary field that had the medium-sized images in that :param:`model`,
  73. like ``image_medium``.
  74. :param str field_small:
  75. Binary field that had the small-sized images in that :param:`model`,
  76. like ``image_small``.
  77. """
  78. env = api.Environment(cr, SUPERUSER_ID, {})
  79. with cr.savepoint():
  80. Image = env["base_multi_image.image"]
  81. images = Image.search([("owner_model", "=", model)],
  82. order="sequence, id")
  83. if images and (field or field_medium or field_small):
  84. main_images = {}
  85. for image in images:
  86. if image.owner_id not in main_images:
  87. main_images[image.owner_id] = image
  88. main_images = main_images.values()
  89. Model = env[model]
  90. Field = field and Model._fields[field]
  91. FieldMedium = field_medium and Model._fields[field_medium]
  92. FieldSmall = field_small and Model._fields[field_small]
  93. # fields.Binary(), save the binary content directly to the table
  94. if field and not Field.attachment \
  95. or field_medium and not FieldMedium.attachment \
  96. or field_small and not FieldSmall.attachment:
  97. fields = []
  98. if field and not Field.attachment:
  99. fields.append(field + " = " + "%(image)s")
  100. if field_medium and not FieldMedium.attachment:
  101. fields.append(field_medium + " = " + "%(image_medium)s")
  102. if field_small and not FieldSmall.attachment:
  103. fields.append(field_small + " = " + "%(image_small)s")
  104. query = """
  105. UPDATE %(table)s
  106. SET %(fields)s
  107. WHERE id = %%(id)s
  108. """ % {
  109. "table": Model._table,
  110. "fields": ", ".join(fields),
  111. }
  112. for main_image in main_images:
  113. vars = {"id": main_image.owner_id}
  114. if field and not Field.attachment:
  115. vars["image"] = main_image.image_main
  116. if field_medium and not FieldMedium.attachment:
  117. vars["image_medium"] = main_image.image_medium
  118. if field_small and not FieldSmall.attachment:
  119. vars["image_small"] = main_image.image_small
  120. cr.execute(query, vars)
  121. # fields.Binary(attachment=True), save the ir_attachment record ID
  122. if field and Field.attachment \
  123. or field_medium and FieldMedium.attachment \
  124. or field_small and FieldSmall.attachment:
  125. for main_image in main_images:
  126. owner = Model.browse(main_image.owner_id)
  127. if field and Field.attachment:
  128. Field.write(owner, main_image.image_main)
  129. if field_medium and FieldMedium.attachment:
  130. FieldMedium.write(owner, main_image.image_medium)
  131. if field_small and FieldSmall.attachment:
  132. FieldSmall.write(owner, main_image.image_small)
  133. images.unlink()
  134. def table_has_column(cr, table, field):
  135. query = """
  136. SELECT %(field)s
  137. FROM information_schema.columns
  138. WHERE table_name=%(table)s and column_name=%(field)s;
  139. """
  140. cr.execute(query, {'table': table, 'field': field})
  141. return bool(cr.fetchall())