Blame view

src/core/pyros_django/routine_manager/functions.py 8.82 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
98621b46   Alexis Koralewski   add DRF, pyros ap...
4
from common.models import PyrosUser, ScientificProgram, Sequence, Album, Plan, Period
ad3b297c   Alexis Koralewski   add pagination to...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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"]
98621b46   Alexis Koralewski   add DRF, pyros ap...
22
    values =  yaml_content["sequence"]["scientific_program"]["values"]
ad3b297c   Alexis Koralewski   add pagination to...
23
    if index_value_sp < 0 or index_value_sp > len(yaml_content["sequence"]["scientific_program"]["values"]):
98621b46   Alexis Koralewski   add DRF, pyros ap...
24
        result["errors"].append(f"Value of scientific program isn't valid, index out of bounds ({index_value_sp} > {len(values)})")
ad3b297c   Alexis Koralewski   add pagination to...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
        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"]
98621b46   Alexis Koralewski   add DRF, pyros ap...
41
                values =  yaml_content["sequence"][field]["values"]
ad3b297c   Alexis Koralewski   add pagination to...
42
                if index_value < 0 or index_value > len(yaml_content["sequence"][field]["values"]):
98621b46   Alexis Koralewski   add DRF, pyros ap...
43
                    result["errors"].append(f"Value of {field} isn't valid, index out of bounds ({index_value} > {len(values)})")
ad3b297c   Alexis Koralewski   add pagination to...
44
45
46
47
                    index_value = 0
                value = yaml_content["sequence"][field]["values"][index_value]
            else:
                if field == "start_date":
0ad59e43   Alexis Koralewski   fix & improve imp...
48
49
50
51
52
53
                    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
ad3b297c   Alexis Koralewski   add pagination to...
54
55
56
57
58
59
60
        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...
61
62
63
    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...
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
    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"]
98621b46   Alexis Koralewski   add DRF, pyros ap...
113
                                values =  plan[field]["values"]
ad3b297c   Alexis Koralewski   add pagination to...
114
                                if index_value < 0 or index_value > len(plan[field]["values"]):
98621b46   Alexis Koralewski   add DRF, pyros ap...
115
                                    result["errors"].append(f"Value of Plan field '{field}' isn't valid, index out of bounds ({index_value} > {len(values)})")
ad3b297c   Alexis Koralewski   add pagination to...
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
                                    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
98621b46   Alexis Koralewski   add DRF, pyros ap...
141
142
143
144
    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...
145
146
147
148
    seq.save()
    if len(result["errors"]) != 0:
        result["succeed"] = False
        seq.delete()
98621b46   Alexis Koralewski   add DRF, pyros ap...
149
150
    else:
        result["sequence_id"] = seq.id
ad3b297c   Alexis Koralewski   add pagination to...
151
    return result