Skip to content

Commit

Permalink
[#14, #15, #19] experiments, experiment-files, experiment states
Browse files Browse the repository at this point in the history
  • Loading branch information
mjstealey committed Sep 11, 2022
1 parent 1a40ce4 commit ecc1643
Show file tree
Hide file tree
Showing 17 changed files with 617 additions and 76 deletions.
9 changes: 5 additions & 4 deletions portal/apps/experiment_files/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ class ExperimentFileSerializerList(serializers.ModelSerializer):
file_name - string
file_notes - string
file_type - enum["ip_list", "ovpn"]
is_active - bool
is_deleted - bool
"""
file_id = serializers.IntegerField(source='id')
file_notes = serializers.CharField(source='notes')

class Meta:
model = ExperimentFile
fields = ['file_id', 'file_location', 'file_name', 'file_notes', 'file_type', 'is_deleted']
fields = ['file_id', 'file_location', 'file_name', 'file_notes', 'file_type', 'is_active', 'is_deleted']


class ExperimentFileSerializerDetail(serializers.ModelSerializer):
Expand All @@ -28,17 +29,17 @@ class ExperimentFileSerializerDetail(serializers.ModelSerializer):
file_name - string
file_notes - string
file_type - enum["ip_list", "ovpn"]
is_active - bool
is_deleted - bool
last_modified_by - string
modified_date - string
"""
created_date = serializers.DateTimeField(source='created')
file_id = serializers.IntegerField(source='id')
file_notes = serializers.CharField(source='notes')
last_modified_by = serializers.CharField(source='modified_by')
modified_date = serializers.DateTimeField(source='modified')

class Meta:
model = ExperimentFile
fields = ['created_by', 'created_date', 'file_id', 'file_location', 'file_name', 'file_notes', 'file_type',
'is_deleted', 'last_modified_by', 'modified_date']
'is_active', 'is_deleted', 'last_modified_by', 'modified_date']
77 changes: 53 additions & 24 deletions portal/apps/experiment_files/api/viewsets.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from datetime import datetime, timezone
from uuid import uuid4

