def remotely_qualified(request, *args, **kws): """ Returns all remotely qualified observers. """ requestor = get_requestor(request) qualified = User.objects.filter(sanctioned = True).order_by('last_name') return render_to_response('users/remotely_qualified.html' , dict(requestor = requestor, q = qualified))
def moc_reschedule(request, *args, **kws): """ Allows an operator to acknowledge when the MOC is bad before an observation. """ requestor = get_requestor(request) period = Period.objects.get(id = args[0]) acknowledge_moc(requestor, period) return render_to_response('users/moc_reschedule.html' , dict(requestor = requestor, p = period))
def moc_degraded(request, *args, **kws): """ Allows an operator to acknowledge when the MOC is bad after an observation has begun. """ requestor = get_requestor(request) period = Period.objects.get(id = args[0]) acknowledge_moc(requestor, period) return render_to_response('users/moc_degraded.html' , dict(requestor = requestor, p = period))
def gbt_schedule(request, *args, **kws): """ Serves up a GBT schedule page tailored for Operations. Note: This view is in either ET or UTC, database is in UTC. """ def cleanSD(startDate): try: return datetime.strptime(startDate, '%m/%d/%Y') if startDate else datetime.now() except: # Bad input? return datetime.now() timezones = ['ET', 'UTC'] # Note: we probably should have better error handling here, # but since the forms are Date Pickers and drop downs, it seems # difficult for the user to send us malformed params. # Default date, days, and timezone. Loaded from the values # saved below, or from defaults if no values were saved. if request.method == 'POST': startDate, days, timezone = (None, 5, 'ET') else: startDate, days, timezone, _ = _get_calendar_defaults(request) data = request.POST if request.method == 'POST' else request.GET timezone = data.get('tz', timezone) days = int(data.get('days', days)) startDate = cleanSD(data.get('start', startDate)) start = TimeAgent.truncateDt(startDate) end = start + timedelta(days = days) # save these values for use in 'GET' above. _save_calendar_defaults(request, start, days, timezone) requestor = get_requestor(request) supervisor_mode = True if (requestor in get_rescal_supervisors()) else False schedule = get_gbt_schedule_events(start, end, timezone) try: tzutc = Schedule_Notification.objects.latest('date').date.replace(tzinfo=UTC) pubdate = tzutc.astimezone(EST) except: pubdate = None printerFriendly = data.get('printerFriendly', None) template = 'users/schedules/schedule_friendly.html' if printerFriendly == '1' \ else 'users/schedule.html' return render_to_response( template, {'calendar' : schedule, 'day_list' : range(1, 32), 'tz_list' : timezones, 'timezone' : timezone, 'today' : datetime.now(EST), 'start' : start, 'startFmt' : start.strftime('%m/%d/%Y'), 'days' : days, 'rschedule' : Receiver_Schedule.extract_schedule(start, days), 'requestor' : requestor, 'supervisor_mode' : supervisor_mode, 'pubdate' : pubdate, })
def _process_activity(request, ma, form): """ Does some processing in common between the add and the edit views. """ # process the returned stuff here... ma.subject = form.cleaned_data['subject'] # The date and time entered into the form will be ET. It # must be converted to UTC. The end-time need not be # converted since a duration is computed and stored in the # database instead of the end time. diffs = {} date = form.cleaned_data['date'] start = datetime(date.year, date.month, date.day, hour = int(form.cleaned_data['time_hr']), minute = int(form.cleaned_data['time_min'])) diffs = _record_diffs('start', ma.get_start('ET') if ma._start else start, start, diffs) ma.set_start(start, 'ET') oldval = ma.duration if form.cleaned_data["end_choice"] == "end_time": end_date = form.cleaned_data['date'] end = datetime(year = end_date.year, month = end_date.month, day = end_date.day, hour = int(form.cleaned_data['end_time_hr']), minute = int(form.cleaned_data['end_time_min'])) delta = end - start ma.duration = delta.seconds / 3600.0 # in decimal hours else: ma.duration = float(form.cleaned_data['end_time_hr']) \ + float(form.cleaned_data["end_time_min"]) / 60.0 diffs = _record_diffs('duration', oldval, ma.duration, diffs) oldval = ma.contacts ma.contacts = form.cleaned_data["responsible"] diffs = _record_diffs('contacts', oldval, ma.contacts, diffs) oldval = ma.location ma.location = form.cleaned_data["location"] diffs = _record_diffs('location', oldval, ma.location, diffs) oldval = ma.telescope_resource trid = form.cleaned_data["telescope"] ma.telescope_resource = Maintenance_Telescope_Resources.objects \ .filter(id = trid)[0] diffs = _record_diffs('telescope', oldval, ma.telescope_resource, diffs) oldval = ma.software_resource srid = form.cleaned_data["software"] ma.software_resource = Maintenance_Software_Resources.objects \ .filter(id = srid)[0] diffs = _record_diffs('software', oldval, ma.software_resource, diffs) oldval = [p for p in ma.other_resources.all()] ma.other_resources.clear() for orid in form.cleaned_data["other_resources"]: other_r = Maintenance_Other_Resources.objects.filter(id = orid)[0] ma.other_resources.add(other_r) diffs = _record_m2m_diffs('other', oldval, ma.other_resources.all(), diffs) oldval = [p for p in ma.receivers.all()] ma.receivers.clear() for rid in form.cleaned_data["receivers"]: rcvr = Receiver.objects.filter(id = rid)[0] ma.receivers.add(rcvr) diffs = _record_m2m_diffs('receivers', oldval, ma.receivers.all(), diffs) if form.cleaned_data["change_receiver"] == True: down_rcvr_id = form.cleaned_data["old_receiver"] up_rcvr_id = form.cleaned_data["new_receiver"] # What is needed is a receiver swap entry that contains our # receivers in the correct order (i.e. a for b, not b for a). # To avoid creating duplicate entries (for instance, repeated # swaps of a for b and b for a), search for an existing one # first. If there is none, then create a new swap pair. mrsg = Maintenance_Receivers_Swap.objects.filter( down_receiver = down_rcvr_id).filter(up_receiver = up_rcvr_id) if len(mrsg) == 0: down_rcvr = Receiver.objects \ .filter(id = form.cleaned_data["old_receiver"])[0] up_rcvr = Receiver.objects \ .filter(id = form.cleaned_data["new_receiver"])[0] mrs = Maintenance_Receivers_Swap(down_receiver = down_rcvr, up_receiver = up_rcvr) mrs.save() else: mrs = mrsg[0] ma.receiver_changes.clear() ma.receiver_changes.add(mrs) else: ma.receiver_changes.clear() oldval = [p for p in ma.backends.all()] ma.backends.clear() for bid in form.cleaned_data["backends"]: be = Backend.objects.filter(id = bid)[0] ma.backends.add(be) diffs = _record_m2m_diffs('backends', oldval, ma.backends.all(), diffs) oldval = ma.description ma.description = form.cleaned_data["description"] diffs = _record_diffs('description', oldval, ma.description, diffs) ma.repeat_interval = int(form.cleaned_data["recurrency_interval"]) if ma.repeat_interval > 0: ma.repeat_end = form.cleaned_data["recurrency_until"] # Normally a maintenance activity comes with a group assigned. # But it is possible to add a maintenance activity without a # group. In this case, assign right period for maintenance # activity, if the activity occurs during a scheduled maintenance # group. If no group, this will remain 'None' if not ma.group: start = TimeAgent.truncateDt(ma._start) end = start + timedelta(days = 1) periods = Period.get_periods_by_observing_type(start, end, "maintenance") for p in periods: if p.isScheduled() and ma._start >= p.start and ma._start < p.end(): g = Maintenance_Activity_Group.objects.filter(period = p) if g.count(): ma.group = g[0] # Now add user and timestamp for modification. Earliest mod is # considered creation. u = get_requestor(request) modifying_user = _get_user_name(u) ma.add_modification(modifying_user) ma.save() # If this is a template, modify all subsequent activities based on # it. if ma.is_repeat_template(): template = ma elif ma.is_future_template(): template = ma.repeat_template else: template = None if template: mas = [m for m in Maintenance_Activity.objects\ .filter(repeat_template = template)\ .filter(_start__gte = ma._start)] # times neet to be carried over as ET so that the underlying # UT will compensate for DST. for i in mas: ma_time = ma.get_start('ET') i_time = i.get_start('ET') start = datetime(i_time.year, i_time.month, i_time.day, ma_time.hour, ma_time.minute) i.copy_data(ma) i.set_start(start, 'ET') i.save() return diffs
def edit_activity(request, activity_id = None): if request.method == 'POST': form = RCAddActivityForm(request.POST) if form.is_valid(): # process the returned stuff here... ma = Maintenance_Activity.objects \ .filter(id = form.cleaned_data["entity_id"])[0] approved = ma.approved # save approval status; _process_activity will clear this. diffs = _process_activity(request, ma, form) if approved: # Notify supervisor if approved activity is modified supervisors = get_rescal_supervisors() view_url = "http://%s/resourcecal_display_activity/%s/" % (request.get_host(), ma.id) rc_notifier.notify(supervisors, "modified", ma.get_start("ET").date(), view_url, changes = diffs) return HttpResponseRedirect('/schedule/') else: u = get_requestor(request) supervisors = get_rescal_supervisors() supervisor_mode = True if (u in supervisors) else False if request.GET['ActionEvent'] == 'Modify': ma = Maintenance_Activity.objects.filter(id = activity_id)[0] form = _modify_activity_form(ma) elif request.GET['ActionEvent'] == 'ModifyFuture': # In this case we want to go back to the template, and set # its 'future_template' to this one. ma = Maintenance_Activity.objects.filter(id = activity_id)[0] ma.set_as_new_template() form = _modify_activity_form(ma) elif request.GET['ActionEvent'] == 'ModifyAll': today = TimeAgent.truncateDt(datetime.now()) ma = Maintenance_Activity.objects.filter(id = activity_id)[0] start_ma = Maintenance_Activity.objects\ .filter(repeat_template = ma.repeat_template)\ .filter(_start__gte = today)\ .order_by('_start')[0] start_ma.set_as_new_template() form = _modify_activity_form(start_ma) elif request.GET['ActionEvent'] == 'Delete': ma = Maintenance_Activity.objects.filter(id = activity_id)[0] ma.deleted = True ma.save() creator = _get_ma_creator(ma) if creator: recipients = supervisors + [creator] else: recipients = supervisors view_url = "http://%s/resourcecal_display_activity/%s/" % (request.get_host(), ma.id) rc_notifier.notify(recipients, "deleted", ma.get_start("ET").date(), view_url) return HttpResponseRedirect('/schedule/') elif request.GET['ActionEvent'] == 'DeleteFuture': ma = Maintenance_Activity.objects.filter(id = activity_id)[0] ma.repeat_template.repeat_end = ma.get_start('ET').date() ma.repeat_template.save() mas = Maintenance_Activity.objects\ .filter(_start__gte = TimeAgent.truncateDt(ma.get_start()))\ .filter(repeat_template = ma.repeat_template) for i in mas: i.deleted = True i.save() return HttpResponseRedirect('/schedule/') elif request.GET['ActionEvent'] == 'DeleteAll': ma = Maintenance_Activity.objects.filter(id = activity_id)[0] ma.repeat_template.deleted = True ma.repeat_template.save() mas = Maintenance_Activity.objects \ .filter(repeat_template = ma.repeat_template) for i in mas: i.deleted = True i.save() return HttpResponseRedirect('/schedule/') elif request.GET['ActionEvent'] == 'Approve': ma = Maintenance_Activity.objects.filter(id = activity_id)[0] u = get_requestor(request) user = _get_user_name(u) ma.add_approval(user) ma.save() # Record any receiver changes in the receiver schedule table. for i in ma.get_receiver_changes(): start = ma.get_start() rsched = datetime(start.year, start.month, start.day, 16) Receiver_Schedule.change_schedule(rsched, [i.up_receiver], [i.down_receiver]) creator = _get_ma_creator(ma) if creator: view_url = "http://%s/resourcecal_display_activity/%s/" % \ (request.get_host(), ma.id) rc_notifier.notify(creator, "approved", ma.get_start("ET").date(), view_url) return HttpResponseRedirect('/schedule/') elif request.GET['ActionEvent'] == 'Move': rank = request.GET['Rank'] ma = Maintenance_Activity.objects.get(id = activity_id) u = get_requestor(request) user = _get_user_name(u) d = request.GET['Destination'].split('-') date = datetime(int(d[0]), int(d[1]), int(d[2])) group = _get_maintenance_activity_group_by_date(date, rank) if group: ma.group = group # assuming here 1 maintenance period ma.approved = False # per day. UI does not support more ma.add_modification(user) # than this. ma.save() return HttpResponseRedirect('/schedule/') elif request.GET['ActionEvent'] == 'Copy': rank = request.GET['Rank'] ma = Maintenance_Activity.objects.get(id = activity_id) u = get_requestor(request) user = _get_user_name(u) d = request.GET['Destination'].split('-') date = datetime(int(d[0]), int(d[1]), int(d[2])) group = _get_maintenance_activity_group_by_date(date, rank) if group: new_ma = ma.clone(group) new_ma.add_modification(user) new_ma.save() return HttpResponseRedirect('/schedule/') return render_to_response('users/rc_add_activity_form.html', {'form': form, 'supervisor_mode': supervisor_mode, 'add_activity' : False })
def add_activity(request, group_id = None, year = None, month = None, day = None): u = get_requestor(request) supervisors = get_rescal_supervisors() user = _get_user_name(u) supervisor_mode = True if (u in supervisors) else False if request.method == 'POST': form = RCAddActivityForm(request.POST) if form.is_valid(): # process the returned stuff here... ma = Maintenance_Activity() if group_id: ma.group = Maintenance_Activity_Group.objects.get(id = group_id) ma.save() # needs to have a primary key for many-to-many # relationships to be set. _process_activity(request, ma, form) view_url = "http://%s/resourcecal_display_activity/%s/" % (request.get_host(), ma.id) rc_notifier.notify(supervisors, "new", ma.get_start("ET").date(), view_url) if request.POST['ActionEvent'] =="Submit And Continue": if form.cleaned_data['entity_id']: redirect_url = '/resourcecal_add_activity/%s/' % \ (form.cleaned_data['entity_id']) elif year and month and day: redirect_url = '/resourcecal_add_activity/%s/%s/%s/' % \ (year, month, day) else: redirect_url = '/resourcecal_add_activity/' return HttpResponseRedirect(redirect_url) else: return HttpResponseRedirect('/schedule/') else: default_telescope = Maintenance_Telescope_Resources.objects \ .filter(rc_code = 'N')[0] default_software = Maintenance_Software_Resources.objects \ .filter(rc_code = 'N')[0] if group_id: g = Maintenance_Activity_Group.objects.get(id = group_id) start = TimeAgent.utc2est(g.get_start()) elif year and month and day: start = datetime(int(year), int(month), int(day)) initial_data = {'date' : start.date(), 'time_hr' : start.hour, 'time_min' : start.minute, 'end_choice' : "end_time", 'end_time_hr' : start.hour + 1, 'end_time_min' : 0, 'responsible' : user, 'telescope' : default_telescope.id, 'software' : default_software.id, 'entity_id' : group_id, 'recurrency_until' : start + timedelta(days = 30), } form = RCAddActivityForm(initial = initial_data) return render_to_response('users/rc_add_activity_form.html', {'form': form, 'supervisor_mode': supervisor_mode, 'add_activity': True })
def display_maintenance_activity(request, activity_id = None): if activity_id: ma = Maintenance_Activity.objects.filter(id = activity_id)[0] start = ma.get_start('ET') duration = timedelta(hours = ma.duration) end = start + duration u = get_requestor(request) supervisors = get_rescal_supervisors() if ma.is_repeat_activity(): repeat_interval = interval_names[ma.repeat_template.repeat_interval] repeat_end = ma.repeat_template.repeat_end repeat_template = ma.repeat_template.id else: repeat_interval = "None" repeat_end = "None" repeat_template = "None" last_modified = str(ma.modifications.all() [ma.modifications.count() - 1] if ma.modifications.all() else "") created = str(ma.modifications.all()[0] if ma.modifications.all() else ""), supervisor_mode = True if (u in supervisors) else False copymove_groups = _get_future_maintenance_dates3() copymove_dates = copymove_groups.keys() params = {'subject' : ma.subject, 'date' : start.date(), 'time' : start.time(), 'end_choice' : "end_time", 'end_time' : end.time(), 'responsible' : ma.contacts, 'location' : ma.location, 'telescope' : ma.telescope_resource.resource, 'software' : ma.software_resource.resource, 'other_resources' : ", ".join([o.full_description() for o in ma.other_resources.all()]), 'receivers' : ", ".join([r.full_description() for r in ma.receivers.all()]), 'backends' : ", ".join([b.full_description() for b in ma.backends.all()]), 'description' : ma.description, 'activity_id' : activity_id, 'approval' : 'Yes' if ma.approved else 'No', 'last_modified' : last_modified, 'created' : created, 'receiver_swap' : ma.receiver_changes.all(), 'supervisor_mode' : supervisor_mode, 'maintenance_group' : ma.group_id, 'repeat_activity' : ma.is_repeat_activity(), 'repeat_interval' : repeat_interval, 'repeat_end' : repeat_end, 'repeat_template' : repeat_template, 'copymove_dates' : copymove_dates, 'copymove_groups' : copymove_groups } else: params = {} return render_to_response('users/rc_display_activity.html', params)