Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add downloadUrl for derives #1290

Draft
wants to merge 11 commits into
base: develop
Choose a base branch
from
18 changes: 18 additions & 0 deletions src/viur/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,24 @@ class Conf(ConfigType):
file_thumbnailer_url: t.Optional[str] = None
# TODO: """docstring"""

file_generate_download_url_for_derives: bool | t.Iterable[str] = False
"""
If True, for all derives, a download URL is created as well.

When an iterable of str is provided, for all entries that match a pattern,
a download URL will be created.

Example:
```py
class Test(Skeleton):
image_bar = FileBone(derive=conf["derives"])
image_foo = FileBone(derive=conf["derives"])
logo = FileBone(derive=conf["derives"])

conf.file_generate_download_url_for_derives = ["test.image*"]
```
"""

main_app: "Module" = None
"""Reference to our pre-build Application-Instance"""

Expand Down
41 changes: 36 additions & 5 deletions src/viur/core/render/json/default.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import fnmatch
import json
import typing as t
from enum import Enum

from viur.core.modules.file import File
from viur.core import bones, db, current
from viur.core.render.abstract import AbstractRenderer
from viur.core.skeleton import SkeletonInstance
Expand Down Expand Up @@ -88,7 +89,11 @@ def renderSingleBoneValue(self, value: t.Any,
if isinstance(bone, bones.RelationalBone):
if isinstance(value, dict):
return {
"dest": self.renderSkelValues(value["dest"], injectDownloadURL=isinstance(bone, bones.FileBone)),
"dest": self.renderSkelValues(
value["dest"],
bone_path=f"{skel.kindName}.{bone.name}",
injectDownloadURL=isinstance(bone, bones.FileBone)
),
"rel": (self.renderSkelValues(value["rel"], injectDownloadURL=isinstance(bone, bones.FileBone))
if value["rel"] else None),
}
Expand Down Expand Up @@ -122,7 +127,10 @@ def renderBoneValue(self, bone: bones.BaseBone, skel: SkeletonInstance, key: str
res = self.renderSingleBoneValue(boneVal, bone, skel, key)
return res

def renderSkelValues(self, skel: SkeletonInstance, injectDownloadURL: bool = False) -> t.Optional[dict]:
def renderSkelValues(self,
skel: SkeletonInstance,
bone_path: t.Optional[str] = None,
injectDownloadURL: bool = False) -> t.Optional[dict]:
"""
Prepares values of one :class:`viur.core.skeleton.Skeleton` or a list of skeletons for output.

Expand All @@ -140,15 +148,38 @@ def renderSkelValues(self, skel: SkeletonInstance, injectDownloadURL: bool = Fal

if (
injectDownloadURL
and (file := getattr(conf.main_app, "file", None))
and "dlkey" in skel
and "name" in skel
):
res["downloadUrl"] = file.create_download_url(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the opposite of #1252, I would keep it as it is.

res["downloadUrl"] = File.create_download_url(
skel["dlkey"],
skel["name"],
expires=conf.render_json_download_url_expiration
)

# generate the downloadUrl for derives
search_paths = []
if search_path := current.request.get().request.headers.get("X-VIUR-DERIVED-DOWNLOAD-URL"):
search_paths.append(search_path)
ArneGudermann marked this conversation as resolved.
Show resolved Hide resolved
if conf.file_generate_download_url_for_derives:

if isinstance(conf.file_generate_download_url_for_derives, t.Iterable):
search_paths.extend(conf.file_generate_download_url_for_derives)
else:
search_paths.append("*")

for search_path in search_paths:
if fnmatch.fnmatch(bone_path, search_path):
break
else:
return res

for derive_name in res.get("derived", {}).get("files", {}):
res["derived"]["files"][derive_name]["downloadUrl"] = File.create_download_url(
skel["dlkey"],
derive_name,
derived=True
)
return res

def renderEntry(self, skel: SkeletonInstance, actionName, params=None):
Expand Down
Loading