diff options
| -rw-r--r-- | archaeological_context_records/models.py | 15 | ||||
| -rw-r--r-- | archaeological_finds/models_finds.py | 25 | ||||
| -rw-r--r-- | archaeological_operations/tests.py | 5 | ||||
| -rw-r--r-- | example_project/settings.py | 2 | ||||
| -rw-r--r-- | ishtar_common/models.py | 23 | ||||
| -rw-r--r-- | ishtar_common/tests.py | 2 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 1 | 
7 files changed, 62 insertions, 11 deletions
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 678b0371d..d27c6a262 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -17,6 +17,7 @@  # See the file COPYING for details. +  from django.conf import settings  from django.contrib.gis.db import models  from django.core.urlresolvers import reverse @@ -30,7 +31,7 @@ from ishtar_common.utils import cached_label_changed  from ishtar_common.models import GeneralType, BaseHistorizedItem, \      HistoricalRecords, OwnPerms, ShortMenuItem, Source, GeneralRelationType,\      GeneralRecordRelations, post_delete_record_relation, get_external_id, \ -    ImageModel, post_save_cache, ValueGetter +    ImageModel, post_save_cache, ValueGetter, BulkUpdatedItem  from archaeological_operations.models import Operation, Period, Parcel @@ -158,7 +159,7 @@ class CRBulkView(object):      """ -class ContextRecord(BaseHistorizedItem, ImageModel, OwnPerms, +class ContextRecord(BulkUpdatedItem, BaseHistorizedItem, ImageModel, OwnPerms,                      ValueGetter, ShortMenuItem):      SHOW_URL = 'show-contextrecord'      SLUG = 'contextrecord' @@ -299,7 +300,13 @@ class ContextRecord(BaseHistorizedItem, ImageModel, OwnPerms,          return self.short_label      @classmethod -    def cached_label_bulk_update(cls, operation_id=None, parcel_id=None): +    def cached_label_bulk_update(cls, operation_id=None, parcel_id=None, +                                 transaction_id=None): +        transaction_id, is_recursion = cls.bulk_recursion( +            transaction_id, [operation_id, parcel_id]) +        if is_recursion: +            return +          if operation_id:              where = "operation_id = %s"              args = [int(operation_id)] @@ -310,6 +317,8 @@ class ContextRecord(BaseHistorizedItem, ImageModel, OwnPerms,              kwargs = {'parcel_id': parcel_id}          else:              return +        kwargs['transaction_id'] = transaction_id +          sql = """          UPDATE "archaeological_context_records_contextrecord" AS cr              SET cached_label = diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 3248e2214..da1823d8a 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -18,6 +18,7 @@  # See the file COPYING for details.  import datetime +import time  from django.conf import settings  from django.contrib.gis.db import models @@ -36,7 +37,8 @@ from ishtar_common.models import GeneralType, ImageModel, BaseHistorizedItem, \  from archaeological_operations.models import AdministrativeAct  from archaeological_context_records.models import ContextRecord, Dating -from ishtar_common.models import PRIVATE_FIELDS, SpatialReferenceSystem +from ishtar_common.models import PRIVATE_FIELDS, SpatialReferenceSystem, \ +    BulkUpdatedItem  class MaterialType(GeneralType): @@ -146,7 +148,7 @@ class BFBulkView(object):      """ -class BaseFind(BaseHistorizedItem, OwnPerms): +class BaseFind(BulkUpdatedItem, BaseHistorizedItem, OwnPerms):      label = models.TextField(_(u"Free ID"))      external_id = models.TextField(_(u"External ID"), blank=True, null=True)      auto_external_id = models.BooleanField( @@ -330,7 +332,12 @@ class BaseFind(BaseHistorizedItem, OwnPerms):      @classmethod      def cached_label_bulk_update(cls, operation_id=None, parcel_id=None, -                                 context_record_id=None): +                                 context_record_id=None, transaction_id=None): +        transaction_id, is_recursion = cls.bulk_recursion( +            transaction_id, [operation_id, parcel_id, context_record_id]) +        if is_recursion: +            return +          if operation_id:              filters = """              INNER JOIN archaeological_context_records_contextrecord acr @@ -353,6 +360,7 @@ class BaseFind(BaseHistorizedItem, OwnPerms):              kwargs = {'context_record_id': context_record_id}          else:              return +        kwargs['transaction_id'] = transaction_id          sql = """          UPDATE "archaeological_finds_basefind" AS bf @@ -487,8 +495,8 @@ class FBulkView(object):      """ -class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, -           ShortMenuItem): +class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, ImageModel, +           OwnPerms, ShortMenuItem):      CHECK_DICT = dict(CHECK_CHOICES)      SHOW_URL = 'show-find'      SLUG = 'find' @@ -911,7 +919,12 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms,      @classmethod      def cached_label_bulk_update(cls, operation_id=None, parcel_id=None, -                                 context_record_id=None): +                                 context_record_id=None, transaction_id=None): +        transaction_id, is_recursion = cls.bulk_recursion( +            transaction_id, [operation_id, parcel_id, context_record_id]) +        if is_recursion: +            return +          if operation_id:              filters = """              INNER JOIN find_first_base_find myfbf diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index a5b83ff1c..0b466c48c 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -25,6 +25,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile  from django.core.urlresolvers import reverse  from django.test.client import Client +from django.contrib.auth.models import User  from django.contrib.auth.models import Permission  import models @@ -593,8 +594,12 @@ def create_operation(user, orga=None, values={}):  class OperationInitTest(object):      def create_user(self):          username, password, self.user = create_user() +        return self.user      def get_default_user(self): +        q = User.objects.filter(is_superuser=False) +        if q.count(): +            return q.all()[0]          return self.create_user()      def create_orgas(self, user=None): diff --git a/example_project/settings.py b/example_project/settings.py index 8241e3fca..ea7aa48fc 100644 --- a/example_project/settings.py +++ b/example_project/settings.py @@ -10,7 +10,7 @@ DEBUG_TOOLBAR = False  TEMPLATE_DEBUG = DEBUG  SQL_DEBUG = False  DJANGO_EXTENSIONS = False -USE_SPATIALITE_FOR_TESTS = True +USE_SPATIALITE_FOR_TESTS = False  TEST_VIEWS = True  if "test" in sys.argv: diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 6c83c8bfb..2475cd289 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -31,6 +31,7 @@ import os  import re  import shutil  import tempfile +import time  import unicodecsv  import zipfile @@ -861,6 +862,28 @@ class HistoryError(Exception):  PRIVATE_FIELDS = ('id', 'history_modifier', 'order') +class BulkUpdatedItem(object): +    @classmethod +    def bulk_recursion(cls, transaction_id, extra_args): +        """ +        Prevent infinite recursion. Should not happen but wrong manipulation +        in the database or messy imports can generate circular relations + +        :param transaction_id: current transaction ID (unix time) - if null +        a transaction ID is generated +        :param extra_args: arguments dealing with +        :return: (transaction ID, is a recursion) +        """ +        if not transaction_id: +            transaction_id = unicode(time.time()) +        args = ['cached_label_bulk_update', transaction_id] + extra_args +        key, val = get_cache(cls, args) +        if val: +            return transaction_id, True +        cache.set(key, 1, settings.CACHE_SMALLTIMEOUT) +        return transaction_id, False + +  class BaseHistorizedItem(Imported):      IS_BASKET = False      history_modifier = models.ForeignKey( diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py index e3958814c..eca722670 100644 --- a/ishtar_common/tests.py +++ b/ishtar_common/tests.py @@ -84,7 +84,7 @@ def create_superuser():  def create_user():      username = 'username678' -    password = 'dcbqj756456!@%' +    password = 'dcbqj756aaa456!@%'      q = User.objects.filter(username=username)      if q.count():          return username, password, q.all()[0] diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 962db5945..555a338f8 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -20,6 +20,7 @@  from functools import wraps  import hashlib  import random +import datetime  from django import forms  from django.conf import settings  | 
