Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Available addons
----------------
addon | version | maintainers | summary
--- | --- | --- | ---
[fs_attachment](fs_attachment/) | 16.0.3.1.0 | <a href='https://github.com/lmignon'><img src='https://github.com/lmignon.png' width='32' height='32' style='border-radius:50%;' alt='lmignon'/></a> | Store attachments on external object store
[fs_attachment](fs_attachment/) | 16.0.3.1.1 | <a href='https://github.com/lmignon'><img src='https://github.com/lmignon.png' width='32' height='32' style='border-radius:50%;' alt='lmignon'/></a> | Store attachments on external object store
[fs_attachment_environment](fs_attachment_environment/) | 16.0.1.0.0 | | Allows to use server environment with fs storage attachment
[fs_attachment_s3](fs_attachment_s3/) | 16.0.3.1.0 | <a href='https://github.com/lmignon'><img src='https://github.com/lmignon.png' width='32' height='32' style='border-radius:50%;' alt='lmignon'/></a> | Store attachments into S3 complient filesystem
[fs_attachment_s3_environment](fs_attachment_s3_environment/) | 16.0.1.0.0 | | Allows to use server environment with fs storage attachment S3
Expand Down
2 changes: 1 addition & 1 deletion fs_attachment/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Base Attachment Object Store
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f04c77a3d6f06a8e26b21554b57811631c1bc9a4c42469598089be3719881db5
!! source digest: sha256:d3192a906b0bd929f34b1c3a36f851f3ce0139e8a47b4b20c28e20eb996474ae
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down
2 changes: 1 addition & 1 deletion fs_attachment/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"name": "Base Attachment Object Store",
"summary": "Store attachments on external object store",
"version": "16.0.3.1.0",
"version": "16.0.3.1.1",
"author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)",
"license": "AGPL-3",
"development_status": "Beta",
Expand Down
13 changes: 12 additions & 1 deletion fs_attachment/models/ir_attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ def _enforce_meaningful_storage_filename(self) -> None:
Keeping the same meaning and mimetype is important to also ease to provide
a meaningful and SEO friendly URL to the file in the filesystem storage.
"""
renamed_attachments = {}
for attachment in self:
if not self._is_file_from_a_storage(attachment.store_fname):
continue
Expand All @@ -491,7 +492,17 @@ def _enforce_meaningful_storage_filename(self) -> None:
new_filename_with_path = os.path.join(
os.path.dirname(filename), new_filename
)
fs.rename(filename, new_filename_with_path)

if filename in renamed_attachments:
if renamed_attachments[filename] == new_filename_with_path:
# we already renamed this file, no need to rename it again
continue
else:
fs.copy(renamed_attachments[filename], new_filename_with_path)
else:
fs.rename(filename, new_filename_with_path)
renamed_attachments[filename] = new_filename_with_path

attachment.fs_filename = new_filename
# we need to update the store_fname with the new filename by
# calling the write method of the field since the write method
Expand Down
2 changes: 1 addition & 1 deletion fs_attachment/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ <h1>Base Attachment Object Store</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f04c77a3d6f06a8e26b21554b57811631c1bc9a4c42469598089be3719881db5
!! source digest: sha256:d3192a906b0bd929f34b1c3a36f851f3ce0139e8a47b4b20c28e20eb996474ae
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/storage/tree/16.0/fs_attachment"><img alt="OCA/storage" src="https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/storage-16-0/storage-16-0-fs_attachment"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/storage&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>In some cases, you need to store attachment in another system that the Odoo’s
Expand Down
50 changes: 50 additions & 0 deletions fs_attachment/tests/test_fs_attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,56 @@ def test_create_attachments_basic_user(self):
}
)

def test_create_two_attachments(self):
self.temp_backend.use_as_default_for_attachments = True
res = self.ir_attachment_model.create(
[
{"name": "test2.txt", "raw": b"content"},
{"name": "test.txt", "raw": b"content"},
]
)
self.assertEqual(len(res), 2)

def test_create_two_attachments_same_name(self):
self.temp_backend.use_as_default_for_attachments = True
res = self.ir_attachment_model.create(
[
{"name": "test.txt", "raw": b"content"},
{"name": "test.txt", "raw": b"content"},
]
)
self.assertEqual(len(res), 2)
attachment1 = res[0]
attachment2 = res[1]
self.assertEqual(attachment1.name, "test.txt")
self.assertEqual(attachment2.name, "test.txt")
self.assertNotEqual(attachment1.store_fname, attachment2.store_fname)
self.assertEqual(attachment1.raw, attachment2.raw)

attachment1.raw = b"new content"
self.assertNotEqual(attachment1.raw, attachment2.raw)

attachment2 = self.ir_attachment_model.browse(attachment2.id)
self.assertEqual(attachment2.raw, b"content")

def test_create_two_attachments_differnt_call(self):
self.temp_backend.use_as_default_for_attachments = True
res = self.ir_attachment_model.create(
[
{"name": "test.txt", "raw": b"content"},
]
)
res2 = self.ir_attachment_model.create(
[
{"name": "test.txt", "raw": b"content"},
]
)
self.assertEqual(len(res), 1)
self.assertEqual(len(res2), 1)

self.assertNotEqual(res[0].store_fname, res2[0].store_fname)
self.assertEqual(res[0].raw, res2[0].raw)

def test_update_png_to_svg(self):
b64_data_png = (
b"iVBORw0KGgoAAAANSUhEUgAAADMAAAAhCAIAAAD73QTtAAAAA3NCSVQICAjb4U/gAA"
Expand Down