summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2025-06-02 17:29:34 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2025-06-13 18:16:05 +0200
commit35eaa21a193e548be2e7478f1cf52b584dbe75d2 (patch)
tree02563973c557644cbe968bee8d0f8402f9394204
parentd829d11aec86a015d3898738ae9d73b5067bb865 (diff)
downloadIshtar-develop-5.0-qgis.tar.bz2
Ishtar-develop-5.0-qgis.zip
WIP GIS importdevelop-5.0-qgis
-rw-r--r--ishtar_common/data_importer.py8
-rw-r--r--ishtar_common/models_imports.py35
-rw-r--r--ishtar_common/urls.py5
-rw-r--r--ishtar_common/views_api.py32
-rw-r--r--ishtar_common/views_item.py18
5 files changed, 93 insertions, 5 deletions
diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py
index 941ccc4af..2210de499 100644
--- a/ishtar_common/data_importer.py
+++ b/ishtar_common/data_importer.py
@@ -174,13 +174,16 @@ class ImporterError(Exception):
return str(self.msg)
-class Formater(object):
+class Formater:
def __init__(self, *args, **kwargs):
self.db_target = kwargs.get("db_target", None)
def format(self, value):
return value
+ def __str__(self):
+ return self.__class__.__name__
+
def check(
self,
values,
@@ -290,6 +293,9 @@ class UnicodeFormater(Formater):
value = self.prefix + value
return value
+ def __str__(self):
+ return f"{self.__class__.__name__}|{self.max_length or 0}"
+
class BooleanFormater(Formater):
def format(self, value):
diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py
index 33d793333..dfd2b0a90 100644
--- a/ishtar_common/models_imports.py
+++ b/ishtar_common/models_imports.py
@@ -149,6 +149,17 @@ IMPORT_TYPES = (
IMPORT_TYPES_DICT = dict(IMPORT_TYPES)
+SPECIFIC_TYPES_COLUMNS = {
+ "point_2d": "Point2D",
+ "point_3d": "Point3D",
+ "multi_points": "MultiPoints",
+ "multi_line": "MultiLine",
+ "multi_polygon": "MultiPolygon",
+ "x": "X",
+ "y": "Y",
+ "z": "Z",
+}
+
class ImporterType(models.Model):
"""
@@ -455,6 +466,30 @@ class ImporterType(models.Model):
col_names.append(formater.label)
return cols, col_names
+ def get_columns_types(self, importer_class=None):
+ """
+ :param importer_class: importer class - if not provided get from self
+ :return: (list): return list of column types - each types is a string
+ """
+ if not importer_class:
+ importer_class = self.get_importer_class()
+ types = []
+ for formater in importer_class.LINE_EXPORT_FORMAT:
+ if not formater:
+ types.append("")
+ continue
+
+ ctype = ""
+ field_name = formater.field_name[0]
+ for k in SPECIFIC_TYPES_COLUMNS:
+ if field_name == k or field_name.endswith(f"__{k}"):
+ ctype = SPECIFIC_TYPES_COLUMNS[k]
+ break
+ if not ctype:
+ ctype = str(formater.formater[0])
+ types.append(ctype)
+ return types
+
def save(self, *args, **kwargs):
if not self.slug:
self.slug = create_slug(ImporterType, self.name)
diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py
index 31d3b40ad..54996b918 100644
--- a/ishtar_common/urls.py
+++ b/ishtar_common/urls.py
@@ -371,6 +371,11 @@ urlpatterns = [
views_api.GISSourceAPI.as_view(),
name="api-gis-sources",
),
+ path(
+ "api/gis/import/<slug:importer_slug>/<int:page>/",
+ views_api.GISImportAPI.as_view(),
+ name="api-gis-sources",
+ ),
re_path(r"^profile(?:/(?P<pk>[0-9]+))?/$", views.ProfileEdit.as_view(), name="profile"),
re_path(
r"^save-search/(?P<app_label>[a-z-]+)/(?P<model>[a-z-]+)/$",
diff --git a/ishtar_common/views_api.py b/ishtar_common/views_api.py
index c054246e4..052a764bc 100644
--- a/ishtar_common/views_api.py
+++ b/ishtar_common/views_api.py
@@ -17,11 +17,14 @@
# See the file COPYING for details.
+from urllib.parse import unquote_plus
+
from rest_framework import serializers
from rest_framework.response import Response
-from ishtar_common.rest import GISAPIView
from ishtar_common.models_imports import ImporterType
+from ishtar_common.rest import GISAPIView
+from ishtar_common.views_item import get_item
class ImporterTypeSerializer(serializers.ModelSerializer):
@@ -49,3 +52,30 @@ class GISSourceAPI(GISAPIView):
def get(self, request, format=None):
serializer = ImporterTypeSerializer(self.get_queryset(), many=True)
return Response(serializer.data)
+
+
+class GISImportAPI(GISAPIView):
+ PAGE_LEN = 50
+
+ def get(self, request, importer_slug, page=1, format=None):
+ user = self.request.user
+ q = ImporterType.q_qgis_importers(user.ishtaruser).filter(slug=importer_slug)
+ if not user.ishtaruser or not q.count():
+ return Response([])
+ query = None
+ if request.GET and request.GET["query"]:
+ query = unquote_plus(request.GET["query"])
+ dct = {"query": query, "length": self.PAGE_LEN}
+ if page > 1:
+ dct["start"] = (page - 1) * self.PAGE_LEN + 1
+ importer = q.all()[0]
+ importer_class = importer.get_importer_class()
+ cols, col_names = importer.get_columns(importer_class=importer_class)
+ obj_name = importer_class.OBJECT_CLS.__name__.lower()
+ return get_item(importer_class.OBJECT_CLS, "get_" + obj_name, obj_name,
+ own_table_cols=cols)(
+ request, data_type="json", full=False, force_own=False,
+ no_link=True, col_names=col_names,
+ col_types=importer.get_columns_types(),
+ **dct
+ )
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py
index 9263ae92a..b97cf77be 100644
--- a/ishtar_common/views_item.py
+++ b/ishtar_common/views_item.py
@@ -51,6 +51,7 @@ from django.db.models import (
from django.db.models.functions import ExtractYear
from django.db.utils import ProgrammingError
from django import forms
+from django.contrib.gis.geos import GEOSGeometry
from django.forms.models import model_to_dict
from django.http import HttpResponse, Http404
from django.shortcuts import render
@@ -2354,6 +2355,7 @@ def get_item(
no_limit=False,
return_query=False,
ishtaruser=None, # could be provided when request is None
+ col_types=None,
**dct,
):
available_perms = []
@@ -2527,7 +2529,11 @@ def get_item(
else:
request_keys[jfield.alt_name] = jkey + "__iexact"
if "query" in dct:
- request_items = dct["query"]
+ if isinstance(dct["query"], dict):
+ request_items = dct["query"]
+ else:
+ request_items = dct
+ request_items["search_vector"] = dct.pop("query")
request_items["submited"] = True
elif request and request.method == "POST":
request_items = request.POST
@@ -2537,12 +2543,14 @@ def get_item(
return HttpResponse(EMPTY, content_type="text/plain")
count = dct.get("count", False)
-
# pager
try:
row_nb = int(request_items.get("length"))
except (ValueError, TypeError):
- row_nb = DEFAULT_ROW_NUMBER
+ if "length" in dct:
+ row_nb = int(dct["length"])
+ else:
+ row_nb = DEFAULT_ROW_NUMBER
if data_type == "json-map": # other limit for map
row_nb = settings.ISHTAR_MAP_MAX_ITEMS
@@ -3107,6 +3115,8 @@ def get_item(
value = value.strftime("%Y-%m-%d")
if isinstance(value, datetime.datetime):
value = value.strftime("%Y-%m-%d %H:%M:%S")
+ if isinstance(value, GEOSGeometry):
+ value = value.ewkt
res[k] = value
if full == "shortcut":
if "cached_label" in res:
@@ -3141,6 +3151,8 @@ def get_item(
"recordsFiltered": items_nb,
"rows": rows,
"table-cols": table_cols,
+ "cols-name": col_names,
+ "cols-types": col_types,
"pinned-search": pinned_search,
"page": page_nb,
"total": total,