You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2020/09/30 23:06:15 UTC
[airavata-django-portal] 01/02: Merge branch 'develop' into
merge-AIRAVATA-3346
This is an automated email from the ASF dual-hosted git repository.
machristie pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git
commit cd47d63afefd65ba4ae60e650a839527fee9a287
Merge: c592887 34be846
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Wed Sep 30 19:05:39 2020 -0400
Merge branch 'develop' into merge-AIRAVATA-3346
.travis.yml | 4 +-
README.md | 9 +
django_airavata/apps/admin/.prettierignore | 2 +
django_airavata/apps/admin/README.md | 4 +
django_airavata/apps/admin/babel.config.js | 6 +-
django_airavata/apps/admin/package.json | 4 +-
.../admin/static/django_airavata_admin/src/App.vue | 4 +-
.../src/components/admin/ComputeResourcesModal.vue | 42 +-
.../BatchQueueResourcePolicy.vue | 20 +-
.../ComputePreference.vue | 86 ++--
.../ComputeResourcePolicyEditor.vue | 40 +-
.../ComputeResourcePolicySummary.vue | 83 ++--
.../ComputeResourceReservationEditor.vue | 24 +-
.../ComputeResourceReservationList.vue | 38 +-
.../ComputeResourceReservationsSummary.vue | 18 +-
.../GroupComputeResourcePreference.vue | 72 ++--
.../applications/ApplicationDeploymentEditor.vue | 185 ++++++--
.../applications/ApplicationDeploymentsList.vue | 109 +++--
.../applications/ApplicationEditorContainer.vue | 303 +++++++------
.../applications/ApplicationInputFieldEditor.vue | 188 ++++++--
.../applications/ApplicationInterfaceEditor.vue | 116 +++--
.../applications/ApplicationModuleEditor.vue | 62 ++-
.../applications/ApplicationOutputFieldEditor.vue | 110 +++--
.../applications/CommandObjectsEditor.vue | 42 +-
.../src/components/applications/JSONEditor.vue | 19 +-
.../components/applications/SetEnvPathsEditor.vue | 46 +-
.../credentials/NewPasswordCredentialModal.vue | 41 +-
.../credentials/NewSSHCredentialModal.vue | 25 +-
.../credentials/SSHCredentialSelector.vue | 44 +-
.../dashboards/ApplicationsDashboard.vue | 34 +-
.../ComputeResourcePreferenceDashboard.vue | 42 +-
.../dashboards/CredentialStoreDashboard.vue | 77 ++--
.../GatewayResourceProfileEditor.vue | 21 +-
.../GatewayResourceProfileEditorContainer.vue | 57 +--
.../gatewayprofile/StoragePreferenceEditor.vue | 47 +-
.../gatewayprofile/StoragePreferenceList.vue | 109 +++--
.../src/components/notices/NoticeEditor.vue | 125 +++---
.../notices/NoticesManagementContainer.vue | 117 ++---
.../statistics/ExperimentDetailsView.vue | 476 ++++++++++++---------
.../statistics/ExperimentStatisticsCard.vue | 27 +-
.../statistics/ExperimentStatisticsContainer.vue | 196 ++++-----
.../src/components/users/ActivateUserPanel.vue | 15 +-
.../src/components/users/DeleteUserPanel.vue | 14 +-
.../src/components/users/EnableUserPanel.vue | 15 +-
.../components/users/GroupMembershipDisplay.vue | 33 +-
.../IdentityServiceUserManagementContainer.vue | 84 ++--
.../UnverifiedEmailUserManagementContainer.vue | 60 ++-
.../src/components/users/UserDetailsContainer.vue | 33 +-
.../components/users/UserGroupMembershipEditor.vue | 49 ++-
.../components/users/UserManagementContainer.vue | 15 +-
.../admin/static/django_airavata_admin/src/main.js | 10 +-
.../static/django_airavata_admin/src/router.js | 73 ++--
.../django_airavata_admin/static/css/admin.css | 80 ++--
.../django_airavata_admin/static/css/main.css | 188 ++++----
django_airavata/apps/admin/vue.config.js | 34 +-
django_airavata/apps/admin/yarn.lock | 5 +
django_airavata/apps/api/.prettierignore | 1 +
django_airavata/apps/api/README.md | 4 +-
django_airavata/apps/api/apps.py | 2 +-
django_airavata/apps/api/babel.config.js | 12 +-
django_airavata/apps/api/exceptions.py | 3 +-
django_airavata/apps/api/helpers.py | 3 +-
django_airavata/apps/api/output_views.py | 12 +-
django_airavata/apps/api/package.json | 4 +-
django_airavata/apps/api/serializers.py | 7 +-
django_airavata/apps/api/signals.py | 3 +-
.../django_airavata_api/js/errors/ErrorReporter.js | 12 +-
.../django_airavata_api/js/errors/ErrorUtils.js | 2 +-
.../js/errors/UnhandledError.js | 25 +-
.../js/errors/UnhandledErrorDispatcher.js | 4 +-
.../js/errors/UnhandledErrorDisplayList.js | 27 +-
.../api/static/django_airavata_api/js/index.js | 12 +-
.../js/models/ApplicationDeploymentDescription.js | 48 +--
.../js/models/ApplicationInterfaceDefinition.js | 24 +-
.../js/models/ApplicationModule.js | 12 +-
.../django_airavata_api/js/models/BaseEnum.js | 53 +--
.../django_airavata_api/js/models/BaseModel.js | 4 +-
.../django_airavata_api/js/models/BatchQueue.js | 34 +-
.../js/models/BatchQueueResourcePolicy.js | 2 +-
.../django_airavata_api/js/models/CommandObject.js | 11 +-
.../models/ComputationalResourceSchedulingModel.js | 143 ++++---
.../js/models/ComputeResourceDescription.js | 74 ++--
.../js/models/ComputeResourceReservation.js | 8 +-
.../js/models/CredentialSummary.js | 6 +-
.../django_airavata_api/js/models/DataProduct.js | 101 ++---
.../js/models/DataReplicaLocation.js | 52 +--
.../django_airavata_api/js/models/DataType.js | 4 +-
.../django_airavata_api/js/models/ErrorModel.js | 34 +-
.../django_airavata_api/js/models/Experiment.js | 34 +-
.../js/models/ExperimentSearchFields.js | 2 +-
.../js/models/ExperimentState.js | 6 +-
.../js/models/ExperimentStatistics.js | 12 +-
.../js/models/ExperimentStatus.js | 6 +-
.../js/models/ExperimentSummary.js | 16 +-
.../js/models/FullExperiment.js | 30 +-
.../js/models/GatewayResourceProfile.js | 4 +-
.../static/django_airavata_api/js/models/Group.js | 14 +-
.../js/models/GroupComputeResourcePreference.js | 12 +-
.../js/models/GroupPermission.js | 33 +-
.../js/models/GroupResourceProfile.js | 36 +-
.../js/models/IAMUserProfile.js | 6 +-
.../js/models/InputDataObjectType.js | 16 +-
.../static/django_airavata_api/js/models/Job.js | 6 +-
.../django_airavata_api/js/models/JobState.js | 23 +-
.../django_airavata_api/js/models/JobStatus.js | 6 +-
.../django_airavata_api/js/models/LogRecord.js | 4 +-
.../django_airavata_api/js/models/Notification.js | 30 +-
.../js/models/NotificationPriority.js | 11 +-
.../js/models/OutputDataObjectType.js | 12 +-
.../js/models/ParallelismType.js | 7 +-
.../static/django_airavata_api/js/models/Parser.js | 11 +-
.../django_airavata_api/js/models/ParserInput.js | 4 +-
.../django_airavata_api/js/models/ParserOutput.js | 4 +-
.../django_airavata_api/js/models/ProcessModel.js | 24 +-
.../django_airavata_api/js/models/ProcessState.js | 2 +-
.../django_airavata_api/js/models/ProcessStatus.js | 6 +-
.../js/models/ProcessWorkflow.js | 4 +-
.../django_airavata_api/js/models/Project.js | 44 +-
.../js/models/ResourcePermissionType.js | 12 +-
.../django_airavata_api/js/models/SetEnvPaths.js | 12 +-
.../django_airavata_api/js/models/SharedEntity.js | 24 +-
.../js/models/StoragePreference.js | 2 +-
.../js/models/StorageResourceDescription.js | 2 +-
.../django_airavata_api/js/models/SummaryType.js | 11 +-
.../static/django_airavata_api/js/models/Task.js | 14 +-
.../django_airavata_api/js/models/TaskStatus.js | 5 +-
.../django_airavata_api/js/models/TaskTypes.js | 2 +-
.../js/models/UnverifiedEmailUserProfile.js | 4 +-
.../js/models/UserConfigurationData.js | 104 ++---
.../js/models/UserPermission.js | 33 +-
.../django_airavata_api/js/models/UserProfile.js | 88 ++--
.../django_airavata_api/js/models/UserStatus.js | 33 +-
.../js/models/UserStorageDirectory.js | 2 +-
.../js/models/UserStorageFile.js | 2 +-
.../js/models/UserStoragePath.js | 10 +-
.../js/models/WorkspacePreferences.js | 2 +-
.../dependencies/BooleanExpressionEvaluator.js | 21 +-
.../js/models/validators/MaxLengthValidator.js | 50 +--
.../js/models/validators/MinLengthValidator.js | 50 +--
.../validators/RegularExpressionValidator.js | 46 +-
.../js/models/validators/ValidatorFactory.js | 41 +-
.../django_airavata_api/js/service_config.js | 162 +++----
.../js/services/CloudJobSubmissionService.js | 12 +-
.../js/services/DataMovementService.js | 14 +-
.../js/services/FullExperimentService.js | 23 +-
.../js/services/GlobusJobSubmissionService.js | 15 +-
.../js/services/GridFTPDataMovementService.js | 12 +-
.../js/services/JobSubmissionService.js | 15 +-
.../js/services/LocaJobSubmissionService.js | 15 +-
.../js/services/ProjectService.js | 74 ++--
.../js/services/SCPDataMovementService.js | 10 +-
.../js/services/ServiceFactory.js | 38 +-
.../js/services/SshJobSubmissionService.js | 13 +-
.../js/services/UnicoreDataMovementService.js | 10 +-
.../js/services/UnicoreJobSubmissionService.js | 15 +-
.../js/services/UserProfileService.js | 22 +-
.../static/django_airavata_api/js/utils/Cache.js | 2 +-
.../django_airavata_api/js/utils/FetchUtils.js | 106 ++---
.../js/utils/PaginationIterator.js | 88 ++--
.../django_airavata_api/js/utils/StringUtils.js | 11 +-
.../static/django_airavata_api/tests/.eslintrc.js | 8 +-
.../BooleanExpressionEvaluator.test.js | 102 ++---
django_airavata/apps/api/tests/test_views.py | 6 +-
django_airavata/apps/api/urls.py | 6 +-
django_airavata/apps/api/views.py | 42 +-
django_airavata/apps/api/webpack.config.js | 4 +-
django_airavata/apps/api/yarn.lock | 5 +
django_airavata/apps/auth/tests/test_signals.py | 4 +-
django_airavata/apps/auth/utils.py | 3 +-
django_airavata/apps/dataparsers/.prettierignore | 2 +
django_airavata/apps/dataparsers/babel.config.js | 6 +-
django_airavata/apps/dataparsers/package.json | 4 +-
.../js/containers/ParserDetailsContainer.vue | 19 +-
.../js/containers/ParserEditContainer.vue | 66 +--
.../js/containers/ParsersManageContainer.vue | 100 ++---
.../js/entry-parser-details.js | 12 +-
.../js/parser-components/ParserEditor.vue | 176 +++++---
.../js/parser-components/ParserList.vue | 71 +--
.../js/parser-components/ParserListItem.vue | 63 ++-
.../js/parser-edit-entry-point.js | 12 +-
.../js/parser-listing-entry-point.js | 4 +-
django_airavata/apps/dataparsers/urls.py | 6 +-
django_airavata/apps/dataparsers/vue.config.js | 49 ++-
django_airavata/apps/dataparsers/yarn.lock | 5 +
django_airavata/apps/groups/.prettierignore | 2 +
django_airavata/apps/groups/babel.config.js | 6 +-
django_airavata/apps/groups/package.json | 4 +-
.../js/containers/GroupCreateContainer.vue | 53 ++-
.../js/containers/GroupEditContainer.vue | 57 ++-
.../js/containers/GroupsManageContainer.vue | 108 ++---
.../js/group-create-entry-point.js | 4 +-
.../js/group-edit-entry-point.js | 40 +-
.../js/group-listing-entry-point.js | 4 +-
.../js/group_components/GroupEditor.vue | 61 ++-
.../js/group_components/GroupList.vue | 87 ++--
.../js/group_components/GroupListItem.vue | 192 +++++----
.../js/group_components/GroupMembersEditor.vue | 54 +--
django_airavata/apps/groups/vue.config.js | 49 ++-
django_airavata/apps/groups/yarn.lock | 5 +
django_airavata/apps/workspace/.prettierignore | 4 +
django_airavata/apps/workspace/babel.config.js | 6 +-
.../.prettierignore | 2 +
.../django-airavata-workspace-plugin-api/README.md | 5 +-
.../babel.config.js | 6 +-
.../js/index.js | 8 +-
.../js/input-editors/InputEditorMixin.js | 140 +++---
.../package.json | 4 +-
.../vue.config.js | 4 +-
.../django-airavata-workspace-plugin-api/yarn.lock | 5 +
django_airavata/apps/workspace/jest.config.js | 29 +-
django_airavata/apps/workspace/package.json | 4 +-
.../js/components/PgaLink.vue | 25 +-
.../ComputationalResourceSchedulingEditor.vue | 84 ++--
.../experiment/ExperimentDescriptionEditor.vue | 31 +-
.../js/components/experiment/ExperimentEditor.vue | 161 +++----
.../js/components/experiment/ExperimentSummary.vue | 419 +++++++++---------
.../experiment/GroupResourceProfileSelector.vue | 168 ++++----
.../components/experiment/QueueSettingsEditor.vue | 81 ++--
.../input-editors/AutocompleteInputEditor.vue | 40 +-
.../input-editors/CheckboxInputEditor.vue | 75 ++--
.../experiment/input-editors/FileInputEditor.vue | 53 +--
.../input-editors/InputEditorContainer.vue | 271 ++++++------
.../input-editors/InputEditorFormGroup.vue | 75 ++--
.../experiment/input-editors/InputFileSelector.vue | 26 +-
.../input-editors/MultiFileInputEditor.vue | 14 +-
.../input-editors/RadioButtonInputEditor.vue | 59 +--
.../experiment/input-editors/SelectInputEditor.vue | 14 +-
.../experiment/input-editors/StringInputEditor.vue | 28 +-
.../input-editors/TextareaInputEditor.vue | 43 +-
.../input-editors/UserFileInputEditor.vue | 41 +-
.../output-displays/DefaultOutputDisplay.vue | 12 +-
.../output-displays/HtmlOutputDisplay.vue | 14 +-
.../output-displays/ImageOutputDisplay.vue | 8 +-
.../output-displays/LinkOutputDisplay.vue | 6 +-
.../output-displays/NotebookOutputDisplay.vue | 17 +-
.../output-displays/OutputDisplayContainer.vue | 34 +-
.../output-displays/OutputViewDataLoader.js | 8 +-
.../InteractiveParameterCheckboxWidget.vue | 8 +-
.../InteractiveParameterRangeWidget.vue | 14 +-
.../InteractiveParameterSelectWidget.vue | 10 +-
.../InteractiveParameterStepperWidget.vue | 14 +-
.../InteractiveParameterTextInputWidget.vue | 12 +-
.../InteractiveParameterWidgetContainer.vue | 10 +-
.../InteractiveParametersPanel.vue | 22 +-
.../js/components/project/ProjectButtonNew.vue | 43 +-
.../js/components/project/ProjectEditor.vue | 33 +-
.../js/components/project/ProjectList.vue | 53 +--
.../js/components/project/ProjectListItem.vue | 18 +-
.../components/storage/UserStorageCreateView.vue | 86 ++--
.../storage/UserStorageFileSelectionContainer.vue | 26 +-
.../storage/UserStoragePathBreadcrumb.vue | 15 +-
.../components/storage/UserStoragePathViewer.vue | 82 ++--
.../storage-edit/UserStorageAudioEditViewer.vue | 29 +-
.../storage-edit/UserStorageDefaultEditViewer.vue | 26 +-
.../storage-edit/UserStorageDownloadButton.vue | 16 +-
.../storage/storage-edit/UserStorageEditViewer.vue | 141 +++---
.../storage-edit/UserStorageImageEditViewer.vue | 27 +-
.../storage-edit/UserStoragePdfEditViewer.vue | 27 +-
.../storage-edit/UserStorageTextEditViewer.vue | 134 +++---
.../storage-edit/UserStorageVideoEditViewer.vue | 29 +-
.../js/containers/CreateExperimentContainer.vue | 20 +-
.../js/containers/DashboardContainer.vue | 69 ++-
.../js/containers/EditExperimentContainer.vue | 32 +-
.../js/containers/EditProjectContainer.vue | 40 +-
.../js/containers/ExperimentListContainer.vue | 84 ++--
.../js/containers/ProjectListContainer.vue | 116 ++---
.../js/containers/RecentExperimentsContainer.vue | 44 +-
.../js/containers/UserStorageContainer.vue | 23 +-
.../js/containers/ViewExperimentContainer.vue | 81 ++--
.../js/entry-create-experiment.js | 12 +-
.../js/entry-dashboard.js | 14 +-
.../js/entry-edit-experiment.js | 12 +-
.../js/entry-edit-project.js | 12 +-
.../js/entry-experiment-list.js | 12 +-
.../js/entry-project-list.js | 12 +-
.../js/entry-user-storage.js | 10 +-
.../js/entry-view-experiment.js | 12 +-
.../django_airavata_workspace/js/utils/urls.js | 8 +-
.../django_airavata_workspace/tests/.eslintrc.js | 6 +-
.../input-editors/InputEditorContainer.spec.js | 37 +-
django_airavata/apps/workspace/views.py | 4 +-
django_airavata/apps/workspace/vue.config.js | 60 +--
django_airavata/apps/workspace/yarn.lock | 10 +
django_airavata/settings.py | 6 +-
django_airavata/settings_local.py.ide | 2 +-
django_airavata/static/common/.prettierignore | 2 +
django_airavata/static/common/babel.config.js | 6 +-
django_airavata/static/common/js/cms.js | 2 +-
.../common/js/components/ApplicationCard.vue | 30 +-
.../common/js/components/ApplicationName.vue | 14 +-
.../common/js/components/AutocompleteTextInput.vue | 52 ++-
.../common/js/components/ClipboardCopyButton.vue | 20 +-
.../common/js/components/ClipboardCopyLink.vue | 23 +-
.../common/js/components/ComputeResourceName.vue | 18 +-
.../common/js/components/ConfirmationDialog.vue | 22 +-
.../common/js/components/DataProductViewer.vue | 22 +-
.../static/common/js/components/DeleteButton.vue | 15 +-
.../static/common/js/components/DeleteLink.vue | 12 +-
.../common/js/components/ExperimentStatusBadge.vue | 12 +-
.../static/common/js/components/FavoriteToggle.vue | 19 +-
.../common/js/components/GatewayGroupsBadge.vue | 9 +-
.../js/components/GatewayNoticesContainer.vue | 47 +-
.../static/common/js/components/HumanDate.vue | 7 +-
.../static/common/js/components/Linkify.vue | 34 ++
.../static/common/js/components/MainLayout.vue | 11 +-
.../common/js/components/NotificationsDisplay.vue | 48 +--
.../static/common/js/components/Pager.vue | 86 ++--
.../static/common/js/components/ShareButton.vue | 129 +++---
.../common/js/components/SharedEntityEditor.vue | 229 +++++-----
.../static/common/js/components/Sidebar.vue | 5 +-
.../static/common/js/components/SidebarFeed.vue | 21 +-
.../common/js/components/SidebarFeedItem.vue | 24 +-
.../static/common/js/components/SidebarHeader.vue | 14 +-
.../common/js/components/UnsavedChangesGuard.vue | 9 +-
.../static/common/js/components/Uppy.vue | 38 +-
.../static/common/js/components/ValidatedForm.vue | 20 +-
.../common/js/components/ValidatedFormGroup.vue | 14 +-
.../static/common/js/errors/GlobalErrorHandler.js | 58 ++-
.../static/common/js/errors/ValidationErrors.js | 6 +-
django_airavata/static/common/js/index.js | 14 +-
.../static/common/js/layouts/ListLayout.vue | 42 +-
django_airavata/static/common/js/main.js | 2 +-
.../static/common/js/mixins/VModelMixin.js | 24 +-
django_airavata/static/common/js/notices.js | 8 +-
.../static/common/js/notifications/Notification.js | 26 +-
.../common/js/notifications/NotificationList.js | 2 +-
django_airavata/static/common/js/utils.js | 4 +-
django_airavata/static/common/package.json | 5 +-
django_airavata/static/common/scss/main.scss | 401 +++++++++--------
django_airavata/static/common/vue.config.js | 10 +-
django_airavata/static/common/yarn.lock | 10 +
django_airavata/utils.py | 9 +-
docs/dev/developing_backend.md | 16 +-
docs/dev/developing_frontend.md | 38 +-
docs/dev/new_django_app.md | 4 +-
docs/tutorial/gateways2019_tutorial.md | 149 ++++++-
requirements-dev.txt | 4 +-
runtests.py | 19 +
setup.cfg | 6 +
tests/__init__.py | 0
tests/settings.py | 30 ++
341 files changed, 7271 insertions(+), 5945 deletions(-)
diff --cc django_airavata/apps/api/serializers.py
index 0ecd926,3c589e9..07f7a43
--- a/django_airavata/apps/api/serializers.py
+++ b/django_airavata/apps/api/serializers.py
@@@ -62,9 -58,11 +58,12 @@@ from airavata.model.workspace.ttypes im
Project
)
from airavata_django_portal_sdk import user_storage
+ from django.conf import settings
+ from django.urls import reverse
+ from rest_framework import serializers
from . import models, thrift_utils
+import requests
log = logging.getLogger(__name__)
diff --cc django_airavata/apps/api/views.py
index 404117b,25f420f..7a07075
--- a/django_airavata/apps/api/views.py
+++ b/django_airavata/apps/api/views.py
@@@ -3,27 -3,7 +3,9 @@@ import jso
import logging
import os
from datetime import datetime, timedelta
+from urllib.parse import quote
+import requests
- from django.conf import settings
- from django.contrib.auth.decorators import login_required
- from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
- from django.http import FileResponse, Http404, HttpResponse, JsonResponse
- from django.urls import reverse
- from rest_framework import mixins
- from rest_framework.decorators import (
- action,
- api_view,
- detail_route,
- list_route
- )
- from rest_framework.exceptions import ParseError
- from rest_framework.renderers import JSONRenderer
- from rest_framework.response import Response
- from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_404_NOT_FOUND
- from rest_framework.views import APIView
-
from airavata.model.appcatalog.computeresource.ttypes import (
CloudJobSubmission,
GlobusJobSubmission,
@@@ -43,6 -23,19 +25,23 @@@ from airavata.model.experiment.ttypes i
from airavata.model.group.ttypes import ResourcePermissionType
from airavata.model.user.ttypes import Status
from airavata_django_portal_sdk import user_storage
+ from django.conf import settings
-from django.contrib.auth.decorators import login_required
+ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
+ from django.http import FileResponse, Http404, HttpResponse, JsonResponse
+ from django.urls import reverse
+ from rest_framework import mixins
-from rest_framework.decorators import action, detail_route, list_route
++from rest_framework.decorators import (
++ action,
++ api_view,
++ detail_route,
++ list_route
++)
+ from rest_framework.exceptions import ParseError
+ from rest_framework.renderers import JSONRenderer
+ from rest_framework.response import Response
+ from rest_framework.status import HTTP_400_BAD_REQUEST
+ from rest_framework.views import APIView
+
from django_airavata.apps.api.view_utils import (
APIBackedViewSet,
APIResultIterator,
@@@ -1610,8 -1577,11 +1609,9 @@@ class UserStoragePathView(APIView)
if uploaded is not None:
data['uploaded'] = uploaded
data['parts'] = self._split_path(path)
- serializer = self.serializer_class(data, context={'request': request})
+ serializer = self.serializer_class(
+ data, context={'request': request})
return Response(serializer.data)
- user_storage.delete_dir(request, path)
- return Response(status=204)
def _split_path(self, path):
head, tail = os.path.split(path)