forked from OCA/server-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hooks.py
135 lines (115 loc) · 4.32 KB
/
hooks.py
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# © 2016 Antiun Ingeniería S.L. - Jairo Llopis
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo import SUPERUSER_ID, api
_logger = logging.getLogger(__name__)
def post_init_hook_for_submodules(cr, model, field):
"""Moves images from single to multi mode.
Feel free to use this as a ``post_init_hook`` for submodules.
:param odoo.sql_db.Cursor cr:
Database cursor.
:param str model:
Model name, like ``product.template``.
:param str field:
Binary field that had the images in that :param:`model`, like
``image``.
"""
env = api.Environment(cr, SUPERUSER_ID, {})
table = env[model]._table
image_obj = env["base_multi_image.image"]
with cr.savepoint():
column_exists = table_has_column(cr, table, field)
if column_exists:
cr.execute(
"SELECT id FROM %(table)s WHERE %(field)s IS NOT NULL"
) # pylint: disable=sql-injection
else:
cr.execute(
"""
SELECT res_id
FROM ir_attachment
WHERE
res_field=%(field)s
AND res_model=%(model)s
""",
{
"field": field,
"model": model,
},
)
record_ids = [row[0] for row in cr.fetchall()]
for record in env[model].browse(record_ids):
image_obj.create(
{
"owner_id": record.id,
"owner_model": model,
"owner_ref_id": "%s,%s" % (model, record.id),
"image_1920": record[field],
},
)
def uninstall_hook_for_submodules(cr, model, field=None):
"""Moves images from multi to single mode and remove multi-images for a
given model.
:param odoo.sql_db.Cursor cr:
Database cursor.
:param odoo.modules.registry.RegistryManager registry:
Database registry, using v7 api.
:param str model:
Model technical name, like "res.partner". All multi-images for that
model will be deleted
:param str field:
Binary field that had the images in that :param:`model`, like
``image``.
"""
env = api.Environment(cr, SUPERUSER_ID, {})
with cr.savepoint():
image_obj = env["base_multi_image.image"]
images = image_obj.search([("owner_model", "=", model)], order="sequence, id")
if images and field:
main_images = {}
for image in images:
if image.owner_id not in main_images:
main_images[image.owner_id] = image
main_images = main_images.values()
model_obj = env[model]
field_field = model_obj._fields[field]
# fields.Binary(), save the binary content directly to the table
if not field_field.attachment:
save_directly_to_table(
cr,
model_obj,
field,
field_field,
main_images,
)
# fields.Binary(attachment=True), save the ir_attachment record ID
if field and field_field.attachment:
for main_image in main_images:
owner = model_obj.browse(main_image.owner_id)
field_field.write(owner, main_image.image_1920)
images.unlink()
def save_directly_to_table(cr, Model, field, Field, main_images):
fields = []
if field and not Field.attachment:
fields.append(field + " = " + "%(image)s")
query = """
UPDATE %(table)s
SET %(fields)s
WHERE id = %%(id)s
""" % {
"table": Model._table,
"fields": ", ".join(fields),
}
for main_image in main_images:
params = {"id": main_image.owner_id}
if field and not Field.attachment:
params["image"] = main_image.image_1920
cr.execute(query, params) # pylint: disable=sql-injection
def table_has_column(cr, table, field):
query = """
SELECT %(field)s
FROM information_schema.columns
WHERE table_name=%(table)s and column_name=%(field)s;
"""
cr.execute(query, {"table": table, "field": field})
return bool(cr.fetchall())