diff --git a/makedoc/serializers.py b/makedoc/serializers.py index 1db4ffd..6236825 100644 --- a/makedoc/serializers.py +++ b/makedoc/serializers.py @@ -20,3 +20,7 @@ class DataDocSerializer(serializers.Serializer[Any]): factory_id = serializers.IntegerField() destination = serializers.CharField() delivery_cost = serializers.IntegerField(min_value=0) + + +class FileNameSerializer(serializers.Serializer[Any]): + file_name = serializers.CharField(required=False, allow_blank=True) diff --git a/makedoc/services.py b/makedoc/services.py index 8f3f82b..c4b372a 100644 --- a/makedoc/services.py +++ b/makedoc/services.py @@ -10,7 +10,6 @@ get_formatted_date_agreement, get_formatted_date_shipment, ) - from .data_service import DataService @@ -194,8 +193,10 @@ def add_workbook_to_archive_xlsx(self, wb, user, client): tempdir = os.path.join("makedoc", "tempdoc", str(user.id)) os.makedirs(tempdir, exist_ok=True) + client_name = client.client_name.replace(' ', '_') + date_today = datetime.today().strftime('%d.%m.%Y_%H:%M:%S') self.archive_name = ( - f"{client.client_name} {datetime.today().strftime('%d.%m.%Y %H:%M:%S')}.zip" + f"{client_name}_{date_today}.zip" ) archive_path = f"{tempdir}/{self.archive_name}" diff --git a/makedoc/tests/test_views_makedoc.py b/makedoc/tests/test_views_makedoc.py index 6b74bef..0d9669b 100644 --- a/makedoc/tests/test_views_makedoc.py +++ b/makedoc/tests/test_views_makedoc.py @@ -52,6 +52,6 @@ def test__create_docs_view__authorized_user_get_no_data(authorized_client): @pytest.mark.django_db def test__download_doc_view__returns_404_when_no_file_exists(authorized_client): url = reverse("downloadfile") - response = authorized_client.get(url) + response = authorized_client.post(url, {}, format="json") assert response.status_code == 404 assert response.json() == {"error": "No file found"} diff --git a/makedoc/urls.py b/makedoc/urls.py index ce10cec..3d7a290 100644 --- a/makedoc/urls.py +++ b/makedoc/urls.py @@ -1,9 +1,9 @@ from django.urls import path -from .views import DataDocView, CreateDocsView, DownloadDocView +from .views import DataDocAPIView, CreateDocsAPIView, DownloadDocAPIView urlpatterns = [ - path("filemake/", CreateDocsView.as_view(), name="file"), - path("downloadfile/", DownloadDocView.as_view(), name="downloadfile"), - path("data/", DataDocView.as_view(), name="data"), + path("filemake/", CreateDocsAPIView.as_view(), name="file"), + path("downloadfile/", DownloadDocAPIView.as_view(), name="downloadfile"), + path("data/", DataDocAPIView.as_view(), name="data"), ] diff --git a/makedoc/views.py b/makedoc/views.py index 4019b5f..e70d900 100644 --- a/makedoc/views.py +++ b/makedoc/views.py @@ -11,10 +11,13 @@ from rest_framework.views import APIView from makedoc.services import Documents -from .serializers import DataDocSerializer, DocumentsSimpleSerializer +from .serializers import DataDocSerializer, DocumentsSimpleSerializer, FileNameSerializer -class CreateDocsView(APIView): +class CreateDocsAPIView(APIView): + """ + Responsible for creating documents based on data from the cache. + """ serializer_class = DocumentsSimpleSerializer permission_classes = [IsAuthenticated] @@ -49,15 +52,32 @@ def get(self, request, *args, **kwargs): return Response({"message": "Documents saved"}, status=status.HTTP_200_OK) -class DownloadDocView(APIView): +# Загрузка документа +class DownloadDocAPIView(APIView): + """ + To download a file: + + - No parameters: get the last created file. + + - With the parameter {"file_name": "name your file"} - load a specific file from the list. + """ permission_classes = [IsAuthenticated] - def get(self, request, *args, **kwargs): - cache_key = f"last_created_file_user:{request.user.id}" - file_name = cache.get(cache_key) + def post(self, request, *args, **kwargs): + serializer = FileNameSerializer(data=request.data) + if not serializer.is_valid(): + return Response({"error": "Incorrect file name"}, status=status.HTTP_404_NOT_FOUND) + + file_name = serializer.validated_data.get("file_name") if not file_name: - return Response({"error": "No file found"}, status=status.HTTP_404_NOT_FOUND) + cache_key = f"last_created_file_user:{request.user.id}" + file_name = cache.get(cache_key) + + if not file_name: + return Response({"error": "No file found"}, status=status.HTTP_404_NOT_FOUND) + + cache.delete(cache_key) file_path = os.path.join("makedoc", "tempdoc", str(request.user.id), file_name) @@ -66,16 +86,16 @@ def get(self, request, *args, **kwargs): response = FileResponse(open(file_path, "rb")) response["Content-Disposition"] = f'attachment; filename="{os.path.basename(file_name)}"' - - cache.delete(cache_key) - response["message"] = "File successfully downloaded" response.status_code = status.HTTP_200_OK return response -class DataDocView(generics.GenericAPIView[Any]): +class DataDocAPIView(generics.GenericAPIView[Any]): + """ + Responsible for receiving data, validating it and storing it in cache. + """ serializer_class = DataDocSerializer permission_classes = (IsAuthenticated,) diff --git a/users/urls.py b/users/urls.py index 8db44ee..7d645bc 100644 --- a/users/urls.py +++ b/users/urls.py @@ -9,6 +9,7 @@ UserCreateView, UserUpdatePasswordView, UserUpdateView, + ListUserFilesAPIView ) urlpatterns = [ @@ -17,6 +18,7 @@ path("logout/", LogoutView.as_view(), name="logout"), path("edit/", UserUpdateView.as_view(), name="edit"), path("edit_password/", UserUpdatePasswordView.as_view(), name="edit_password"), + path("listuserfiles/", ListUserFilesAPIView.as_view(), name="list_user_files"), path("departments/", DepartmentListView.as_view(), name="departments"), path("positions/", PositionListView.as_view(), name="positions"), path("registration/", UserCreateView.as_view(), name="registration"), diff --git a/users/views.py b/users/views.py index de2b530..43b65ee 100644 --- a/users/views.py +++ b/users/views.py @@ -1,3 +1,5 @@ +import os.path + from django.dispatch import receiver from django_rest_passwordreset.signals import reset_password_token_created from rest_framework import generics, status @@ -70,6 +72,32 @@ class UserUpdatePasswordView(UserRelatedView): serializer_class = UserUpdatePasswordSerializer +class ListUserFilesAPIView(APIView): + """ + Responsible for displaying a list of documents of an authorized user. + """ + permission_classes = (IsAuthenticated,) + + def get(self, request, *args, **kwargs): + user_folder = os.path.join("makedoc", "tempdoc", str(request.user.id)) + + if not os.path.exists(user_folder): + return Response({"error": "User folder not found"}, status=status.HTTP_404_NOT_FOUND) + + try: + files = os.listdir(user_folder) + except OSError as e: + return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + files_list = [] + for file_name in files: + file_path = os.path.join(user_folder, file_name) + if os.path.isfile(file_path): + files_list.append(file_name) + + return Response({"files": files_list}, status=status.HTTP_200_OK) + + # Сброс пароля @receiver(reset_password_token_created) def password_reset_token_created(sender, instance, reset_password_token, *args, **kwargs):