models.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. from hashlib import sha1
  2. from django.db import models
  3. from glitchtip.base_models import CreatedModel
  4. class FileBlob(CreatedModel):
  5. """
  6. Port of sentry.models.file.FileBlog with some simplifications
  7. """
  8. blob = models.FileField(upload_to="uploads/file_blobs")
  9. size = models.PositiveIntegerField(null=True)
  10. checksum = models.CharField(max_length=40, unique=True)
  11. @classmethod
  12. def from_files(cls, files, organization=None, logger=None):
  13. logger.debug("FileBlob.from_files.start")
  14. files_with_checksums = []
  15. for fileobj in files:
  16. if isinstance(fileobj, tuple):
  17. files_with_checksums.append(fileobj)
  18. else:
  19. files_with_checksums.append((fileobj, None))
  20. for file_with_checksum in files_with_checksums:
  21. blob = cls()
  22. blob_file = file_with_checksum[0]
  23. blob.checksum = file_with_checksum[1]
  24. blob.blob.save(blob_file.name, blob_file)
  25. blob.save()
  26. @classmethod
  27. def from_file(cls, fileobj):
  28. """
  29. Retrieve a single FileBlob instances for the given file.
  30. """
  31. checksum = sha1()
  32. with fileobj.open("rb") as f:
  33. if f.multiple_chunks():
  34. for chunk in f.chunks():
  35. checksum.update(chunk)
  36. else:
  37. checksum.update(f.read())
  38. # Significant deviation from OSS Sentry
  39. file_blob, _ = cls.objects.get_or_create(
  40. checksum=checksum.hexdigest(),
  41. defaults={"blob": fileobj, "size": fileobj.size},
  42. )
  43. return file_blob
  44. class File(CreatedModel):
  45. """
  46. Port of sentry.models.file.File
  47. """
  48. name = models.TextField()
  49. headers = models.JSONField()
  50. blobs = models.ManyToManyField(FileBlob)
  51. size = models.PositiveIntegerField(null=True)
  52. checksum = models.CharField(max_length=40, null=True, db_index=True)
  53. def putfile(self, fileobj):
  54. self.size = fileobj.size
  55. file_blob = FileBlob.from_file(fileobj)
  56. self.checksum = file_blob.checksum
  57. self.save()