RequestBuilder.py
6.8 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
172
173
174
175
176
177
from django.contrib.auth.models import User
from common.models import *
import scheduler.tasks
from decimal import Decimal
from django.conf import settings
class RequestBuilder():
def __init__(self):
'''
Might do nothing if this is not a simulation
'''
if settings.SIMULATION == False:
pass
else:
''' creating dependencies in DB if they don't exist '''
if PyrosUser.objects.count() == 0:
if Country.objects.count() == 0:
country = Country.objects.create(name="default")
else:
country = Country.objects.get()
if UserLevel.objects.count() == 0:
user_level = UserLevel.objects.create(name="default")
else:
user_level = UserLevel.objects.get()
if User.objects.count() == 0:
user = User.objects.create(username="default")
else:
user = User.objects.get()
PyrosUser.objects.create(
country=country, user_level=user_level, user=user, quota=1000)
if ScientificProgram.objects.count() == 0:
ScientificProgram.objects.create(name="default")
def start_new_request(self, pyros_user, scientific_program, is_alert, name="default"):
'''
This function MUST be called to build a request.
It erases the previous one, and creates the sequences', albums' and plans' dictionaries.
'''
self.request = Request(name=name,
scientific_program=scientific_program, pyros_user=pyros_user, is_alert=is_alert, complete=True, submitted=True)
self.sequence_id = 1
self.album_id = 1
self.plan_id = 1
self.sequences = {}
self.albums = {}
self.plans = {}
def add_sequence(self, priority, jd1, jd2, t_prefered=-1, name="default", duration=0):
'''
Add a sequence to the current request
start_new_request must be called one before it
:returns : The local ID of the sequence (to add albums to it)
'''
if not hasattr(self, "request"):
raise RuntimeError(
"start_new_request MUST be invoked before creating any sequence")
sequence = Sequence(name=name, status=Sequence.OBSERVABLE, priority=priority,
jd1=jd1, jd2=jd2, t_prefered=t_prefered, duration=duration)
self.sequences[self.sequence_id] = sequence
self.sequence_id += 1
return self.sequence_id - 1
def delete_sequence(self, seq_id):
'''
Removes locally a sequence from the current request
'''
if seq_id in self.sequences.keys():
del self.sequences[seq_id]
def add_album(self, seq_id, detector_name, name="default"):
'''
Creates a new album for the given sequence
:returns : The local ID of the new album
'''
if not Detector.objects.filter(device__name=detector_name).exists():
raise RuntimeError("Detector %s doesn't exist" % (detector_name,))
if seq_id not in self.sequences.keys():
raise RuntimeError("The sequence %d doesn't exist" % (seq_id,))
detector = Detector.objects.get(device__name=detector_name)
album = Album(name=name, detector=detector)
self.albums[self.album_id] = (album, seq_id)
self.album_id += 1
return self.album_id - 1
def del_album(self, album_id):
'''
Removes locally an album from the current request
'''
if album_id in self.albums.keys():
del self.albums[album_id]
def add_plan(self, album_id, filter_name, duration, nb_images, name="default"):
'''
Creates a new plan for the given album
:returns : The local ID of the new plan
'''
if not Filter.objects.filter(device__name=filter_name).exists():
raise RuntimeError("Filer %s doesn't exist" % (filter_name,))
if album_id not in self.albums.keys():
raise RuntimeError("The album %d doesn't exist" % (album_id,))
filter_ = Filter.objects.get(device__name=filter_name)
duration = Decimal(float(duration) / 86400.0)
plan = Plan(name=name, filter=filter_,
duration=duration, nb_images=nb_images)
self.plans[self.plan_id] = (plan, album_id)
self.plan_id += 1
return self.plan_id - 1
def del_plan(self, plan_id):
'''
Removes locally a plan from the current request
'''
if plan_id in self.plans.keys():
del self.plans[plan_id]
def validate_request(self):
'''
Saves the different objects : request, sequences, albums, plans
Computes sequences' duration
Creates a scheduling task
:returns : The request
'''
if len(self.sequences) == 0:
raise RuntimeError(
"There must be at least one sequence in a request")
if settings.SIMULATION == False:
sequences_having_album = list(set([
seq_id for album, seq_id in self.albums.values()]))
if len(sequences_having_album) != len(self.sequences):
raise RuntimeError("All sequences must have at least one album")
albums_having_plan = list(set([
album_id for plan, album_id in self.plans.values()]))
if len(albums_having_plan) != len(self.albums):
raise RuntimeError("All albums must have at least one plan")
self.request.save()
for sequence in self.sequences.values():
sequence.request = self.request
sequence.save()
for album, seq_id in self.albums.values():
album.sequence = self.sequences[seq_id]
album.save()
for plan, album_id in self.plans.values():
plan.album = self.albums[album_id][0]
plan.save()
if settings.SIMULATION == False:
''' computes the duration of all sequences '''
for sequence in self.sequences.values():
max_duration = 0
for album in sequence.albums.all():
duration = sum([plan.duration for plan in album.plans.all()])
max_duration = duration if duration > max_duration else max_duration
sequence.duration = max_duration
sequence.save()
if settings.CELERY_TEST == False:
pass
# TODO: mettre une condition de temps pour lancer le scheduling (il faut être nuit -2 min au minimum)
# scheduler.tasks.scheduling.delay(first_schedule=True, alert=self.request.is_alert) # TODO : changer le first_schedule ...
return self.request