* adds unit tests for new methods in konova/tests/test_documents.py * refactors _accepted_mime_types of AbstractDocument into _valid_mime_types
104 lines
3.2 KiB
Python
104 lines
3.2 KiB
Python
"""
|
|
Author: Michel Peltriaux
|
|
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
|
Contact: michel.peltriaux@sgdnord.rlp.de
|
|
Created on: 15.11.21
|
|
|
|
"""
|
|
import mimetypes
|
|
import os
|
|
|
|
from django.db import models
|
|
|
|
from konova.models import BaseResource
|
|
from konova.settings import INTERVENTION_REVOCATION_DOC_PATH
|
|
|
|
|
|
def generate_document_file_upload_path(instance, filename):
|
|
""" Generates the file upload path for certain document instances
|
|
|
|
Documents derived from AbstractDocument need specific upload paths for their related models.
|
|
|
|
Args:
|
|
instance (): The document instance
|
|
filename (): The filename
|
|
|
|
Returns:
|
|
|
|
"""
|
|
from compensation.models import CompensationDocument, EcoAccountDocument
|
|
from ema.models import EmaDocument
|
|
from intervention.models import InterventionDocument, RevocationDocument
|
|
from konova.settings import ECO_ACCOUNT_DOC_PATH, EMA_DOC_PATH, \
|
|
COMPENSATION_DOC_PATH, \
|
|
INTERVENTION_DOC_PATH
|
|
|
|
# Map document types to paths on the hard drive
|
|
path_map = {
|
|
InterventionDocument: INTERVENTION_DOC_PATH,
|
|
CompensationDocument: COMPENSATION_DOC_PATH,
|
|
EmaDocument: EMA_DOC_PATH,
|
|
RevocationDocument: INTERVENTION_REVOCATION_DOC_PATH,
|
|
EcoAccountDocument: ECO_ACCOUNT_DOC_PATH,
|
|
}
|
|
path = path_map.get(instance.__class__, None)
|
|
if path is None:
|
|
raise NotImplementedError("Unidentified document type: {}".format(instance.__class__))
|
|
|
|
# RevocationDocument needs special treatment, since these files need to be stored in a subfolder of the related
|
|
# instance's (Revocation) legaldata interventions folder
|
|
if instance.__class__ is RevocationDocument:
|
|
path = path.format(instance.intervention.id)
|
|
else:
|
|
path = path.format(instance.instance.id)
|
|
return path + filename
|
|
|
|
|
|
class AbstractDocument(BaseResource):
|
|
"""
|
|
Documents can be attached to compensation or intervention for uploading legal documents or pictures.
|
|
"""
|
|
title = models.CharField(max_length=500, null=True, blank=True)
|
|
date_of_creation = models.DateField()
|
|
file = models.FileField()
|
|
comment = models.TextField()
|
|
|
|
_valid_mime_types = {
|
|
mimetypes.types_map[".pdf"],
|
|
mimetypes.types_map[".jpg"],
|
|
mimetypes.types_map[".jpeg"],
|
|
mimetypes.types_map[".png"],
|
|
}
|
|
# _maximum_file_size in MB
|
|
_maximum_file_size = 15
|
|
|
|
class Meta:
|
|
abstract = True
|
|
|
|
def delete(self, using=None, keep_parents=False):
|
|
""" Custom delete function to remove the real file from the hard drive
|
|
|
|
Args:
|
|
using ():
|
|
keep_parents ():
|
|
|
|
Returns:
|
|
|
|
"""
|
|
try:
|
|
os.remove(self.file.file.name)
|
|
except FileNotFoundError:
|
|
# File seems to missing anyway - continue!
|
|
pass
|
|
super().delete(using=using, keep_parents=keep_parents)
|
|
|
|
@classmethod
|
|
def is_mime_type_valid(cls, _file: str):
|
|
mime_type = _file.content_type
|
|
return mime_type in cls._valid_mime_types
|
|
|
|
@classmethod
|
|
def is_file_size_valid(cls, _file):
|
|
max_size = cls._maximum_file_size * pow(1000, 2)
|
|
return _file.size <= max_size
|