Commit 10252292b688d5588b9e64f5d3eca8cd5af6e4d7

Authored by Alexis Koralewski
1 parent 2c54f472
Exists in dev

Change function to read sequence yml file to understand a simplified version

src/core/pyros_django/api/views.py
1 1 from django.shortcuts import render
2 2 from rest_framework.views import APIView
3   -from rest_framework.response import Response
  3 +from rest_framework.response import Response
4 4 from rest_framework import viewsets, renderers
5 5 from rest_framework.permissions import IsAuthenticated, AllowAny
6 6 from rest_framework.decorators import api_view, permission_classes, action
... ... @@ -11,7 +11,7 @@ from api.serializers import AgentSurveySerializer, AlbumSerializer, FullSequence
11 11 from common.models import PyrosUser, SP_Period, ScientificProgram, UserLevel, SP_Period_User, AgentSurvey, AgentCmd
12 12 from routine_manager.models import Sequence, Album, Plan
13 13  
14   -from routine_manager.functions import check_sequence_file_validity
  14 +from routine_manager.functions import check_sequence_file_validity_and_save
15 15 from rest_framework.request import Request
16 16 from django.db.models import Q
17 17 from datetime import datetime, timezone, timedelta
... ... @@ -92,7 +92,8 @@ class SequenceViewSet(viewsets.ModelViewSet):
92 92 if user_role in ("Unit-PI", "Admin"):
93 93 return Sequence.objects.all().order_by("-updated")
94 94 else:
95   - return Sequence.objects.filter(pyros_user=user).order_by("-updated")
  95 + sp_of_user = user.get_scientific_program()
  96 + return Sequence.objects.filter(scientific_program__in=sp_of_user).order_by("-updated")
96 97  
97 98  
98 99 class ScientificProgramViewSet(viewsets.ModelViewSet):
... ... @@ -235,7 +236,7 @@ class PlanViewSet(viewsets.ModelViewSet):
235 236 @api_view(["PUT"])
236 237 def submit_sequence_with_json(request):
237 238 sequence_json = request.data
238   - response = check_sequence_file_validity(sequence_json, request)
  239 + response = check_sequence_file_validity_and_save(sequence_json, request)
239 240 if response.get("succeed") == True:
240 241 seq = Sequence.objects.get(id=response.get("sequence_id"))
241 242 log.info(
... ...
src/core/pyros_django/routine_manager/functions.py
... ... @@ -7,7 +7,8 @@ import datetime
7 7 import os, yaml
8 8  
9 9  
10   -def check_sequence_file_validity(yaml_content,request):
  10 +def check_sequence_file_validity_and_save(yaml_content,request):
  11 + is_simplified = yaml_content.get("simplified", False)
11 12 sp_of_user = request.user.get_scientific_program()
12 13 sp_list = ScientificProgram.objects.observable_programs().filter(id__in=sp_of_user)
13 14 seq = Sequence.objects.create()
... ... @@ -19,39 +20,49 @@ def check_sequence_file_validity(yaml_content,request):
19 20 "succeed": True,
20 21 "errors": [],
21 22 }
22   - index_value_sp = yaml_content["sequence"]["scientific_program"]["value"]
23   - values = yaml_content["sequence"]["scientific_program"]["values"]
24   - if index_value_sp < 0 or index_value_sp > len(yaml_content["sequence"]["scientific_program"]["values"]):
25   - result["errors"].append(f"Value of scientific program isn't valid, index out of bounds ({index_value_sp} > {len(values)})")
26   - index_value_sp = 0
27   - chosen_sp = ScientificProgram.objects.get(name=yaml_content["sequence"]["scientific_program"]["values"][index_value_sp])
28   - if chosen_sp in sp_list:
29   - seq.scientific_program = ScientificProgram.objects.get(name=yaml_content["sequence"]["scientific_program"]["values"][index_value_sp])
  23 + if is_simplified:
  24 + seq.scientific_program = sp_list[yaml_content["sequence"]["scientific_program"]]
30 25 else:
31   - result["errors"].append(f"Scientific program {chosen_sp.name} is not assigned to that user ")
  26 + index_value_sp = yaml_content["sequence"]["scientific_program"]["value"]
  27 + values = yaml_content["sequence"]["scientific_program"]["values"]
  28 + if index_value_sp < 0 or index_value_sp > len(yaml_content["sequence"]["scientific_program"]["values"]):
  29 + result["errors"].append(f"Value of scientific program isn't valid, index out of bounds ({index_value_sp} > {len(values)})")
  30 + index_value_sp = 0
  31 + chosen_sp = ScientificProgram.objects.get(name=yaml_content["sequence"]["scientific_program"]["values"][index_value_sp])
  32 + if chosen_sp in sp_list:
  33 + seq.scientific_program = ScientificProgram.objects.get(name=yaml_content["sequence"]["scientific_program"]["values"][index_value_sp])
  34 + else:
  35 + result["errors"].append(f"Scientific program {chosen_sp.name} is not assigned to that user ")
