summaryrefslogtreecommitdiff
path: root/ishtar_common/models_rest.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2021-10-22 19:33:29 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2022-12-12 12:20:59 +0100
commit62e05e799962d810804d0cd5f8d377ac8b434a01 (patch)
tree2ad3d5f85dde8137c519f9c8e1c362df5ba49d7d /ishtar_common/models_rest.py
parentfede10bc3ed5a9df9325d3c9d671a167760a9381 (diff)
downloadIshtar-62e05e799962d810804d0cd5f8d377ac8b434a01.tar.bz2
Ishtar-62e05e799962d810804d0cd5f8d377ac8b434a01.zip
Syndication - update keys from match document
Diffstat (limited to 'ishtar_common/models_rest.py')
-rw-r--r--ishtar_common/models_rest.py90
1 files changed, 82 insertions, 8 deletions
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):