Skip to content

Commit

Permalink
[Fixes #12880] Asset download doesn't work with 3D Tiles (#12454)
Browse files Browse the repository at this point in the history
* Fix download urls

* Fix download urls

* Fix download urls
  • Loading branch information
mattiagiupponi authored Feb 6, 2025
1 parent 16c2831 commit e5bb6b7
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 29 deletions.
15 changes: 2 additions & 13 deletions geonode/base/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from django.forms.models import model_to_dict
from django.contrib.auth import get_user_model
from django.db.models.query import QuerySet
from geonode.assets.utils import get_default_asset
from geonode.people import Roles
from django.http import QueryDict
from deprecated import deprecated
Expand Down Expand Up @@ -64,7 +63,6 @@
from geonode.groups.models import GroupCategory, GroupProfile
from geonode.base.api.fields import ComplexDynamicRelationField
from geonode.layers.utils import get_download_handlers, get_default_dataset_download_handler
from geonode.assets.handlers import asset_handler_registry
from geonode.utils import build_absolute_uri
from geonode.security.utils import get_resources_with_perms, get_geoapp_subtypes
from geonode.resource.models import ExecutionRequest
Expand Down Expand Up @@ -301,10 +299,6 @@ def get_attribute(self, instance):
logger.exception(e)
raise e

asset = get_default_asset(_instance)
if asset is not None:
asset_url = asset_handler_registry.get_handler(asset).create_download_url(asset)

if _instance.resource_type in ["map"] + get_geoapp_subtypes():
return []
elif _instance.resource_type in ["document"]:
Expand All @@ -314,26 +308,21 @@ def get_attribute(self, instance):
"ajax_safe": _instance.download_is_ajax_safe,
},
]
if asset:
payload.append({"url": asset_url, "ajax_safe": False, "default": False})
return payload

elif _instance.resource_type in ["dataset"]:
download_urls = []
# lets get only the default one first to set it
default_handler = get_default_dataset_download_handler()
obj = default_handler(self.context.get("request"), _instance.alternate)
obj = default_handler(self.context.get("request"), _instance.alternate, resource_pk=_instance.pk)
if obj.download_url:
download_urls.append({"url": obj.download_url, "ajax_safe": obj.is_ajax_safe, "default": True})
# then let's prepare the payload with everything
for handler in get_download_handlers():
obj = handler(self.context.get("request"), _instance.alternate)
obj = handler(self.context.get("request"), _instance.alternate, resource_pk=_instance.pk)
if obj.download_url:
download_urls.append({"url": obj.download_url, "ajax_safe": obj.is_ajax_safe, "default": False})

if asset:
download_urls.append({"url": asset_url, "ajax_safe": True, "default": False if download_urls else True})

return download_urls
else:
return []
Expand Down
9 changes: 1 addition & 8 deletions geonode/base/api/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@
from geonode.assets.utils import create_asset_and_link
from geonode.maps.models import Map, MapLayer
from geonode.tests.base import GeoNodeBaseTestSupport
from geonode.assets.utils import get_default_asset
from geonode.assets.handlers import asset_handler_registry

from geonode.base import enumerations
from geonode.base.api.serializers import ResourceBaseSerializer
Expand Down Expand Up @@ -2509,12 +2507,7 @@ def test_base_resources_return_download_links_for_documents(self):
Ensure we can access the Resource Base list.
"""
doc = Document.objects.first()
asset = get_default_asset(doc)
handler = asset_handler_registry.get_handler(asset)
expected_payload = [
{"url": build_absolute_uri(doc.download_url), "ajax_safe": doc.download_is_ajax_safe},
{"ajax_safe": False, "default": False, "url": handler.create_download_url(asset)},
]
expected_payload = [{"url": build_absolute_uri(doc.download_url), "ajax_safe": doc.download_is_ajax_safe}]
# From resource base API
json = self._get_for_object(doc, "base-resources-detail")
download_url = json.get("resource").get("download_urls")
Expand Down
37 changes: 29 additions & 8 deletions geonode/layers/download_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.conf import settings
from geonode.assets.utils import get_default_asset
from geonode.assets.handlers import asset_handler_registry
from geonode.base.auth import get_or_create_token
from geonode.base.views import _resolve_resourcebase
from geonode.geoserver.helpers import wps_format_is_supported
from geonode.layers.views import _resolve_dataset
from geonode.proxy.views import fetch_response_headers
Expand All @@ -41,9 +44,10 @@ def __str__(self):
def __repr__(self):
return self.__str__()

def __init__(self, request, resource_name) -> None:
def __init__(self, request, resource_name, resource_pk=None) -> None:
self.request = request
self.resource_name = resource_name
self.resource_pk = resource_pk
self._resource = None

def get_download_response(self):
Expand Down Expand Up @@ -75,13 +79,19 @@ def download_url(self):
resource = self.get_resource()
if not resource:
return None
if resource.subtype not in ["vector", "raster", "vector_time"]:

if resource.subtype not in ["vector", "raster", "vector_time", "3dtiles"]:
logger.info("Download URL is available only for datasets that have been harvested and copied locally")
return None

if self.is_link_resource:
return resource.link_set.filter(resource=resource.get_self_resource(), link_type="original").first().url

if resource.subtype == "3dtiles":
asset = get_default_asset(resource)
if asset is not None:
return asset_handler_registry.get_handler(asset).create_download_url(asset)

return reverse("dataset_download", args=[resource.alternate])

def get_resource(self):
Expand All @@ -90,12 +100,23 @@ def get_resource(self):
"""
if not self._resource:
try:
self._resource = _resolve_dataset(
self.request,
self.resource_name,
"base.download_resourcebase",
_("You do not have download permissions for this dataset."),
)

if self.resource_pk:
self._resource = _resolve_resourcebase(
self.request,
self.resource_pk,
"base.download_resourcebase",
_("You do not have download permissions for this dataset."),
)
elif self.resource_name:
self._resource = _resolve_dataset(
self.request,
self.resource_name,
"base.download_resourcebase",
_("You do not have download permissions for this dataset."),
)
else:
raise Exception("Layer not found")
except Exception as e:
logger.debug(e)

Expand Down

0 comments on commit e5bb6b7

Please sign in to comment.