Skip to content

Commit

Permalink
implement portals
Browse files Browse the repository at this point in the history
  • Loading branch information
nicokant committed Dec 21, 2023
1 parent 6949bcd commit 1c33dda
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 1 deletion.
39 changes: 38 additions & 1 deletion metadata_catalogue/maps/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
from treebeard.admin import TreeAdmin
from treebeard.forms import movenodeform_factory

from .models import Layer, LayerGroup, Map, RasterSource, Source, VectorSource
from .models import Layer, LayerGroup, Map, Portal, PortalMap, RasterSource, Source, VectorSource


class LayerInline(admin.TabularInline):
model = Layer


class PortalMapInline(admin.TabularInline):
model = PortalMap


@admin.register(LayerGroup)
class LayerGroupAdmin(TreeAdmin):
form = movenodeform_factory(LayerGroup)
Expand Down Expand Up @@ -84,3 +88,36 @@ class LayerAdmin(admin.ModelAdmin):
"group",
"group_order",
]


@admin.register(Portal)
class PortalAdmin(admin.ModelAdmin):
list_display = [
"id",
"title",
"visibility",
"uuid",
]

search_fields = [
"title",
"uuid",
]

list_filter = [
"visibility",
]

inlines = [
PortalMapInline,
]


@admin.register(PortalMap)
class PortalMapAdmin(admin.ModelAdmin):
list_display = [
"id",
"portal",
"map",
"order",
]
45 changes: 45 additions & 0 deletions metadata_catalogue/maps/api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import uuid
from typing import List

from django.db.models import Q
from ninja import Router
from ninja.responses import codes_4xx

from . import models, schema
from .enums import Visibility

maps_router = Router()

Expand Down Expand Up @@ -42,3 +47,43 @@ def get_map_style(request, map_slug: str):
return 200, m.get_style(request)
except models.Map.DoesNotExist:
return 404, {"message": "Not found"}


@maps_router.get(
"/portals/{portal_uuid}/",
response={200: schema.Portal, codes_4xx: schema.StatusMessage},
url_name="portals_get",
by_alias=True,
exclude_none=True,
)
def get_portal(request, portal_uuid: uuid.UUID):
try:
portal = models.Portal.objects.get(uuid=portal_uuid)
if not request.user.has_perm("maps.portal_view", portal):
return 404, {"message": "Not found"}
return 200, portal
except models.Map.DoesNotExist:
return 404, {"message": "Not found"}


@maps_router.get(
"/portals/{portal_uuid}/maps/",
response={200: list[schema.PortalMaps], codes_4xx: schema.StatusMessage},
url_name="portals_get_maps",
exclude_none=True,
)
def get_portal_maps(request, portal_uuid: uuid.UUID):
try:
portal = models.Portal.objects.get(uuid=portal_uuid)
if not request.user.has_perm("maps.portal_view", portal):
return 404, {"message": "Not found"}

expression = Q()
if request.user.is_authenticated:
if not request.user.is_staff:
expression = Q(map__visibility=Visibility.PUBLIC) | Q(map__owner=request.user)
else:
expression = Q(map__visibility=Visibility.PUBLIC)
return 200, portal.maps.filter(expression).select_related("map")
except models.Map.DoesNotExist:
return 404, {"message": "Not found"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Generated by Django 4.2.8 on 2023-12-21 11:07

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import metadata_catalogue.maps.models
import uuid


class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("maps", "0004_map_visibility"),
]

operations = [
migrations.CreateModel(
name="Portal",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("uuid", models.UUIDField(default=uuid.uuid4)),
("title", models.CharField(max_length=250)),
(
"visibility",
models.CharField(
choices=[("public", "Public"), ("private", "Private")], default="private", max_length=10
),
),
("extra", models.JSONField(blank=True, default=metadata_catalogue.maps.models.empty_json)),
(
"owner",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.CreateModel(
name="PortalMap",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("order", models.IntegerField(blank=True, default=0)),
("extra", models.JSONField(blank=True, default=metadata_catalogue.maps.models.empty_json)),
(
"map",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, related_name="portals", to="maps.map"
),
),
(
"portal",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, related_name="maps", to="maps.portal"
),
),
],
),
migrations.AddConstraint(
model_name="portal",
constraint=models.UniqueConstraint(models.F("uuid"), name="portal_unique_uuid"),
),
]
28 changes: 28 additions & 0 deletions metadata_catalogue/maps/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import uuid

from django.conf import settings
from django.db import models
from django.urls import reverse
Expand Down Expand Up @@ -232,3 +234,29 @@ def as_layer_tree(self):
)

return current_group


class Portal(models.Model):
uuid = models.UUIDField(default=uuid.uuid4)
title = models.CharField(max_length=250)
visibility = models.CharField(max_length=10, choices=Visibility.choices, default=Visibility.PRIVATE)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL)
extra = models.JSONField(default=empty_json, blank=True)

class Meta:
constraints = [
models.UniqueConstraint("uuid", name="portal_unique_uuid"),
]

def __str__(self) -> str:
return self.title


class PortalMap(models.Model):
map = models.ForeignKey("maps.Map", on_delete=models.CASCADE, related_name="portals")
portal = models.ForeignKey("maps.Portal", on_delete=models.CASCADE, related_name="maps")
order = models.IntegerField(default=0, blank=True)
extra = models.JSONField(default=empty_json, blank=True)

def __str__(self) -> str:
return f"{self.map} @ {self.portal}"
6 changes: 6 additions & 0 deletions metadata_catalogue/maps/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ def is_public(user, object):
rules.add_perm("maps.map_edit", is_owner | rules.is_staff)
rules.add_perm("maps.map_add", is_owner | rules.is_staff)
rules.add_perm("maps.map_delete", is_owner | rules.is_staff)


rules.add_perm("maps.portal_view", is_public | is_owner | rules.is_staff)
rules.add_perm("maps.portal_edit", is_owner | rules.is_staff)
rules.add_perm("maps.portal_add", is_owner | rules.is_staff)
rules.add_perm("maps.portal_delete", is_owner | rules.is_staff)
14 changes: 14 additions & 0 deletions metadata_catalogue/maps/schema.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import uuid
from typing import Dict, List, Optional

from ninja import Schema
Expand Down Expand Up @@ -67,3 +68,16 @@ class MapMetadata(Schema):

class StatusMessage(Schema):
message: str


class PortalMaps(Schema):
slug: str = Field(None, alias="map.slug")
title: str = Field(None, alias="map.title")
description: str = Field(None, alias="map.description")
extra: JsonValue


class Portal(Schema):
title: str
uuid: uuid.UUID
extra: JsonValue

0 comments on commit 1c33dda

Please sign in to comment.