RequestBuilder.py 5.53 KB
from django.contrib.auth.models import User
from pyrosapp.models import *
from scheduler.tasks import scheduling

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, userlevel=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.
        '''
        if settings.SIMULATION == False:
            self.request = Request(
                scientific_program=scientific_program, pyros_user=pyros_user, is_alert=is_alert)
        else:
            self.request = Request(name=name, scientific_program=ScientificProgram.objects.get(
            ), pyros_user=PyrosUser.objects.get(), is_alert=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"):
        '''
            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)
        '''

        sequence = Sequence(name=name, status=Sequence.OBSERVABLE, priority=priority,
                            jd1=jd1, jd2=jd2, t_prefered=t_prefered)
        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
        '''

        # TODO: à checker : existance de detector dans la DB et seq_id dans
        # self.sequences

        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
        '''

        # TODO: à checker : existance de l'album en local, du filtre en db

        filter_ = Filter.objects.get(device__name=filter_name)

        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
        '''

        # TODO: a checker -> que toutes les séquences ont bien au moins un
        # album, les albums au moins un plan, qu'il y a au moins une séquence

        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()
#         scheduling.delay()
        return self.request