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
13 changes: 13 additions & 0 deletions src/viur/core/config.py
Original file line number Diff line number Diff line change
@@ -798,6 +798,19 @@ class Conf(ConfigType):
file_thumbnailer_url: t.Optional[str] = None
# TODO: """docstring"""

file_generate_download_url_for_derives: bool | list[str] = False
"""
If true for all derives a download Url is created
If this is a list all entries used as a search string:
Example:
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"""

42 changes: 37 additions & 5 deletions src/viur/core/render/json/default.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import fnmatch
import json
import logging
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
@@ -88,7 +90,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),
}
@@ -122,7 +128,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.

@@ -140,15 +149,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)
if conf.file_generate_download_url_for_derives:

if isinstance(conf.file_generate_download_url_for_derives, list):
search_paths.extend(conf.file_generate_download_url_for_derives)
else:
search_path.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):