summaryrefslogtreecommitdiff
path: root/ishtar_common/utils.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2020-10-07 19:09:30 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2021-02-28 12:15:21 +0100
commit1e3da04336b9095e4497d098ea19c3178bc74cf6 (patch)
tree9cd21bf7e51d271b958a9a4b2b85367adbb97992 /ishtar_common/utils.py
parentcf6139abc5a64a2ff52eccdcf0424870cff6d57c (diff)
downloadIshtar-1e3da04336b9095e4497d098ea19c3178bc74cf6.tar.bz2
Ishtar-1e3da04336b9095e4497d098ea19c3178bc74cf6.zip
Refactoring of models. Document container - declare only id
Diffstat (limited to 'ishtar_common/utils.py')
-rw-r--r--ishtar_common/utils.py118
1 files changed, 114 insertions, 4 deletions
diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py
index 41a844026..31459f861 100644
--- a/ishtar_common/utils.py
+++ b/ishtar_common/utils.py
@@ -37,6 +37,7 @@ import subprocess
import sys
import tempfile
import time
+import uuid
import xmltodict
import zipfile
@@ -48,7 +49,7 @@ from django.contrib.contenttypes.models import ContentType
from django.contrib.gis.geos import GEOSGeometry
from django.contrib.sessions.backends.db import SessionStore
from django.core.cache import cache
-from django.core.exceptions import SuspiciousOperation
+from django.core.exceptions import SuspiciousOperation, ObjectDoesNotExist
from django.core.files import File
from django.core.validators import EMPTY_VALUES
from django.core.urlresolvers import reverse
@@ -713,9 +714,6 @@ def _post_save_geo(sender, **kwargs):
"""
Convert raw x, y, z point to real geo field
"""
- from ishtar_common.models import get_current_profile # not clean but utils
- # is loaded before models
-
profile = get_current_profile()
if not profile.mapping:
return
@@ -1758,3 +1756,115 @@ def try_fix_file(filename, make_copy=True, hard=False):
if make_copy:
shutil.copy2(full_file, filename)
return f
+
+
+def get_current_profile(force=False):
+ IshtarSiteProfile = apps.get_model("ishtar_common", "IshtarSiteProfile")
+ return IshtarSiteProfile.get_current_profile(force=force)
+
+
+PARSE_FORMULA = re.compile("{([^}]*)}")
+
+
+def _deduplicate(value):
+ new_values = []
+ for v in value.split('-'):
+ if v not in new_values:
+ new_values.append(v)
+ return '-'.join(new_values)
+
+
+FORMULA_FILTERS = {
+ 'upper': lambda x: x.upper(),
+ 'lower': lambda x: x.lower(),
+ 'capitalize': lambda x: x.capitalize(),
+ 'slug': lambda x: slugify(x),
+ 'deduplicate': _deduplicate
+}
+
+
+def get_external_id(key, item):
+ profile = get_current_profile()
+ if not hasattr(profile, key):
+ return
+ formula = getattr(profile, key)
+ dct = {}
+ for fkey in PARSE_FORMULA.findall(formula):
+ filtered = fkey.split('|')
+ initial_key = fkey[:]
+ fkey = filtered[0]
+ filters = []
+ for filtr in filtered[1:]:
+ if filtr in FORMULA_FILTERS:
+ filters.append(FORMULA_FILTERS[filtr])
+ if fkey.startswith('settings__'):
+ dct[fkey] = getattr(settings, fkey[len('settings__'):]) or ''
+ continue
+ obj = item
+ for k in fkey.split('__'):
+ try:
+ obj = getattr(obj, k)
+ except ObjectDoesNotExist:
+ obj = None
+ if hasattr(obj, 'all') and hasattr(obj, 'count'): # query manager
+ if not obj.count():
+ break
+ obj = obj.all()[0]
+ elif callable(obj):
+ obj = obj()
+ if obj is None:
+ break
+ if obj is None:
+ dct[initial_key] = ''
+ else:
+ dct[initial_key] = str(obj)
+ for filtr in filters:
+ dct[initial_key] = filtr(dct[initial_key])
+ values = formula.format(**dct).split('||')
+ value = values[0]
+ for filtr in values[1:]:
+ if filtr not in FORMULA_FILTERS:
+ value += '||' + filtr
+ continue
+ value = FORMULA_FILTERS[filtr](value)
+ return value
+
+
+PRIVATE_FIELDS = ('id', 'history_modifier', 'order', 'uuid')
+
+
+def duplicate_item(item, user=None, data=None):
+ model = item.__class__
+ new = model.objects.get(pk=item.pk)
+
+ for field in model._meta.fields:
+ # pk is in PRIVATE_FIELDS so: new.pk = None and a new
+ # item will be created on save
+ if field.name == "uuid":
+ new.uuid = uuid.uuid4()
+ elif field.name in PRIVATE_FIELDS:
+ setattr(new, field.name, None)
+ if user:
+ new.history_user = user
+ if data:
+ for k in data:
+ setattr(new, k, data[k])
+ new.save()
+
+ # m2m fields
+ m2m = [field.name for field in model._meta.many_to_many
+ if field.name not in PRIVATE_FIELDS]
+ for field in m2m:
+ for val in getattr(item, field).all():
+ if val not in getattr(new, field).all():
+ getattr(new, field).add(val)
+ return new
+
+
+def get_image_path(instance, filename):
+ # when using migrations instance is not a real ImageModel instance
+ if not hasattr(instance, '_get_image_path'):
+ n = datetime.datetime.now()
+ return "upload/{}/{:02d}/{:02d}/{}".format(
+ n.year, n.month, n.day, filename)
+ return instance._get_image_path(filename)