def publish_periods(request, *args, **kwds): """ Publishes pending periods within a time range specified by a start time and duration. We tweet to let the world know we published. However, the default is to tweet unless we are using our sandboxes. Note: Supports publishing periods by time range, or a single one by id. """ if len(args) == 1: # publish a single period specified in args by its ID p = Period.objects.get(id = int(args[0])) p.publish() p.save() else: # publish periods identified by time range startPeriods = request.POST.get("start", datetime.now().strftime("%Y-%m-%d %H:%M:%S")) startPeriods = datetime.strptime(startPeriods, '%Y-%m-%d %H:%M:%S') start, duration = ScheduleTools().getSchedulingRange( startPeriods , request.POST.get("tz", "UTC") , int(request.POST.get("duration", "1")) - 1) Period.publish_periods(start, duration) revision.comment = get_rev_comment(request, None, "publish_periods") if DATABASES['default']['NAME'] == 'dss' and request.POST.get("tweet", "True") == "True": update = 'GBT schedule updated. See https://dss.gb.nrao.edu/schedule/public for details.' try: twitter.Api( consumer_key = settings.TWITTER['consumer_key'] , consumer_secret = settings.TWITTER['consumer_secret'] , access_token_key = settings.TWITTER['access_token_key'] , access_token_secret = settings.TWITTER['access_token_secret'] ).PostUpdate(update) except: # That's ok, the world doesn't HAVE to know. formatExceptionInfo() return HttpResponse(json.dumps({'success':'ok'}), mimetype = "text/plain")
def _get_fixed_mags(utc_day): mags = [] try: delta = timedelta(days = 7) # get maintenance periods for the date span mp = Period.objects\ .filter(session__observing_type__type = "maintenance")\ .filter(start__gte = utc_day)\ .filter(start__lt = utc_day + delta)\ .filter(session__session_type__type = 'fixed')\ .filter(state__name = "Scheduled") for i in mp: if i.maintenance_activity_group_set.count() == 0: mag = Maintenance_Activity_Group() mag.deleted = False mag.rank = 'x' mag.week = utc_day i.maintenance_activity_group_set.add(mag) else: mag = i.maintenance_activity_group_set.all()[0] # for backwards compatibility, mark groups # belonging to fixed periods with rank 'x' so that # they are not picked up by _get_elective_mags(). if mag.rank != 'x': mag.rank = 'x' mag.save() if not mag.week: mag.week = utc_day mag.save() mags.append(mag) mags.sort(key = lambda x: x.get_start()) except: if settings.DEBUG == True: printException(formatExceptionInfo()) return mags
def _get_elective_mags(utc_day): mags = [] try: delta = timedelta(days = 7) # get maintenance electives for the date span me = Elective.objects\ .filter(session__observing_type__type = 'maintenance')\ .filter(periods__start__gte = utc_day)\ .filter(periods__start__lt = utc_day + delta)\ .distinct() # don't care about elective with all deleted periods. me = [e for e in me if e.periods.count() > e.deletedPeriods().count()] # need as many floating groups as there are elective # maintenance days. First, count up the maintenance days, # then the groups. If not equal, we must either truncate # the groups or add to them. Finally any groups within # the tally must be marked not deleted (in case they were # deleted earlier), and any outside the tally must be # marked deleted. maintenance_periods = len(me) # When obtaining the maintenance activity groups for this # week, ensure that the query will match the mag's 'week' # field by stripping off the time of 'utc_day'. Otherwise # it may not pick it up. Also we include a generous time # range for 'week' just to make sure time issues don't # crop in and exclude any group. dbmags = Maintenance_Activity_Group.objects\ .filter(week__gte = TimeAgent.truncateDt(utc_day))\ .filter(week__lt = TimeAgent.truncateDt(utc_day) + delta)\ .exclude(rank = 'x') \ .order_by("rank") mags = [mag for mag in dbmags] # these are all ordered by rank now, relabel rank in case # it doesn't start with 'A' ('B', 'C', etc.), or there is # a gap ('A', 'B', 'D', etc.) (would occur if manually # deleted from database, etc., and leaving old rank might # confuse users.) for i in range(0, len(mags)): if mags[i].rank != chr(65 + i): mags[i].rank = chr(65 + i) mags[i].save() # either too many or not enough mags. Deal with it # accordingly... if maintenance_periods != len(mags): # too many; mark the excess as deleted. if len(mags) > maintenance_periods: for i in range(maintenance_periods, len(mags)): mag = mags[i] mag.deleted = True mag.period = None mag.save() # too few; create more to make up the numbers. if len(mags) < maintenance_periods: for i in range(len(mags), maintenance_periods): mag = Maintenance_Activity_Group() mag.week = TimeAgent.truncateDt(utc_day) mag.deleted = False mag.rank = chr(65 + i) mag.save() mags.append(mag) # Mark all mags from 0 to number of maintenance periods as # undeleted. This reuses any previously deleted mags. for i in range(0, maintenance_periods): mag = mags[i] if mag.deleted: mag.deleted = False mag.save() # now make sure scheduled electives get assigned the # correct group. sched_periods = [] for i in me: sched_periods += i.periodsByState('S') # sort periods by start, groups by rank. Makes them easy # to match up. Any previous matchups will be undone. sched_periods.sort(key = lambda x: x.start) mags.sort(key = lambda x: x.rank) def in_query_set(item, qset): for i in qset: if item == i: return True return False for i in range(0, len(mags)): mag = mags[i] if i < len(sched_periods): p = sched_periods[i] # update the period if the mag is not the right # one, or if it has more than one mag, to ensure # just one per period. if not in_query_set(mag, p.maintenance_activity_group_set.all()) \ or p.maintenance_activity_group_set.count() > 1: p.maintenance_activity_group_set.clear() p.maintenance_activity_group_set.add(mag) else: if mag.period: mag.period = None mag.save() except: if settings.DEBUG == True: printException(formatExceptionInfo()) return mags
revision.comment = get_rev_comment(request, None, "restore_schedule") return HttpResponse(json.dumps({'success':'ok'}), mimetype = "text/plain") ###################################################################### # Declaring 'notifier' as a global allows it to keep state between # 'GET' and 'POST' calls of scheduling_email. ###################################################################### try: notifier = SchedulingNotifier() except: if DEBUG: printException(formatExceptionInfo()) @catch_json_parse_errors def scheduling_email(request, *args, **kwds): address_key = ["observer_address", "changed_address", "staff_address"] subject_key = ["observer_subject", "changed_subject", "staff_subject"] body_key = ["observer_body", "changed_body", "staff_body"] email_key = ["observer", "changed", "staff"] if request.method == 'GET': # Show the schedule from now until 8am eastern 'duration' days from now. start = datetime.utcnow() duration = int(request.GET.get("duration")) end = TimeAgent.est2utc(TimeAgent.utc2est(start + timedelta(days = duration - 1)) .replace(hour = 8, minute = 0, second = 0,