def get_sanctioned_users_blackout_times(self, start, end): """ A project is 'blacked out' when all of its sanctioned observers are unavailable or it is using Project Blackouts. User blackouts are much more complicated, thus this method. Returns a list of tuples describing the time ranges where the project is 'blacked out' by user blackouts in UTC. """ if not self.has_sanctioned_observers(): return [] blackouts = [o.user.blackout_set.all() \ for o in self.get_sanctioned_observers()] # Change all to UTC. utcBlackouts = [] for set in blackouts: utc = [] for b in set: utc.extend(b.generateDates(start, end)) utcBlackouts.append(utc) if len(utcBlackouts) == 1: # One observer runs the show. return sorted(utcBlackouts[0]) return AnalogSet.unions(AnalogSet.intersects(utcBlackouts))
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 get_blackout_times(self, start, end): """ A project is 'blacked out' when all of its sanctioned and unsanctioned, on-site observers are unavailable, or it is using Project Blackouts. Returns a list of tuples describing the time ranges where the project is 'blacked out' in UTC. """ blackouts = self.get_project_blackout_times(start, end) blackouts.extend(self.get_users_blackout_times(start, end)) return AnalogSet.unions(blackouts)
def get_prescheduled_times(self, start, end): """ 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. """ def truncatePeriodRange(p, start, end): s = max(p.start, start) e = min(p.end(), end) return (s, e) times = [truncatePeriodRange(d, start, end) \ for p in Project.objects.all() \ # TBF: that's why this takes so long! limit the # periods by the time range a little!!!! for d in p.getPeriods() \ if p != self and \ d.state.abbreviation == 'S' and \ AnalogSet.overlaps((d.start, d.end()), (start, end))] return sorted(AnalogSet.unions(times))