32 36 seq.config_attributes = {}
33 37 for field in sequence_form.fields.keys():
34 38 if sequence_form.fields[field].required == False or field == "scientific_program":
35 39 continue
36   - value = yaml_content["sequence"][field]["value"]
  40 + if is_simplified:
  41 + value = yaml_content["sequence"][field]
  42 + else:
  43 + value = yaml_content["sequence"][field]["value"]
37 44 if field not in yaml_content["sequence"]:
38 45 result["errors"].append(f"{field} not in yaml file")
39 46 else:
40   - if yaml_content["sequence"][field].get("values"):
41   - index_value = yaml_content["sequence"][field]["value"]
42   - values = yaml_content["sequence"][field]["values"]
43   - if index_value < 0 or index_value > len(yaml_content["sequence"][field]["values"]):
44   - result["errors"].append(f"Value of {field} isn't valid, index out of bounds ({index_value} > {len(values)})")
45   - index_value = 0
46   - value = yaml_content["sequence"][field]["values"][index_value]
  47 + if not is_simplified:
  48 + if yaml_content["sequence"][field].get("values"):
  49 + index_value = yaml_content["sequence"][field]["value"]
  50 + values = yaml_content["sequence"][field]["values"]
  51 + if index_value < 0 or index_value > len(yaml_content["sequence"][field]["values"]):
  52 + result["errors"].append(f"Value of {field} isn't valid, index out of bounds ({index_value} > {len(values)})")
  53 + index_value = 0
  54 + value = yaml_content["sequence"][field]["values"][index_value]
  55 + else:
  56 + if field == "start_date":
  57 + if type(value) != datetime.datetime:
  58 + #value = datetime.datetime.strptime(yaml_content["sequence"][field]["value"],'%d/%m/%Y %H:%M:%S')
  59 + # ISO format
  60 + value = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f')
  61 + seq.__dict__[field] = value
47 62 else:
48   - if field == "start_date":
49   - if type(yaml_content["sequence"][field]["value"]) != datetime.datetime:
50   - #value = datetime.datetime.strptime(yaml_content["sequence"][field]["value"],'%d/%m/%Y %H:%M:%S')
51   - # ISO format
52   - value = datetime.datetime.strptime(yaml_content["sequence"][field]["value"],'%Y-%m/%dT%H:%M:%S.%f')
53   - seq.__dict__[field] = value
54   - continue
  63 + if sequence_form.fields[field].__dict__.get("_choices"):
  64 + values = [value[0] for value in sequence_form.fields[field].__dict__.get("_choices")]
  65 + value = values[value]
55 66 if field in seq.__dict__.keys():
56 67 seq.__dict__[field] = value
57 68 else:
... ... @@ -92,48 +103,55 @@ def check_sequence_file_validity(yaml_content,request):
92 103 result["errors"].append(f"Missing field : '{field}' for plan {plans.index(plan)}")
93 104 else:
94 105 # TODO : ajouter max_value, min_value, suppression plan et album si invalides
95   - if plan[field].get("value_type"):
96   - value_type = plan[field]["value_type"]
97   - if type(plan[field]["value"]) == str and ast.literal_eval(plan[field]["value"]) != value_type:
98   - result["errors"].append(f"Field {field} value doesn't correspond to the assigned type (type required : {value_type})")
99   - if plan[field].get("min_value"):
100   - if type(plan[field]["min_value"]) == str:
101   - min_value = ast.literal_eval(plan[field]["min_value"])
102   - else:
103   - min_value = plan[field]["min_value"]
104   - if plan[field].get("max_value"):
105   - if type(plan[field].get("max_value")) == str:
106   - max_value = ast.literal_eval(plan[field]["max_value"])
107   - else:
108   - max_value = plan[field]["max_value"]
  106 + if not is_simplified:
  107 + if plan[field].get("value_type"):
  108 + value_type = plan[field]["value_type"]
  109 + if type(plan[field]["value"]) == str and ast.literal_eval(plan[field]["value"]) != value_type:
  110 + result["errors"].append(f"Field {field} value doesn't correspond to the assigned type (type required : {value_type})")
  111 + if plan[field].get("min_value"):
  112 + if type(plan[field]["min_value"]) == str:
  113 + min_value = ast.literal_eval(plan[field]["min_value"])
  114 + else:
  115 + min_value = plan[field]["min_value"]
  116 + if plan[field].get("max_value"):
  117 + if type(plan[field].get("max_value")) == str:
  118 + max_value = ast.literal_eval(plan[field]["max_value"])
  119 + else:
  120 + max_value = plan[field]["max_value"]
109 121 if field == "nb_images":
110   - new_plan_object.__dict__[field] = plan[field]["value"]
  122 + if is_simplified:
  123 + new_plan_object.__dict__[field] = plan[field]
  124 + else:
  125 + new_plan_object.__dict__[field] = plan[field]["value"]
