diff options
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 |
commit | 35eaa21a193e548be2e7478f1cf52b584dbe75d2 (patch) | |
tree | 02563973c557644cbe968bee8d0f8402f9394204 | |
parent | d829d11aec86a015d3898738ae9d73b5067bb865 (diff) | |
download | Ishtar-35eaa21a193e548be2e7478f1cf52b584dbe75d2.tar.bz2 Ishtar-35eaa21a193e548be2e7478f1cf52b584dbe75d2.zip |
WIP GIS importdevelop-5.0-qgis
-rw-r--r-- | ishtar_common/data_importer.py | 8 | ||||
-rw-r--r-- | ishtar_common/models_imports.py | 35 | ||||
-rw-r--r-- | ishtar_common/urls.py | 5 | ||||
-rw-r--r-- | ishtar_common/views_api.py | 32 | ||||
-rw-r--r-- | ishtar_common/views_item.py | 18 |
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, |