Merge pull request #470 from taigaio/astagi-feature/attachments-sha1

Astagi feature/attachments sha1
remotes/origin/logger
David Barragán Merino 2015-09-25 19:43:22 +02:00
commit 503f320942
6 changed files with 58 additions and 5 deletions

View File

@ -19,6 +19,7 @@
- Add externall apps: now Taiga can integrate with hundreds of applications and service.
- Improve searching system, now full text searchs are supported
- Improve export system, now is more efficient and prevents possible crashes with heavy projects.
- Add sha1 hash to attachments to verify the integrity of files (thanks to [@astagi](https://github.com/astagi)).
- i18n.
- Add italian (it) translation.
- Add polish (pl) translation.

View File

@ -0,0 +1,12 @@
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from taiga.projects.attachments.models import Attachment
class Command(BaseCommand):
@transaction.atomic
def handle(self, *args, **options):
for attachment in Attachment.objects.all():
attachment.save()

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('attachments', '0004_auto_20150508_1141'),
]
operations = [
migrations.AddField(
model_name='attachment',
name='sha1',
field=models.CharField(default='', verbose_name='sha1', max_length=40, blank=True),
preserve_default=True,
),
]

View File

@ -68,6 +68,7 @@ class Attachment(models.Model):
upload_to=get_attachment_file_path,
verbose_name=_("attached file"))
sha1 = models.CharField(default="", max_length=40, verbose_name=_("sha1"), blank=True)
is_deprecated = models.BooleanField(default=False, verbose_name=_("is deprecated"))
description = models.TextField(null=False, blank=True, verbose_name=_("description"))
@ -83,11 +84,30 @@ class Attachment(models.Model):
("view_attachment", "Can view attachment"),
)
def __init__(self, *args, **kwargs):
super(Attachment, self).__init__(*args, **kwargs)
self._orig_attached_file = self.attached_file
def _generate_sha1(self, blocksize=65536):
hasher = hashlib.sha1()
while True:
buff = self.attached_file.file.read(blocksize)
if not buff:
break
hasher.update(buff)
self.sha1 = hasher.hexdigest()
def save(self, *args, **kwargs):
if not self._importing or not self.modified_date:
self.modified_date = timezone.now()
return super().save(*args, **kwargs)
if self.attached_file:
if not self.sha1 or self.attached_file != self._orig_attached_file:
self._generate_sha1()
save = super().save(*args, **kwargs)
self._orig_attached_file = self.attached_file
if self.attached_file:
self.attached_file.file.close()
return save
def __str__(self):
return "Attachment: {}".format(self.id)

View File

@ -34,8 +34,8 @@ class AttachmentSerializer(serializers.ModelSerializer):
model = models.Attachment
fields = ("id", "project", "owner", "name", "attached_file", "size", "url",
"description", "is_deprecated", "created_date", "modified_date",
"object_id", "order")
read_only_fields = ("owner", "created_date", "modified_date")
"object_id", "order", "sha1")
read_only_fields = ("owner", "created_date", "modified_date", "sha1")
def get_url(self, obj):
return obj.attached_file.url