111 126 else:
112   - if plan[field].get("values"):
113   - index_value = plan[field]["value"]
114   - values = plan[field]["values"]
115   - if index_value < 0 or index_value > len(plan[field]["values"]):
116   - result["errors"].append(f"Value of Plan field '{field}' isn't valid, index out of bounds ({index_value} > {len(values)})")
117   - index_value = 0
118   - value = plan[field]["values"][index_value]
119   - try:
120   - # linked values
121   - splitted_values = value.split(";")
122   - config_attributes[field] = {}
123   - for splitted_value in splitted_values:
124   - subkey,subvalue = splitted_value.split(":")
125   - config_attributes[field][subkey] = ast.literal_eval(subvalue)
126   - except:
127   - # Do nothing, normal string
128   - config_attributes[field] = ast.literal_eval(value)
129   - new_plan_object.config_attributes[field] = config_attributes[field]
  127 + if not is_simplified:
  128 + if plan[field].get("values"):
  129 + index_value = plan[field]["value"]
  130 + values = plan[field]["values"]
  131 + if index_value < 0 or index_value > len(plan[field]["values"]):
  132 + result["errors"].append(f"Value of Plan field '{field}' isn't valid, index out of bounds ({index_value} > {len(values)})")
  133 + index_value = 0
  134 + value = plan[field]["values"][index_value]
  135 + try:
  136 + # linked values
  137 + splitted_values = value.split(";")
  138 + config_attributes[field] = {}
  139 + for splitted_value in splitted_values:
  140 + subkey,subvalue = splitted_value.split(":")
  141 + config_attributes[field][subkey] = ast.literal_eval(subvalue)
  142 + except:
  143 + # Do nothing, normal string
  144 + config_attributes[field] = ast.literal_eval(value)
  145 + new_plan_object.config_attributes[field] = config_attributes[field]
  146 + else:
  147 + if max_value and min_value:
  148 + if plan[field]["value"] > max_value:
  149 + result["errors"].append(f"Plan field {field} doesn't respect max value")
  150 + if plan[field]["value"] < min_value:
  151 + result["errors"].append(f"Plan field {field} doesn't respect min value")
  152 + new_plan_object.config_attributes[field] = plan[field]["value"]
130 153 else:
131   - if max_value and min_value:
132   - if plan[field]["value"] > max_value:
133   - result["errors"].append(f"Plan field {field} doesn't respect max value")
134   - if plan[field]["value"] < min_value:
135   - result["errors"].append(f"Plan field {field} doesn't respect min value")
136   - new_plan_object.config_attributes[field] = plan[field]["value"]
  154 + new_plan_object.config_attributes[field] = plan[field]
137 155 new_plan_object.save()
138 156  
139 157  
... ...
src/core/pyros_django/routine_manager/views.py
... ... @@ -28,7 +28,7 @@ from .forms import SequenceForm, AlbumForm, PlanForm, uneditablePlanForm
28 28 #from .forms import RequestForm, SequenceForm, AlbumForm, PlanForm, uneditablePlanForm
29 29  
30 30 from .validators import check_plan_validity, check_album_validity, check_sequence_validity, check_request_validity
31   -from .functions import check_sequence_file_validity
  31 +from .functions import check_sequence_file_validity_and_save
32 32 from .RequestSerializer import RequestSerializer
33 33 import scheduler
34 34 from django.contrib import messages
... ... @@ -854,7 +854,7 @@ def import_sequence(request):
854 854 message = "File is too big (more than 1 000 000 bytes)"
855 855 else:
856 856 yaml_content = yaml.safe_load(file.read())
857   - import_response = check_sequence_file_validity(
  857 + import_response = check_sequence_file_validity_and_save(
858 858 yaml_content, request)
859 859 if import_response["succeed"]:
860 860 message = "Request imported successfully. Please check it before submitting for scheduling."
... ... @@ -896,10 +896,13 @@ def export_sequence(request, seq_id: int, type: str):
896 896 elif field == "start_date":
897 897 #field_dict["value"] = seq.start_date.strftime("%d/%m/%Y %H:%M:%S")
898 898 # ISO format
899   - field_dict["value"] = seq.start_date.strftime("Y-%m/%dT%H:%M:%S.%f")
  899 + field_dict["value"] = seq.start_date.strftime("%Y-%m-%dT%H:%M:%S.%f")
900 900 field_dict["value_type"] = "str"
901 901 else:
902   - field_dict["value_type"] = sequence_form.fields[field].widget.input_type
  902 + if hasattr(sequence_form.fields[field].widget,"input_type"):
  903 + field_dict["value_type"] = sequence_form.fields[field].widget.input_type
  904 + else:
  905 + field_dict["value_type"] = "str"
903 906 if seq.__dict__.get(field) == None:
904 907 value = seq.config_attributes.get(field)
905 908 else:
... ...