Skip to content
Open
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
13 changes: 12 additions & 1 deletion fs_attachment/models/ir_attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,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 @@ -485,7 +486,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)
Comment thread
lmignon marked this conversation as resolved.

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
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 @@ -431,6 +431,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
Loading