diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 9571e312cc..79bf5c2ebe 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -2,7 +2,6 @@ exclude: |
(?x)
# NOT INSTALLABLE ADDONS
^fs_file/|
- ^fs_folder/|
^fs_folder_demo/|
^fs_folder_ms_drive/|
^fs_folder_webdav/|
diff --git a/fs_folder/README.rst b/fs_folder/README.rst
index 4af4f51770..acb4d9f1d1 100644
--- a/fs_folder/README.rst
+++ b/fs_folder/README.rst
@@ -21,13 +21,13 @@ Fs Folder
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github
- :target: https://github.com/OCA/storage/tree/18.0/fs_folder
+ :target: https://github.com/OCA/storage/tree/19.0/fs_folder
:alt: OCA/storage
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-fs_folder
+ :target: https://translation.odoo-community.org/projects/storage-19-0/storage-19-0-fs_folder
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
- :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=18.0
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=19.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -311,7 +311,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -358,6 +358,6 @@ Current `maintainer `__:
|maintainer-lmignon|
-This module is part of the `OCA/storage `_ project on GitHub.
+This module is part of the `OCA/storage `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/fs_folder/__manifest__.py b/fs_folder/__manifest__.py
index 2022a3c53d..ad05e13987 100644
--- a/fs_folder/__manifest__.py
+++ b/fs_folder/__manifest__.py
@@ -5,13 +5,11 @@
"name": "Fs Folder",
"summary": """A module to link to Odoo records and manage from record forms forlders
from external file systems """,
- "version": "18.0.1.0.0",
+ "version": "19.0.1.0.0",
"license": "LGPL-3",
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/storage",
- "depends": [
- "fs_storage",
- ],
+ "depends": ["fs_storage", "bus"],
"data": [
"views/fs_storage.xml",
],
@@ -21,6 +19,5 @@
],
},
"demo": [],
- "installable": False,
"maintainers": ["lmignon"],
}
diff --git a/fs_folder/controllers/fs_folder_controller.py b/fs_folder/controllers/fs_folder_controller.py
index ab384034c9..4f2738e224 100644
--- a/fs_folder/controllers/fs_folder_controller.py
+++ b/fs_folder/controllers/fs_folder_controller.py
@@ -29,7 +29,7 @@ def get_file(self, res_id, res_model, field_name, path, download=False, **kwargs
@http.route(
"/fs_folder/get_children///",
- type="json",
+ type="jsonrpc",
auth="user",
methods=["POST"],
)
@@ -43,7 +43,7 @@ def get_children(self, res_id, res_model, field_name, path=""):
@http.route(
"/fs_folder/add_folder///",
- type="json",
+ type="jsonrpc",
auth="user",
methods=["POST"],
)
@@ -54,7 +54,7 @@ def add_folder(self, res_id, res_model, field_name, path, name):
@http.route(
"/fs_folder/delete///",
- type="json",
+ type="jsonrpc",
auth="user",
methods=["POST"],
)
@@ -65,7 +65,7 @@ def delete(self, res_id, res_model, field_name, path, name):
@http.route(
"/fs_folder/move///",
- type="json",
+ type="jsonrpc",
auth="user",
methods=["POST"],
)
@@ -83,7 +83,7 @@ def move_file(self, res_id, res_model, field_name, path, origin_path, record):
@http.route(
"/fs_folder/copy///",
- type="json",
+ type="jsonrpc",
auth="user",
methods=["POST"],
)
@@ -101,7 +101,7 @@ def copy_file(self, res_id, res_model, field_name, path, origin_path, record):
@http.route(
"/fs_folder/rename///",
- type="json",
+ type="jsonrpc",
auth="user",
methods=["POST"],
)
@@ -116,7 +116,7 @@ def rename(self, res_id, res_model, field_name, path, name, new_name):
@http.route(
"/fs_folder/upload///",
- type="json",
+ type="jsonrpc",
auth="user",
methods=["POST"],
)
@@ -132,7 +132,7 @@ def upload(self, res_id, res_model, field_name, path, name, data):
@http.route(
"/fs_folder/initialize///",
- type="json",
+ type="jsonrpc",
auth="user",
methods=["POST"],
)
diff --git a/fs_folder/fields.py b/fs_folder/fields.py
index d539f4eac2..079344a8d4 100644
--- a/fs_folder/fields.py
+++ b/fs_folder/fields.py
@@ -8,7 +8,8 @@
import fsspec
-from odoo import api, fields, models, registry
+from odoo import api, fields, models
+from odoo.modules.registry import Registry
from odoo.tools.misc import SENTINEL, Sentinel
from odoo.tools.sql import pg_varchar
@@ -356,7 +357,7 @@ def create_value_in_fs(self, records: models.BaseModel) -> list[FsFolderValue]:
fs.mkdir(path, **kwargs)
def clean_up_folder(path, storage_code, dbname, user_id):
- db_registry = registry(dbname)
+ db_registry = Registry(dbname)
with db_registry.cursor() as cr:
env = api.Environment(cr, user_id, {})
fs = env["fs.storage"].get_fs_by_code(storage_code)
diff --git a/fs_folder/models/fs_folder_field_web_api.py b/fs_folder/models/fs_folder_field_web_api.py
index 5a93513218..51834c9e58 100644
--- a/fs_folder/models/fs_folder_field_web_api.py
+++ b/fs_folder/models/fs_folder_field_web_api.py
@@ -7,7 +7,7 @@
import fsspec
from werkzeug import Response
-from odoo import _, api, models
+from odoo import api, models
from odoo.exceptions import AccessError, UserError
from ..fs_stream import FsStream
@@ -31,10 +31,10 @@ def _check_field_access(self, res_id, res_model, field_name, access):
:param access: the access rights to check
"""
if res_model not in self.env:
- raise AccessError(_("Unknown model"))
+ raise AccessError(self.env._("Unknown model"))
record = self.env[res_model].browse(res_id)
if field_name not in record._fields:
- raise AccessError(_("Unknown field"))
+ raise AccessError(self.env._("Unknown field"))
record.check_access(access)
@api.model
@@ -76,7 +76,9 @@ def _get_fs(
if field.type == "fs_folder":
fs = record[field_name].fs
if not fs:
- raise ValueError(_("The field is not an external filesystem field."))
+ raise ValueError(
+ self.env._("The field is not an external filesystem field.")
+ )
return fs
@api.model
@@ -113,13 +115,13 @@ def get_children(self, res_id, res_model, field_name, path, **kwargs) -> list[di
return fs.ls(path, detail=True)
except Exception as e:
raise UserError(
- _(
- "An error occurred while listing files: '%s'\n"
+ self.env._(
+ "An error occurred while listing files: '%(exception)s'\n"
"This might happen if the folder was moved, renamed or deleted "
"on the external storage.\n"
- "If this is expected you might want to unlink this folder."
+ "If this is expected you might want to unlink this folder.",
+ exception=e,
)
- % e
) from e
@api.model
diff --git a/fs_folder/models/fs_storage.py b/fs_folder/models/fs_storage.py
index db7e57daca..e8793624d8 100644
--- a/fs_folder/models/fs_storage.py
+++ b/fs_folder/models/fs_storage.py
@@ -2,7 +2,7 @@
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
import re
-from odoo import _, api, fields, models, tools
+from odoo import api, fields, models, tools
from odoo.exceptions import UserError, ValidationError
@@ -33,18 +33,23 @@ def _check_fs_name_sanitization_replace_char(self):
if rc and self._invalid_fs_name_chars_re_pattern.findall(rc):
raise ValidationError(
- _("The character to use as replacement can not be one of '%s'")
- % self._invalid_fs_name_chars
+ self.env._(
+ "The character to use as replacement can not be one of "
+ "'%(invalid_chars)s'",
+ invalid_chars=self._invalid_fs_name_chars,
+ )
)
@api.constrains("use_as_default_for_fs_contents")
def _check_use_as_default_for_fs_contents(self):
# constrains are checked in python since values can be provided by
# the server environment
- defaults = self.search([]).filtered("use_as_default_for_fs_contents")
+ defaults = self.search([]).filtered("use_as_default_for_fs_contents") # pylint: disable=no-search-all
if len(defaults) > 1:
raise ValidationError(
- _("Only one storage can be used as default for filesystem contents.")
+ self.env._(
+ "Only one storage can be used as default for filesystem contents."
+ )
)
@property
@@ -60,6 +65,7 @@ def _server_env_fields(self):
@api.model
@tools.ormcache()
def get_storage_code_for_fs_content_fallback(self) -> str | None:
+ # pylint: disable=no-search-all
storages = (
self.sudo()
.search([])
@@ -80,7 +86,7 @@ def get_default_storage_code_for_fs_content(self, model_name, field_name) -> str
storage_code = self.get_storage_code_for_fs_content_fallback()
if not storage_code:
raise ValueError(
- _(
+ self.env._(
"No default storage found for the content of the external "
"filesystem fields for model %(model)s and field %(field)s. "
"Please set a default storage in the filesystem storage "
@@ -105,7 +111,7 @@ def is_fs_name_valid(self, name, raise_if_invalid=False) -> bool:
invalid = self._invalid_fs_name_chars_re_pattern.findall(name)
if invalid and raise_if_invalid:
raise UserError(
- _(
+ self.env._(
"The name '%(name)s' contains invalid characters"
" %(invalid_chars)s.\n"
"The following chars are not allowed: %(all_invalid_chars)s",
diff --git a/fs_folder/static/description/index.html b/fs_folder/static/description/index.html
index e7ba62b0b8..2eacfad379 100644
--- a/fs_folder/static/description/index.html
+++ b/fs_folder/static/description/index.html
@@ -374,7 +374,7 @@ Fs Folder
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:c4cce3679f458dfca0f84f2626680d41bd9ae5049b0fde289ecb07ee4359a869
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-

+

If you need to link some specific models to a specific folder into an
external filesystem and be able to manage the content of this folder
from the model form view, this module is for you.
@@ -645,7 +645,7 @@
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-feedback.
+feedback.
Do not contact contributors directly about support or help with technical issues.
diff --git a/fs_folder/tests/common.py b/fs_folder/tests/common.py
index ef546898a8..28e0041a97 100644
--- a/fs_folder/tests/common.py
+++ b/fs_folder/tests/common.py
@@ -23,6 +23,7 @@ def setUpClass(cls):
cls.loader.update_registry(
(FsTestModel, FsTestModelInherits, FsTestModelRelated)
)
+
cls.fs_test_model = cls.env[FsTestModel._name]
cls.fs_test_model_inherits = cls.env[FsTestModelInherits._name]
cls.fs_test_model_related = cls.env[FsTestModelRelated._name]
diff --git a/fs_folder/tests/test_fs_storage.py b/fs_folder/tests/test_fs_storage.py
index 39d9d53109..d1de9270a4 100644
--- a/fs_folder/tests/test_fs_storage.py
+++ b/fs_folder/tests/test_fs_storage.py
@@ -5,6 +5,7 @@
from odoo.tests.common import TransactionCase
from odoo.addons.base.tests.common import BaseCommon
+from odoo.addons.fs_storage.models.fs_storage import FSStorage
class TestFsStorage(TransactionCase):
@@ -12,7 +13,13 @@ class TestFsStorage(TransactionCase):
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env["base"].with_context(**BaseCommon.default_env_context()).env
- cls.backend = cls.env.ref("fs_storage.fs_storage_demo")
+ cls.backend: FSStorage = cls.env["fs.storage"].create(
+ {
+ "name": "Odoo Filesystem Backend",
+ "protocol": "odoofs",
+ "code": "odoofs",
+ }
+ )
def test_is_fs_name_valid(self):
self.assertFalse(self.backend.is_fs_name_valid(r'my\/:*?"<>| directory'))