summaryrefslogtreecommitdiff
path: root/ishtar_common/views_item.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common/views_item.py')
-rw-r--r--ishtar_common/views_item.py135
1 files changed, 69 insertions, 66 deletions
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py
index 23752c8a9..b5c63cc65 100644
--- a/ishtar_common/views_item.py
+++ b/ishtar_common/views_item.py
@@ -13,6 +13,7 @@ import requests
import subprocess # nosec
from tempfile import NamedTemporaryFile
+from django.apps import apps
from django.conf import settings
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
@@ -46,6 +47,7 @@ from django.utils.translation import (
deactivate,
pgettext_lazy,
)
+from guardian.models import UserObjectPermission
from tidylib import tidy_document as tidy
from unidecode import unidecode
from weasyprint import HTML, CSS
@@ -54,50 +56,24 @@ from weasyprint.fonts import FontConfiguration
from bootstrap_datepicker.widgets import DateField
from ishtar_common.utils import (
+ API_MAIN_MODELS,
check_model_access_control,
CSV_OPTIONS,
+ GENERAL_TYPE_PREFIX,
get_all_field_names,
- Round,
+ get_current_item_keys_dict,
+ get_current_profile,
+ HistoryError,
PRIVATE_FIELDS,
+ SearchAltName,
+ Round,
)
-from ishtar_common.models import get_current_profile, GeneralType, SearchAltName
-from ishtar_common.models_common import HistoryError
from .menus import Menu
-from . import models, models_rest
-from archaeological_files.models import File
-from archaeological_operations.models import (
- Operation,
- ArchaeologicalSite,
- AdministrativeAct,
-)
-from archaeological_context_records.models import ContextRecord
-from archaeological_finds.models import Find, FindBasket, Treatment, TreatmentFile
-from archaeological_warehouse.models import Warehouse, Container
-
logger = logging.getLogger(__name__)
ENCODING = settings.ENCODING or "utf-8"
-CURRENT_ITEM_KEYS = (
- ("file", File),
- ("operation", Operation),
- ("site", ArchaeologicalSite),
- ("contextrecord", ContextRecord),
- ("warehouse", Warehouse),
- ("container", Container),
- ("find", Find),
- ("findbasket", FindBasket),
- ("treatmentfile", TreatmentFile),
- ("treatment", Treatment),
- ("administrativeact", AdministrativeAct),
- ("administrativeactop", AdministrativeAct),
- ("administrativeactfile", AdministrativeAct),
- ("administrativeacttreatment", AdministrativeAct),
- ("administrativeacttreatmentfile", AdministrativeAct),
-)
-CURRENT_ITEM_KEYS_DICT = dict(CURRENT_ITEM_KEYS)
-
HIERARCHIC_LEVELS = 5
LIST_FIELDS = { # key: hierarchic depth
@@ -354,11 +330,11 @@ def show_source_item(request, source_id, model, name, base_dct, extra_dct):
source_id, external_id = int(source_id), int(external_id)
except ValueError:
raise Http404()
- models_rest.ApiExternalSource.objects.get()
+ ApiExternalSource = apps.get_model("ishtar_common", "ApiExternalSource")
# TODO: check permissions
try:
- src = models_rest.ApiExternalSource.objects.get(pk=source_id)
- except models_rest.ApiExternalSource.DoesNotExist:
+ src = ApiExternalSource.objects.get(pk=source_id)
+ except ApiExternalSource.DoesNotExist:
return HttpResponse("{}", content_type="text/plain")
url = src.url
if not url.endswith("/"):
@@ -618,6 +594,8 @@ def _get_values(request, val):
else:
vals = [val]
new_vals = []
+ Organization = apps.get_model("ishtar_common", "Organization")
+ Person = apps.get_model("ishtar_common", "Person")
for v in vals:
if callable(v):
try:
@@ -626,7 +604,7 @@ def _get_values(request, val):
continue
try:
if (
- not isinstance(v, (models.Person, models.Organization))
+ not isinstance(v, (Person, Organization))
and hasattr(v, "url")
and v.url
):
@@ -1144,7 +1122,7 @@ def _manage_dated_fields(dated_fields, dct):
def _clean_type_val(val):
- for prefix in GeneralType.PREFIX_CODES:
+ for prefix in GENERAL_TYPE_PREFIX["prefix_codes"]:
val = val.replace(prefix, "")
val = val.strip()
if val.startswith('"') and val.endswith('"'):
@@ -1210,6 +1188,7 @@ def _manage_hierarchic_fields(model, dct, and_reqs):
hierarchic_fields = HIERARCHIC_FIELDS[:]
if hasattr(model, "hierarchic_fields"):
hierarchic_fields += model.hierarchic_fields()
+ Town = apps.get_model("ishtar_common", "Town")
for reqs in dct.copy():
if type(reqs) not in (list, tuple):
reqs = [reqs]
@@ -1257,6 +1236,7 @@ def _manage_hierarchic_fields(model, dct, and_reqs):
and_reqs.append(main_req)
continue
+ Container = apps.get_model("archaeological_warehouse", "Container")
for val in vals:
attr = "cached_label__iexact"
if val.endswith("*"):
@@ -1277,7 +1257,7 @@ def _manage_hierarchic_fields(model, dct, and_reqs):
vals = [v.replace('"', "") for v in val.split(";")]
town_ids = []
for val in vals:
- q = models.Town.objects.filter(cached_label__iexact=val).values_list(
+ q = Town.objects.filter(cached_label__iexact=val).values_list(
"id", flat=True)
if not q.count():
continue
@@ -1287,7 +1267,7 @@ def _manage_hierarchic_fields(model, dct, and_reqs):
for rel_query in ("parents__", "children__"):
for idx in range(HIERARCHIC_LEVELS):
k = rel_query * (idx + 1) + "pk"
- q = models.Town.objects.filter(
+ q = Town.objects.filter(
**{k: town_id}).values_list("id", flat=True)
if not q.count():
break
@@ -1595,6 +1575,7 @@ def _manage_default_search(
dct, request, model, default_name, my_base_request, my_relative_session_names
):
pinned_search = ""
+ current_item_keys_dict = get_current_item_keys_dict()
pin_key = "pin-search-" + default_name
base_request = my_base_request if isinstance(my_base_request, dict) else {}
dct = {k: v for k, v in dct.items() if v}
@@ -1606,6 +1587,7 @@ def _manage_default_search(
): # an item is pinned
value = request.session[default_name]
if "basket-" in value:
+ FindBasket = apps.get_model("archaeological_finds", "FindBasket")
try:
dct = {"basket__pk": request.session[default_name].split("-")[-1]}
pinned_search = str(FindBasket.objects.get(pk=dct["basket__pk"]))
@@ -1630,9 +1612,9 @@ def _manage_default_search(
name in request.session
and request.session[name]
and "basket-" not in request.session[name]
- and name in CURRENT_ITEM_KEYS_DICT
+ and name in current_item_keys_dict
):
- up_model = CURRENT_ITEM_KEYS_DICT[name]
+ up_model = current_item_keys_dict[name]
try:
dct.update({key: request.session[name]})
up_item = up_model.objects.get(pk=dct[key])
@@ -2031,6 +2013,7 @@ def get_item(
no_link=False,
no_limit=False,
return_query=False,
+ ishtaruser=None, # could be provided when request is None
**dct,
):
available_perms = []
@@ -2044,7 +2027,8 @@ def get_item(
if "json" in data_type:
EMPTY = "[]"
- if data_type not in ("json", "csv", "json-image", "json-map", "json-stats"):
+ if not return_query and data_type not in (
+ "json", "csv", "json-image", "json-map", "json-stats"):
return HttpResponse(EMPTY, content_type="text/plain")
if data_type == "json-stats" and len(model.STATISTIC_MODALITIES) < 2:
@@ -2070,6 +2054,7 @@ def get_item(
own = True
if (
full == "shortcut"
+ and request
and "SHORTCUT_SEARCH" in request.session
and request.session["SHORTCUT_SEARCH"] == "own"
):
@@ -2077,13 +2062,23 @@ def get_item(
query_own = None
if own:
- q = models.IshtarUser.objects.filter(user_ptr=request.user)
- if not q.count():
- return HttpResponse(EMPTY, content_type="text/plain")
+ # TODO: verify alt_query_own
+ """
if alt_query_own:
query_own = getattr(model, alt_query_own)(q.all()[0])
else:
query_own = model.get_query_owns(q.all()[0])
+ print(query_own) # TODO - get old request to transform them
+ """
+ user_pk = request.user.pk if request else ishtaruser.pk
+ q = UserObjectPermission.objects.filter(
+ user_id=user_pk,
+ permission__codename=f"view_own_{model._meta.model_name}",
+ content_type=ContentType.objects.get_for_model(model)
+ )
+ query_own = Q(
+ pk__in=[int(pk) for pk in q.values_list("object_pk", flat=True)]
+ )
query_parameters = {}
@@ -2191,14 +2186,10 @@ def get_item(
request_keys.update(my_extra_request_keys)
# manage search on json fields and excluded fields
- if (
- search_form
- and request
- and request.user
- and getattr(request.user, "ishtaruser", None)
- ):
+ if search_form:
+ ishtaruser = request.user.ishtaruser if request else ishtaruser
available, __, excluded_fields, json_fields = search_form.check_custom_form(
- request.user.ishtaruser
+ ishtaruser
)
# for now no manage on excluded_fields: should we prevent search on
# some fields regarding the user concerned?
@@ -2218,10 +2209,12 @@ def get_item(
if "query" in dct:
request_items = dct["query"]
request_items["submited"] = True
- elif request.method == "POST":
+ elif request and request.method == "POST":
request_items = request.POST
- else:
+ elif request:
request_items = request.GET
+ else:
+ return HttpResponse(EMPTY, content_type="text/plain")
count = dct.get("count", False)
@@ -2271,7 +2264,7 @@ def get_item(
key = "name__icontains"
else:
key = "cached_label__icontains"
- dct[key] = request.GET.get("term", None)
+ dct[key] = (request and request.GET.get("term", None)) or None
try:
old = "old" in request_items and int(request_items["old"])
@@ -2332,11 +2325,12 @@ def get_item(
# manage default and pinned search and not bookmark
if (
not has_a_search
+ and request
and not request_items.get("search_vector", "")
and not request_items.get("submited", "")
and full != "shortcut"
):
- if data_type == "csv" and func_name in request.session:
+ if data_type == "csv" and func_name and func_name in request.session:
dct = request.session[func_name]
else:
# default search
@@ -2451,6 +2445,10 @@ def get_item(
# manage hierarchic in shortcut menu
if full == "shortcut":
+ File = apps.get_model("archaeological_files", "File")
+ Operation = apps.get_model("archaeological_operations", "Operation")
+ ContextRecord = apps.get_model("archaeological_context_records", "ContextRecord")
+ Find = apps.get_model("archaeological_finds", "Find")
ASSOCIATED_ITEMS = {
Operation: (File, "associated_file__pk"),
ContextRecord: (Operation, "operation__pk"),
@@ -2463,6 +2461,7 @@ def get_item(
if current:
dct = {upper_key: current}
query &= Q(**dct)
+ # print("ishtar_common/views_item.py - 2455")
# print(query, distinct_queries, base_query, exc_query, extras)
items = model.objects.filter(query)
for d_q in distinct_queries:
@@ -2540,6 +2539,7 @@ def get_item(
for col in cols:
query_table_cols += col.split("|")
+ Document = apps.get_model("ishtar_common", "Document")
# contextual (full, simple, etc.) col
contxt = full and "full" or "simple"
if (
@@ -2559,7 +2559,7 @@ def get_item(
table_cols.append("cached_label")
if data_type == "json-image":
prefix = ""
- if model != models.Document:
+ if model != Document:
prefix = "main_image__"
query_table_cols.append(prefix + "thumbnail")
table_cols.append(prefix + "thumbnail")
@@ -2584,7 +2584,7 @@ def get_item(
for k in request_items:
if not k.startswith("order["):
continue
- num = int(k.split("]")[0][len("order[") :])
+ num = int(k.split("]")[0][len("order["):])
if num not in sorts:
sorts[num] = ["", ""] # sign, col_num
if k.endswith("[dir]"):
@@ -2907,9 +2907,10 @@ def adapt_distant_search(params, src, model):
search_vector = params["search_vector"][0]
match = RE_FACET.search(search_vector)
final_search_vector = ""
+ ApiKeyMatch = apps.get_model("ishtar_common", "ApiKeyMatch")
while match:
key, value, __ = match.groups()
- q = models_rest.ApiKeyMatch.objects.filter(
+ q = ApiKeyMatch.objects.filter(
source=src,
search_model__model__iexact=model,
search_keys__contains=[key],
@@ -2929,10 +2930,11 @@ def adapt_distant_search(params, src, model):
def get_distant_item(request, model, external_source_id, data_type=None):
- # TODO: check permissions
+ # TODO: verify/test check permissions
+ ApiExternalSource = apps.get_model("ishtar_common", "ApiExternalSource")
try:
- src = models_rest.ApiExternalSource.objects.get(pk=external_source_id)
- except (models_rest.ApiExternalSource.DoesNotExist, ValueError):
+ src = ApiExternalSource.objects.get(pk=external_source_id)
+ except (ApiExternalSource.DoesNotExist, ValueError):
return HttpResponse("{}", content_type="text/plain")
url = src.url
url += reverse(f"api-search-{model}")
@@ -2954,7 +2956,7 @@ def get_distant_item(request, model, external_source_id, data_type=None):
"submited",
"data_type",
]
- app = models_rest.MAIN_MODELS[model]
+ app = API_MAIN_MODELS[model]
model_class = ContentType.objects.get(app_label=app, model=model).model_class()
bool_fields = model_class.REVERSED_BOOL_FIELDS + model_class.BOOL_FIELDS + model_class.CALLABLE_BOOL_FIELDS
is_empty_params = not any(
@@ -3010,9 +3012,10 @@ def external_export(request, source_id, model_name, slug):
if not url:
return HttpResponse('Unauthorized', status=401)
+ ApiExternalSource = apps.get_model("ishtar_common", "ApiExternalSource")
try:
- src = models_rest.ApiExternalSource.objects.get(pk=source_id)
- except (models_rest.ApiExternalSource.DoesNotExist, ValueError):
+ src = ApiExternalSource.objects.get(pk=source_id)
+ except (ApiExternalSource.DoesNotExist, ValueError):
return HttpResponse('Unauthorized', status=401)
url = src.url + url