import hashlib import os import time from random import random from django.db import models from boards.models.attachment.viewers import get_viewers, AbstractViewer FILES_DIRECTORY = 'files/' FILE_EXTENSION_DELIMITER = '.' class AttachmentManager(models.Manager): def create_with_hash(self, file): file_hash = self.get_hash(file) existing = self.filter(hash=file_hash) if len(existing) > 0: attachment = existing[0] else: file_type = file.name.split(FILE_EXTENSION_DELIMITER)[-1].lower() attachment = Attachment.objects.create(file=file, mimetype=file_type, hash=file_hash) return attachment def get_hash(self, file): """ Gets hash of an file. """ md5 = hashlib.md5() for chunk in file.chunks(): md5.update(chunk) return md5.hexdigest() class Attachment(models.Model): objects = AttachmentManager() # TODO Dedup the method def _update_filename(self, filename): """ Gets unique filename """ # TODO Use something other than random number in file name new_name = '{}{}.{}'.format( str(int(time.mktime(time.gmtime()))), str(int(random() * 1000)), filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]) return os.path.join(FILES_DIRECTORY, new_name) file = models.FileField(upload_to=_update_filename) mimetype = models.CharField(max_length=50) hash = models.CharField(max_length=36) def get_view(self): file_viewer = None for viewer in get_viewers(): if viewer.supports(self.mimetype): file_viewer = viewer(self.file, self.mimetype) break if file_viewer is None: file_viewer = AbstractViewer(self.file, self.mimetype) return file_viewer.get_view()