from common.models import * import scheduler.tasks from decimal import Decimal from django.conf import settings class RequestBuilder(): 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 = {} self.is_alert = is_alert 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.TOBEPLANNED, priority=priority, jd1=jd1, jd2=jd2, t_prefered=t_prefered, duration=duration, is_alert=self.is_alert) 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(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(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(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(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 ''' print("this request has", len(self.sequences), "sequences") if len(self.sequences) == 0: raise RuntimeError( "There must be at least one sequence in a request") 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() ''' 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() print("here is the new request built: ", self.request) # TODO: uncomment # mettre une condition de temps pour lancer le scheduling (il faut ĂȘtre nuit -2 min au minimum) # TODO : changer le first_schedule ... if settings.USE_CELERY: print("RB: schedule WITH CELERY") scheduler.tasks.scheduling.delay(first_schedule=True, alert=self.request.is_alert) else: print("RB: schedule WITHOUT CELERY") scheduler.tasks.scheduling().run(first_schedule=True, alert=self.request.is_alert) return self.request