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 @@ -29,7 +29,7 @@ addon | version | maintainers | summary
[fs_folder_ms_drive](fs_folder_ms_drive/) | 18.0.2.0.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> | Display and manage your files from Microsoft drives from within Odoo
[fs_folder_webdav](fs_folder_webdav/) | 18.0.1.0.0 | <a href='https://github.com/jguenat'><img src='https://github.com/jguenat.png' width='32' height='32' style='border-radius:50%;' alt='jguenat'/></a> | UI improvement when managing WebDAV folder
[fs_image](fs_image/) | 18.0.1.0.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> | Field to store images into filesystem storages
[fs_storage](fs_storage/) | 18.0.2.1.1 | | Implement the concept of Storage with amazon S3, sftp...
[fs_storage](fs_storage/) | 18.0.2.1.2 | | Implement the concept of Storage with amazon S3, sftp...
[fs_storage_ms_drive](fs_storage_ms_drive/) | 18.0.2.0.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> | Add the microsoft drives (OneDrive, Sharepoint) as a storage backend
[image_tag](image_tag/) | 18.0.1.0.0 | | Image tag model
[microsoft_drive_account](microsoft_drive_account/) | 18.0.2.0.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> | Link user with Microsoft
Expand Down
12 changes: 6 additions & 6 deletions fs_file/tests/test_fs_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def setUpClass(cls):
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.loader = FakeModelLoader(cls.env, cls.__module__)
cls.loader.backup_registry()
cls.addClassCleanup(cls.loader.restore_registry)
from .models import TestModel

cls.loader.update_registry((TestModel,))
Expand All @@ -38,13 +39,13 @@ def setUpClass(cls):
f.seek(0)
cls.png_content = f

def check_attrs(self):
# Deactivate check_attrs to avoid conflict with FakeModelLoader.
# since superClass uses it for its own puposes not relevant for our tests.
pass

