diff options
Diffstat (limited to 'ishtar_common/models.py')
| -rw-r--r-- | ishtar_common/models.py | 131 | 
1 files changed, 99 insertions, 32 deletions
| diff --git a/ishtar_common/models.py b/ishtar_common/models.py index e3a052a87..5fa668faf 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -1164,6 +1164,7 @@ class ImageModel(models.Model, ImageContainerModel):          filename = os.path.splitext(os.path.split(self.image.name)[-1])[0]          old_path = self.image.path          filename = "%s.jpg" % filename +        image = None          try:              image = Image.open(self.image.file)              # convert to RGB @@ -1191,6 +1192,9 @@ class ImageModel(models.Model, ImageContainerModel):                  save=False)          except IOError:              pass +        finally: +            if image: +                image.close()          return super(ImageModel, self).save(*args, **kwargs)      def _get_thumb_name(self, filename): @@ -1208,7 +1212,7 @@ class HistoryError(Exception):          return repr(self.value) -PRIVATE_FIELDS = ('id', 'history_modifier', 'order') +PRIVATE_FIELDS = ('id', 'history_modifier', 'order', 'uuid')  class BulkUpdatedItem(object): @@ -1804,8 +1808,8 @@ class QRCodeItem(models.Model, ImageContainerModel):              tmpdir_created = True          filename = tmpdir + os.sep + 'qrcode.png'          qr.png(filename, scale=settings.ISHTAR_QRCODE_SCALE) -        self.qrcode.save( -            "qrcode.png", File(open(filename, 'rb'))) +        with open(filename, 'rb') as qrfile: +            self.qrcode.save("qrcode.png", File(qrfile))          self.skip_history_when_saving = True          self._no_move = True          self.save() @@ -1814,6 +1818,21 @@ class QRCodeItem(models.Model, ImageContainerModel):  class DocumentItem(object): +    ALT_NAMES = { +        'documents__image__isnull': +            SearchAltName( +                pgettext_lazy("key for text search", "has-image"), +                'documents__image__isnull'), +        'documents__associated_url__isnull': +            SearchAltName( +                pgettext_lazy("key for text search", "has-url"), +                'documents__associated_url__isnull'), +        'documents__associated_file__isnull': +            SearchAltName( +                pgettext_lazy("key for text search", "has-attached-file"), +                'documents__associated_file__isnull'), +    } +      def public_representation(self):          images = []          if getattr(self, "main_image", None): @@ -1848,7 +1867,10 @@ class DocumentItem(object):          For sheet template: return "Add document / image" action          """          # url, base_text, icon, extra_text, extra css class, is a quick action -        actions = super(DocumentItem, self).get_extra_actions(request) +        try: +            actions = super(DocumentItem, self).get_extra_actions(request) +        except AttributeError: +            actions = []          if not hasattr(self, 'SLUG'):              return actions @@ -2120,6 +2142,34 @@ class CascasdeUpdate:                      post_save_geo(item.__class__, instance=item) +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 + +  class BaseHistorizedItem(StatisticItem, TemplateItem, FullSearch, Imported,                           JsonData, FixAssociated, CascasdeUpdate):      """ @@ -2187,29 +2237,7 @@ class BaseHistorizedItem(StatisticItem, TemplateItem, FullSearch, Imported,          return {}      def duplicate(self, user=None, data=None): -        model = self.__class__ -        new = model.objects.get(pk=self.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 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(self, field).all(): -                if val not in getattr(new, field).all(): -                    getattr(new, field).add(val) -        return new +        return duplicate_item(self, user, data)      def update_external_id(self, save=False):          if not self.EXTERNAL_ID_KEY or ( @@ -3568,8 +3596,8 @@ class DocumentTemplate(models.Model):              raise TemplateSyntaxError(str(e), 0)          except Exception as e:              raise TemplateSyntaxError(str(e), 0) -        output = open(output_name, 'wb') -        output.write(result) +        with open(output_name, 'wb') as output: +            output.write(result)          return output_name      def publish_labels(self, objects): @@ -3599,8 +3627,8 @@ class DocumentTemplate(models.Model):                  raise TemplateSyntaxError(str(e), e.lineno)              output_name = main_output_name + "-" + str(idx) + suffix              names.append(output_name) -            output = open(output_name, 'wb') -            output.write(result) +            with open(output_name, 'wb') as output: +                output.write(result)          output_name = main_output_name + suffix          o = OOoPy(infile=names[0], outfile=output_name)          if len(names) > 1: @@ -3735,6 +3763,13 @@ class Town(Imported, models.Model):                    'year': self.year or ""}          return values +    def get_values(self, prefix='', no_values=False, no_base_finds=True): +        return { +            prefix or "label": str(self), +            prefix + "name": self.name, +            prefix + "numero_insee": self.numero_insee +        } +      @classmethod      def history_decompress(cls, full_value, create=False):          if not full_value: @@ -5219,7 +5254,12 @@ class Document(BaseHistorizedItem, QRCodeItem, OwnPerms, ImageModel,          text=_(u"Bulk update"), target="many",          rights=['change_document', 'change_own_document'])      QUICK_ACTIONS = [ -        QA_EDIT +        QA_EDIT, +        QuickAction( +            url="document-qa-duplicate", icon_class="fa fa-clone", +            text=_("Duplicate"), target="one", +            rights=['change_document', +                    'change_own_document']),      ]      SERIALIZATION_FILES = ["image", "thumbnail", "associated_file"] @@ -5307,6 +5347,8 @@ class Document(BaseHistorizedItem, QRCodeItem, OwnPerms, ImageModel,          return "{}-{:04d}".format(self.operation.code_patriarche or '',                                     self.index)      """ +    def duplicate_item(self, user=None, data=None): +        return duplicate_item(self, user, data)      def public_representation(self):          site = Site.objects.get_current() @@ -5338,6 +5380,28 @@ class Document(BaseHistorizedItem, QRCodeItem, OwnPerms, ImageModel,              "thumbnail": thumbnail,          } +    def get_extra_actions(self, request): +        """ +        For sheet template +        """ +        # url, base_text, icon, extra_text, extra css class, is a quick action +        actions = super(Document, self).get_extra_actions(request) +        # is_locked = self.is_locked(request.user) + +        can_edit_document = self.can_do(request, 'change_document') +        if can_edit_document: +            actions += [ +                (reverse("document-qa-duplicate", args=[self.pk]), +                 _("Duplicate"), "fa fa-clone", "", "", True), +            ] +        return actions + +    @property +    def thumbnail_path(self): +        if not self.thumbnail: +            return "" +        return self.thumbnail.path +      @property      def image_path(self):          if not self.image: @@ -5348,6 +5412,7 @@ class Document(BaseHistorizedItem, QRCodeItem, OwnPerms, ImageModel,          values = super(Document, self).get_values(prefix=prefix,                                                    no_values=no_values)          values[prefix + "image_path"] = self.image_path +        values[prefix + "thumbnail_path"] = self.thumbnail_path          return values      @property @@ -5550,6 +5615,8 @@ class Document(BaseHistorizedItem, QRCodeItem, OwnPerms, ImageModel,          no_path_change = 'no_path_change' in kwargs \                           and kwargs.pop('no_path_change')          self.set_index() +        if not self.associated_url: +            self.associated_url = None          super(Document, self).save(*args, **kwargs)          if self.image and not no_path_change and \ | 
