Skip to content

Commit

Permalink
chore: override_existing option for base storage
Browse files Browse the repository at this point in the history
  • Loading branch information
smotornyuk committed Jun 27, 2024
1 parent 3d70bdd commit ca7b139
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 14 deletions.
12 changes: 10 additions & 2 deletions ckanext/files/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,10 @@ def __str__(self):
return self.settings.get("name", "unknown")

def __init__(self, **settings: Any):
settings.setdefault("override_existing", False)
settings.setdefault("supported_types", [])
settings.setdefault("max_size", 0)

self.settings = settings

self.uploader = self.make_uploader()
Expand All @@ -443,13 +447,13 @@ def max_size(self) -> int:
"""

return self.settings.get("max_size", 0)
return self.settings["max_size"]

@property
def supported_types(self) -> list[str]:
"""List of supported MIMEtypes or their parts."""

return self.settings.get("supported_types", [])
return self.settings["supported_types"]

@classmethod
def declare_config_options(cls, declaration: Declaration, key: Key):
Expand All @@ -466,6 +470,10 @@ def declare_config_options(cls, declaration: Declaration, key: Key):
+ "\nExample: text/csv pdf application video jpeg",
)

declaration.declare_bool(key.override_existing).set_description(
"If file already exists, replace it with new content.",
)

declaration.declare(key.name, key[-1]).set_description(
"Descriptive name of the storage used for debugging. When empty,"
+ " name from the config option is used,"
Expand Down
5 changes: 0 additions & 5 deletions ckanext/files/storage/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ def __init__(self, **settings: Any):
path = self.ensure_option(settings, "path")
settings.setdefault("create_path", False)
settings.setdefault("recursive", False)
settings.setdefault("override_existing", False)

if not os.path.exists(path):
if tk.asbool(settings["create_path"]):
Expand Down Expand Up @@ -72,10 +71,6 @@ def declare_config_options(cls, declaration: Declaration, key: Key):
+ " of the main storage path.",
)

declaration.declare_bool(key.override_existing).set_description(
"If file already exists, replace it with new content.",
)


class FsUploader(Uploader):
required_options = ["path"]
Expand Down
10 changes: 8 additions & 2 deletions ckanext/files/storage/redis.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,10 @@ def copy(
if not self.storage.redis.exists(src):
raise exceptions.MissingFileError(self.storage, src)

if self.storage.redis.exists(dest):
if (
self.storage.redis.exists(dest)
and not self.storage.settings["override_existing"]
):
raise exceptions.ExistingFileError(self.storage, dest)

try:
Expand Down Expand Up @@ -249,7 +252,10 @@ def move(
if not self.storage.redis.exists(src):
raise exceptions.MissingFileError(self.storage, src)

if self.storage.redis.exists(dest):
if (
self.storage.redis.exists(dest)
and not self.storage.settings["override_existing"]
):
raise exceptions.ExistingFileError(self.storage, dest)

self.storage.redis.rename(src, dest)
Expand Down
7 changes: 6 additions & 1 deletion ckanext/files/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,13 @@ def test_settings(self, faker: Faker):
"""Storage keeps all incoming arguments as settings."""

settings = faker.pydict()

storage = base.Storage(**settings)
assert storage.settings == settings
expected = dict(
{"supported_types": [], "max_size": 0, "override_existing": False},
**settings,
)
assert storage.settings == expected

def test_max_size(self, faker: Faker):
"""Storage has a dedicated property for `max_size` setting."""
Expand Down
3 changes: 3 additions & 0 deletions ckanext/files/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def test_empty(self):
"default": {
"type": "files:redis",
"prefix": "ckanext:files:test.ckan.net:file_content:",
"override_existing": False,
"name": "default",
"supported_types": [],
"max_size": 0,
Expand All @@ -55,6 +56,7 @@ def test_customized(self, monkeypatch: MonkeyPatch, ckan_config: dict[str, Any])
"default": {
"type": "files:redis",
"prefix": "ckanext:files:test.ckan.net:file_content:",
"override_existing": False,
"name": "default",
"supported_types": [],
"max_size": 0,
Expand Down Expand Up @@ -82,6 +84,7 @@ def test_non_setting(self):
"default": {
"type": "files:redis",
"prefix": "ckanext:files:test.ckan.net:file_content:",
"override_existing": False,
"name": "default",
"supported_types": [],
"max_size": 0,
Expand Down
4 changes: 0 additions & 4 deletions docs/configuration/fs.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ ckanext.files.storage.NAME.create_path = false
## Use this flag if files can be stored inside subfolders
## of the main storage path.
ckanext.files.storage.NAME.recursive = false
## If file already exists, replace it with new content.
ckanext.files.storage.NAME.override_existing = false
```


Expand All @@ -29,8 +27,6 @@ ckanext.files.storage.NAME.create_path = false
## Use this flag if files can be stored inside subfolders
## of the main storage path.
ckanext.files.storage.NAME.recursive = false
## If file already exists, replace it with new content.
ckanext.files.storage.NAME.override_existing = false
## URL of the storage folder. `public_root + location` must produce a public URL
ckanext.files.storage.NAME.public_root =
```
2 changes: 2 additions & 0 deletions docs/configuration/storage/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ ckanext.files.storage.NAME.max_size = 0
## Space-separated list of MIME types or just type or subtype part.
## Example: text/csv pdf application video jpeg
ckanext.files.storage.NAME.supported_types =
## If file already exists, replace it with new content.
ckanext.files.storage.NAME.override_existing = false
## Descriptive name of the storage used for debugging. When empty, name from
## the config option is used, i.e: `ckanext.files.storage.DEFAULT_NAME...`
ckanext.files.storage.NAME.name = NAME
Expand Down

0 comments on commit ca7b139

Please sign in to comment.