Skip to content

Commit 067ff4f

Browse files
committed
Merge PR #414 into 17.0
Signed-off-by lmignon
2 parents ccba0e6 + 705250d commit 067ff4f

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed

fs_attachment/models/ir_binary.py

+18-9
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,14 @@
1616
class IrBinary(models.AbstractModel):
1717
_inherit = "ir.binary"
1818

19-
def _record_to_stream(self, record, field_name):
20-
# Extend base implementation to support attachment stored into a
21-
# filesystem storage
22-
fs_attachment = None
19+
def _get_fs_attachment_for_field(self, record, field_name):
2320
if record._name == "ir.attachment" and record.fs_filename:
24-
fs_attachment = record
21+
return record
22+
2523
record.check_field_access_rights("read", [field_name])
2624
field_def = record._fields[field_name]
27-
if field_def.attachment and not field_def.compute and not field_def.related:
28-
field_attachment = (
25+
if field_def.attachment and field_def.store:
26+
fs_attachment = (
2927
self.env["ir.attachment"]
3028
.sudo()
3129
.search(
@@ -37,8 +35,14 @@ def _record_to_stream(self, record, field_name):
3735
limit=1,
3836
)
3937
)
40-
if field_attachment.fs_filename:
41-
fs_attachment = field_attachment
38+
if fs_attachment and fs_attachment.fs_filename:
39+
return fs_attachment
40+
return None
41+
42+
def _record_to_stream(self, record, field_name):
43+
# Extend base implementation to support attachment stored into a
44+
# filesystem storage
45+
fs_attachment = self._get_fs_attachment_for_field(record, field_name)
4246
if fs_attachment:
4347
return FsStream.from_fs_attachment(fs_attachment)
4448
return super()._record_to_stream(record, field_name)
@@ -100,6 +104,11 @@ def _get_image_stream_from(
100104
if value:
101105
record = value.attachment
102106
field_name = "raw"
107+
elif field_def.type in ("binary"):
108+
fs_attachment = self._get_fs_attachment_for_field(record, field_name)
109+
if fs_attachment:
110+
record = fs_attachment
111+
field_name = "raw"
103112
stream = super()._get_image_stream_from(
104113
record,
105114
field_name=field_name,

fs_attachment/tests/test_stream.py

+29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Copyright 2023 ACSONE SA/NV (http://acsone.eu).
22
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3+
import base64
34
import io
45
import os
56
import shutil
@@ -163,3 +164,31 @@ def test_response_csp_header(self):
163164
"Content-Security-Policy": "default-src 'none'",
164165
},
165166
)
167+
168+
def test_serving_field_image(self):
169+
self.authenticate("admin", "admin")
170+
demo_partner = self.env.ref("base.partner_demo")
171+
demo_partner.with_context(
172+
storage_location=self.temp_backend.code,
173+
).write({"image_128": base64.encodebytes(self._create_image(128, 128))})
174+
url = f"/web/image/{demo_partner._name}/{demo_partner.id}/image_128"
175+
res = self.assertDownload(
176+
url,
177+
headers={},
178+
assert_status_code=200,
179+
assert_headers={
180+
"Content-Type": "image/png",
181+
},
182+
)
183+
self.assertEqual(Image.open(io.BytesIO(res.content)).size, (128, 128))
184+
185+
url = f"/web/image/{demo_partner._name}/{demo_partner.id}/avatar_128"
186+
avatar_res = self.assertDownload(
187+
url,
188+
headers={},
189+
assert_status_code=200,
190+
assert_headers={
191+
"Content-Type": "image/png",
192+
},
193+
)
194+
self.assertEqual(Image.open(io.BytesIO(avatar_res.content)).size, (128, 128))

0 commit comments

Comments
 (0)