def reset_charter_milestones(request, acronym): """Reset charter milestones to the currently in-use milestones.""" login = request.user.get_profile() group = get_object_or_404(Group, acronym=acronym) if (not has_role(request.user, ("Area Director", "Secretariat")) and not group.role_set.filter(name="chair", person=login)): return HttpResponseForbidden("You are not chair of this group.") current_milestones = group.groupmilestone_set.filter(state="active") charter_milestones = group.groupmilestone_set.filter(state="charter") if request.method == 'POST': try: milestone_ids = [int(v) for v in request.POST.getlist("milestone")] except ValueError as e: return HttpResponseBadRequest("error in list of ids - %s" % e) # delete existing for m in charter_milestones: save_milestone_in_history(m) m.state_id = "deleted" m.save() DocEvent.objects.create(type="changed_charter_milestone", doc=group.charter, desc='Deleted milestone "%s"' % m.desc, by=login, ) # add current for m in current_milestones.filter(id__in=milestone_ids): new = GroupMilestone.objects.create(group=m.group, state_id="charter", desc=m.desc, due=m.due, resolved=m.resolved, ) new.docs = m.docs.all() DocEvent.objects.create(type="changed_charter_milestone", doc=group.charter, desc='Added milestone "%s", due %s, from current group milestones' % (new.desc, new.due.strftime("%B %Y")), by=login, ) return redirect('wg_edit_charter_milestones', acronym=group.acronym) return render_to_response('wginfo/reset_charter_milestones.html', dict(group=group, charter_milestones=charter_milestones, current_milestones=current_milestones, ), context_instance=RequestContext(request))
def reset_charter_milestones(request, group_type, acronym): """Reset charter milestones to the currently in-use milestones.""" group = get_group_or_404(acronym, group_type) if not group.features.has_milestones: raise Http404 if (not can_manage_group_type(request.user, group_type) and not group.role_set.filter(name="chair", person__user=request.user)): return HttpResponseForbidden("You are not chair of this group.") current_milestones = group.groupmilestone_set.filter(state="active") charter_milestones = group.groupmilestone_set.filter(state="charter") if request.method == 'POST': try: milestone_ids = [int(v) for v in request.POST.getlist("milestone")] except ValueError as e: return HttpResponseBadRequest("error in list of ids - %s" % e) # delete existing for m in charter_milestones: save_milestone_in_history(m) m.state_id = "deleted" m.save() DocEvent.objects.create(type="changed_charter_milestone", doc=group.charter, desc='Deleted milestone "%s"' % m.desc, by=request.user.person, ) # add current for m in current_milestones.filter(id__in=milestone_ids): new = GroupMilestone.objects.create(group=m.group, state_id="charter", desc=m.desc, due=m.due, resolved=m.resolved, ) new.docs = m.docs.all() DocEvent.objects.create(type="changed_charter_milestone", doc=group.charter, desc='Added milestone "%s", due %s, from current group milestones' % (new.desc, new.due.strftime("%B %Y")), by=request.user.person, ) return redirect('group_edit_charter_milestones', group_type=group.type_id, acronym=group.acronym) return render(request, 'group/reset_charter_milestones.html', dict(group=group, charter_milestones=charter_milestones, current_milestones=current_milestones, ))
def reset_charter_milestones(request, acronym): """Reset charter milestones to the currently in-use milestones.""" login = request.user.get_profile() group = get_object_or_404(Group, acronym=acronym) if (not has_role(request.user, ("Area Director", "Secretariat")) and not group.role_set.filter(name="chair", person=login)): return HttpResponseForbidden("You are not chair of this group.") current_milestones = group.groupmilestone_set.filter(state="active") charter_milestones = group.groupmilestone_set.filter(state="charter") if request.method == 'POST': try: milestone_ids = [int(v) for v in request.POST.getlist("milestone")] except ValueError as e: return HttpResponseBadRequest("error in list of ids - %s" % e) # delete existing for m in charter_milestones: save_milestone_in_history(m) m.state_id = "deleted" m.save() DocEvent.objects.create( type="changed_charter_milestone", doc=group.charter, desc='Deleted milestone "%s"' % m.desc, by=login, ) # add current for m in current_milestones.filter(id__in=milestone_ids): new = GroupMilestone.objects.create( group=m.group, state_id="charter", desc=m.desc, due=m.due, resolved=m.resolved, ) new.docs = m.docs.all() DocEvent.objects.create( type="changed_charter_milestone", doc=group.charter, desc= 'Added milestone "%s", due %s, from current group milestones' % (new.desc, new.due.strftime("%B %Y")), by=login, ) return redirect('wg_edit_charter_milestones', acronym=group.acronym) return render_to_response('wginfo/reset_charter_milestones.html', dict( group=group, charter_milestones=charter_milestones, current_milestones=current_milestones, ), context_instance=RequestContext(request))
def save_milestone_form(f): c = f.cleaned_data if f.milestone: m = f.milestone named_milestone = 'milestone "%s"' % m.desc if milestone_set == "charter": named_milestone = "charter " + named_milestone if c["delete"]: save_milestone_in_history(m) m.state_id = "deleted" m.save() return 'Deleted %s' % named_milestone # compute changes history = None changes = ['Changed %s' % named_milestone] if m.state_id == "review" and not needs_review and c[ "accept"] != "noaction": if not history: history = save_milestone_in_history(m) if c["accept"] == "accept": m.state_id = "active" changes.append( "set state to active from review, accepting new milestone" ) elif c["accept"] == "reject": m.state_id = "deleted" changes.append( "set state to deleted from review, rejecting new milestone" ) if c["desc"] != m.desc and not needs_review: if not history: history = save_milestone_in_history(m) m.desc = c["desc"] changes.append('set description to "%s"' % m.desc) c_due = due_month_year_to_date(c) if c_due != m.due: if not history: history = save_milestone_in_history(m) changes.append( 'set due date to %s from %s' % (c_due.strftime("%B %Y"), m.due.strftime("%B %Y"))) m.due = c_due resolved = c["resolved"] if resolved != m.resolved: if resolved and not m.resolved: changes.append('resolved as "%s"' % resolved) elif not resolved and m.resolved: changes.append("reverted to not being resolved") elif resolved and m.resolved: changes.append('set resolution to "%s"' % resolved) if not history: history = save_milestone_in_history(m) m.resolved = resolved new_docs = set(c["docs"]) old_docs = set(m.docs.all()) if new_docs != old_docs: added = new_docs - old_docs if added: changes.append('added %s to milestone' % ", ".join(d.name for d in added)) removed = old_docs - new_docs if removed: changes.append('removed %s from milestone' % ", ".join(d.name for d in removed)) if not history: history = save_milestone_in_history(m) m.docs = new_docs if len(changes) > 1: m.save() return ", ".join(changes) else: # new milestone m = f.milestone = GroupMilestone() set_attributes_from_form(f, m) m.save() m.docs = c["docs"] named_milestone = 'milestone "%s"' % m.desc if milestone_set == "charter": named_milestone = "charter " + named_milestone if m.state_id in ("active", "charter"): return 'Added %s, due %s' % (named_milestone, m.due.strftime("%B %Y")) elif m.state_id == "review": return 'Added %s for review, due %s' % ( named_milestone, m.due.strftime("%B %Y"))
def approve(request, name): """Approve charter, changing state, fixing revision, copying file to final location.""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group login = request.user.get_profile() e = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") if not e: announcement = default_action_text(group, charter, login).text else: announcement = e.text if request.method == 'POST': new_charter_state = State.objects.get(used=True, type="charter", slug="approved") prev_charter_state = charter.get_state() save_document_in_history(charter) charter.set_state(new_charter_state) close_open_ballots(charter, login) # approve e = DocEvent(doc=charter, by=login) e.type = "iesg_approved" e.desc = "IESG has approved the charter" e.save() change_description = e.desc new_state = GroupStateName.objects.get(slug="active") if group.state != new_state: save_group_in_history(group) prev_state = group.state group.state = new_state group.time = e.time group.save() # create an event for the wg state change, too e = ChangeStateGroupEvent(group=group, type="changed_state") e.time = group.time e.by = login e.state_id = "active" e.desc = "Charter approved, group active" e.save() change_description += " and %s state has been changed to %s" % ( group.type.name, new_state.name) e = log_state_changed(request, charter, login, prev_charter_state) # according to spec, 00-02 becomes 01, so copy file and record new revision try: old = os.path.join( charter.get_file_path(), '%s-%s.txt' % (charter.canonical_name(), charter.rev)) new = os.path.join( charter.get_file_path(), '%s-%s.txt' % (charter.canonical_name(), next_approved_revision(charter.rev))) shutil.copy(old, new) except IOError: return HttpResponse( "There was an error copying %s to %s" % ('%s-%s.txt' % (charter.canonical_name(), charter.rev), '%s-%s.txt' % (charter.canonical_name(), next_approved_revision( charter.rev)))) e = NewRevisionDocEvent(doc=charter, by=login, type="new_revision") e.rev = next_approved_revision(charter.rev) e.desc = "New version available: <b>%s-%s.txt</b>" % ( charter.canonical_name(), e.rev) e.save() charter.rev = e.rev charter.time = e.time charter.save() email_secretariat(request, group, "state-%s" % new_charter_state.slug, change_description) # move milestones over milestones_to_delete = list( group.groupmilestone_set.filter(state__in=("active", "review"))) for m in group.groupmilestone_set.filter(state="charter"): # see if we got this milestone already (i.e. it was copied # verbatim to the charter) found = False for i, o in enumerate(milestones_to_delete): if o.desc == m.desc and o.due == m.due and set( o.docs.all()) == set(m.docs.all()): found = True break if found: # keep existing, whack charter milestone if not o.state_id == "active": save_milestone_in_history(o) o.state_id = "active" o.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc= "Changed milestone \"%s\", set state to active from review" % o.desc, milestone=o) del milestones_to_delete[i] # don't generate a DocEvent for this, it's implicit in the approval event save_milestone_in_history(m) m.state_id = "deleted" m.save() else: # move charter milestone save_milestone_in_history(m) m.state_id = "active" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Added milestone \"%s\", due %s, from approved charter" % (m.desc, m.due), milestone=m) for m in milestones_to_delete: save_milestone_in_history(m) m.state_id = "deleted" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Deleted milestone \"%s\", not present in approved charter" % m.desc, milestone=m) # send announcement send_mail_preformatted(request, announcement) return HttpResponseRedirect(charter.get_absolute_url()) return render_to_response('wgcharter/approve.html', dict(charter=charter, announcement=announcement), context_instance=RequestContext(request))
def reset_charter_milestones(request, group_type, acronym): """Reset charter milestones to the currently in-use milestones.""" group = get_group_or_404(acronym, group_type) if not group.features.has_milestones: raise Http404 if not can_manage_group(request.user, group): return HttpResponseForbidden( "You are not authorized to change the milestones for this group.") current_milestones = group.groupmilestone_set.filter(state="active") charter_milestones = group.groupmilestone_set.filter(state="charter") if request.method == 'POST': try: milestone_ids = [int(v) for v in request.POST.getlist("milestone")] except ValueError as e: return HttpResponseBadRequest("error in list of ids - %s" % e) # delete existing for m in charter_milestones: save_milestone_in_history(m) m.state_id = "deleted" m.save() DocEvent.objects.create( type="changed_charter_milestone", doc=group.charter, rev=group.charter.rev, desc='Deleted milestone "%s"' % m.desc, by=request.user.person, ) # add current for m in current_milestones.filter(id__in=milestone_ids): new = GroupMilestone.objects.create( group=m.group, state_id="charter", desc=m.desc, due=m.due, resolved=m.resolved, ) new.docs = m.docs.all() DocEvent.objects.create( type="changed_charter_milestone", doc=group.charter, rev=group.charter.rev, desc= 'Added milestone "%s", due %s, from current group milestones' % (new.desc, new.due.strftime("%B %Y")), by=request.user.person, ) return redirect('ietf.group.milestones.edit_milestones;charter', group_type=group.type_id, acronym=group.acronym) return render( request, 'group/reset_charter_milestones.html', dict( group=group, charter_milestones=charter_milestones, current_milestones=current_milestones, ))
def save_milestone_form(f): c = f.cleaned_data if f.milestone: m = f.milestone named_milestone = 'milestone "%s"' % m.desc if milestone_set == "charter": named_milestone = "charter " + named_milestone if c["delete"]: save_milestone_in_history(m) m.state_id = "deleted" m.save() return 'Deleted %s' % named_milestone # compute changes history = None changes = ['Changed %s' % named_milestone] if m.state_id == "review" and not needs_review and c["accept"] != "noaction": if not history: history = save_milestone_in_history(m) if c["accept"] == "accept": m.state_id = "active" changes.append("set state to active from review, accepting new milestone") elif c["accept"] == "reject": m.state_id = "deleted" changes.append("set state to deleted from review, rejecting new milestone") if c["desc"] != m.desc and not needs_review: if not history: history = save_milestone_in_history(m) m.desc = c["desc"] changes.append('set description to "%s"' % m.desc) c_due = due_month_year_to_date(c) if c_due != m.due: if not history: history = save_milestone_in_history(m) changes.append('set due date to %s from %s' % (c_due.strftime("%B %Y"), m.due.strftime("%B %Y"))) m.due = c_due resolved = c["resolved"] if resolved != m.resolved: if resolved and not m.resolved: changes.append('resolved as "%s"' % resolved) elif not resolved and m.resolved: changes.append("reverted to not being resolved") elif resolved and m.resolved: changes.append('set resolution to "%s"' % resolved) if not history: history = save_milestone_in_history(m) m.resolved = resolved new_docs = set(c["docs"]) old_docs = set(m.docs.all()) if new_docs != old_docs: added = new_docs - old_docs if added: changes.append('added %s to milestone' % ", ".join(d.name for d in added)) removed = old_docs - new_docs if removed: changes.append('removed %s from milestone' % ", ".join(d.name for d in removed)) if not history: history = save_milestone_in_history(m) m.docs = new_docs if len(changes) > 1: m.save() return ", ".join(changes) else: # new milestone m = f.milestone = GroupMilestone() set_attributes_from_form(f, m) m.save() m.docs = c["docs"] named_milestone = 'milestone "%s"' % m.desc if milestone_set == "charter": named_milestone = "charter " + named_milestone if m.state_id in ("active", "charter"): return 'Added %s, due %s' % (named_milestone, m.due.strftime("%B %Y")) elif m.state_id == "review": return 'Added %s for review, due %s' % (named_milestone, m.due.strftime("%B %Y"))
def approve(request, name): """Approve charter, changing state, fixing revision, copying file to final location.""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group login = request.user.person e = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") if not e: announcement = default_action_text(group, charter, login).text else: announcement = e.text if request.method == 'POST': new_charter_state = State.objects.get(used=True, type="charter", slug="approved") prev_charter_state = charter.get_state() save_document_in_history(charter) charter.set_state(new_charter_state) close_open_ballots(charter, login) # approve e = DocEvent(doc=charter, by=login) e.type = "iesg_approved" e.desc = "IESG has approved the charter" e.save() change_description = e.desc group_state_change_event = change_group_state_after_charter_approval(group, login) if group_state_change_event: change_description += " and group state has been changed to %s" % group.state.name add_state_change_event(charter, login, prev_charter_state, new_charter_state) fix_charter_revision_after_approval(charter, login) email_admin_re_charter(request, group, "Charter state changed to %s" % new_charter_state.name, change_description,'charter_state_edit_admin_needed') # move milestones over milestones_to_delete = list(group.groupmilestone_set.filter(state__in=("active", "review"))) for m in group.groupmilestone_set.filter(state="charter"): # see if we got this milestone already (i.e. it was copied # verbatim to the charter) found = False for i, o in enumerate(milestones_to_delete): if o.desc == m.desc and o.due == m.due and set(o.docs.all()) == set(m.docs.all()): found = True break if found: # keep existing, whack charter milestone if not o.state_id == "active": save_milestone_in_history(o) o.state_id = "active" o.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Changed milestone \"%s\", set state to active from review" % o.desc, milestone=o) del milestones_to_delete[i] # don't generate a DocEvent for this, it's implicit in the approval event save_milestone_in_history(m) m.state_id = "deleted" m.save() else: # move charter milestone save_milestone_in_history(m) m.state_id = "active" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Added milestone \"%s\", due %s, from approved charter" % (m.desc, m.due), milestone=m) for m in milestones_to_delete: save_milestone_in_history(m) m.state_id = "deleted" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Deleted milestone \"%s\", not present in approved charter" % m.desc, milestone=m) # send announcement send_mail_preformatted(request, announcement) return HttpResponseRedirect(charter.get_absolute_url()) return render_to_response('doc/charter/approve.html', dict(charter=charter, announcement=announcement), context_instance=RequestContext(request))
def approve(request, name): """Approve charter, changing state, fixing revision, copying file to final location.""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group by = request.user.person e = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") if not e: announcement = default_action_text(group, charter, by).text else: announcement = e.text if request.method == 'POST': new_charter_state = State.objects.get(used=True, type="charter", slug="approved") prev_charter_state = charter.get_state() charter.set_state(new_charter_state) close_open_ballots(charter, by) events = [] # approve e = DocEvent(doc=charter, rev=charter.rev, by=by) e.type = "iesg_approved" e.desc = "IESG has approved the charter" e.save() events.append(e) change_description = e.desc group_state_change_event = change_group_state_after_charter_approval( group, by) if group_state_change_event: change_description += " and group state has been changed to %s" % group.state.name e = add_state_change_event(charter, by, prev_charter_state, new_charter_state) if e: events.append(e) fix_charter_revision_after_approval(charter, by) charter.save_with_history(events) email_admin_re_charter( request, group, "Charter state changed to \"%s\"" % new_charter_state.name, change_description, 'charter_state_edit_admin_needed') # move milestones over milestones_to_delete = list( group.groupmilestone_set.filter(state__in=("active", "review"))) for m in group.groupmilestone_set.filter(state="charter"): # see if we got this milestone already (i.e. it was copied # verbatim to the charter) found = False for i, o in enumerate(milestones_to_delete): if o.desc == m.desc and o.due == m.due and set( o.docs.all()) == set(m.docs.all()): found = True break if found: # keep existing, whack charter milestone if not o.state_id == "active": save_milestone_in_history(o) o.state_id = "active" o.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=by, desc= "Changed milestone \"%s\", set state to active from review" % o.desc, milestone=o) del milestones_to_delete[i] # don't generate a DocEvent for this, it's implicit in the approval event save_milestone_in_history(m) m.state_id = "deleted" m.save() else: # move charter milestone save_milestone_in_history(m) m.state_id = "active" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=by, desc="Added milestone \"%s\", due %s, from approved charter" % (m.desc, m.due), milestone=m) for m in milestones_to_delete: save_milestone_in_history(m) m.state_id = "deleted" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=by, desc="Deleted milestone \"%s\", not present in approved charter" % m.desc, milestone=m) # send announcement send_mail_preformatted(request, announcement) return HttpResponseRedirect(charter.get_absolute_url()) return render(request, 'doc/charter/approve.html', dict(charter=charter, announcement=announcement))
def approve(request, name): """Approve charter, changing state, fixing revision, copying file to final location.""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group login = request.user.get_profile() e = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") if not e: announcement = default_action_text(group, charter, login).text else: announcement = e.text if request.method == 'POST': new_charter_state = State.objects.get(used=True, type="charter", slug="approved") prev_charter_state = charter.get_state() save_document_in_history(charter) charter.set_state(new_charter_state) close_open_ballots(charter, login) # approve e = DocEvent(doc=charter, by=login) e.type = "iesg_approved" e.desc = "IESG has approved the charter" e.save() change_description = e.desc new_state = GroupStateName.objects.get(slug="active") if group.state != new_state: save_group_in_history(group) prev_state = group.state group.state = new_state group.time = e.time group.save() # create an event for the wg state change, too e = ChangeStateGroupEvent(group=group, type="changed_state") e.time = group.time e.by = login e.state_id = "active" e.desc = "Charter approved, group active" e.save() change_description += " and %s state has been changed to %s" % (group.type.name, new_state.name) e = log_state_changed(request, charter, login, prev_charter_state) # according to spec, 00-02 becomes 01, so copy file and record new revision try: old = os.path.join(charter.get_file_path(), '%s-%s.txt' % (charter.canonical_name(), charter.rev)) new = os.path.join(charter.get_file_path(), '%s-%s.txt' % (charter.canonical_name(), next_approved_revision(charter.rev))) shutil.copy(old, new) except IOError: return HttpResponse("There was an error copying %s to %s" % ('%s-%s.txt' % (charter.canonical_name(), charter.rev), '%s-%s.txt' % (charter.canonical_name(), next_approved_revision(charter.rev)))) e = NewRevisionDocEvent(doc=charter, by=login, type="new_revision") e.rev = next_approved_revision(charter.rev) e.desc = "New version available: <b>%s-%s.txt</b>" % (charter.canonical_name(), e.rev) e.save() charter.rev = e.rev charter.time = e.time charter.save() email_secretariat(request, group, "state-%s" % new_charter_state.slug, change_description) # move milestones over milestones_to_delete = list(group.groupmilestone_set.filter(state__in=("active", "review"))) for m in group.groupmilestone_set.filter(state="charter"): # see if we got this milestone already (i.e. it was copied # verbatim to the charter) found = False for i, o in enumerate(milestones_to_delete): if o.desc == m.desc and o.due == m.due and set(o.docs.all()) == set(m.docs.all()): found = True break if found: # keep existing, whack charter milestone if not o.state_id == "active": save_milestone_in_history(o) o.state_id = "active" o.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Changed milestone \"%s\", set state to active from review" % o.desc, milestone=o) del milestones_to_delete[i] # don't generate a DocEvent for this, it's implicit in the approval event save_milestone_in_history(m) m.state_id = "deleted" m.save() else: # move charter milestone save_milestone_in_history(m) m.state_id = "active" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Added milestone \"%s\", due %s, from approved charter" % (m.desc, m.due), milestone=m) for m in milestones_to_delete: save_milestone_in_history(m) m.state_id = "deleted" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Deleted milestone \"%s\", not present in approved charter" % m.desc, milestone=m) # send announcement send_mail_preformatted(request, announcement) return HttpResponseRedirect(charter.get_absolute_url()) return render_to_response('wgcharter/approve.html', dict(charter=charter, announcement=announcement), context_instance=RequestContext(request))