from django.db.models import Q
from django.shortcuts import get_object_or_404
from rest_framework import permissions
from rest_framework.exceptions import NotFound, PermissionDenied, ValidationError
Expand Down Expand Up @@ -28,30 +30,41 @@ class ExperimentFileViewSet(GenericViewSet, RetrieveModelMixin, ListModelMixin,
serializer_class = ExperimentFileSerializerDetail

def get_queryset(self):
search = self.request.query_params.get('search', None)
experiment_id = self.request.query_params.get('experiment_id', None)
show_deleted = True if str(self.request.query_params.get('show_deleted', None)).casefold() == 'true' else False
print(show_deleted)
q_filter = None
if experiment_id:
experiment = get_object_or_404(AerpawExperiment, pk=experiment_id)
if not experiment:
raise NotFound(
detail="NotFound: unable to GET /experiment-files list")
if show_deleted:
queryset = ExperimentFile.objects.filter(
id__in=experiment.experiment_files.all()
).order_by('file_name').distinct()
else:
queryset = ExperimentFile.objects.filter(
is_deleted=False,
id__in=experiment.experiment_files.all()
).order_by('file_name').distinct()
if search and show_deleted:
q_filter = Q(id__in=experiment.experiment_files.all()) & \
(Q(file_type__icontains=search) | Q(file_name__icontains=search) | Q(file_notes__icontains=search))
elif search and not show_deleted:
q_filter = Q(id__in=experiment.experiment_files.all()) & Q(is_deleted=False) & \
(Q(file_type__icontains=search) | Q(file_name__icontains=search) | Q(file_notes__icontains=search))
elif not search and not show_deleted:
q_filter = Q(id__in=experiment.experiment_files.all()) & Q(is_deleted=False)
elif not search and show_deleted:
q_filter = Q(id__in=experiment.experiment_files.all())
else:
if show_deleted:
queryset = ExperimentFile.objects.all().order_by('file_name').distinct()
else:
queryset = ExperimentFile.objects.filter(
is_deleted=False
).order_by('file_name').distinct()
if search and show_deleted:
q_filter = (Q(file_type__icontains=search) | Q(file_name__icontains=search) | Q(file_notes__icontains=search))
elif search and not show_deleted:
q_filter = Q(is_deleted=False) & \
(Q(file_type__icontains=search) | Q(file_name__icontains=search) | Q(file_notes__icontains=search))
elif not search and not show_deleted:
q_filter = Q(is_deleted=False)
elif not search and show_deleted:
q_filter = None
if q_filter:
queryset = ExperimentFile.objects.filter(
q_filter
).order_by('file_name', 'file_notes').distinct()
else:
queryset = ExperimentFile.objects.all().order_by('file_name', 'file_notes').distinct()
return queryset

def list(self, request, *args, **kwargs):
Expand All @@ -62,6 +75,7 @@ def list(self, request, *args, **kwargs):
- file_name - string
- file_notes - string
- file_type - string in ["ip_list", "ovpn"]
- is_active - bool
- is_deleted - bool
Permission:
Expand Down Expand Up @@ -92,6 +106,7 @@ def list(self, request, *args, **kwargs):
'file_name': du.get('file_name'),
'file_notes': du.get('file_notes'),
'file_type': du.get('file_type'),
'is_active': du.get('is_active'),
'is_deleted': du.get('is_deleted')
}
)
Expand All @@ -113,18 +128,16 @@ def create(self, request):
- file_name * - string
- file_notes - string
- file_type * - string in ["ip_list", "ovpn"]
- is_active - bool
- is_deleted - bool
- last_modified_by - string
- modified_date - string
Permission:
- user is_operator
"""
try:
user = get_object_or_404(AerpawUser.objects.all(), pk=request.user.id)
except Exception as exc:
raise ValidationError(
detail="ValidationError: {0}".format(exc))
if user.is_operator():
user = get_object_or_404(AerpawUser.objects.all(), pk=request.user.id)
if request.user.is_operator():
# validate file_location
file_location = request.data.get('file_location', None)
if not file_location:
Expand All @@ -141,15 +154,19 @@ def create(self, request):
raise ValidationError(
detail="file_type: must include a valid Linked File Type {0}".format(
[c[0] for c in ExperimentFile.LinkedFileType.choices]))
# validate is_active
is_active = str(request.data.get('is_active')).casefold() == 'true'
# create experiment linked file
linked_file = ExperimentFile()
linked_file.created = datetime.now(timezone.utc)
linked_file.created_by = user.username
linked_file.file_location = file_location
linked_file.file_name = file_name
linked_file.file_notes = request.data.get('file_notes', None)
linked_file.file_type = file_type
linked_file.is_active = is_active
linked_file.modified_by = user.username
linked_file.notes = request.data.get('file_notes', None)
linked_file.uuid = uuid4()
linked_file.save()

return self.retrieve(request, pk=linked_file.id)
Expand All @@ -167,6 +184,7 @@ def retrieve(self, request, *args, **kwargs):
- file_name * - string
- file_notes - string
- file_type * - string in ["ip_list", "ovpn"]
- is_active - bool
- is_deleted - bool
- last_modified_by - string
- modified_date - string
Expand Down Expand Up @@ -198,6 +216,7 @@ def retrieve(self, request, *args, **kwargs):
'file_name': du.get('file_name'),
'file_notes': du.get('file_notes'),
'file_type': du.get('file_type'),
'is_active': du.get('is_active'),
'is_deleted': du.get('is_deleted'),
'last_modified_by': AerpawUser.objects.get(username=du.get('last_modified_by')).id,
'modified_date': str(du.get('modified_date'))
Expand All @@ -214,10 +233,12 @@ def update(self, request, *args, **kwargs):
- file_name - string
- file_notes - string
- file_type - string in ["ip_list", "ovpn"]
- is_active - bool
Permission:
- user is_operator
"""
print(request.data)
linked_file = get_object_or_404(self.queryset, pk=kwargs.get('pk'))
if request.user.is_operator():
modified = False
Expand All @@ -231,7 +252,7 @@ def update(self, request, *args, **kwargs):
modified = True
# check for file_notes
if request.data.get('file_notes', None):
linked_file.notes = request.data.get('file_notes')
linked_file.file_notes = request.data.get('file_notes')
modified = True
# check for file_type
if request.data.get('file_type', None):
Expand All @@ -241,6 +262,11 @@ def update(self, request, *args, **kwargs):
[c[0] for c in ExperimentFile.LinkedFileType.choices]))
linked_file.file_type = request.data.get('file_type')
modified = True
# check for is_active
if str(request.data.get('is_active')).casefold() in ['true', 'false']:
is_active = str(request.data.get('is_active')).casefold() == 'true'
linked_file.is_active = is_active
modified = True
# save if modified
if modified:
linked_file.modified_by = request.user.email
Expand All @@ -257,6 +283,7 @@ def partial_update(self, request, *args, **kwargs):
- file_name - string
- file_notes - string
- file_type - string in ["ip_list", "ovpn"]
- is_active - bool
Permission:
- user is_operator
Expand All @@ -266,13 +293,15 @@ def partial_update(self, request, *args, **kwargs):
def destroy(self, request, pk=None):
"""
DELETE: soft delete existing linked file
- is_active - bool
- is_deleted - bool
Permission:
- user is_operator
"""
linked_file = get_object_or_404(self.queryset, pk=pk)
if request.user.is_operator():
linked_file.is_active = False
linked_file.is_deleted = True
linked_file.modified_by = request.user.username
linked_file.save()
Expand Down
34 changes: 34 additions & 0 deletions portal/apps/experiment_files/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from django import forms

