Commit 793d01902f575a3fad242077aa9ae7e9e811ea9a
1 parent
d6e916dc
Exists in
dev
rework routine_manager functions.py
Showing
1 changed file
with
216 additions
and
202 deletions
Show diff stats
src/core/pyros_django/routine_manager/functions.py
@@ -12,155 +12,33 @@ from django.db import IntegrityError | @@ -12,155 +12,33 @@ from django.db import IntegrityError | ||
12 | # Project imports | 12 | # Project imports |
13 | from src.core.pyros_django.obsconfig.obsconfig_class import OBSConfig | 13 | from src.core.pyros_django.obsconfig.obsconfig_class import OBSConfig |
14 | from django.http import HttpRequest | 14 | from django.http import HttpRequest |
15 | +#from silk.profiling.profiler import silk_profile | ||
15 | 16 | ||
17 | +#@silk_profile(name="check_sequence_file") | ||
16 | def check_sequence_file_validity_and_save(yaml_content: dict, request: HttpRequest): | 18 | def check_sequence_file_validity_and_save(yaml_content: dict, request: HttpRequest): |
17 | ''' Create a sequence in DB from the uploaded sequence (yaml_content) ''' | 19 | ''' Create a sequence in DB from the uploaded sequence (yaml_content) ''' |
18 | 20 | ||
19 | - # Get boolean to simplified to know if the file is written in simplified mode (i.e. : Each field of the form is directly associated to its value) | ||
20 | - is_simplified = yaml_content.get("simplified", False) | ||
21 | - # Get scientific programs for the user who is submitting the sequence file | ||
22 | - user_sp = request.user.get_scientific_programs() | ||
23 | - # From user sp, get all SP that can observe / submit sequence for the current period | ||
24 | - sp_list = ScientificProgram.objects.observable_programs().filter(id__in=user_sp) | ||
25 | - | ||
26 | # Create a sequence seq object (from yaml_content) to be saved in DB | 21 | # Create a sequence seq object (from yaml_content) to be saved in DB |
27 | seq = Sequence.objects.create() | 22 | seq = Sequence.objects.create() |
28 | seq.pyros_user = PyrosUser.objects.get(id=request.user.id) | 23 | seq.pyros_user = PyrosUser.objects.get(id=request.user.id) |
29 | 24 | ||
30 | # Get the unit config | 25 | # Get the unit config |
31 | unit_name = os.environ["unit_name"] | 26 | unit_name = os.environ["unit_name"] |
27 | + #with silk_profile(name="init obsconfig"): | ||
32 | config = OBSConfig(os.environ["PATH_TO_OBSCONF_FILE"], unit_name) | 28 | config = OBSConfig(os.environ["PATH_TO_OBSCONF_FILE"], unit_name) |
33 | - | ||
34 | - # Create a Sequence form | ||
35 | - sequence_form = SequenceForm(instance=seq, data_from_config=config.getEditableMountAttributes(config.unit_name), layouts = config.get_layouts(config.unit_name), sp_list=sp_list) | ||
36 | result = { | 29 | result = { |
37 | "succeed": True, | 30 | "succeed": True, |
38 | "errors": [], | 31 | "errors": [], |
39 | } | 32 | } |
40 | - | ||
41 | - if is_simplified: | ||
42 | - seq.scientific_program = sp_list[yaml_content["sequence"]["scientific_program"]] | 33 | + # Get boolean to simplified to know if the file is written in simplified mode (i.e. : Each field of the form is directly associated to its value) |
34 | + is_simplified = yaml_content.get("simplified", False) | ||
35 | + # Get scientific programs for the user who is submitting the sequence file | ||
36 | + user_sp = request.user.get_scientific_programs() | ||
37 | + process_sequence(yaml_content, seq, config, is_simplified, result, user_sp) | ||
43 | 38 | ||
44 | - else: | ||
45 | - # pour la lisibilité du code (et éviter la redondance) | ||
46 | - # get scientific program field's attributes | ||
47 | - yaml_seq_sp = yaml_content["sequence"]["scientific_program"] | ||
48 | - sp_index_value = yaml_seq_sp["value"] | ||
49 | - values = yaml_seq_sp["values"] | ||
50 | - # Check if index of sp is valid (in range of possible index from values) | ||
51 | - if sp_index_value < 0 or sp_index_value > len(values): | ||
52 | - result["errors"].append(f"SP value isn't valid, index out of bounds ({sp_index_value} > {len(values)})") | ||
53 | - sp_index_value = 0 | ||
54 | - chosen_sp = ScientificProgram.objects.get(name=values[sp_index_value]) | ||
55 | - # If the sp is associated to that user, associate the sp to the sequence | ||
56 | - if chosen_sp in sp_list: | ||
57 | - #seq.scientific_program = ScientificProgram.objects.get(name=yaml_content["sequence"]["scientific_program"]["values"][sp_index_value]) | ||
58 | - seq.scientific_program = chosen_sp | ||
59 | - else: | ||
60 | - result["errors"].append(f"SP {chosen_sp.name} is not assigned to that user ") | 39 | + process_albums(yaml_content, result, config, seq, is_simplified) |
61 | 40 | ||
62 | - seq.config_attributes = {} | ||
63 | - | ||
64 | - # Fill all Sequence form fields | ||
65 | - # keys() inutile ? => for field in sequence_form.fields : | ||
66 | - # Sinon, y a aussi => for key,val in sequence_form.fields.items(): | ||
67 | - # => Ca éviterait de faire => sequence_form.fields[field] pour recuperer "val" | ||
68 | - for field, field_attribute in sequence_form.fields.items(): | ||
69 | 41 | ||
70 | - #if sequence_form.fields[field].required == False or field == "scientific_program": | ||
71 | - if not field_attribute.required or field=="scientific_program": | ||
72 | - continue | ||
73 | - # pour lisibilité, simplicité et éviter redondance | ||
74 | - yaml_field = yaml_content["sequence"][field] | ||
75 | - value = yaml_field if is_simplified else yaml_field["value"] | ||
76 | - ''' (orig) | ||
77 | - if is_simplified: | ||
78 | - value = yaml_content["sequence"][field] | ||
79 | - else: | ||
80 | - value = yaml_content["sequence"][field]["value"] | ||
81 | - ''' | ||
82 | - # If the current field of the sequence isn't found in the file, add an error message to inform the user the missing field | ||
83 | - if field not in yaml_content["sequence"]: | ||
84 | - result["errors"].append(f"{field} not in yaml file") | ||
85 | - else: | ||
86 | - if is_simplified: | ||
87 | - # If the field is a choicefield, get choices and associate the index to the real value | ||
88 | - if sequence_form.fields[field].__dict__.get("_choices"): | ||
89 | - # y a pas conflit ici avec la variable "value" définie au-dessus ? -> Non car on transforme l'ancien value qui est un index en une vraie valeur | ||
90 | - values = [value[0] for value in sequence_form.fields[field].__dict__.get("_choices")] | ||
91 | - value = values[value] | ||
92 | - else: | ||
93 | - if yaml_field.get("values"): | ||
94 | - # Transform the original value which is an index to a "real" value from the "values" attributes | ||
95 | - index_value = yaml_field["value"] | ||
96 | - values = yaml_field["values"] | ||
97 | - if index_value < 0 or index_value > len(yaml_field["values"]): | ||
98 | - result["errors"].append(f"Value of {field} isn't valid, index out of bounds ({index_value} > {len(values)})") | ||
99 | - index_value = 0 | ||
100 | - value = yaml_field["values"][index_value] | ||
101 | - else: | ||
102 | - # Transform the string value to a datetime value | ||
103 | - if field == "start_date": | ||
104 | - if type(value) != datetime.datetime: | ||
105 | - #value = datetime.datetime.strptime(yaml_content["sequence"][field]["value"],'%d/%m/%Y %H:%M:%S') | ||
106 | - # ISO format | ||
107 | - value = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f') | ||
108 | - seq.__dict__[field] = value | ||
109 | - ''' (orig) | ||
110 | - else: | ||
111 | - if not is_simplified: | ||
112 | - if yaml_content["sequence"][field].get("values"): | ||
113 | - index_value = yaml_content["sequence"][field]["value"] | ||
114 | - values = yaml_content["sequence"][field]["values"] | ||
115 | - if index_value < 0 or index_value > len(yaml_content["sequence"][field]["values"]): | ||
116 | - result["errors"].append(f"Value of {field} isn't valid, index out of bounds ({index_value} > {len(values)})") | ||
117 | - index_value = 0 | ||
118 | - value = yaml_content["sequence"][field]["values"][index_value] | ||
119 | - else: | ||
120 | - if field == "start_date": | ||
121 | - if type(value) != datetime.datetime: | ||
122 | - #value = datetime.datetime.strptime(yaml_content["sequence"][field]["value"],'%d/%m/%Y %H:%M:%S') | ||
123 | - # ISO format | ||
124 | - value = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f') | ||
125 | - seq.__dict__[field] = value | ||
126 | - else: | ||
127 | - if sequence_form.fields[field].__dict__.get("_choices"): | ||
128 | - values = [value[0] for value in sequence_form.fields[field].__dict__.get("_choices")] | ||
129 | - value = values[value] | ||
130 | - ''' | ||
131 | - | ||
132 | - # suffisant ? => if field in seq.__dict__ | ||
133 | - # If field is an attribute of the sequence, associate the field to the value | ||
134 | - if field in seq.__dict__: | ||
135 | - seq.__dict__[field] = value | ||
136 | - else: | ||
137 | - # else associate field & value in config_attributes sequence's field (JsonField) = variable fields of an sequence | ||
138 | - seq.config_attributes[field] = value | ||
139 | - | ||
140 | - # Create ALBUMS | ||
141 | - albums_from_file = yaml_content["sequence"]["ALBUMS"] | ||
142 | - chosen_layout = seq.config_attributes["layout"] | ||
143 | - if type(chosen_layout) == int: | ||
144 | - layouts = config.get_layouts(config.unit_name)["layouts"] | ||
145 | - chosen_layout = list(layouts.keys())[chosen_layout] | ||
146 | - # Get album of the selected layout | ||
147 | - layout_albums = config.getLayoutByName(unit_name=config.unit_name, name_of_layout=chosen_layout)["ALBUMS"] | ||
148 | - | ||
149 | - # check if we have all the albums of that layout described in the sequence file | ||
150 | - if len(layout_albums) == len(albums_from_file): | ||
151 | - for album in albums_from_file: | ||
152 | - album = album["Album"] | ||
153 | - if album["name"] not in layout_albums: | ||
154 | - result["errors"].append(f"Album {album['name']} is not the chosen layout") | ||
155 | - else: | ||
156 | - # Create album | ||
157 | - Album.objects.create(name=album["name"], sequence=seq, complete=True) | ||
158 | - # Create plan for that album | ||
159 | - plans = [a["Album"].get("Plans") for a in albums_from_file] | ||
160 | - process_plans(plans, result, is_simplified, config, album, seq) | ||
161 | - else: | ||
162 | - result["errors"].append(f"The number of albums doesn't correspond to the chosen layout") | ||
163 | - | ||
164 | # optim possible ? | 42 | # optim possible ? |
165 | #[ process_plans(a["Album"].get("Plans")) for a in albums_from_file ] | 43 | #[ process_plans(a["Album"].get("Plans")) for a in albums_from_file ] |
166 | # Puis écrire la fonction process_plans() | 44 | # Puis écrire la fonction process_plans() |
@@ -291,19 +169,51 @@ def check_sequence_file_validity_and_save(yaml_content: dict, request: HttpReque | @@ -291,19 +169,51 @@ def check_sequence_file_validity_and_save(yaml_content: dict, request: HttpReque | ||
291 | result["sequence_id"] = seq.id | 169 | result["sequence_id"] = seq.id |
292 | return result | 170 | return result |
293 | 171 | ||
172 | +def process_albums(yaml_content, result, config, seq, is_simplified): | ||
173 | + # Create ALBUMS | ||
174 | + albums_from_file = yaml_content["sequence"]["ALBUMS"] | ||
175 | + chosen_layout = seq.config_attributes["layout"] | ||
176 | + if type(chosen_layout) == int: | ||
177 | + #with silk_profile(name="Get layout from config"): | ||
178 | + layouts = config.get_layouts(config.unit_name)["layouts"] | ||
179 | + chosen_layout = list(layouts)[chosen_layout] | ||
180 | + # Get album of the selected layout | ||
181 | + #with silk_profile(name="Get album of layout from config"): | ||
182 | + layout_albums = config.getLayoutByName(unit_name=config.unit_name, name_of_layout=chosen_layout)["ALBUMS"] | ||
183 | + | ||
184 | + # check if we have all the albums of that layout described in the sequence file | ||
185 | + #with silk_profile(name="Iterate on each album & plan (create)"): | ||
186 | + if len(layout_albums) == len(albums_from_file): | ||
187 | + for album in albums_from_file: | ||
188 | + album = album["Album"] | ||
189 | + if album["name"] not in layout_albums: | ||
190 | + result["errors"].append(f"Album {album['name']} is not the chosen layout") | ||
191 | + else: | ||
192 | + # Create album | ||
193 | + Album.objects.create(name=album["name"], sequence=seq, complete=True) | ||
194 | + # Create plan for that album | ||
195 | + plans = album.get("Plans") | ||
196 | + process_plans(plans, result, is_simplified, config, album, seq) | ||
197 | + else: | ||
198 | + result["errors"].append(f"The number of albums doesn't correspond to the chosen layout") | ||
199 | + | ||
294 | 200 | ||
201 | +#@silk_profile(name="process_plans") | ||
295 | def process_plans(plans: dict, result: dict, is_simplified: bool, config: OBSConfig, album: dict, seq: dict): | 202 | def process_plans(plans: dict, result: dict, is_simplified: bool, config: OBSConfig, album: dict, seq: dict): |
296 | if plans == None: | 203 | if plans == None: |
297 | result["errors"].append(f"Album {album['name']} has no plans. Please add at least one plan") | 204 | result["errors"].append(f"Album {album['name']} has no plans. Please add at least one plan") |
298 | # exit function | 205 | # exit function |
299 | return None | 206 | return None |
300 | for plan in plans: | 207 | for plan in plans: |
301 | - new_plan_object = Plan.objects.create(album=Album.objects.get(name=album["name"], sequence=seq), complete=True) | ||
302 | - new_plan_object.config_attributes = {} | 208 | + #new_plan_object = Plan.objects.create(album=Album.objects.get(name=album["name"], sequence=seq), complete=True) |
209 | + #new_plan_object.config_attributes = {} | ||
303 | plan = plan["Plan"] | 210 | plan = plan["Plan"] |
211 | + nb_images = 0 | ||
304 | config_attributes = {} | 212 | config_attributes = {} |
213 | + #with silk_profile(name="Create plan form"): | ||
305 | plan_form = PlanForm(data_from_config=config.getEditableChannelAttributes(config.unit_name, list(config.get_channels(config.unit_name).keys())[0]), edited_plan=None) | 214 | plan_form = PlanForm(data_from_config=config.getEditableChannelAttributes(config.unit_name, list(config.get_channels(config.unit_name).keys())[0]), edited_plan=None) |
306 | # Process each plan field | 215 | # Process each plan field |
216 | + #with silk_profile(name="iterate on plan fields"): | ||
307 | for field in plan_form.fields: | 217 | for field in plan_form.fields: |
308 | plan_field = plan[field] | 218 | plan_field = plan[field] |
309 | ''' | 219 | ''' |
@@ -311,78 +221,180 @@ def process_plans(plans: dict, result: dict, is_simplified: bool, config: OBSCon | @@ -311,78 +221,180 @@ def process_plans(plans: dict, result: dict, is_simplified: bool, config: OBSCon | ||
311 | max_value = None | 221 | max_value = None |
312 | value_type = None | 222 | value_type = None |
313 | ''' | 223 | ''' |
314 | - min_value = max_value = value_type = None | ||
315 | - if field not in plan.keys(): | ||
316 | - result["errors"].append(f"Missing field : '{field}' for plan {plans.index(plan)}") | ||
317 | - continue | ||
318 | - # TODO : ajouter max_value, min_value, suppression plan et album si invalides | ||
319 | - if not is_simplified: | ||
320 | - if plan_field.get("value_type"): | ||
321 | - value_type = plan_field["value_type"] | ||
322 | - if type(plan_field["value"]) == str and ast.literal_eval(plan_field["value"]) != value_type: | ||
323 | - result["errors"].append(f"Field {field} value doesn't correspond to the assigned type (type required : {value_type})") | ||
324 | - if plan_field.get("min_value"): | ||
325 | - min_value = plan_field["min_value"] | ||
326 | - if type(min_value) == str: | ||
327 | - min_value = ast.literal_eval(min_value) | ||
328 | - ''' | ||
329 | - if type(plan_field["min_value"]) == str: | ||
330 | - min_value = ast.literal_eval(plan_field["min_value"]) | ||
331 | - else: | ||
332 | - min_value = plan_field["min_value"] | ||
333 | - ''' | ||
334 | - if plan_field.get("max_value"): | ||
335 | - max_value = plan_field["max_value"] | ||
336 | - if type(max_value) == str: | ||
337 | - max_value = ast.literal_eval(max_value) | ||
338 | - ''' | ||
339 | - if type(plan_field.get("max_value")) == str: | ||
340 | - max_value = ast.literal_eval(plan_field["max_value"]) | ||
341 | - else: | ||
342 | - max_value = plan_field["max_value"] | ||
343 | - ''' | ||
344 | if field == "nb_images": | 224 | if field == "nb_images": |
345 | - new_plan_object.__dict__[field] = plan_field if is_simplified else plan_field["value"] | ||
346 | - ''' | ||
347 | - if is_simplified: | ||
348 | - new_plan_object.__dict__[field] = plan_field | ||
349 | - else: | ||
350 | - new_plan_object.__dict__[field] = plan_field["value"] | ||
351 | - ''' | 225 | + nb_images = plan_field if is_simplified else plan_field["value"] |
352 | else: | 226 | else: |
353 | - # shortcut possible ? | ||
354 | - #new_plan_object_field = new_plan_object.config_attributes[field] | ||
355 | - if is_simplified: | ||
356 | - new_plan_object.config_attributes[field] = plan_field | ||
357 | - else: | ||
358 | - if plan_field.get("values"): | ||
359 | - index_value = plan_field["value"] | ||
360 | - values = plan_field["values"] | ||
361 | - if index_value < 0 or index_value > len(plan_field["values"]): | ||
362 | - result["errors"].append(f"Value of Plan field '{field}' isn't valid, index out of bounds ({index_value} > {len(values)})") | ||
363 | - index_value = 0 | ||
364 | - value = plan_field["values"][index_value] | ||
365 | - try: | ||
366 | - # linked values | ||
367 | - splitted_values = value.split(";") | ||
368 | - config_attributes[field] = {} | ||
369 | - for splitted_value in splitted_values: | ||
370 | - subkey,subvalue = splitted_value.split(":") | ||
371 | - config_attributes[field][subkey] = ast.literal_eval(subvalue) | ||
372 | - # vaudrait mieux préciser l'exception ici | ||
373 | - except: | ||
374 | - # Do nothing, normal string | ||
375 | - config_attributes[field] = ast.literal_eval(value) | ||
376 | - new_plan_object.config_attributes[field] = config_attributes[field] | ||
377 | - else: | ||
378 | - if max_value and min_value: | ||
379 | - if plan_field["value"] > max_value: | ||
380 | - result["errors"].append(f"Plan field {field} doesn't respect max value") | ||
381 | - if plan_field["value"] < min_value: | ||
382 | - result["errors"].append(f"Plan field {field} doesn't respect min value") | ||
383 | - new_plan_object.config_attributes[field] = plan_field["value"] | 227 | + process_plan_field(result, config_attributes, plan_field, field, plans, plan, is_simplified) |
384 | # end foreach plan field | 228 | # end foreach plan field |
385 | - new_plan_object.save() | 229 | + Plan.objects.create(album=Album.objects.get(name=album["name"], sequence=seq), complete=True, nb_images=nb_images, config_attributes=config_attributes) |
230 | + | ||
231 | +def process_plan_field(result, config_attributes, plan_field, field, plans, plan, is_simplified): | ||
232 | + | ||
233 | + | ||
234 | + if field not in plan.keys(): | ||
235 | + result["errors"].append(f"Missing field : '{field}' for plan {plans.index(plan)}") | ||
236 | + # exit function | ||
237 | + return None | ||
238 | + if is_simplified: | ||
239 | + #new_plan_object.config_attributes[field] = plan_field | ||
240 | + config_attributes[field] = plan_field | ||
241 | + else: | ||
242 | + value_type, min_value, max_value = prepare_check_plan_field_value(plan_field, field, result) | ||
243 | + check_and_set_plan_field_value(config_attributes, plan_field, field, result, value_type, min_value, max_value) | ||
244 | + | ||
245 | + | ||
246 | +def check_and_set_plan_field_value(config_attributes, plan_field, field, result, value_type, min_value, max_value): | ||
247 | + # if the value is a index of a list, get the value from this index | ||
248 | + if plan_field.get("values"): | ||
249 | + index_value = plan_field["value"] | ||
250 | + values = plan_field["values"] | ||
251 | + if index_value < 0 or index_value > len(plan_field["values"]): | ||
252 | + result["errors"].append(f"Value of Plan field '{field}' isn't valid, index out of bounds ({index_value} > {len(values)})") | ||
253 | + index_value = 0 | ||
254 | + value = plan_field["values"][index_value] | ||
255 | + try: | ||
256 | + # linked values | ||
257 | + splitted_values = value.split(";") | ||
258 | + config_attributes[field] = {} | ||
259 | + for splitted_value in splitted_values: | ||
260 | + subkey,subvalue = splitted_value.split(":") | ||
261 | + config_attributes[field][subkey] = ast.literal_eval(subvalue) | ||
262 | + # vaudrait mieux préciser l'exception ici | ||
263 | + except ValueError: | ||
264 | + # Do nothing, normal string | ||
265 | + config_attributes[field] = ast.literal_eval(value) | ||
266 | + #new_plan_object.config_attributes[field] = config_attributes[field] | ||
267 | + else: | ||
268 | + # check min and max values if they exist | ||
269 | + if max_value and min_value: | ||
270 | + if plan_field["value"] > max_value: | ||
271 | + result["errors"].append(f"Plan field {field} doesn't respect max value") | ||
272 | + if plan_field["value"] < min_value: | ||
273 | + result["errors"].append(f"Plan field {field} doesn't respect min value") | ||
274 | + #new_plan_object.config_attributes[field] = plan_field["value"] | ||
275 | + config_attributes[field] = plan_field["value"] | ||
276 | + | ||
277 | + | ||
278 | +def prepare_check_plan_field_value(plan_field, field, result): | ||
279 | + min_value = max_value = value_type = None | ||
280 | + # get value type, min_value and max_value if they're in the plan form | ||
281 | + if plan_field.get("value_type"): | ||
282 | + value_type = plan_field["value_type"] | ||
283 | + # If value type doesn't match with the value from the form, add an error to result | ||
284 | + if type(plan_field["value"]) == str and ast.literal_eval(plan_field["value"]) != value_type: | ||
285 | + result["errors"].append(f"Field {field} value doesn't correspond to the assigned type (type required : {value_type})") | ||
286 | + if plan_field.get("min_value"): | ||
287 | + min_value = plan_field["min_value"] | ||
288 | + if type(min_value) == str: | ||
289 | + min_value = ast.literal_eval(min_value) | ||
290 | + if plan_field.get("max_value"): | ||
291 | + max_value = plan_field["max_value"] | ||
292 | + if type(max_value) == str: | ||
293 | + max_value = ast.literal_eval(max_value) | ||
294 | + return value_type, min_value, max_value | ||
295 | + | ||
296 | + | ||
297 | +def process_sequence(yaml_content, seq, config, is_simplified, result, user_sp): | ||
298 | + | ||
299 | + # From user sp, get all SP that can observe / submit sequence for the current period | ||
300 | + sp_list = ScientificProgram.objects.observable_programs().filter(id__in=user_sp) | ||
301 | + # Create a Sequence form | ||
302 | + sequence_form = SequenceForm(instance=seq, data_from_config=config.getEditableMountAttributes(config.unit_name), layouts = config.get_layouts(config.unit_name), sp_list=sp_list) | ||
303 | + | ||
304 | + if is_simplified: | ||
305 | + seq.scientific_program = sp_list[yaml_content["sequence"]["scientific_program"]] | ||
306 | + else: | ||
307 | + # get scientific program field's attributes | ||
308 | + yaml_seq_sp = yaml_content["sequence"]["scientific_program"] | ||
309 | + sp_index_value = yaml_seq_sp["value"] | ||
310 | + values = yaml_seq_sp["values"] | ||
311 | + # Check if index of sp is valid (in range of possible index from values) | ||
312 | + if sp_index_value < 0 or sp_index_value > len(values): | ||
313 | + result["errors"].append(f"SP value isn't valid, index out of bounds ({sp_index_value} > {len(values)})") | ||
314 | + sp_index_value = 0 | ||
315 | + chosen_sp = ScientificProgram.objects.get(name=values[sp_index_value]) | ||
316 | + # If the sp is associated to that user, associate the sp to the sequence | ||
317 | + if chosen_sp in sp_list: | ||
318 | + #seq.scientific_program = ScientificProgram.objects.get(name=yaml_content["sequence"]["scientific_program"]["values"][sp_index_value]) | ||
319 | + seq.scientific_program = chosen_sp | ||
320 | + else: | ||
321 | + result["errors"].append(f"SP {chosen_sp.name} is not assigned to that user ") | ||
322 | + | ||
323 | + seq.config_attributes = {} | ||
324 | + | ||
325 | + # Fill all Sequence form fields | ||
326 | + #with silk_profile(name="iterate sequence fields form"): | ||
327 | + for field, field_attributes in sequence_form.fields.items(): | ||
328 | + #if sequence_form.fields[field].required == False or field == "scientific_program": | ||
329 | + if not field_attributes.required or field=="scientific_program": | ||
330 | + continue | ||
331 | + # pour lisibilité, simplicité et éviter redondance | ||
332 | + yaml_field = yaml_content["sequence"][field] | ||
333 | + value = yaml_field if is_simplified else yaml_field["value"] | ||
334 | + ''' (orig) | ||
335 | + if is_simplified: | ||
336 | + value = yaml_content["sequence"][field] | ||
337 | + else: | ||
338 | + value = yaml_content["sequence"][field]["value"] | ||
339 | + ''' | ||
340 | + # If the current field of the sequence isn't found in the file, add an error message to inform the user the missing field | ||
341 | + if field not in yaml_content["sequence"]: | ||
342 | + result["errors"].append(f"{field} not in yaml file") | ||
343 | + else: | ||
344 | + if is_simplified: | ||
345 | + # If the field is a choicefield, get choices and associate the index to the real value | ||
346 | + if sequence_form.fields[field].__dict__.get("_choices"): | ||
347 | + # y a pas conflit ici avec la variable "value" définie au-dessus ? -> Non car on transforme l'ancien value qui est un index en une vraie valeur | ||
348 | + values = [value[0] for value in sequence_form.fields[field].__dict__.get("_choices")] | ||
349 | + value = values[value] | ||
350 | + else: | ||
351 | + if yaml_field.get("values"): | ||
352 | + # Transform the original value which is an index to a "real" value from the "values" attributes | ||
353 | + index_value = yaml_field["value"] | ||
354 | + values = yaml_field["values"] | ||
355 | + if index_value < 0 or index_value > len(yaml_field["values"]): | ||
356 | + result["errors"].append(f"Value of {field} isn't valid, index out of bounds ({index_value} > {len(values)})") | ||
357 | + index_value = 0 | ||
358 | + value = yaml_field["values"][index_value] | ||
359 | + else: | ||
360 | + # Transform the string value to a datetime value | ||
361 | + if field == "start_date": | ||
362 | + if type(value) != datetime.datetime: | ||
363 | + #value = datetime.datetime.strptime(yaml_content["sequence"][field]["value"],'%d/%m/%Y %H:%M:%S') | ||
364 | + # ISO format | ||
365 | + value = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f') | ||
366 | + seq.__dict__[field] = value | ||
367 | + ''' (orig) | ||
368 | + else: | ||
369 | + if not is_simplified: | ||
370 | + if yaml_content["sequence"][field].get("values"): | ||
371 | + index_value = yaml_content["sequence"][field]["value"] | ||
372 | + values = yaml_content["sequence"][field]["values"] | ||
373 | + if index_value < 0 or index_value > len(yaml_content["sequence"][field]["values"]): | ||
374 | + result["errors"].append(f"Value of {field} isn't valid, index out of bounds ({index_value} > {len(values)})") | ||
375 | + index_value = 0 | ||
376 | + value = yaml_content["sequence"][field]["values"][index_value] | ||
377 | + else: | ||
378 | + if field == "start_date": | ||
379 | + if type(value) != datetime.datetime: | ||
380 | + #value = datetime.datetime.strptime(yaml_content["sequence"][field]["value"],'%d/%m/%Y %H:%M:%S') | ||
381 | + # ISO format | ||
382 | + value = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f') | ||
383 | + seq.__dict__[field] = value | ||
384 | + else: | ||
385 | + if sequence_form.fields[field].__dict__.get("_choices"): | ||
386 | + values = [value[0] for value in sequence_form.fields[field].__dict__.get("_choices")] | ||
387 | + value = values[value] | ||
388 | + ''' | ||
389 | + | ||
390 | + # suffisant ? => if field in seq.__dict__ | ||
391 | + # If field is an attribute of the sequence, associate the field to the value | ||
392 | + if field in seq.__dict__: | ||
393 | + seq.__dict__[field] = value | ||
394 | + else: | ||
395 | + # else associate field & value in config_attributes sequence's field (JsonField) = variable fields of an sequence | ||
396 | + seq.config_attributes[field] = value | ||
397 | + | ||
386 | 398 | ||
387 | def create_sequence_pickle(sequence): | 399 | def create_sequence_pickle(sequence): |
388 | seq_dict = model_to_dict(sequence) | 400 | seq_dict = model_to_dict(sequence) |
@@ -404,4 +416,6 @@ def create_sequence_pickle(sequence): | @@ -404,4 +416,6 @@ def create_sequence_pickle(sequence): | ||
404 | if not os.path.exists(data_path +f"sequences_pickle/P{period.id}/{sequence.night_id}"): | 416 | if not os.path.exists(data_path +f"sequences_pickle/P{period.id}/{sequence.night_id}"): |
405 | os.mkdir(data_path +f"sequences_pickle/P{period.id}/{sequence.night_id}") | 417 | os.mkdir(data_path +f"sequences_pickle/P{period.id}/{sequence.night_id}") |
406 | seq_pickle_file_name = data_path +f"./sequences_pickle/P{period.id}/{sequence.night_id}/{sequence.id}.p" | 418 | seq_pickle_file_name = data_path +f"./sequences_pickle/P{period.id}/{sequence.night_id}/{sequence.id}.p" |
419 | + # get guitastro ephemeris | ||
420 | + #fullseq_dict["ephem"] = fn.ephem(sequence.target) | ||
407 | pickle.dump(fullseq_dict,open(seq_pickle_file_name,"wb")) | 421 | pickle.dump(fullseq_dict,open(seq_pickle_file_name,"wb")) |
408 | \ No newline at end of file | 422 | \ No newline at end of file |