Commit 10252292b688d5588b9e64f5d3eca8cd5af6e4d7
1 parent
2c54f472
Exists in
dev
Change function to read sequence yml file to understand a simplified version
Showing
3 changed files
with
94 additions
and
72 deletions
Show diff stats
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: | ... | ... |