From 62e05e799962d810804d0cd5f8d377ac8b434a01 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 22 Oct 2021 19:33:29 +0200 Subject: Syndication - update keys from match document --- ishtar_common/models_rest.py | 90 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 8 deletions(-) (limited to 'ishtar_common/models_rest.py') diff --git a/ishtar_common/models_rest.py b/ishtar_common/models_rest.py index e29356567..cc07a8803 100644 --- a/ishtar_common/models_rest.py +++ b/ishtar_common/models_rest.py @@ -2,11 +2,13 @@ import datetime import os import tempfile +from django.apps import apps from django.conf import settings from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.contrib.gis.db import models from django.contrib.postgres.fields import ArrayField +from django.core.files import File from django.utils.text import slugify try: @@ -153,14 +155,13 @@ class ApiExternalSource(models.Model): .values_list("associated_type", flat=True) .distinct() ) - lst_sheet = uno.get_sheet(calc, len(types), str(_("List types"))) + lst_sheet = uno.get_or_create_sheet(calc, len(types), str(_("List types"))) for idx, tpe in enumerate(types): self._generate_match_page(idx, tpe, uno, calc, lst_sheet) tmpdir = tempfile.mkdtemp(prefix="ishtar-matches-") base = "{}-{}.ods".format(datetime.date.today().isoformat(), slugify(self.name)) dest_filename = "{}{}{}".format(tmpdir, os.sep, base) uno.save_calc(calc, dest_filename) - from django.core.files import File with open(dest_filename, "rb") as fle: self.match_document = File(fle, base) @@ -170,8 +171,14 @@ class ApiExternalSource(models.Model): def _generate_match_page(self, page_number, tpe, uno, calc, lst_sheet): model = ContentType.objects.get(pk=tpe).model_class() ROW_NUMBER = 1000 - sheet = uno.get_sheet(calc, page_number) - sheet.Name = str(model._meta.verbose_name) + sheet = uno.get_or_create_sheet(calc, page_number) + q = ApiKeyMatch.objects.filter(source=self, associated_type=tpe) + if not q.count(): + return + sm = q.all()[0].search_model + sheet.Name = ( + f"{sm.app_label}.{sm.model}-{model._meta.app_label}.{model.__name__.lower()}" + ) for col_number, column in enumerate( (_("Distant key"), _("Distant label"), _("Local")) ): @@ -180,9 +187,7 @@ class ApiExternalSource(models.Model): cell.CharWeight = 150 cell.setString(str(column)) - for idx, match in enumerate( - ApiKeyMatch.objects.filter(source=self, associated_type=tpe).all() - ): + for idx, match in enumerate(q.all()): cell = sheet.getCellByPosition(0, idx + 1) cell.setString(match.distant_slug) cell = sheet.getCellByPosition(1, idx + 1) @@ -207,7 +212,76 @@ class ApiExternalSource(models.Model): ) def update_from_match_document(self): - pass + if not self.match_document: + return + if not UnoCalc: + return + uno = UnoCalc() + calc = uno.open_calc(self.match_document.path) + if not calc: + return + errors = [] + updated = 0 + for idx in range(uno.get_sheet_number(calc) - 1): # do not read the last sheet + sheet = uno.get_sheet(calc, idx) + sheet_name = sheet.Name + try: + search_model_name, ctype = sheet.Name.split("-") + app_label, model_name = search_model_name.split(".") + search_model = ContentType.objects.get( + app_label=app_label, model=model_name + ) + except (ValueError, ContentType.DoesNotExist): + errors.append(str(_(f"{sheet_name} is not a correct sheet name."))) + continue + try: + app_label, model_name = ctype.split(".") + ct = ContentType.objects.get(app_label=app_label, model=model_name) + except (ValueError, ContentType.DoesNotExist): + errors.append(str(_(f"{sheet_name} is not a correct sheet name."))) + continue + data = uno.sheet_get_data(sheet) + base_q = ApiKeyMatch.objects.filter( + source=self, search_model=search_model, associated_type=ct + ) + model = ct.model_class() + for idx_line, line in enumerate(data): + if not idx_line: # header + continue + distant_key, distant_label, local_name = line + q = base_q.filter(distant_slug=distant_key, distant_label=distant_label) + if not q.count(): + errors.append( + str( + _( + f"{ctype} - {distant_key}, {distant_label} not referenced in the database." + ) + ) + ) + continue + if q.filter(local_label=local_name).count(): + # no change + continue + api_key = q.all()[0] + key_name = "slug" + if hasattr(model, "txt_idx"): + key_name = "txt_idx" + q = model.objects.filter(label=local_name) + if not q.count(): + errors.append( + str( + _( + f"{ctype} - {local_name} do not exists in local database." + ) + ) + ) + continue + tpe = q.all()[0] + api_key.local_slug = getattr(tpe, key_name) + api_key.local_label = local_name + api_key.save() + updated += 1 + return {"errors": errors, "updated": updated} class ApiKeyMatch(models.Model): -- cgit v1.2.3