diff options
Diffstat (limited to 'ishtar_common/models.py')
-rw-r--r-- | ishtar_common/models.py | 184 |
1 files changed, 158 insertions, 26 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 9509b36a6..3c46573dd 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -243,10 +243,15 @@ class OwnPerms: user = IshtarUser.objects.get(user_ptr=user) if user.is_anonymous(): return cls.objects.filter(pk__isnull=True) + items = [] + if hasattr(cls, 'BASKET_MODEL'): + items = list(cls.BASKET_MODEL.objects.filter(user=user).all()) query = cls.get_query_owns(user) if not query: return cls.objects.filter(pk__isnull=True) - return cls.objects.filter(query).order_by(*cls._meta.ordering) + items += list( + cls.objects.filter(query).order_by(*cls._meta.ordering).all()) + return items class Cached(object): @@ -321,13 +326,34 @@ class GeneralType(models.Model, Cached): @classmethod def get_types(cls, dct={}, instances=False, exclude=[], empty_first=True, default=None): + # cache + cache_key = None + if not instances: + keys = [u"{}".format(ex) for ex in exclude] + [ + empty_first and 'empty_first' or ''] + [u"{}".format(default)] + cache_key, value = get_cache(cls, keys) + if value: + return value 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_types(base_dct, instances, exclude=exclude, - empty_first=empty_first, default=default) + if not cache_key: + return cls._get_parent_types( + base_dct, instances, exclude=exclude, + empty_first=empty_first, default=default) + vals = [v for v in cls._get_parent_types( + base_dct, instances, exclude=exclude, + empty_first=empty_first, default=default)] + cache.set(cache_key, vals, settings.CACHE_TIMEOUT) + return vals + + if not cache_key: + return cls._get_types(base_dct, instances, exclude=exclude, + empty_first=empty_first, default=default) + vals = [v for v in cls._get_types( + base_dct, instances, exclude=exclude, empty_first=empty_first, + default=default)] + cache.set(cache_key, vals, settings.CACHE_TIMEOUT) + return vals @classmethod def _get_types(cls, dct={}, instances=False, exclude=[], empty_first=True, @@ -475,6 +501,33 @@ class GeneralType(models.Model, Cached): item.generate_key() +class Basket(models.Model): + """ + Abstract class for a basket + Subclass must be defined with an "items" ManyToManyField + """ + IS_BASKET = True + label = models.CharField(_(u"Label"), max_length=1000) + comment = models.TextField(_(u"Comment"), blank=True, null=True) + user = models.ForeignKey('IshtarUser', blank=True, null=True) + available = models.BooleanField(_(u"Available"), default=True) + + class Meta: + abstract = True + unique_together = (('label', 'user'),) + + def __unicode__(self): + return self.label + + def get_short_menu_class(self): + return 'basket' + + @property + def associated_filename(self): + return "{}-{}".format(datetime.date.today().strftime( + "%Y-%m-%d"), slugify(self.label)) + + class ItemKey(models.Model): key = models.CharField(_(u"Key"), max_length=100) content_type = models.ForeignKey(ContentType) @@ -520,25 +573,27 @@ class ImageModel(models.Model): filename = os.path.splitext(os.path.split(self.image.name)[-1])[0] old_path = self.image.path filename = "%s.jpg" % filename - image = Image.open(self.image.file) - - # convert to RGB - if image.mode not in ('L', 'RGB'): - image = image.convert('RGB') - - # resize if necessary - self.image.save(filename, - self.create_thumb(image, self.IMAGE_MAX_SIZE), - save=False) - - if old_path != self.image.path: - os.remove(old_path) - - # save the thumbnail - self.thumbnail.save( - '_%s' % filename, - self.create_thumb(image, self.THUMB_MAX_SIZE), - save=False) + try: + image = Image.open(self.image.file) + # convert to RGB + if image.mode not in ('L', 'RGB'): + image = image.convert('RGB') + + # resize if necessary + self.image.save(filename, + self.create_thumb(image, self.IMAGE_MAX_SIZE), + save=False) + + if old_path != self.image.path: + os.remove(old_path) + + # save the thumbnail + self.thumbnail.save( + '_%s' % filename, + self.create_thumb(image, self.THUMB_MAX_SIZE), + save=False) + except IOError: + pass super(ImageModel, self).save(*args, **kwargs) @@ -549,8 +604,11 @@ class HistoryError(Exception): def __str__(self): return repr(self.value) +PRIVATE_FIELDS = ('id', 'history_modifier', 'order') + class BaseHistorizedItem(Imported): + IS_BASKET = False history_modifier = models.ForeignKey( User, related_name='+', on_delete=models.SET_NULL, verbose_name=_(u"Last editor"), blank=True, null=True) @@ -691,6 +749,8 @@ class BaseHistorizedItem(Imported): class GeneralRelationType(GeneralType): order = models.IntegerField(_(u"Order"), default=1) symmetrical = models.BooleanField(_(u"Symmetrical")) + tiny_label = models.CharField(_(u"Tiny label"), max_length=50, + blank=True, null=True) # # an inverse must be set # inverse_relation = models.ForeignKey( # 'RelationType', verbose_name=_(u"Inverse relation"), blank=True, @@ -705,6 +765,9 @@ class GeneralRelationType(GeneralType): raise ValidationError( _(u"Cannot have symmetrical and an inverse_relation")) + def get_tiny_label(self): + return self.tiny_label or self.label or u"" + def save(self, *args, **kwargs): obj = super(GeneralRelationType, self).save(*args, **kwargs) # after saving check that the inverse_relation of the inverse_relation @@ -769,6 +832,35 @@ class LightHistorizedItem(BaseHistorizedItem): super(LightHistorizedItem, self).save(*args, **kwargs) return True +PARSE_FORMULA = re.compile("{([^}]*)}") + + +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): + 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 callable(obj): + obj = obj() + if obj is None: + break + if obj is None: + dct[fkey] = '' + else: + dct[fkey] = obj + return formula.format(**dct) + class IshtarSiteProfile(models.Model, Cached): slug_field = 'slug' @@ -783,6 +875,46 @@ class IshtarSiteProfile(models.Model, Cached): warehouse = models.BooleanField( _(u"Warehouses module"), default=False, help_text=_(u"Need finds module")) + homepage = models.TextField( + _(u"Home page"), null=True, blank=True, + help_text=_(u"Homepage of Ishtar - if not defined a default homepage " + u"will appear. Use the markdown syntax.")) + file_external_id = models.TextField( + _(u"File external id"), + default="{settings__ISHTAR_LOCAL_PREFIX}{year}-{numeric_reference}", + help_text=_(u"Formula to manage file external ID. " + u"Change this with care. With incorrect formula, the " + u"application might be unusable and import of external " + u"data can be destructive.")) + parcel_external_id = models.TextField( + _(u"Parcel external id"), + default="{associated_file__external_id}{operation__code_patriarche}-" + "{town__numero_insee}-{section}{parcel_number}", + help_text=_(u"Formula to manage parcel external ID. " + u"Change this with care. With incorrect formula, the " + u"application might be unusable and import of external " + u"data can be destructive.")) + context_record_external_id = models.TextField( + _(u"Context record external id"), + default="{parcel__external_id}-{label}", + help_text=_(u"Formula to manage context record external ID. " + u"Change this with care. With incorrect formula, the " + u"application might be unusable and import of external " + u"data can be destructive.")) + base_find_external_id = models.TextField( + _(u"Base find external id"), + default="{context_record__external_id}-{label}", + help_text=_(u"Formula to manage base find external ID. " + u"Change this with care. With incorrect formula, the " + u"application might be unusable and import of external " + u"data can be destructive.")) + find_external_id = models.TextField( + _(u"Find external id"), + default="{get_first_base_find__context_record__external_id}-{label}", + help_text=_(u"Formula to manage find external ID. " + u"Change this with care. With incorrect formula, the " + u"application might be unusable and import of external " + u"data can be destructive.")) active = models.BooleanField(_(u"Current active"), default=False) class Meta: @@ -974,7 +1106,7 @@ class Dashboard: 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: + for dpt, lbl in settings.ISHTAR_DPTS: self.serie_labels.append(unicode(dpt)) idx = 'number_' + unicode(dpt) kwargs_num['fltr']["towns__numero_insee__startswith"] = \ |