def setComplete(self, complete): """ The setting of the complete flag will automatically delete all associated Pending periods; conversely clearing the flag will restore all future opportunities to Pending. """ # if we haven't initilized yet, get out of town if self.complete is None: self.complete = complete self.save() return # only make changes on *transitions* of state if complete and not self.complete: # False -> True: delete all pending for p in self.pendingPeriods(): p.move_to_deleted_state() elif not complete and self.complete: # True -> False: resurrect all deleted for p in self.deletedPeriods(): p.state = Period_State.get_state("P") p.save() self.complete = complete self.save()
def get_prescheduled_times(start, end, project = None): """ Returns a list of binary tuples of the form (start, end) that describe when this project cannot observe because other projects already have scheduled telescope periods during the time range specified by the start and end arguments. NOTE: this is functionally identical to Project.get_prescheduled_times, but uses a DB query to improve performance; Project cannot do this becuase the query causes circular references. """ def truncatePeriodRange(p, start, end): "we don't care about periods outside of range" s = max(p.start, start) e = min(p.end(), end) return (s, e) # first query DB simply by the time range minutes = timedelta2minutes(end - start) ps1 = Period.get_periods(start, minutes) # now filter out other stuff pId = None if project is not None: pId = project.id scheduled = Period_State.get_state('S') times = [truncatePeriodRange(p, start, end) for p in ps1 \ if p.session.project.id != pId \ and p.state == scheduled \ and AnalogSet.overlaps((p.start, p.end()), (start, end))] return sorted(AnalogSet.unions(times))
def getBlackedOutSchedulablePeriods(self, now): """ Of the future periods for this elective overlapping in the time range that are not deleted or completed, which schedulable ones have been blacked out? Returns a list of offending periods. """ state = Period_State.get_state('D') ps = self.periods.exclude(state=state).order_by('start') periods = list(ps) if not periods: return [] pranges = [(p.start, p.end(), p) for p in periods] start = max(now, pranges[0][0]) _, _, _, brs = \ self.session.getBlackedOutSchedulableTime(start , pranges[-1][1]) branges = [r for sublist in brs for r in sublist] # flatten lists retval = [] for p in pranges: for b in branges: if p[0] < b[1] and b[0] < p[1]: retval.append(p[2]) break return retval
def getRange(self): state = Period_State.get_state('D') ps = self.periods.exclude(state=state).order_by('start') periods = list(ps) if periods: return [periods[0].start, periods[-1].end()] else: return []
def getPeriodRange(self): state = Period_State.get_state("D") ps = self.period_set.exclude(state=state).order_by("start") periods = list(ps) if periods: return [periods[0].start, periods[-1].end()] else: return []
def restore_electives(start, duration): """ Looks for any elective periods in the deleted state, and brings them back to pending. """ for p in Period.get_periods(start , duration , ignore_deleted = False): if p.isDeleted() and p.session.isElective(): p.state = Period_State.get_state("P") p.save()
def setComplete(self, complete): """ When a window is set as not complete, the default period comes back. """ remaining = self.timeRemaining() if not complete and self.complete and \ remaining != 0 and self.default_period is not None: self.default_period.duration = remaining self.default_period.state = Period_State.get_state("P") self.default_period.save() self.complete = complete self.save()
def periodDateRange(self): """ Returns the earliest & latest start times of all its non-deleted periods """ deleted = Period_State.get_state('D') try: min = self.periods.exclude(state=deleted).order_by('start')[0].start except IndexError: min = None try: max = self.periods.exclude(state=deleted).order_by('-start')[0].start except IndexError: max = None return (min, max)
def restore_windows(start, duration): """ Looks for any windowed periods in the deleted state, and brings them back to pending if: * a default period * from a non-gauranteed window """ for p in Period.get_periods(start , duration , ignore_deleted = False): if p.isDeleted() and p.session.isWindowed() and \ p.is_windowed_default() and not p.session.guaranteed(): p.state = Period_State.get_state("P") p.save()
def periodsByState(self, s): "get periods by their state, which is one of ['P', 'D', 'S']" state = Period_State.get_state(s) return self.periods.filter(state=state)
def nonDefaultPeriods(self): deleted = Period_State.get_state('D') return [p for p in self.periods.exclude(state=deleted).all() if p != self.default_period]
def hasPeriodsAfter(self, dt): deleted = Period_State.get_state('D') return self.periods.exclude(state=deleted).filter(start__gt=dt).exists()
def move_to_deleted_state(self): "all in the name" self.state = Period_State.get_state("D") self.save()