diff options
| author | Étienne Loks <etienne.loks@proxience.com> | 2015-08-28 12:11:01 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@proxience.com> | 2015-08-28 12:11:01 +0200 | 
| commit | 51a047d697917141fda34a310c8706b4729592c1 (patch) | |
| tree | a45322231185919090bfcb0faf34c17375205477 | |
| parent | 1c450cb70ba182df6ca9e793afc6ebc7b7f06c76 (diff) | |
| download | Ishtar-51a047d697917141fda34a310c8706b4729592c1.tar.bz2 Ishtar-51a047d697917141fda34a310c8706b4729592c1.zip | |
flake8
| -rw-r--r-- | archaeological_files/forms.py | 6 | ||||
| -rw-r--r-- | archaeological_files/models.py | 12 | ||||
| -rw-r--r-- | ishtar_common/models.py | 268 | ||||
| -rw-r--r-- | ishtar_common/widgets.py | 2 | 
4 files changed, 176 insertions, 112 deletions
| diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py index 4bde6f97e..b701bac49 100644 --- a/archaeological_files/forms.py +++ b/archaeological_files/forms.py @@ -170,9 +170,9 @@ class DashboardForm(forms.Form):          if self.cleaned_data.get('file_type'):              fltr['file_type_id'] = self.cleaned_data['file_type']          if self.cleaned_data.get('after'): -            fltr[date_source+'_date__gte'] = self.cleaned_data['after'] +            fltr[date_source + '_date__gte'] = self.cleaned_data['after']          if self.cleaned_data.get('before'): -            fltr[date_source+'_date__lte'] = self.cleaned_data['before'] +            fltr[date_source + '_date__lte'] = self.cleaned_data['before']          return fltr @@ -269,7 +269,7 @@ class FileFormPreventive(forms.Form):              reverse_lazy(                  'autocomplete-person',                  args=[PersonType.objects.get(txt_idx='general_contractor').pk] -                ), +            ),              limit={'person_types': [                  PersonType.objects.get(txt_idx='general_contractor').pk]},              associated_model=Person, new=True), diff --git a/archaeological_files/models.py b/archaeological_files/models.py index a7b23564d..a090e0290 100644 --- a/archaeological_files/models.py +++ b/archaeological_files/models.py @@ -245,7 +245,7 @@ class File(BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem,              delta = datetime.date.today() - self.reception_date              cls = 'red'              if self.saisine_type and self.saisine_type.delay: -                if delta.days <= (self.saisine_type.delay*2/3): +                if delta.days <= (self.saisine_type.delay * 2 / 3):                      cls = 'green'                  elif delta.days <= self.saisine_type.delay:                      cls = 'orange' @@ -277,7 +277,7 @@ class File(BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem,      @property      def reference(self): -        return settings.FILE_PREFIX+u"-".join( +        return settings.FILE_PREFIX + u"-".join(              (unicode(self.year), unicode(self.numeric_reference or '0')))      def _generate_cached_label(self): @@ -330,11 +330,11 @@ class File(BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem,      def total_surface_ha(self):          if self.total_surface: -            return self.total_surface/10000.0 +            return self.total_surface / 10000.0      def total_developed_surface_ha(self):          if self.total_developed_surface: -            return self.total_developed_surface/10000.0 +            return self.total_developed_surface / 10000.0      def operation_acts(self):          acts = [] @@ -524,7 +524,7 @@ class FileDashboard:          if self.rescue['total_number']:              self.rescue['with_associated_operation_percent'] = round(                  float(self.rescue['with_associated_operation']) -                / self.rescue['total_number']*100, 2) +                / self.rescue['total_number'] * 100, 2)          by_year_operationnal = rescues.filter(operations__isnull=False)\              .extra({'date': 'date_trunc(\'year\', ' @@ -539,7 +539,7 @@ class FileDashboard:                 not dct['number']:                  continue              val = round(float(by_year_operationnal[idx]['number']) / -                        dct['number']*100, 2) +                        dct['number'] * 100, 2)              percents.append({'date': dct['date'], 'number': val})          self.rescue['operational_by_year'] = percents diff --git a/ishtar_common/models.py b/ishtar_common/models.py index a21df0529..d997d667d 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -22,7 +22,6 @@ Models description  """  from cStringIO import StringIO  import copy -import csv  import datetime  from PIL import Image  from importlib import import_module @@ -50,11 +49,9 @@ from django.contrib.auth.models import User, Group  from django.contrib.contenttypes.models import ContentType  from django.contrib.contenttypes import generic  from django.contrib.gis.db import models -from django.contrib import admin  from simple_history.models import HistoricalRecords as BaseHistoricalRecords -from ishtar_common.unicode_csv import UnicodeWriter  from ishtar_common.ooo_replace import ooo_replace  from ishtar_common.model_merging import merge_model_objects  from ishtar_common.utils import get_cache @@ -62,6 +59,7 @@ from ishtar_common.data_importer import Importer, ImportFormater, \      IntegerFormater, FloatFormater, UnicodeFormater, DateFormater, \      TypeFormater, YearFormater, StrToBoolean +  def post_save_user(sender, **kwargs):      user = kwargs['instance']      ishtaruser = None @@ -72,22 +70,27 @@ def post_save_user(sender, **kwargs):          else:              ishtaruser = q.all()[0]          ADMINISTRATOR, created = PersonType.objects.get_or_create( -                                                txt_idx='administrator') +            txt_idx='administrator')          if ishtaruser.is_superuser \             and not ishtaruser.has_right('administrator'):              ishtaruser.person.person_types.add(ADMINISTRATOR) -    except DatabaseError: # manage when db is not synced +    except DatabaseError:  # manage when db is not synced          pass  post_save.connect(post_save_user, sender=User) +  class Imported(models.Model): -    imports = models.ManyToManyField('Import', blank=True, null=True, -                    related_name="imported_%(app_label)s_%(class)s") +    imports = models.ManyToManyField( +        'Import', blank=True, null=True, +        related_name="imported_%(app_label)s_%(class)s") +      class Meta:          abstract = True +  class ValueGetter(object):      _prefix = "" +      def get_values(self, prefix=''):          if not prefix:              prefix = self._prefix @@ -107,8 +110,8 @@ class ValueGetter(object):                  continue              value_list.append((key, unicode(values[key])))          values['VALUES'] = u'\n'.join( -                        [u"%s: %s" % (k, v) for k, v in sorted(value_list, -                                                        key=lambda x:x[0])]) +            [u"%s: %s" % (k, v) for k, v in sorted(value_list, +                                                   key=lambda x:x[0])])          for global_var in GlobalVar.objects.all():              values[global_var.slug] = global_var.value or ""          return values @@ -116,12 +119,13 @@ class ValueGetter(object):      @classmethod      def get_empty_values(cls, prefix=''):          if not prefix: -            prefix = self._prefix +            prefix = cls._prefix          values = {}          for field_name in cls._meta.get_all_field_names():              values[prefix + field_name] = ''          return values +  class HistoricalRecords(BaseHistoricalRecords):      def create_historical_record(self, instance, type):          try: @@ -134,9 +138,9 @@ class HistoricalRecords(BaseHistoricalRecords):          attrs = {}          for field in instance._meta.fields:              attrs[field.attname] = getattr(instance, field.attname) -        q_history = instance.history.filter( -                                   history_modifier_id=history_modifier.pk -                                   ).order_by('-history_date', '-history_id') +        q_history = instance.history\ +            .filter(history_modifier_id=history_modifier.pk)\ +            .order_by('-history_date', '-history_id')          if not q_history.count():              manager.create(history_type=type, **attrs)              return @@ -144,10 +148,10 @@ class HistoricalRecords(BaseHistoricalRecords):          # multiple saving by the same user in a very short time are generaly          # caused by post_save signals it is not relevant to keep them          min_history_date = datetime.datetime.now() \ -                           - datetime.timedelta(seconds=5) +            - datetime.timedelta(seconds=5)          q = q_history.filter(history_date__isnull=False, -                             history_date__gt=min_history_date -                     ).order_by('-history_date', '-history_id') +                             history_date__gt=min_history_date)\ +                     .order_by('-history_date', '-history_id')          if q.count():              return @@ -157,8 +161,9 @@ class HistoricalRecords(BaseHistoricalRecords):                  manager.create(history_type=type, **attrs)                  return -# valid ID validator for models +  def valid_id(cls): +    # valid ID validator for models      def func(value):          try:              cls.objects.get(pk=value) @@ -166,6 +171,7 @@ def valid_id(cls):              raise ValidationError(_(u"Not a valid item."))      return func +  def valid_ids(cls):      def func(value):          if "," in value: @@ -175,19 +181,21 @@ def valid_ids(cls):                  cls.objects.get(pk=v)              except ObjectDoesNotExist:                  raise ValidationError( -                                   _(u"An item selected is not a valid item.")) +                    _(u"An item selected is not a valid item."))      return func -# unique validator for models +  def is_unique(cls, field): +    # unique validator for models      def func(value): -        query = {field:value} +        query = {field: value}          try:              assert cls.objects.filter(**query).count() == 0          except AssertionError:              raise ValidationError(_(u"This item already exist."))      return func +  class OwnPerms:      """      Manage special permissions for object's owner @@ -197,7 +205,7 @@ class OwnPerms:          """          Query object to get own items          """ -        return None # implement for each object +        return None  # implement for each object      def is_own(self, user):          """ @@ -207,7 +215,7 @@ class OwnPerms:          if not query:              return False          query = query & Q(pk=self.pk) -        return cls.objects.filter(query).count() +        return self.objects.filter(query).count()      @classmethod      def has_item_of(cls, user): @@ -233,13 +241,15 @@ class OwnPerms:              return cls.objects.filter(pk__isnull=True)          return cls.objects.filter(query).order_by(*cls._meta.ordering) +  class GeneralType(models.Model):      """      Abstract class for "types"      """      label = models.CharField(_(u"Label"), max_length=100) -    txt_idx = models.CharField(_(u"Textual ID"), -                         validators=[validate_slug], max_length=100, unique=True) +    txt_idx = models.CharField( +        _(u"Textual ID"), validators=[validate_slug], max_length=100, +        unique=True)      comment = models.TextField(_(u"Comment"), blank=True, null=True)      available = models.BooleanField(_(u"Available"), default=True)      HELP_TEXT = u"" @@ -275,11 +285,11 @@ class GeneralType(models.Model):              elif c_rank < item.rank:                  help_items += u"<dl>\n"              c_rank = item.rank -            help_items += u"<dt>%s</dt><dd>%s</dd>" % (item.label, -                                u"<br/>".join(item.comment.split('\n'))) +            help_items += u"<dt>%s</dt><dd>%s</dd>" % ( +                item.label, u"<br/>".join(item.comment.split('\n')))          c_rank += 1          if c_rank: -            help_items += c_rank*u"</dl>" +            help_items += c_rank * u"</dl>"          if help_text or help_items != u'\n':              return mark_safe(help_text + help_items)          return u"" @@ -289,8 +299,9 @@ class GeneralType(models.Model):                    default=None):          base_dct = dct.copy()          if hasattr(cls, 'parent'): -            return cls._get_parent_types(base_dct, instances, exclude=exclude, -                                     empty_first=empty_first, default=default) +            return cls._get_parent_types( +                base_dct, instances, exclude=exclude, empty_first=empty_first, +                default=default)          return cls._get_types(base_dct, instances, exclude=exclude,                                empty_first=empty_first, default=default) @@ -334,8 +345,8 @@ class GeneralType(models.Model):                  child.rank = prefix                  yield child              else: -                yield (child.pk, SafeUnicode(prefix*cls.PREFIX + \ -                                         unicode(_(unicode(child))) )) +                yield (child.pk, SafeUnicode(prefix * cls.PREFIX + +                       unicode(_(unicode(child)))))              for sub_child in cls._get_childs(child, dct, prefix, instances,                                               exclude=exclude):                  yield sub_child @@ -358,13 +369,14 @@ class GeneralType(models.Model):                  yield item              else:                  yield (item.pk, unicode(item)) -            for child in cls._get_childs(item, dct, instances, exclude=exclude): +            for child in cls._get_childs(item, dct, instances, +                                         exclude=exclude):                  yield child      def save(self, *args, **kwargs):          if not self.id and not self.label: -            self.label = u" ".join(u" ".join(self.txt_idx.split('-') -                                                        ).split('_')).title() +            self.label = u" ".join(u" ".join(self.txt_idx.split('-')) +                                   .split('_')).title()          if not self.txt_idx:              self.txt_idx = slugify(self.label)[:100] @@ -373,11 +385,13 @@ class GeneralType(models.Model):              old = self.__class__.objects.get(pk=self.pk)              content_type = ContentType.objects.get_for_model(self.__class__)              if slugify(self.label) != slugify(old.label): -                ItemKey.objects.filter(object_id=self.pk, key=slugify(old.label), -                                   content_type=content_type).delete() +                ItemKey.objects.filter( +                    object_id=self.pk, key=slugify(old.label), +                    content_type=content_type).delete()              if self.txt_idx != old.txt_idx: -                ItemKey.objects.filter(object_id=self.pk, key=old.txt_idx, -                                   content_type=content_type).delete() +                ItemKey.objects.filter( +                    object_id=self.pk, key=old.txt_idx, +                    content_type=content_type).delete()          obj = super(GeneralType, self).save(*args, **kwargs)          self.generate_key(force=True) @@ -385,12 +399,12 @@ class GeneralType(models.Model):      def add_key(self, key, force=False):          content_type = ContentType.objects.get_for_model(self.__class__) -        if not force and ItemKey.objects.filter(key=key, -                              content_type=content_type).count(): +        if not force and ItemKey.objects.filter( +                key=key, content_type=content_type).count():              return          if force: -            ItemKey.objects.filter(key=key, content_type=content_type).exclude( -                                                    object_id=self.pk).delete() +            ItemKey.objects.filter(key=key, content_type=content_type)\ +                           .exclude(object_id=self.pk).delete()          ItemKey.objects.get_or_create(object_id=self.pk, key=key,                                        content_type=content_type) @@ -408,21 +422,24 @@ class GeneralType(models.Model):      @classmethod      def generate_keys(cls): -        content_type = ContentType.objects.get_for_model(cls) +        # content_type = ContentType.objects.get_for_model(cls)          for item in cls.objects.all():              item.generate_key() +  class ItemKey(models.Model):      key = models.CharField(_(u"Key"), max_length=100)      content_type = models.ForeignKey(ContentType)      object_id = models.PositiveIntegerField()      content_object = generic.GenericForeignKey('content_type', 'object_id') -    importer = models.ForeignKey('Import', null=True, blank=True, -                            help_text=_(u"Key specific to an import")) +    importer = models.ForeignKey( +        'Import', null=True, blank=True, +        help_text=_(u"Key specific to an import"))      def __unicode__(self):          return self.key +  class ImageModel(models.Model):      image = models.ImageField(upload_to="upload/", blank=True, null=True)      thumbnail = models.ImageField(upload_to='upload/thumbs/', blank=True, @@ -470,31 +487,34 @@ class ImageModel(models.Model):                  os.remove(old_path)              # save the thumbnail -            self.thumbnail.save('_%s' % filename, -                             self.create_thumb(image, self.THUMB_MAX_SIZE), -                             save=False) +            self.thumbnail.save( +                '_%s' % filename, +                self.create_thumb(image, self.THUMB_MAX_SIZE), +                save=False)          super(ImageModel, self).save(*args, **kwargs) +  class HistoryError(Exception):      def __init__(self, value):          self.value = value +      def __str__(self):          return repr(self.value) +  class BaseHistorizedItem(Imported): -    history_modifier = models.ForeignKey(User, related_name='+', -                              on_delete=models.SET_NULL, -                              verbose_name=_(u"Last editor"), blank=True, -                              null=True) -    history_creator = models.ForeignKey(User, related_name='+', -                              on_delete=models.SET_NULL, -                              verbose_name=_(u"Creator"), blank=True, -                              null=True) +    history_modifier = models.ForeignKey( +        User, related_name='+', on_delete=models.SET_NULL, +        verbose_name=_(u"Last editor"), blank=True, null=True) +    history_creator = models.ForeignKey( +        User, related_name='+', on_delete=models.SET_NULL, +        verbose_name=_(u"Creator"), blank=True, null=True) +      class Meta:          abstract = True      def save(self, *args, **kwargs): -        assert hasattr(self, 'history_modifier') == True +        assert hasattr(self, 'history_modifier')          if not self.id:              self.history_creator = self.history_modifier          super(BaseHistorizedItem, self).save(*args, **kwargs) @@ -531,10 +551,10 @@ class BaseHistorizedItem(Imported):          for k in model._meta.get_all_field_names():              field = model._meta.get_field_by_name(k)[0]              if hasattr(field, 'rel') and field.rel: -                if not hasattr(item, k+'_id'): +                if not hasattr(item, k + '_id'):                      setattr(item, k, getattr(self, k))                      continue -                val = getattr(item, k+'_id') +                val = getattr(item, k + '_id')                  if not val:                      setattr(item, k, None)                      continue @@ -577,7 +597,7 @@ class BaseHistorizedItem(Imported):                      setattr(self, k, getattr(new_item, k))              try:                  self.history_modifier = User.objects.get( -                           pk=new_item.history_modifier_id) +                    pk=new_item.history_modifier_id)              except User.ObjectDoesNotExist:                  pass              self.save() @@ -597,8 +617,8 @@ class BaseHistorizedItem(Imported):      def get_show_url(self):          try: -            return reverse('show-'+self.__class__.__name__.lower(), -                                            args=[self.pk, '']) +            return reverse('show-' + self.__class__.__name__.lower(), +                           args=[self.pk, ''])          except NoReverseMatch:              return @@ -619,12 +639,15 @@ class BaseHistorizedItem(Imported):              items.append('00000000')          return u"-".join([unicode(item) for item in items]) +  class ShortMenuItem(object):      def get_short_menu_class(self):          return '' +  class LightHistorizedItem(BaseHistorizedItem):      history_date = models.DateTimeField(default=datetime.datetime.now) +      class Meta:          abstract = True @@ -632,11 +655,13 @@ class LightHistorizedItem(BaseHistorizedItem):          super(LightHistorizedItem, self).save(*args, **kwargs)          return True +  class GlobalVar(models.Model):      slug = models.SlugField(_(u"Variable name"), unique=True)      description = models.TextField(_(u"Description of the variable"),                                     null=True, blank=True)      value = models.TextField(_(u"Value"), null=True, blank=True) +      class Meta:          verbose_name = _(u"Global variable")          verbose_name_plural = _(u"Global variables") @@ -657,6 +682,7 @@ class GlobalVar(models.Model):          except cls.DoesNotExist:              return None +  def cached_globalvar_changed(sender, **kwargs):      if not kwargs['instance']:          return @@ -666,6 +692,7 @@ def cached_globalvar_changed(sender, **kwargs):  post_save.connect(cached_globalvar_changed, sender=GlobalVar) +  class UserDashboard:      def __init__(self):          types = IshtarUser.objects.values('person__person_types', @@ -673,37 +700,38 @@ class UserDashboard:          self.types = types.annotate(number=Count('pk'))\                            .order_by('person__person_types') +  class DashboardFormItem(object):      @classmethod      def get_periods(cls, slice='month', fltr={}, date_source='creation'):          date_var = date_source + '_date' -        q = cls.objects.filter(**{date_var+'__isnull':False}) +        q = cls.objects.filter(**{date_var + '__isnull': False})          if fltr:              q = q.filter(**fltr)          if slice == 'year': -            return [res[date_var].year for res in list(q.values(date_var -                                ).annotate(Count("id")).order_by())] +            return [res[date_var].year for res in list(q.values(date_var) +                    .annotate(Count("id")).order_by())]          elif slice == 'month':              return [(res[date_var].year, res[date_var].month) -                               for res in list(q.values(date_var -                                ).annotate(Count("id")).order_by())] +                    for res in list(q.values(date_var) +                    .annotate(Count("id")).order_by())]          return []      @classmethod      def get_by_year(cls, year, fltr={}, date_source='creation'):          date_var = date_source + '_date' -        q = cls.objects.filter(**{date_var+'__isnull':False}) +        q = cls.objects.filter(**{date_var + '__isnull': False})          if fltr:              q = q.filter(**fltr) -        return q.filter(**{date_var+'__year':year}).distinct('pk') +        return q.filter(**{date_var + '__year': year}).distinct('pk')      @classmethod      def get_by_month(cls, year, month, fltr={}, date_source='creation'):          date_var = date_source + '_date' -        q = cls.objects.filter(**{date_var+'__isnull':False}) +        q = cls.objects.filter(**{date_var + '__isnull': False})          if fltr:              q = q.filter(**fltr) -        q = q.filter(**{date_var+'__year':year, date_var+'__month':month}) +        q = q.filter(**{date_var + '__year': year, date_var + '__month': month})          return q.distinct('pk')      @classmethod @@ -713,6 +741,7 @@ class DashboardFormItem(object):              q = q.filter(**fltr)          return q.distinct('pk').count() +  class Dashboard:      def __init__(self, model, slice='year', date_source=None, show_detail=None,                   fltr={}): @@ -729,9 +758,11 @@ class Dashboard:              last_ids = last_ids.filter(history_type=modif_type)              from archaeological_finds.models import Find              if self.model == Find: -                last_ids = last_ids.filter(downstream_treatment_id__isnull=True) +                last_ids = last_ids.filter( +                    downstream_treatment_id__isnull=True)                  if modif_type == '+': -                   last_ids = last_ids.filter(upstream_treatment_id__isnull=True) +                    last_ids = last_ids.filter( +                        upstream_treatment_id__isnull=True)              last_ids = last_ids.order_by('-hd').distinct().all()[:5]              for idx in last_ids:                  try: @@ -742,7 +773,7 @@ class Dashboard:                  obj.history_date = idx['hd']                  last_lst.append(obj)          # years -        base_kwargs = {'fltr':fltr.copy()} +        base_kwargs = {'fltr': fltr.copy()}          if date_source:              base_kwargs['date_source'] = date_source          periods_kwargs = copy.deepcopy(base_kwargs) @@ -764,19 +795,18 @@ class Dashboard:                              list(reversed(self.numbers)))]          if slice == 'month':              periods = list(reversed(self.periods)) -            self.periods = ["%d-%s-01" % (p[0], ('0'+str(p[1])) -                    if len(str(p[1])) == 1 else p[1]) -                            for p in periods] +            self.periods = ["%d-%s-01" % (p[0], ('0' + str(p[1])) +                            if len(str(p[1])) == 1 else p[1]) for p in periods]              self.values = [('month', "", self.periods)]              if show_detail:                  for dpt in settings.ISHTAR_DPTS:                      self.serie_labels.append(unicode(dpt))                      idx = 'number_' + unicode(dpt)                      kwargs_num['fltr']["towns__numero_insee__startswith"] = \ -                                                                 unicode(dpt) +                        unicode(dpt)                      numbers = [model.get_by_month(*p.split('-')[:2],                                                    **kwargs_num).count() -                                for p in self.periods] +                               for p in self.periods]                      self.values += [(idx, dpt, list(numbers))]                  # put "Total" at the end                  self.serie_labels.append(self.serie_labels.pop(0)) @@ -802,30 +832,30 @@ class Dashboard:          self.operation_average = self.get_average(operation_numbers)          self.operation_variance = self.get_variance(operation_numbers)          self.operation_standard_deviation = self.get_standard_deviation( -                                                       operation_numbers) +            operation_numbers)          self.operation_median = self.get_median(operation_numbers)          operation_mode_pk = self.get_mode(dict(zip(operations, -                                                     operation_numbers))) +                                                   operation_numbers)))          if operation_mode_pk:              from archaeological_operations.models import Operation -            self.operation_mode = unicode(Operation.objects.get( -                                                       pk=operation_mode_pk)) +            self.operation_mode = unicode(Operation.objects +                                                   .get(pk=operation_mode_pk))      def get_average(self, vals=[]):          if not vals:              vals = self.numbers[:] -        return sum(vals)/len(vals) +        return sum(vals) / len(vals)      def get_variance(self, vals=[]):          if not vals:              vals = self.numbers[:]          avrg = self.get_average(vals) -        return self.get_average([(x-avrg)**2 for x in vals]) +        return self.get_average([(x - avrg) ** 2 for x in vals])      def get_standard_deviation(self, vals=[]):          if not vals:              vals = self.numbers[:] -        return round(self.get_variance(vals)**0.5, 3) +        return round(self.get_variance(vals) ** 0.5, 3)      def get_median(self, vals=[]):          if not vals: @@ -833,9 +863,9 @@ class Dashboard:          len_vals = len(vals)          vals.sort()          if (len_vals % 2) == 1: -            return vals[len_vals/2] +            return vals[len_vals / 2]          else: -            return (vals[len_vals/2-1] + vals[len_vals/2])/2.0 +            return (vals[len_vals / 2 - 1] + vals[len_vals / 2]) / 2.0      def get_mode(self, vals={}):          if not vals: @@ -845,13 +875,14 @@ class Dashboard:              if vals[v] == mx:                  return v +  class DocumentTemplate(models.Model):      CLASSNAMES = (('archaeological_operations.models.AdministrativeAct',                    _(u"Administrative Act")),)      name = models.CharField(_(u"Name"), max_length=100)      template = models.FileField(_(u"Template"), upload_to="upload/templates/") -    associated_object_name = models.CharField(_(u"Associated object"), -                                             max_length=100, choices=CLASSNAMES) +    associated_object_name = models.CharField( +        _(u"Associated object"), max_length=100, choices=CLASSNAMES)      available = models.BooleanField(_(u"Available"), default=True)      class Meta: @@ -878,9 +909,10 @@ class DocumentTemplate(models.Model):              datetime.date.today().strftime('%Y-%m-%d') +\              u"." + self.template.name.split('.')[-1]          values = c_object.get_values() -        missing = ooo_replace(self.template, output_name, values) +        ooo_replace(self.template, output_name, values)          return output_name +  class State(models.Model):      label = models.CharField(_(u"Label"), max_length=30)      number = models.CharField(_(u"Number"), unique=True, max_length=3) @@ -892,6 +924,7 @@ class State(models.Model):      def __unicode__(self):          return self.label +  class Department(models.Model):      label = models.CharField(_(u"Label"), max_length=30)      number = models.CharField(_(u"Number"), unique=True, max_length=3) @@ -906,6 +939,7 @@ class Department(models.Model):      def __unicode__(self):          return self.label +  class Address(BaseHistorizedItem):      address = models.TextField(_(u"Address"), null=True, blank=True)      address_complement = models.TextField(_(u"Address complement"), null=True, @@ -918,19 +952,21 @@ class Address(BaseHistorizedItem):      phone = models.CharField(_(u"Phone"), max_length=18, null=True, blank=True)      mobile_phone = models.CharField(_(u"Mobile phone"), max_length=18,                                      null=True, blank=True) -    email = models.EmailField(_(u"Email"), max_length=75, blank=True, null=True) +    email = models.EmailField( +        _(u"Email"), max_length=75, blank=True, null=True)      history = HistoricalRecords()      class Meta:          abstract = True +  class Merge(models.Model):      merge_key = models.CharField(_("Merge key"), max_length=300, -                                    blank=True, null=True) +                                 blank=True, null=True)      merge_candidate = models.ManyToManyField("self", -                                    blank=True, null=True) +                                             blank=True, null=True)      merge_exclusion = models.ManyToManyField("self", -                                    blank=True, null=True) +                                             blank=True, null=True)      # 1 for one word similarity, 2 for two word similarity, etc.      MERGE_CLEMENCY = None      EMPTY_MERGE_KEY = '--' @@ -950,16 +986,17 @@ class Merge(models.Model):              self.save()          if not self.pk or self.merge_key == self.EMPTY_MERGE_KEY:              return -        q = self.__class__.objects.exclude(pk=self.pk -                                ).exclude(merge_exclusion=self -                                ).exclude(merge_candidate=self) +        q = self.__class__.objects\ +                          .exclude(pk=self.pk)\ +                          .exclude(merge_exclusion=self)\ +                          .exclude(merge_candidate=self)          if not self.MERGE_CLEMENCY:              q = q.filter(merge_key=self.merge_key)          else:              subkeys_front = u"-".join( -                        self.merge_key.split('-')[:self.MERGE_CLEMENCY]) +                self.merge_key.split('-')[:self.MERGE_CLEMENCY])              subkeys_back = u"-".join( -                        self.merge_key.split('-')[-self.MERGE_CLEMENCY:]) +                self.merge_key.split('-')[-self.MERGE_CLEMENCY:])              q = q.filter(Q(merge_key__istartswith=subkeys_front) |                           Q(merge_key__iendswith=subkeys_back))          for item in q.all(): @@ -969,11 +1006,13 @@ class Merge(models.Model):          self.generate_merge_key()          item = super(Merge, self).save(*args, **kwargs)          self.generate_merge_candidate() +        return item      def merge(self, item):          merge_model_objects(self, item)          self.generate_merge_candidate() +  class OrganizationType(GeneralType):      class Meta:          verbose_name = _(u"Organization type") @@ -998,6 +1037,7 @@ if 'archaeological_finds' in settings.INSTALLED_APPS:                _(u"Finds")),               ] + MODELS +  def get_model_fields(model):      """      Return a dict of fields from  model @@ -1011,6 +1051,7 @@ def get_model_fields(model):          fields.update(model.get_extra_fields())      return fields +  def import_class(full_path_classname):      mods = full_path_classname.split('.')      if len(mods) == 1: @@ -1018,6 +1059,7 @@ def import_class(full_path_classname):      module = import_module('.'.join(mods[:-1]))      return getattr(module, mods[-1]) +  class ImporterType(models.Model):      """      Description of a table to be mapped with ishtar database @@ -1078,6 +1120,7 @@ class ImporterType(models.Model):          newclass = type(name, (Importer,), args)          return newclass +  def get_associated_model(parent_model, keys):      model = None      OBJECT_CLS = None @@ -1097,6 +1140,7 @@ def get_associated_model(parent_model, keys):              return get_associated_model(model, keys[1:])      return model +  class ImporterDefault(models.Model):      """      Targets of default values in an import @@ -1122,6 +1166,7 @@ class ImporterDefault(models.Model):              values[default_value.target] = default_value.get_value()          return values +  class ImporterDefaultValues(models.Model):      """      Default values in an import @@ -1158,6 +1203,7 @@ class ImporterDefaultValues(models.Model):              pass          return "" +  class ImporterColumn(models.Model):      """      Import file column description @@ -1171,6 +1217,7 @@ class ImporterColumn(models.Model):          verbose_name = _(u"Importer - Column")          verbose_name_plural = _(u"Importer - Columns") +  class ImporterDuplicateField(models.Model):      """      Direct copy of result in other fields @@ -1182,6 +1229,7 @@ class ImporterDuplicateField(models.Model):          verbose_name = _(u"Importer - Duplicate field")          verbose_name_plural = _(u"Importer - Duplicate fields") +  class Regexp(models.Model):      name = models.CharField(_(u"Name"), max_length=100)      description = models.CharField(_(u"Description"), blank=True, null=True, @@ -1194,6 +1242,7 @@ class Regexp(models.Model):      def __unicode__(self):          return self.name +  class ImportTarget(models.Model):      """      Ishtar database target for a column @@ -1220,6 +1269,7 @@ class ImportTarget(models.Model):              return []          return self.associated_model.get_types() +  class TargetKey(models.Model):      """      User's link between import source and ishtar database. @@ -1310,8 +1360,9 @@ DATE_FORMATS = (      ('%d/%m/%Y', _(u"Day/month/4 digit year. e.g.: \"04/02/2015\"")),  ) -IMPORTER_TYPES_CHOICES = {'TypeFormater':TARGET_MODELS, -                          'DateFormater':DATE_FORMATS} +IMPORTER_TYPES_CHOICES = {'TypeFormater': TARGET_MODELS, +                          'DateFormater': DATE_FORMATS} +  class FormaterType(models.Model):      formater_type = models.CharField(u"Formater type", max_length=20, @@ -1379,6 +1430,7 @@ ENCODINGS = [(settings.ENCODING, settings.ENCODING),               (settings.ALT_ENCODING, settings.ALT_ENCODING),               ('utf-8', 'utf-8')] +  class Import(models.Model):      user = models.ForeignKey('IshtarUser')      importer_type = models.ForeignKey(ImporterType) @@ -1506,6 +1558,7 @@ class Import(models.Model):                           for obj in getattr(self, accessor).all()]          return imported +  def pre_delete_import(sender, **kwargs):      # deleted imported items when an import is delete      instance = kwargs.get('instance') @@ -1520,6 +1573,7 @@ def pre_delete_import(sender, **kwargs):  pre_delete.connect(pre_delete_import, sender=Import) +  class Organization(Address, Merge, OwnPerms, ValueGetter):      TABLE_COLS = ('name', 'organization_type',)      name = models.CharField(_(u"Name"), max_length=300) @@ -1555,6 +1609,7 @@ class Organization(Address, Merge, OwnPerms, ValueGetter):                                 if getattr(self, attr)]          return slugify(u"-".join(values)) +  class PersonType(GeneralType):      #rights = models.ManyToManyField(WizardStep, verbose_name=_(u"Rights"))      groups = models.ManyToManyField(Group, verbose_name=_(u"Groups"), @@ -1564,6 +1619,7 @@ class PersonType(GeneralType):          verbose_name_plural = _(u"Person types")          ordering = ('label',) +  class Person(Address, Merge, OwnPerms, ValueGetter) :      _prefix = 'person_'      TYPE = ( @@ -1689,6 +1745,7 @@ class Person(Address, Merge, OwnPerms, ValueGetter) :              for fle in self.general_contractor.all():                  fle.save() # force update of raw_general_contractor +  class IshtarUser(User):      person = models.ForeignKey(Person, verbose_name=_(u"Person"), unique=True,                                 related_name='ishtaruser') @@ -1724,11 +1781,13 @@ class IshtarUser(User):      def full_label(self):          return self.person.full_label() +  class AuthorType(GeneralType):      class Meta:          verbose_name = _(u"Author type")          verbose_name_plural = _(u"Author types") +  class Author(models.Model):      person = models.ForeignKey(Person, verbose_name=_(u"Person"),                                 related_name='author') @@ -1747,21 +1806,25 @@ class Author(models.Model):                 list(self.findsource_related.all()) + \                 list(self.contextrecordsource_related.all()) +  class SourceType(GeneralType):      class Meta:          verbose_name = _(u"Source type")          verbose_name_plural = _(u"Source types") +  class SupportType(GeneralType):      class Meta:          verbose_name = _(u"Support type")          verbose_name_plural = _(u"Support types") +  class Format(GeneralType):      class Meta:          verbose_name = _(u"Format")          verbose_name_plural = _(u"Formats") +  class Source(models.Model):      title = models.CharField(_(u"Title"), max_length=300)      external_id = models.CharField(_(u"External ID"), max_length=12, null=True, @@ -1813,6 +1876,7 @@ if settings.COUNTRY == 'fr':          def __unicode__(self):              return settings.JOINT.join((self.name, unicode(self.arrondissement))) +  class Town(models.Model):      name = models.CharField(_(u"Name"), max_length=100)      surface = models.IntegerField(_(u"Surface (m²)"), blank=True, null=True) diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index efafa38e2..9bffe4ec5 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -67,7 +67,7 @@ class MultipleAutocompleteField(forms.MultipleChoiceField):          new = kwargs.pop('new') if 'new' in kwargs else None          if 'widget' not in kwargs and self.model:              kwargs['widget'] = JQueryAutoComplete( -                reverse_lazy('autocomplete-'+self.model.__name__.lower()), +                reverse_lazy('autocomplete-' + self.model.__name__.lower()),                  associated_model=self.model, new=new,                  multiple=True)          super(MultipleAutocompleteField, self).__init__(*args, **kwargs) | 
