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