functions.py
9.92 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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
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_and_save(yaml_content,request):
is_simplified = yaml_content.get("simplified", False)
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": [],
}
if is_simplified:
seq.scientific_program = sp_list[yaml_content["sequence"]["scientific_program"]]
else:
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
if is_simplified:
value = yaml_content["sequence"][field]
else:
value = yaml_content["sequence"][field]["value"]
if field not in yaml_content["sequence"]:
result["errors"].append(f"{field} not in yaml file")
else:
if not is_simplified:
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(value) != datetime.datetime:
#value = datetime.datetime.strptime(yaml_content["sequence"][field]["value"],'%d/%m/%Y %H:%M:%S')
# ISO format
value = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f')
seq.__dict__[field] = value
else:
if sequence_form.fields[field].__dict__.get("_choices"):
values = [value[0] for value in sequence_form.fields[field].__dict__.get("_choices")]
value = values[value]
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 not is_simplified:
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":
if is_simplified:
new_plan_object.__dict__[field] = plan[field]
else:
new_plan_object.__dict__[field] = plan[field]["value"]
else:
if not is_simplified:
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"]
else:
new_plan_object.config_attributes[field] = plan[field]
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