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"] = \ | 
