Skip to content

Commit

Permalink
remplace la classe CSVImportApiView par un fichier utils dédié
Browse files Browse the repository at this point in the history
  • Loading branch information
raphodn committed Jan 28, 2025
1 parent 314296d commit 0b86819
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 37 deletions.
10 changes: 6 additions & 4 deletions api/views/diagnostic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from rest_framework.exceptions import NotFound, PermissionDenied
from rest_framework.generics import CreateAPIView, ListAPIView, UpdateAPIView
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.views import APIView

from api.exceptions import DuplicateException
from api.permissions import (
Expand All @@ -22,7 +23,8 @@
IsCanteenManager,
)
from api.serializers import DiagnosticAndCanteenSerializer, ManagerDiagnosticSerializer
from api.views.utils import CSVImportApiView, update_change_reason_with_auth
from api.views.utils import update_change_reason_with_auth
from common import file_import as file_import
from common.utils import send_mail
from data.models import Canteen, Teledeclaration
from data.models.diagnostic import Diagnostic
Expand Down Expand Up @@ -92,14 +94,14 @@ def perform_update(self, serializer):
update_change_reason_with_auth(self, diagnostic)


class EmailDiagnosticImportFileView(CSVImportApiView):
class EmailDiagnosticImportFileView(APIView):
permission_classes = [IsAuthenticated]

def post(self, request):
try:
self.file = request.data["file"]
super()._verify_file_size()
super()._verify_file_format()
file_import.validate_file_size(self.file)
file_import.validate_file_format(self.file)
email = request.data.get("email", request.user.email).strip()
context = {
"from": email,
Expand Down
8 changes: 4 additions & 4 deletions api/views/diagnosticimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from api.permissions import IsAuthenticated
from api.serializers import FullCanteenSerializer
from api.views.utils import CSVImportApiView
from common import file_import as file_import
from data.models import Canteen, ImportFailure, ImportType, Sector
from data.models.diagnostic import Diagnostic
from data.models.teledeclaration import Teledeclaration
Expand All @@ -30,7 +30,7 @@
logger = logging.getLogger(__name__)


class ImportDiagnosticsView(ABC, CSVImportApiView):
class ImportDiagnosticsView(ABC):
permission_classes = [IsAuthenticated]
value_error_regex = re.compile(r"Field '(.+)' expected .+? got '(.+)'.")
annotated_sectors = Sector.objects.annotate(name_lower=Lower("name"))
Expand Down Expand Up @@ -79,8 +79,8 @@ def post(self, request):
try:
with transaction.atomic():
self.file = request.data["file"]
super()._verify_file_size()
super()._verify_file_format()
file_import.validate_file_size(self.file)
file_import.validate_file_format(self.file)
self._process_file(self.file)

if self.errors:
Expand Down
11 changes: 6 additions & 5 deletions api/views/purchaseimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,19 @@
from django.http import JsonResponse
from rest_framework import status
from rest_framework.exceptions import PermissionDenied
from rest_framework.views import APIView

from api.permissions import IsAuthenticated
from api.serializers import PurchaseSerializer
from api.views.utils import CSVImportApiView
from common import file_import as file_import
from data.models import Canteen, ImportFailure, ImportType, Purchase

from .utils import camelize, decode_bytes, normalise_siret

logger = logging.getLogger(__name__)


class ImportPurchasesView(CSVImportApiView):
class ImportPurchasesView(APIView):
permission_classes = [IsAuthenticated]
max_error_items = 30

Expand All @@ -48,10 +49,10 @@ def post(self, request):
logger.info("Purchase bulk import started")
try:
self.file = request.data["file"]
super()._verify_file_size()
super()._verify_file_format()
file_import.validate_file_size(self.file)
file_import.validate_file_format(self.file)

self.file_digest = super()._get_file_digest()
self.file_digest = file_import.get_file_digest(self.file)
self._check_duplication()

with transaction.atomic():
Expand Down
24 changes: 0 additions & 24 deletions api/views/utils.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,13 @@
import hashlib
import json
import logging

import chardet
from django.conf import settings
from django.core.exceptions import ValidationError
from djangorestframework_camel_case.render import CamelCaseJSONRenderer
from rest_framework.views import APIView
from simple_history.utils import update_change_reason

logger = logging.getLogger(__name__)


class CSVImportApiView(APIView):
def _verify_file_size(self):
if self.file.size > settings.CSV_IMPORT_MAX_SIZE:
raise ValidationError(
f"Ce fichier est trop grand, merci d'utiliser un fichier de moins de {settings.CSV_IMPORT_MAX_SIZE_PRETTY}"
)

def _verify_file_format(self):
if self.file.content_type not in ["text/csv", "text/tab-separated-values"]:
raise ValidationError(
f"Ce fichier est au format {self.file.content_type}, merci d'exporter votre fichier au format CSV et réessayer."
)

def _get_file_digest(self):
file_hash = hashlib.md5()
for row in self.file:
file_hash.update(row)
return file_hash.hexdigest()


def camelize(data):
camel_case_bytes = CamelCaseJSONRenderer().render(data)
return json.loads(camel_case_bytes.decode("utf-8"))
Expand Down
34 changes: 34 additions & 0 deletions common/file_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import hashlib

from django.conf import settings
from django.core.exceptions import ValidationError


def get_file_size(file):
return file.size


def validate_file_size(file):
if get_file_size(file) > settings.CSV_IMPORT_MAX_SIZE:
raise ValidationError(
f"Ce fichier est trop grand, merci d'utiliser un fichier de moins de {settings.CSV_IMPORT_MAX_SIZE_PRETTY}"
)


def get_file_content_type(file):
return file.content_type


def validate_file_format(file):
file_format = get_file_content_type(file)
if file_format not in ["text/csv", "text/tab-separated-values"]:
raise ValidationError(
f"Ce fichier est au format {file_format}, merci d'exporter votre fichier au format CSV et réessayer."
)


def get_file_digest(file):
file_hash = hashlib.md5()
for row in file:
file_hash.update(row)
return file_hash.hexdigest()

0 comments on commit 0b86819

Please sign in to comment.