functions.py
8.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import ast
from src.core.pyros_django.obsconfig.obsconfig_class import OBSConfig
from .forms import SequenceForm, AlbumForm, PlanForm
from common.models import PyrosUser, ScientificProgram, Period
from routine_manager.models import Sequence, Album, Plan
import datetime
import os, yaml
def check_sequence_file_validity(yaml_content,request):
sp_of_user = request.user.get_scientific_program()
sp_list = ScientificProgram.objects.observable_programs().filter(id__in=sp_of_user)
seq = Sequence.objects.create()
seq.pyros_user = PyrosUser.objects.get(id=request.user.id)
unit_name = os.environ["unit_name"]
config = OBSConfig(os.environ["PATH_TO_OBSCONF_FILE"], unit_name)
sequence_form = SequenceForm(instance=seq, data_from_config=config.getEditableAttributesOfMount(config.unit_name), layouts = config.get_layouts(config.unit_name), sp_list=sp_list)
result = {
"succeed": True,
"errors": [],
}
index_value_sp = yaml_content["sequence"]["scientific_program"]["value"]
values = yaml_content["sequence"]["scientific_program"]["values"]
if index_value_sp < 0 or index_value_sp > len(yaml_content["sequence"]["scientific_program"]["values"]):
result["errors"].append(f"Value of scientific program isn't valid, index out of bounds ({index_value_sp} > {len(values)})")
index_value_sp = 0
chosen_sp = ScientificProgram.objects.get(name=yaml_content["sequence"]["scientific_program"]["values"][index_value_sp])
if chosen_sp in sp_list:
seq.scientific_program = ScientificProgram.objects.get(name=yaml_content["sequence"]["scientific_program"]["values"][index_value_sp])
else:
result["errors"].append(f"Scientific program {chosen_sp.name} is not assigned to that user ")
seq.config_attributes = {}
for field in sequence_form.fields.keys():
if sequence_form.fields[field].required == False or field == "scientific_program":
continue
value = yaml_content["sequence"][field]["value"]
if field not in yaml_content["sequence"]:
result["errors"].append(f"{field} not in yaml file")
else:
if yaml_content["sequence"][field].get("values"):
index_value = yaml_content["sequence"][field]["value"]
values = yaml_content["sequence"][field]["values"]
if index_value < 0 or index_value > len(yaml_content["sequence"][field]["values"]):
result["errors"].append(f"Value of {field} isn't valid, index out of bounds ({index_value} > {len(values)})")
index_value = 0
value = yaml_content["sequence"][field]["values"][index_value]
else:
if field == "start_date":
if type(yaml_content["sequence"][field]["value"]) != datetime.datetime:
#value = datetime.datetime.strptime(yaml_content["sequence"][field]["value"],'%d/%m/%Y %H:%M:%S')
# ISO format
value = datetime.datetime.strptime(yaml_content["sequence"][field]["value"],'%Y-%m/%dT%H:%M:%S.%f')
seq.__dict__[field] = value
continue
if field in seq.__dict__.keys():
seq.__dict__[field] = value
else:
seq.config_attributes[field] = value
albums_from_file = yaml_content["sequence"]["ALBUMS"]
choosen_layout = seq.config_attributes["layout"]
if type(choosen_layout) == int:
layouts = config.get_layouts(config.unit_name)["layouts"]
choosen_layout = list(layouts.keys())[choosen_layout]
albums_of_layout = config.getLayoutByName(unit_name=config.unit_name,name_of_layout=choosen_layout)["ALBUMS"]
if len(albums_of_layout) == len(albums_from_file):
for album in albums_from_file:
album = album["Album"]
if album["name"] not in albums_of_layout:
result["errors"].append(f"Album {album['name']} is not the chosen layout")
else:
alb = Album.objects.create(name=album["name"], sequence=seq, complete=True)
else:
result["errors"].append(f"The number of albums doesn't correspond to the chosen layout")
for album in yaml_content["sequence"]["ALBUMS"]:
album = album["Album"]
plans = album.get("Plans")
if plans == None:
result["errors"].append(f"Album {album['name']} has no plans. Please add at least one plan")
else:
for plan in plans:
new_plan_object = Plan.objects.create(album=Album.objects.get(name=album["name"],sequence=seq),complete=True)
new_plan_object.config_attributes = {}
plan = plan["Plan"]
config_attributes = {}
plan_form = PlanForm(data_from_config=config.getEditableAttributesOfChannel(config.unit_name,list(config.get_channels(config.unit_name).keys())[0]),edited_plan=None)
for field in plan_form.fields:
min_value = None
max_value = None
value_type = None
if field not in plan.keys():
result["errors"].append(f"Missing field : '{field}' for plan {plans.index(plan)}")
else:
# TODO : ajouter max_value, min_value, suppression plan et album si invalides
if plan[field].get("value_type"):
value_type = plan[field]["value_type"]
if type(plan[field]["value"]) == str and ast.literal_eval(plan[field]["value"]) != value_type:
result["errors"].append(f"Field {field} value doesn't correspond to the assigned type (type required : {value_type})")
if plan[field].get("min_value"):
if type(plan[field]["min_value"]) == str:
min_value = ast.literal_eval(plan[field]["min_value"])
else:
min_value = plan[field]["min_value"]
if plan[field].get("max_value"):
if type(plan[field].get("max_value")) == str:
max_value = ast.literal_eval(plan[field]["max_value"])
else:
max_value = plan[field]["max_value"]
if field == "nb_images":
new_plan_object.__dict__[field] = plan[field]["value"]
else:
if plan[field].get("values"):
index_value = plan[field]["value"]
values = plan[field]["values"]
if index_value < 0 or index_value > len(plan[field]["values"]):
result["errors"].append(f"Value of Plan field '{field}' isn't valid, index out of bounds ({index_value} > {len(values)})")
index_value = 0
value = plan[field]["values"][index_value]
try:
# linked values
splitted_values = value.split(";")
config_attributes[field] = {}
for splitted_value in splitted_values:
subkey,subvalue = splitted_value.split(":")
config_attributes[field][subkey] = ast.literal_eval(subvalue)
except:
# Do nothing, normal string
config_attributes[field] = ast.literal_eval(value)
new_plan_object.config_attributes[field] = config_attributes[field]
else:
if max_value and min_value:
if plan[field]["value"] > max_value:
result["errors"].append(f"Plan field {field} doesn't respect max value")
if plan[field]["value"] < min_value:
result["errors"].append(f"Plan field {field} doesn't respect min value")
new_plan_object.config_attributes[field] = plan[field]["value"]
new_plan_object.save()
seq.status = Sequence.TOBEPLANNED
seq.complete = True
period = Period.objects.exploitation_period()
if Period.objects.next_period() != None and Period.objects.next_period().start_date < seq.start_date.date():
period = Period.objects.next_period()
seq.period = period
seq.save()
if len(result["errors"]) != 0:
result["succeed"] = False
seq.delete()
else:
result["sequence_id"] = seq.id
return result