Blame view

src/core/pyros_django/routine_manager/functions.py 9.92 KB
ad3b297c   Alexis Koralewski   add pagination to...
1
2
3
import ast
from src.core.pyros_django.obsconfig.obsconfig_class import OBSConfig
from .forms import SequenceForm, AlbumForm, PlanForm
43e6176d   Etienne Pallier   Model splitting g...
4
5
from common.models import PyrosUser, ScientificProgram, Period
from routine_manager.models import Sequence, Album, Plan
ad3b297c   Alexis Koralewski   add pagination to...
6
7
8
9
import datetime
import os, yaml


10252292   Alexis Koralewski   Change function t...
10
11
def check_sequence_file_validity_and_save(yaml_content,request):
    is_simplified = yaml_content.get("simplified", False)
ad3b297c   Alexis Koralewski   add pagination to...
12
13
14
15
16
17
18
19
20
21
22
    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": [],
    }
10252292   Alexis Koralewski   Change function t...
23
24
    if is_simplified:
        seq.scientific_program = sp_list[yaml_content["sequence"]["scientific_program"]]
ad3b297c   Alexis Koralewski   add pagination to...
25
    else:
10252292   Alexis Koralewski   Change function t...
26
27
28
29
30
31
32
33
34
35
        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 ")
ad3b297c   Alexis Koralewski   add pagination to...
36
37
38
39
    seq.config_attributes = {}
    for field in sequence_form.fields.keys():
        if sequence_form.fields[field].required == False or field == "scientific_program":
            continue
10252292   Alexis Koralewski   Change function t...
40
41
42
43
        if is_simplified:
            value = yaml_content["sequence"][field]    
        else:
            value = yaml_content["sequence"][field]["value"]
ad3b297c   Alexis Koralewski   add pagination to...
44
45
46
        if field not in yaml_content["sequence"]:
            result["errors"].append(f"{field} not in yaml file")
        else:
10252292   Alexis Koralewski   Change function t...
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
            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
ad3b297c   Alexis Koralewski   add pagination to...
62
            else:
10252292   Alexis Koralewski   Change function t...
63
64
65
                if sequence_form.fields[field].__dict__.get("_choices"):
                    values = [value[0] for value in sequence_form.fields[field].__dict__.get("_choices")]
                    value = values[value]
ad3b297c   Alexis Koralewski   add pagination to...
66
67
68
69
70
71
72
        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"]
0ad59e43   Alexis Koralewski   fix & improve imp...
73
74
75
    if type(choosen_layout) == int:
        layouts = config.get_layouts(config.unit_name)["layouts"]
        choosen_layout = list(layouts.keys())[choosen_layout]
ad3b297c   Alexis Koralewski   add pagination to...
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
    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
10252292   Alexis Koralewski   Change function t...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
                        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"]
ad3b297c   Alexis Koralewski   add pagination to...
121
                        if field == "nb_images":
10252292   Alexis Koralewski   Change function t...
122
123
124
125
                            if is_simplified:
                                new_plan_object.__dict__[field] = plan[field]    
                            else:
                                new_plan_object.__dict__[field] = plan[field]["value"]
ad3b297c   Alexis Koralewski   add pagination to...
126
                        else:
10252292   Alexis Koralewski   Change function t...
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
                            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"]
ad3b297c   Alexis Koralewski   add pagination to...
153
                            else:
10252292   Alexis Koralewski   Change function t...
154
                                new_plan_object.config_attributes[field] = plan[field]
ad3b297c   Alexis Koralewski   add pagination to...
155
156
157
158
159
                new_plan_object.save()
        
                    
    seq.status = Sequence.TOBEPLANNED
    seq.complete = True
98621b46   Alexis Koralewski   add DRF, pyros ap...
160
161
162
163
    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
ad3b297c   Alexis Koralewski   add pagination to...
164
165
166
167
    seq.save()
    if len(result["errors"]) != 0:
        result["succeed"] = False
        seq.delete()
98621b46   Alexis Koralewski   add DRF, pyros ap...
168
169
    else:
        result["sequence_id"] = seq.id
ad3b297c   Alexis Koralewski   add pagination to...
170
    return result