from portal.apps.experiment_files.models import ExperimentFile


class ExperimentFileCreateForm(forms.ModelForm):
file_name = forms.CharField(
widget=forms.TextInput(attrs={'size': 60}),
required=True,
label='File Name',
)

file_notes = forms.CharField(
widget=forms.Textarea(attrs={'rows': 6, 'cols': 60}),
required=True,
label='Notes',
)

file_location = forms.CharField(
widget=forms.TextInput(attrs={'size': 60}),
required=True,
label='Full File Path',
)

file_type = forms.ChoiceField(
choices=ExperimentFile.LinkedFileType.choices,
widget=forms.Select(),
required=True,
label='Type',
)

class Meta:
model = ExperimentFile
fields = ['file_name', 'file_notes', 'file_location', 'file_type', 'is_active']
11 changes: 7 additions & 4 deletions portal/apps/experiment_files/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ class ExperimentFile(BaseModel, AuditModelMixin, models.Model):
- is_deleted
- modified (from AuditModelMixin)
- modified_by (from AuditModelMixin)
- notes
- file_notes
- uuid
"""

class LinkedFileType(models.TextChoices):
IP_LIST = 'ip_list', _('IP List')
OVPN = 'ovpn', _('OVPN')

is_active = models.BooleanField(default=True)
is_deleted = models.BooleanField(default=False)
file_location = models.CharField(max_length=255, blank=False, null=False)
file_name = models.CharField(max_length=255, blank=False, null=False)
Expand All @@ -37,15 +38,17 @@ class LinkedFileType(models.TextChoices):
choices=LinkedFileType.choices,
default=LinkedFileType.OVPN
)
notes = models.TextField(blank=True, null=True)
file_notes = models.TextField(blank=True, null=True)
uuid = models.CharField(max_length=255, primary_key=False, editable=False)

class Meta:
ordering = ['file_name']
ordering = ["file_type", "file_name"]

def __str__(self):
max_length = 40
display_name = '{0} - {1}'.format(self.file_name, self.notes) if self.notes else self.file_name
display_name = '[{0}] {1} - {2}'.format(self.file_type, self.file_name,
self.file_notes) if self.file_notes else '[{0}] {1}'.format(
self.file_type, self.file_name)
str_end = '...'
length = len(display_name)
if length > max_length:
Expand Down
36 changes: 18 additions & 18 deletions portal/apps/experiment_files/urls.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# from django.urls import path
#
# from portal.apps.experiments.views import experiment_create, experiment_detail, experiment_edit, experiment_list, \
# experiment_members, experiment_resource_list, experiment_resource_target_edit, experiment_resource_targets
#
# urlpatterns = [
# path('', experiment_list, name='experiment_list'),
# path('create', experiment_create, name='experiment_create'),
# path('<int:experiment_id>', experiment_detail, name='experiment_detail'),
# path('<int:experiment_id>/edit', experiment_edit, name='experiment_edit'),
# path('<int:experiment_id>/members', experiment_members, name='experiment_members'),
# path('<int:experiment_id>/resources', experiment_resource_list, name='experiment_resource_list'),
# path('<int:experiment_id>/resource-targets', experiment_resource_targets,
# name='experiment_resource_targets'),
# path('<int:experiment_id>/resource-targets/<int:canonical_experiment_resource_id>/edit',
# experiment_resource_target_edit,
# name='experiment_resource_target_edit'),
# ]
from django.urls import path

from portal.apps.experiment_files.views import experiment_file_create, experiment_file_detail, experiment_file_edit, \
experiment_file_list

urlpatterns = [
path('', experiment_file_list, name='experiment_file_list'),
path('create', experiment_file_create, name='experiment_file_create'),
path('<int:file_id>', experiment_file_detail, name='experiment_file_detail'),
path('<int:file_id>/edit', experiment_file_edit, name='experiment_file_edit'),
# path('<int:experiment_id>/members', experiment_members, name='experiment_members'),
# path('<int:experiment_id>/resources', experiment_resource_list, name='experiment_resource_list'),
# path('<int:experiment_id>/resource-targets', experiment_resource_targets,
# name='experiment_resource_targets'),
# path('<int:experiment_id>/resource-targets/<int:canonical_experiment_resource_id>/edit',
# experiment_resource_target_edit,
# name='experiment_resource_target_edit'),
]
Loading

0 comments on commit ecc1643

Please sign in to comment.