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.

157 lines
6.1 KiB

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