def setUp(self):
super().setUp()
# Remove check_attrs cleanup if exists to avoid conflict with FakeModelLoader.
# since superClass uses it for its own puposes not relevant for our tests.
check_attrs = (getattr(self, "check_attrs", None), tuple(), {})
if check_attrs in self._cleanups:
self._cleanups.remove(check_attrs)
self.temp_dir: FSStorage = self.env["fs.storage"].create(
{
"name": "Temp FS Storage",
Expand All @@ -59,7 +60,6 @@ def setUp(self):
def tearDownClass(cls):
if os.path.exists(cls.tmpfile_path):
os.remove(cls.tmpfile_path)
cls.loader.restore_registry()
return super().tearDownClass()

def _test_create(self, fs_file_value):
Expand Down
10 changes: 5 additions & 5 deletions fs_folder/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ def setUpClass(cls):
def cleanup_tempdir():
shutil.rmtree(cls.temp_dir)

def check_attrs(self):
# Deactivate check_attrs to avoid conflict with FakeModelLoader.
# since superClass uses it for its own puposes not relevant for our tests.
pass

def setUp(self):
super().setUp()
# Remove check_attrs cleanup if exists to avoid conflict with FakeModelLoader.
# since superClass uses it for its own puposes not relevant for our tests.
check_attrs = (getattr(self, "check_attrs", None), tuple(), {})
if check_attrs in self._cleanups:
self._cleanups.remove(check_attrs)
# enforce temp_backend field since it seems that they are reset on
# savepoint rollback when managed by server_environment -> TO Be investigated
self.temp_backend.write(
Expand Down
12 changes: 6 additions & 6 deletions fs_image/tests/test_fs_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def setUpClass(cls):
)
cls.loader = FakeModelLoader(cls.env, cls.__module__)
cls.loader.backup_registry()
cls.addClassCleanup(cls.loader.restore_registry)
from .models import TestImageModel, TestRelatedImageModel

cls.loader.update_registry((TestImageModel, TestRelatedImageModel))
Expand All @@ -40,13 +41,13 @@ def setUpClass(cls):
f.write(cls.create_content)
cls.filename = os.path.basename(cls.tmpfile_path)

def check_attrs(self):
# Deactivate check_attrs to avoid conflict with FakeModelLoader.
# since superClass uses it for its own puposes not relevant for our tests.
pass

def setUp(self):
super().setUp()
# Remove check_attrs cleanup if exists to avoid conflict with FakeModelLoader.
# since superClass uses it for its own puposes not relevant for our tests.
check_attrs = (getattr(self, "check_attrs", None), tuple(), {})
if check_attrs in self._cleanups:
self._cleanups.remove(check_attrs)
self.temp_dir: FSStorage = self.env["fs.storage"].create(
{
"name": "Temp FS Storage",
Expand All @@ -61,7 +62,6 @@ def setUp(self):
def tearDownClass(cls):
if os.path.exists(cls.tmpfile_path):
os.remove(cls.tmpfile_path)
cls.loader.restore_registry()
return super().tearDownClass()

@classmethod
Expand Down
2 changes: 1 addition & 1 deletion fs_storage/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Filesystem Storage Backend
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:56e35c5816f37443d3bfb1ac7d6ebd4451e7b8c6e3d7c94a0f176f2b7d38b520
!! source digest: sha256:b12a9e0e041121ef9301a2e54de2547c3a8a49408067c074b4fdfea8e5d0d74c
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down
2 changes: 1 addition & 1 deletion fs_storage/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"name": "Filesystem Storage Backend",
"summary": "Implement the concept of Storage with amazon S3, sftp...",
"version": "18.0.2.1.1",
"version": "18.0.2.1.2",
"category": "FS Storage",
"website": "https://github.com/OCA/storage",
"author": " ACSONE SA/NV, Odoo Community Association (OCA)",
Expand Down
16 changes: 12 additions & 4 deletions fs_storage/i18n/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ msgstr "Opciones disponibles"
msgid "Available properties"
msgstr "Propiedades disponibles"

#. module: fs_storage
#. odoo-python
#: code:addons/fs_storage/models/fs_storage.py:0
msgid "Calling fs.storage.%(reason)s is not allowed in a safe_eval context."
msgstr ""

#. module: fs_storage
#: model:ir.model.fields,field_description:fs_storage.field_fs_storage__check_connection_method
#: model:ir.model.fields,field_description:fs_storage.field_fs_test_connection__check_connection_method
Expand Down Expand Up @@ -368,14 +374,16 @@ msgstr ""
msgid ""
"Technical code used to identify the storage backend into the code.This code "
"must be unique. This code is used for example to define the storage backend "
"to store the attachments via the configuration parameter 'ir_attachment."
"storage.force.database' when the module 'fs_attachment' is installed."
"to store the attachments via the configuration parameter "
"'ir_attachment.storage.force.database' when the module 'fs_attachment' is "
"installed."
msgstr ""
"Código técnico utilizado para identificar el servidor de almacenamiento en "
"el código. Este código debe ser único. Este código se utiliza, por ejemplo, "
"para definir el servidor de almacenamiento para guardar los archivos "
"adjuntos mediante el parámetro de configuración \"ir_attachment.storage."
"force.database\" cuando se instala el módulo \"fs_attachment\"."
"adjuntos mediante el parámetro de configuración "
"\"ir_attachment.storage.force.database\" cuando se instala el módulo "
"\"fs_attachment\"."

#. module: fs_storage
#: model_terms:ir.ui.view,arch_db:fs_storage.fs_test_connection_form_view
Expand Down
33 changes: 24 additions & 9 deletions fs_storage/i18n/fr.po
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ msgstr "Options disponibles"
msgid "Available properties"
msgstr "Propriétés disponibles"

#. module: fs_storage
#. odoo-python
#: code:addons/fs_storage/models/fs_storage.py:0
msgid "Calling fs.storage.%(reason)s is not allowed in a safe_eval context."
msgstr ""

#. module: fs_storage
#: model:ir.model.fields,field_description:fs_storage.field_fs_storage__check_connection_method
#: model:ir.model.fields,field_description:fs_storage.field_fs_test_connection__check_connection_method
Expand Down Expand Up @@ -166,8 +172,11 @@ msgstr ""
#: model:ir.model.fields,help:fs_storage.field_fs_storage__is_cacheable
msgid ""
"If True, once instantiated, the filesystem will be cached and reused.\n"
"By default, the filesystem is cacheable but in some cases, like when using OAuth2 authentication, the filesystem cannot be cached because it depends on the user and the token can change.\n"
"In this case, you can set this field to False to avoid caching the filesystem."
"By default, the filesystem is cacheable but in some cases, like when using "
"OAuth2 authentication, the filesystem cannot be cached because it depends on "
"the user and the token can change.\n"
"In this case, you can set this field to False to avoid caching the "
"filesystem."
msgstr ""

#. module: fs_storage
Expand Down Expand Up @@ -346,7 +355,9 @@ msgstr "Serveur par défaut de l’environnement"
#: model:ir.model.fields,help:fs_storage.field_fs_storage__check_connection_method
#: model:ir.model.fields,help:fs_storage.field_fs_storage__x_check_connection_method_env_default
msgid ""
"Set a method if you want the connection to remote to be checked every time the storage is used, in order to remove the obsolete connection from the cache.\n"
"Set a method if you want the connection to remote to be checked every time "
"the storage is used, in order to remove the obsolete connection from the "
"cache.\n"
"* Create Marker file : Create a file on remote and check it exists\n"
"* List File : List all files from root directory"
msgstr ""
Expand Down Expand Up @@ -376,9 +387,9 @@ msgid ""
msgstr ""
"Code technique utilisé pour identifier le stockage dans le code. Le code "
"doit être unique. Le code est entre autre utilisé pour définir le stockage à "
"utiliser pour stocker les pièces jointes via le paramètre de configuration «"
" ir_attachment.storage.force.database » lorsque le module fs_attachhment est "
"installé."
"utiliser pour stocker les pièces jointes via le paramètre de configuration "
"« ir_attachment.storage.force.database » lorsque le module fs_attachhment "
"est installé."

#. module: fs_storage
#: model_terms:ir.ui.view,arch_db:fs_storage.fs_test_connection_form_view
Expand Down Expand Up @@ -423,7 +434,8 @@ msgid ""
" }\n"
"}\n"
"For more information, please refer to the fsspec documentation:\n"
"https://filesystem-spec.readthedocs.io/en/latest/api.html#built-in-implementations"
"https://filesystem-spec.readthedocs.io/en/latest/api.html#built-in-"
"implementations"
msgstr ""
"Les options pour initialiser le système de fichier.\n"
"C’est un champ JSON qui dépend du protocole utilisé.\n"
Expand All @@ -447,8 +459,11 @@ msgstr ""
#: model:ir.model.fields,help:fs_storage.field_fs_storage__x_protocol_env_default
msgid ""
"The protocol used to access the content of filesystem.\n"
"This list is the one supported by the fsspec library (see https://filesystem-spec.readthedocs.io/en/latest). A filesystem protocolis added by default and refers to the odoo local filesystem.\n"
"Pay attention that according to the protocol, some options must beprovided through the options field."
"This list is the one supported by the fsspec library (see https://filesystem-"
"spec.readthedocs.io/en/latest). A filesystem protocolis added by default and "
"refers to the odoo local filesystem.\n"
"Pay attention that according to the protocol, some options must beprovided "
"through the options field."
msgstr ""
"Le protocole utilisé pour accéder le contenu du système de fichier.\n"
"Cette liste contient ce qui est supporté par la bibliothèque fsspec (voir "
Expand Down
6 changes: 6 additions & 0 deletions fs_storage/i18n/fs_storage.pot
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ msgstr ""
msgid "Available properties"
msgstr ""

#. module: fs_storage
#. odoo-python
#: code:addons/fs_storage/models/fs_storage.py:0
msgid "Calling fs.storage.%(reason)s is not allowed in a safe_eval context."
msgstr ""

#. module: fs_storage
#: model:ir.model.fields,field_description:fs_storage.field_fs_storage__check_connection_method
#: model:ir.model.fields,field_description:fs_storage.field_fs_test_connection__check_connection_method
Expand Down
25 changes: 17 additions & 8 deletions fs_storage/i18n/it.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-10-21 08:43+0000\n"
"PO-Revision-Date: 2026-03-23 10:45+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.4\n"
"X-Generator: Weblate 5.15.2\n"

#. module: fs_storage
#: model_terms:ir.ui.view,arch_db:fs_storage.fs_storage_form_view
Expand All @@ -26,6 +26,14 @@ msgstr "Opzioni disponibili"
msgid "Available properties"
msgstr "Proprietà disponibili"

#. module: fs_storage
#. odoo-python
#: code:addons/fs_storage/models/fs_storage.py:0
msgid "Calling fs.storage.%(reason)s is not allowed in a safe_eval context."
msgstr ""
"La chiamata a fs.storage.%(reason)s non è consentita in un contesto "
"safe_eval."

#. module: fs_storage
#: model:ir.model.fields,field_description:fs_storage.field_fs_storage__check_connection_method
#: model:ir.model.fields,field_description:fs_storage.field_fs_test_connection__check_connection_method
Expand Down Expand Up @@ -140,8 +148,8 @@ msgstr "Campo"
msgid ""
"Field %(field)s already stored in another FS storage ('%(other_storage)s')"
msgstr ""
"Il campo %(field)s è già archiviato in un altro deposito FS "
"('%(other_storage)s')"
"Il campo %(field)s è già archiviato in un altro deposito FS ('%"
"(other_storage)s')"

#. module: fs_storage
#: model:ir.model.fields,field_description:fs_storage.field_fs_storage__field_xmlids
Expand Down Expand Up @@ -286,8 +294,8 @@ msgstr "Modello"
msgid ""
"Model %(model)s already stored in another FS storage ('%(other_storage)s')"
msgstr ""
"Il modello %(model)s è già archiviato in un altro deposito FS "
"('%(other_storage)s')"
"Il modello %(model)s è già archiviato in un altro deposito FS ('%"
"(other_storage)s')"

#. module: fs_storage
#: model:ir.model.fields,field_description:fs_storage.field_fs_storage__model_xmlids
Expand Down Expand Up @@ -400,8 +408,9 @@ msgstr "Deposito"
msgid ""
"Technical code used to identify the storage backend into the code.This code "
"must be unique. This code is used for example to define the storage backend "
"to store the attachments via the configuration parameter 'ir_attachment."
"storage.force.database' when the module 'fs_attachment' is installed."
"to store the attachments via the configuration parameter "
"'ir_attachment.storage.force.database' when the module 'fs_attachment' is "
"installed."
msgstr ""
"Codice tecnico usato per identificare il backend deposito nel codice. Questo "
"codice deve essere univoco. Questo codice è utilizzato per esempio per "
Expand Down
15 changes: 11 additions & 4 deletions fs_storage/i18n/zh_CN.po
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ msgstr "可用选项"
msgid "Available properties"
msgstr "可用属性"

#. module: fs_storage
#. odoo-python
#: code:addons/fs_storage/models/fs_storage.py:0
msgid "Calling fs.storage.%(reason)s is not allowed in a safe_eval context."
msgstr ""

#. module: fs_storage
#: model:ir.model.fields,field_description:fs_storage.field_fs_storage__check_connection_method
#: model:ir.model.fields,field_description:fs_storage.field_fs_test_connection__check_connection_method
Expand Down Expand Up @@ -367,12 +373,13 @@ msgstr ""
msgid ""
"Technical code used to identify the storage backend into the code.This code "
"must be unique. This code is used for example to define the storage backend "
"to store the attachments via the configuration parameter 'ir_attachment."
"storage.force.database' when the module 'fs_attachment' is installed."
"to store the attachments via the configuration parameter "
"'ir_attachment.storage.force.database' when the module 'fs_attachment' is "
"installed."
msgstr ""
"用于在代码中标识存储后端的技术代码。此代码必须是唯一的。例如,当安"
"装'fs_attachment'模块时,此代码用于通过配置参数'ir_attachment.storage.force."
"database'定义存储附件的存储后端。"
"装'fs_attachment'模块时,此代码用于通过配置参"
"数'ir_attachment.storage.force.database'定义存储附件的存储后端。"

#. module: fs_storage
#: model_terms:ir.ui.view,arch_db:fs_storage.fs_test_connection_form_view
Expand Down
45 changes: 45 additions & 0 deletions fs_storage/models/fs_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,32 @@ def new_func1(*args, **kwargs):
return decorator


def prevent_call_from_safe_eval(reason):
"""Decorator to prevent the call to the method in the context of a
safe_eval.
"""

def deorator(func):
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
for frame_info in inspect.stack():
filename = frame_info.filename or ""
function = frame_info.function or ""
if "safe_eval" in filename or function == "safe_eval":
raise ValidationError(
_(
"Calling fs.storage.%(reason)s is not allowed "
"in a safe_eval context.",
reason=reason,
)
)
return func(self, *args, **kwargs)

return wrapper

return deorator


class FSStorage(models.Model):
_name = "fs.storage"
_inherit = "server.env.mixin"
Expand Down Expand Up @@ -288,11 +314,30 @@ def _server_env_fields(self):
"check_connection_method": {},
}

@api.model_create_multi
@prevent_call_from_safe_eval("create")
def create(self, vals_list):
return super().create(vals_list)

@prevent_call_from_safe_eval("create")
def _create(self, data_list):
return super()._create(data_list)

@prevent_call_from_safe_eval("write")
def write(self, vals):
self.__fs = None
self.env.registry.clear_cache()
return super().write(vals)

@prevent_call_from_safe_eval("write")
def _write_multi(self, vals_list):
return super()._write_multi(vals_list)

@api.ondelete(at_uninstall=False)
@prevent_call_from_safe_eval("unlink")
def _check_no_safe_eval_call(self):
pass

def get_directory_path(self):
"""Returns directory path with substitution done."""
return (
Expand Down
Loading
Loading