Exemple #1
0
def stream_delegates(request, stream_name):
    stream = get_object_or_404(Stream, name=stream_name)
    if not is_chair_of_stream(request.user, stream):
        return HttpResponseForbidden('You have no permission to access this view')
    chairs = stream.get_chairs()
    form = StreamDelegatesForm(stream=stream)
    if request.method == 'POST':
        if request.POST.get('delete', False):
            pk_list = request.POST.getlist('remove_delegate')
            if settings.USE_DB_REDESIGN_PROXY_CLASSES:
                stream_group = Group.objects.get(acronym=stream.slug)
                save_group_in_history(stream_group)
                Role.objects.filter(person__in=pk_list, group=stream_group, name="delegate").delete()
            else:
                StreamDelegate.objects.filter(stream=stream, person__pk__in=pk_list).delete()
        else:
            form = StreamDelegatesForm(request.POST, stream=stream)
            if form.is_valid():
                form.save()
                form = StreamDelegatesForm(stream=stream)
    delegates = stream.get_delegates()
    return render_to_response('ietfworkflows/stream_delegates.html',
                              {'stream': stream,
                               'chairs': chairs,
                               'delegates': delegates,
                               'form': form,
                               },
                              context_instance=RequestContext(request))
Exemple #2
0
 def create_delegate(self, person):
     if settings.USE_DB_REDESIGN_PROXY_CLASSES:
         created = False
         e = Email.objects.get(address=self.cleaned_data.get('email'))
         if not Role.objects.filter(
                 name="delegate", group=self.wg, person=person, email=e):
             created = True
             save_group_in_history(Group.objects.get(pk=self.wg.pk))
             delegate, _ = Role.objects.get_or_create(
                 name=RoleName.objects.get(slug="delegate"),
                 group=self.wg,
                 person=e.person,
                 email=e)
     else:
         (delegate,
          created) = WGDelegate.objects.get_or_create(wg=self.wg,
                                                      person=person)
     if not created:
         self.set_message(
             'error',
             'The email belongs to a person who is already a delegate')
     else:
         self.next_form = AddDelegateForm(wg=self.wg, user=self.user)
         self.next_form.set_message('success',
                                    'A new delegate has been added')
Exemple #3
0
def stream_delegates(request, stream_name):
    stream = get_object_or_404(Stream, name=stream_name)
    if not is_chair_of_stream(request.user, stream):
        return HttpResponseForbidden(
            'You have no permission to access this view')
    chairs = stream.get_chairs()
    form = StreamDelegatesForm(stream=stream)
    if request.method == 'POST':
        if request.POST.get('delete', False):
            pk_list = request.POST.getlist('remove_delegate')
            if settings.USE_DB_REDESIGN_PROXY_CLASSES:
                stream_group = Group.objects.get(acronym=stream.slug)
                save_group_in_history(stream_group)
                Role.objects.filter(person__in=pk_list,
                                    group=stream_group,
                                    name="delegate").delete()
            else:
                StreamDelegate.objects.filter(stream=stream,
                                              person__pk__in=pk_list).delete()
        else:
            form = StreamDelegatesForm(request.POST, stream=stream)
            if form.is_valid():
                form.save()
                form = StreamDelegatesForm(stream=stream)
    delegates = stream.get_delegates()
    return render_to_response('ietfworkflows/stream_delegates.html', {
        'stream': stream,
        'chairs': chairs,
        'delegates': delegates,
        'form': form,
    },
                              context_instance=RequestContext(request))
Exemple #4
0
def modify(request, name):
    """ 
    Handle state changes of Area Directors (enable voting, retire)
    # Legacy --------------------------
    Enable Voting actions
    - user_level = 1
    - create TelechatUser object
    Per requirements, the Retire button shall perform the following DB updates
    - update iesg_login row, user_level = 2 (per Matt Feb 7, 2011)
    - remove telechat_user row (to revoke voting rights)
    - update IETFWG(groups) set area_director = TBD 
    - remove area_director row
    # New ------------------------------
    Enable Voting: change Role from 'pre-ad' to 'ad'
    Retire: save in history, delete role record, set group assn to TBD

    **Templates:**

    * none

    Redirects to view page on success.
    """

    area = get_object_or_404(Group, type='area', acronym=name)

    # should only get here with POST method
    if request.method == 'POST':
        # setup common request variables
        tag = request.POST.get('tag', '')
        person = Person.objects.get(id=tag)
        
        # save group
        save_group_in_history(area)
                
        # handle retire request
        if request.POST.get('submit', '') == "Retire":
            role = Role.objects.get(group=area,name__in=('ad','pre-ad'),person=person)
            role.delete()
            
            # update groups that have this AD as primary AD
            for group in Group.objects.filter(ad=person,type='wg',state__in=('active','bof')):
                group.ad = None
                group.save()
            
            messages.success(request, 'The Area Director has been retired successfully!')

        # handle voting request
        if request.POST.get('submit', '') == "Enable Voting":
            role = Role.objects.get(group=area,name__slug='pre-ad',person=person)
            role.name_id = 'ad'
            role.save()
            
            messages.success(request, 'Voting rights have been granted successfully!')

        url = reverse('areas_view', kwargs={'name':name})
        return HttpResponseRedirect(url)
Exemple #5
0
    def save(self):
        if settings.USE_DB_REDESIGN_PROXY_CLASSES:
            stream_group = Group.objects.get(acronym=self.stream.slug)
            save_group_in_history(stream_group)
            Role.objects.get_or_create(person=self.person,
                                       group=stream_group,
                                       name=RoleName.objects.get(slug="delegate"),
                                       email=Email.objects.get(address=self.cleaned_data.get('email')))
            return

        StreamDelegate.objects.get_or_create(
            person=self.person,
            stream=self.stream)
Exemple #6
0
def main(request):
    '''
    Main view for generic Roles App
    '''
    groups = Group.objects.filter(type__in=('sdo', 'ietf')).order_by('acronym')
    choices = build_choices(groups)
    choices.insert(0, ('', '------------'))
    group_form = GroupSelectForm(choices=choices)

    # prime form with random sdo group so all roles are available
    group = Group.objects.filter(type='sdo')[0]

    if request.method == 'POST':
        role_form = RoleForm(request.POST, group=group)
        if role_form.is_valid():
            name = role_form.cleaned_data['name']
            person = role_form.cleaned_data['person']
            email = role_form.cleaned_data['email']
            acronym = role_form.cleaned_data['group_acronym']

            group = Group.objects.get(acronym=acronym)

            # save group
            save_group_in_history(group)

            Role.objects.create(name=name,
                                person=person,
                                email=email,
                                group=group)

            messages.success(request, 'New %s added successfully!' % name)
            url = reverse(
                'ietf.secr.roles.views.main') + '?group=%s' % group.acronym
            return HttpResponseRedirect(url)

    else:
        role_form = RoleForm(initial={'name': 'chair'}, group=group)
        # accept get argument to select group if we're returning after a change
        if 'group' in request.GET:
            group_form = GroupSelectForm(
                choices=choices, initial={'group': request.GET['group']})

    return render(
        request,
        'roles/main.html',
        {
            'group_form': group_form,
            'role_form': role_form
        },
    )
Exemple #7
0
    def save(self):
        if settings.USE_DB_REDESIGN_PROXY_CLASSES:
            stream_group = Group.objects.get(acronym=self.stream.slug)
            save_group_in_history(stream_group)
            Role.objects.get_or_create(
                person=self.person,
                group=stream_group,
                name=RoleName.objects.get(slug="delegate"),
                email=Email.objects.get(
                    address=self.cleaned_data.get('email')))
            return

        StreamDelegate.objects.get_or_create(person=self.person,
                                             stream=self.stream)
Exemple #8
0
def people(request, acronym):
    """
    Edit Group Roles (Chairs, Secretary, etc)

    **Templates:**

    * ``groups/people.html``

    **Template Variables:**

    * form, group

    """

    group = get_object_or_404(Group, acronym=acronym)

    if request.method == 'POST':
        # we need to pass group for form validation
        form = RoleForm(request.POST, group=group)
        if form.is_valid():
            name = form.cleaned_data['name']
            person = form.cleaned_data['person']
            email = form.cleaned_data['email']

            # save group
            save_group_in_history(group)

            Role.objects.create(name=name,
                                person=person,
                                email=email,
                                group=group)

            messages.success(request, 'New %s added successfully!' % name)
            return redirect('ietf.secr.groups.views.people',
                            acronym=group.acronym)
    else:
        form = RoleForm(initial={
            'name': 'chair',
            'group_acronym': group.acronym
        },
                        group=group)

    return render(
        request,
        'groups/people.html',
        {
            'form': form,
            'group': group
        },
    )
Exemple #9
0
def people(request, name):
    """ 
    Edit People associated with Areas, Area Directors.
    
    # Legacy ------------------
    When a new Director is first added they get a user_level of 4, read-only.
    Then, when Director is made active (Enable Voting) user_level = 1.
    
    # New ---------------------
    First Director's are assigned the Role 'pre-ad' Incoming Area director
    Then they get 'ad' role
    
    **Templates:**

    * ``areas/people.html``

    **Template Variables:**

    * directors, area

    """
    area = get_object_or_404(Group, type='area', acronym=name)

    if request.method == 'POST':
        if request.POST.get('submit', '') == "Add":
            form = AreaDirectorForm(request.POST)
            if form.is_valid():
                email = form.cleaned_data['email']
                person = form.cleaned_data['ad_name']

                # save group
                save_group_in_history(area)
                
                # create role
                Role.objects.create(name_id='pre-ad',group=area,email=email,person=person)
                
                messages.success(request, 'New Area Director added successfully!')
                url = reverse('areas_view', kwargs={'name':name})
                return HttpResponseRedirect(url)
    else:
        form = AreaDirectorForm()

    directors = area.role_set.filter(name__slug__in=('ad','pre-ad'))
    return render_to_response('areas/people.html', {
        'area': area,
        'form': form,
        'directors': directors},
        RequestContext(request, {}),
    )
Exemple #10
0
 def create_delegate(self, person):
     if settings.USE_DB_REDESIGN_PROXY_CLASSES:
         created = False
         e = Email.objects.get(address=self.cleaned_data.get('email'))
         if not Role.objects.filter(name="delegate", group=self.wg, person=person, email=e):
             created = True
             save_group_in_history(Group.objects.get(pk=self.wg.pk))
             delegate, _ = Role.objects.get_or_create(
                 name=RoleName.objects.get(slug="delegate"), group=self.wg, person=e.person, email=e)
     else:
         (delegate, created) = WGDelegate.objects.get_or_create(wg=self.wg,
                                                                person=person)
     if not created:
         self.set_message('error', 'The email belongs to a person who is already a delegate')
     else:
         self.next_form = AddDelegateForm(wg=self.wg, user=self.user)
         self.next_form.set_message('success', 'A new delegate has been added')
Exemple #11
0
def main(request):
    '''
    Main view for generic Roles App
    '''
    groups = Group.objects.filter(type__in=('sdo','ietf')).order_by('acronym')
    choices=build_choices(groups)
    choices.insert(0,('','------------'))
    group_form = GroupSelectForm(choices=choices)
    
    # prime form with random sdo group so all roles are available
    group = Group.objects.filter(type='sdo')[0]
    
    if request.method == 'POST':
        role_form = RoleForm(request.POST,group=group)
        if role_form.is_valid():
            name = role_form.cleaned_data['name']
            person = role_form.cleaned_data['person']
            email = role_form.cleaned_data['email']
            acronym = role_form.cleaned_data['group_acronym']
            
            group = Group.objects.get(acronym=acronym)
            
            # save group
            save_group_in_history(group)
                
            Role.objects.create(name=name,
                                person=person,
                                email=email,
                                group=group)

            messages.success(request, 'New %s added successfully!' % name)
            url = reverse('roles') + '?group=%s' % group.acronym
            return HttpResponseRedirect(url)
    
    else:
        role_form = RoleForm(initial={'name':'chair'},group=group)
        # accept get argument to select group if we're returning after a change
        if 'group' in request.GET:
            group_form = GroupSelectForm(choices=choices,initial={'group':request.GET['group']})
            
    return render_to_response('roles/main.html', {
        'group_form': group_form,
        'role_form': role_form},
        RequestContext(request, {}),
    )
Exemple #12
0
def change_group_state_after_charter_approval(group, by):
    new_state = GroupStateName.objects.get(slug="active")
    if group.state == new_state:
        return None

    save_group_in_history(group)
    group.state = new_state
    group.time = datetime.datetime.now()
    group.save()

    # create an event for the group state change, too
    e = ChangeStateGroupEvent(group=group, type="changed_state")
    e.time = group.time
    e.by = by
    e.state_id = "active"
    e.desc = "Charter approved, group active"
    e.save()

    return e
Exemple #13
0
def people(request, acronym):
    """ 
    Edit Group Roles (Chairs, Secretary, etc)

    **Templates:**

    * ``groups/people.html``

    **Template Variables:**

    * form, group

    """

    group = get_object_or_404(Group, acronym=acronym)
    
    if request.method == 'POST':
        # we need to pass group for form validation
        form = RoleForm(request.POST,group=group)
        if form.is_valid():
            name = form.cleaned_data['name']
            person = form.cleaned_data['person']
            email = form.cleaned_data['email']
            
            # save group
            save_group_in_history(group)
                
            Role.objects.create(name=name,
                                person=person,
                                email=email,
                                group=group)

            messages.success(request, 'New %s added successfully!' % name)
            url = reverse('groups_people', kwargs={'acronym':group.acronym})
            return HttpResponseRedirect(url)
    else:
        form = RoleForm(initial={'name':'chair'},group=group)

    return render_to_response('groups/people.html', {
        'form':form,
        'group':group},
        RequestContext(request, {}),
    )
Exemple #14
0
def change_group_state_after_charter_approval(group, by):
    new_state = GroupStateName.objects.get(slug="active")
    if group.state == new_state:
        return None

    save_group_in_history(group)
    group.state = new_state
    group.time = datetime.datetime.now()
    group.save()

    # create an event for the group state change, too
    e = ChangeStateGroupEvent(group=group, type="changed_state")
    e.time = group.time
    e.by = by
    e.state_id = "active"
    e.desc = "Charter approved, group active"
    e.save()

    return e
Exemple #15
0
def people(request, acronym):
    """
    Edit Group Roles (Chairs, Secretary, etc)

    **Templates:**

    * ``groups/people.html``

    **Template Variables:**

    * form, group

    """

    group = get_object_or_404(Group, acronym=acronym)

    if request.method == 'POST':
        # we need to pass group for form validation
        form = RoleForm(request.POST,group=group)
        if form.is_valid():
            name = form.cleaned_data['name']
            person = form.cleaned_data['person']
            email = form.cleaned_data['email']

            # save group
            save_group_in_history(group)

            Role.objects.create(name=name,
                                person=person,
                                email=email,
                                group=group)

            messages.success(request, 'New %s added successfully!' % name)
            return redirect('groups_people', acronym=group.acronym)
    else:
        form = RoleForm(initial={'name':'chair'},group=group)

    return render_to_response('groups/people.html', {
        'form':form,
        'group':group},
        RequestContext(request, {}),
    )
Exemple #16
0
def delete_role(request, acronym, id):
    """ 
    Handle deleting roles

    **Templates:**

    * none

    """
    role = get_object_or_404(Role, id=id)
    group = get_object_or_404(Group, acronym=acronym)

    # save group
    save_group_in_history(role.group)
                
    role.delete()
    
    messages.success(request, 'The entry was deleted successfully')
    url = reverse('roles') + '?group=%s' % group.acronym
    return HttpResponseRedirect(url)
Exemple #17
0
def delete_role(request, acronym, id):
    """ 
    Handle deleting roles

    **Templates:**

    * none

    """
    role = get_object_or_404(Role, id=id)
    group = get_object_or_404(Group, acronym=acronym)

    # save group
    save_group_in_history(role.group)

    role.delete()

    messages.success(request, 'The entry was deleted successfully')
    url = reverse('roles') + '?group=%s' % group.acronym
    return HttpResponseRedirect(url)
Exemple #18
0
def delete_role(request, acronym, id):
    """
    Handle deleting roles for groups (chair, editor, advisor, secretary)

    **Templates:**

    * none

    Redirects to people page on success.

    """
    group = get_object_or_404(Group, acronym=acronym)
    role = get_object_or_404(Role, id=id)

    # save group
    save_group_in_history(group)

    role.delete()

    messages.success(request, 'The entry was deleted successfully')
    return redirect('groups_people', acronym=acronym)
Exemple #19
0
def delete_role(request, acronym, id):
    """ 
    Handle deleting roles

    **Templates:**

    * none

    """
    role = get_object_or_404(Role, id=id)
    group = get_object_or_404(Group, acronym=acronym)

    if request.method == 'POST' and request.POST['post'] == 'yes':
        # save group
        save_group_in_history(group)

        role.delete()
        messages.success(request, 'The entry was deleted successfully')
        return redirect('ietf.secr.roles.views.main')

    return render(request, 'confirm_delete.html', {'object': role})
Exemple #20
0
def stream_edit(request, acronym):
    group = get_object_or_404(Group, acronym=acronym)

    if not (has_role(request.user, "Secretariat") or group.has_role(request.user, "chair")):
        return HttpResponseForbidden("You don't have permission to access this page.")

    chairs = Email.objects.filter(role__group=group, role__name="chair").select_related("person")

    if request.method == 'POST':
        form = StreamEditForm(request.POST)

        if form.is_valid():
            save_group_in_history(group)

            # update roles
            attr, slug, title = ('delegates', 'delegate', "Delegates")

            new = form.cleaned_data[attr]
            old = Email.objects.filter(role__group=group, role__name=slug).select_related("person")
            if set(new) != set(old):
                desc = "%s changed to <b>%s</b> from %s" % (
                    title, ", ".join(x.get_name() for x in new), ", ".join(x.get_name() for x in old))

                GroupEvent.objects.create(group=group, by=request.user.person, type="info_changed", desc=desc)

                group.role_set.filter(name=slug).delete()
                for e in new:
                    Role.objects.get_or_create(name_id=slug, email=e, group=group, person=e.person)

            return redirect("ietf.group.views.streams")
    else:
        form = StreamEditForm(initial=dict(delegates=Email.objects.filter(role__group=group, role__name="delegate")))

    return render_to_response('group/stream_edit.html',
                              {'group': group,
                               'chairs': chairs,
                               'form': form,
                               },
                              context_instance=RequestContext(request))
Exemple #21
0
def delete_role(request, acronym, id):
    """ 
    Handle deleting roles for groups (chair, editor, advisor, secretary)

    **Templates:**

    * none

    Redirects to people page on success.

    """
    group = get_object_or_404(Group, acronym=acronym)
    role = get_object_or_404(Role, id=id)
    
    # save group
    save_group_in_history(group)
                
    role.delete()
    
    messages.success(request, 'The entry was deleted successfully')
    url = reverse('groups_people', kwargs={'acronym':acronym})
    return HttpResponseRedirect(url)
Exemple #22
0
def delete_role(request, acronym, id):
    """
    Handle deleting roles for groups (chair, editor, advisor, secretary)

    **Templates:**

    * none

    Redirects to people page on success.

    """
    group = get_object_or_404(Group, acronym=acronym)
    role = get_object_or_404(Role, id=id)

    if request.method == 'POST' and request.POST['post'] == 'yes':
        # save group
        save_group_in_history(group)

        role.delete()
        messages.success(request, 'The entry was deleted successfully')
        return redirect('ietf.secr.groups.views.people', acronym=acronym)

    return render(request, 'confirm_delete.html', {'object': role})
Exemple #23
0
def edit(request, name):
    """ 
    Edit IETF Areas 

    **Templates:**

    * ``areas/edit.html``

    **Template Variables:**

    * acronym, area_formset, awp_formset, acronym_form 

    """
    area = get_object_or_404(Group, acronym=name, type='area')

    AWPFormSet = inlineformset_factory(Group, GroupURL, form=AWPForm, max_num=2)
    if request.method == 'POST':
        button_text = request.POST.get('submit', '')
        if button_text == 'Save':
            form = AreaForm(request.POST, instance=area)
            awp_formset = AWPFormSet(request.POST, instance=area)
            if form.is_valid() and awp_formset.is_valid():
                state = form.cleaned_data['state']
                
                # save group
                save_group_in_history(area)
                
                new_area = form.save()
                new_area.time = datetime.datetime.now()
                new_area.save()
                awp_formset.save()
                
                # create appropriate GroupEvent
                if 'state' in form.changed_data:
                    ChangeStateGroupEvent.objects.create(group=new_area,
                                                         type='changed_state',
                                                         by=request.user.get_profile(),
                                                         state=state,
                                                         time=new_area.time)
                    form.changed_data.remove('state')
                    
                # if anything else was changed
                if form.changed_data:
                    GroupEvent.objects.create(group=new_area,
                                              type='info_changed',
                                              by=request.user.get_profile(),
                                              time=new_area.time)
                
                messages.success(request, 'The Area entry was changed successfully')
                url = reverse('areas_view', kwargs={'name':name})
                return HttpResponseRedirect(url)
        else:
            url = reverse('areas_view', kwargs={'name':name})
            return HttpResponseRedirect(url)
    else:
        form = AreaForm(instance=area)
        awp_formset = AWPFormSet(instance=area)

    return render_to_response('areas/edit.html', {
        'area': area,
        'form': form,
        'awp_formset': awp_formset,
        },
        RequestContext(request,{}),
    )
Exemple #24
0
def submit(request, name=None, option=None):
    if not name.startswith('charter-'):
        raise Http404

    charter = get_object_or_404(Document, type="charter", name=name)
    group = charter.group

    if not can_manage_group_type(request.user, group.type_id):
        return HttpResponseForbidden("You don't have permission to access this view")

    path = os.path.join(settings.CHARTER_PATH, '%s-%s.txt' % (charter.canonical_name(), charter.rev))
    not_uploaded_yet = charter.rev.endswith("-00") and not os.path.exists(path)

    if not_uploaded_yet:
        # this case is special - we recently chartered or rechartered and have no file yet
        next_rev = charter.rev
    else:
        # search history for possible collisions with abandoned efforts
        prev_revs = list(charter.history_set.order_by('-time').values_list('rev', flat=True))
        next_rev = next_revision(charter.rev)
        while next_rev in prev_revs:
            next_rev = next_revision(next_rev)

    if request.method == 'POST':
        form = UploadForm(request.POST, request.FILES)
        if form.is_valid():
            save_document_in_history(charter)
            # Also save group history so we can search for it
            save_group_in_history(group)

            charter.rev = next_rev

            e = NewRevisionDocEvent(doc=charter, by=request.user.person, type="new_revision")
            e.desc = "New version available: <b>%s-%s.txt</b>" % (charter.canonical_name(), charter.rev)
            e.rev = charter.rev
            e.save()

            # Save file on disk
            form.save(group, charter.rev)

            if option in ['initcharter','recharter'] and charter.ad == None:
                charter.ad = getattr(group.ad_role(),'person',None)

            charter.time = datetime.datetime.now()
            charter.save()

            if option:
                return redirect('charter_startstop_process', name=charter.name, option=option)
            else:
                return redirect("doc_view", name=charter.name)
    else:
        init = { "content": ""}
        c = charter

        if not_uploaded_yet:
            # use text from last approved revision
            last_approved = charter.rev.split("-")[0]
            h = charter.history_set.filter(rev=last_approved).order_by("-time", "-id")
            if h:
                c = h[0]

        filename = os.path.join(settings.CHARTER_PATH, '%s-%s.txt' % (c.canonical_name(), c.rev))

        try:
            with open(filename, 'r') as f:
                init["content"] = f.read()
        except IOError:
            pass
        form = UploadForm(initial=init)
    return render_to_response('doc/charter/submit.html',
                              {'form': form,
                               'next_rev': next_rev,
                               'group': group,
                               'name': name },
                              context_instance=RequestContext(request))
Exemple #25
0
 def save(self):
     delegates = self.cleaned_data.get('delete')
     save_group_in_history(Group.objects.get(pk=self.wg.pk))
     WGDelegate.objects.filter(pk__in=delegates).delete()
     self.set_message('success', 'Delegates removed')
Exemple #26
0
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))
Exemple #27
0
def submit(request, name=None, acronym=None, option=None):
    if name:
        if not name.startswith('charter-'):
            name = "charter-ietf-" + name
    elif acronym:
        name = "charter-ietf-" + acronym
    charter = get_object_or_404(Document, type="charter", name=name)
    group = charter.group

    login = request.user.get_profile()

    path = os.path.join(settings.CHARTER_PATH,
                        '%s-%s.txt' % (charter.canonical_name(), charter.rev))
    not_uploaded_yet = charter.rev.endswith("-00") and not os.path.exists(path)

    if not_uploaded_yet:
        # this case is special - we recently chartered or rechartered and have no file yet
        next_rev = charter.rev
    else:
        # search history for possible collisions with abandoned efforts
        prev_revs = list(
            charter.history_set.order_by('-time').values_list('rev',
                                                              flat=True))
        next_rev = next_revision(charter.rev)
        while next_rev in prev_revs:
            next_rev = next_revision(next_rev)

    if request.method == 'POST':
        form = UploadForm(request.POST, request.FILES)
        if form.is_valid():
            save_document_in_history(charter)
            # Also save group history so we can search for it
            save_group_in_history(group)

            charter.rev = next_rev

            e = NewRevisionDocEvent(doc=charter, by=login, type="new_revision")
            e.desc = "New version available: <b>%s-%s.txt</b>" % (
                charter.canonical_name(), charter.rev)
            e.rev = charter.rev
            e.save()

            # Save file on disk
            form.save(group, charter.rev)

            charter.time = datetime.datetime.now()
            charter.save()

            if option:
                return redirect('charter_startstop_process',
                                name=charter.name,
                                option=option)
            else:
                return redirect("doc_view", name=charter.name)
    else:
        init = {"content": ""}
        c = charter

        if not_uploaded_yet:
            # use text from last approved revision
            last_approved = charter.rev.split("-")[0]
            h = charter.history_set.filter(rev=last_approved).order_by(
                "-time", "-id")
            if h:
                c = h[0]

        filename = os.path.join(settings.CHARTER_PATH,
                                '%s-%s.txt' % (c.canonical_name(), c.rev))

        try:
            with open(filename, 'r') as f:
                init["content"] = f.read()
        except IOError:
            pass
        form = UploadForm(initial=init)
    return render_to_response('wgcharter/submit.html', {
        'form': form,
        'next_rev': next_rev,
        'group': group
    },
                              context_instance=RequestContext(request))
Exemple #28
0
    def test_edit_info(self):
        make_test_data()
        group = Group.objects.get(acronym="mars")

        url = urlreverse('group_edit', kwargs=dict(group_type=group.type_id, acronym=group.acronym))
        login_testing_unauthorized(self, "secretary", url)

        # normal get
        r = self.client.get(url)
        self.assertEqual(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertEqual(len(q('form select[name=parent]')), 1)
        self.assertEqual(len(q('form input[name=acronym]')), 1)

        # faulty post
        Group.objects.create(name="Collision Test Group", acronym="collide")
        r = self.client.post(url, dict(acronym="collide"))
        self.assertEqual(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertTrue(len(q('form ul.errorlist')) > 0)

        # create old acronym
        group.acronym = "oldmars"
        group.save()
        save_group_in_history(group)
        group.acronym = "mars"
        group.save()

        # post with warning
        r = self.client.post(url, dict(acronym="oldmars"))
        self.assertEqual(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertTrue(len(q('form ul.errorlist')) > 0)
        
        # edit info
        with open(os.path.join(self.charter_dir, "%s-%s.txt" % (group.charter.canonical_name(), group.charter.rev)), "w") as f:
            f.write("This is a charter.")
        area = group.parent
        ad = Person.objects.get(name="Aread Irector")
        state = GroupStateName.objects.get(slug="bof")
        r = self.client.post(url,
                             dict(name="Mars Not Special Interest Group",
                                  acronym="mars",
                                  parent=area.pk,
                                  ad=ad.pk,
                                  state=state.pk,
                                  chairs="[email protected], [email protected]",
                                  secretaries="[email protected], [email protected], [email protected]",
                                  techadv="*****@*****.**",
                                  delegates="*****@*****.**",
                                  list_email="mars@mail",
                                  list_subscribe="subscribe.mars",
                                  list_archive="archive.mars",
                                  urls="http://mars.mars (MARS site)"
                                  ))
        self.assertEqual(r.status_code, 302)

        group = Group.objects.get(acronym="mars")
        self.assertEqual(group.name, "Mars Not Special Interest Group")
        self.assertEqual(group.parent, area)
        self.assertEqual(group.ad, ad)
        for k in ("chair", "secr", "techadv"):
            self.assertTrue(group.role_set.filter(name=k, email__address="*****@*****.**"))
        self.assertTrue(group.role_set.filter(name="delegate", email__address="*****@*****.**"))
        self.assertEqual(group.list_email, "mars@mail")
        self.assertEqual(group.list_subscribe, "subscribe.mars")
        self.assertEqual(group.list_archive, "archive.mars")
        self.assertEqual(group.groupurl_set.all()[0].url, "http://mars.mars")
        self.assertEqual(group.groupurl_set.all()[0].name, "MARS site")
        self.assertTrue(os.path.exists(os.path.join(self.charter_dir, "%s-%s.txt" % (group.charter.canonical_name(), group.charter.rev))))
Exemple #29
0
def edit(request, acronym):
    """ 
    Edit Group details

    **Templates:**

    * ``groups/edit.html``

    **Template Variables:**

    * group, form, awp_formset

    """

    group = get_object_or_404(Group, acronym=acronym)
    AWPFormSet = inlineformset_factory(Group, GroupURL, form=AWPForm, max_num=2)

    if request.method == 'POST':
        button_text = request.POST.get('submit', '')
        if button_text == 'Cancel':
            url = reverse('groups_view', kwargs={'acronym':acronym})
            return HttpResponseRedirect(url)

        form = GroupModelForm(request.POST, instance=group)
        awp_formset = AWPFormSet(request.POST, instance=group)
        if form.is_valid() and awp_formset.is_valid():
            
            awp_formset.save()
            if form.changed_data:
                state = form.cleaned_data['state']
                
                # save group
                save_group_in_history(group)
                
                form.save()
                
                # create appropriate GroupEvent
                if 'state' in form.changed_data:
                    if state.name == 'Active':
                        desc = 'Started group'
                    else:
                        desc = state.name + ' group'
                    ChangeStateGroupEvent.objects.create(group=group,
                                                         type='changed_state',
                                                         by=request.user.get_profile(),
                                                         state=state,
                                                         desc=desc)
                    form.changed_data.remove('state')
                    
                # if anything else was changed
                if form.changed_data:
                    GroupEvent.objects.create(group=group,
                                              type='info_changed',
                                              by=request.user.get_profile(),
                                              desc='Info Changed')
                
                # if the acronym was changed we'll want to redirect using the new acronym below
                if 'acronym' in form.changed_data:
                    acronym = form.cleaned_data['acronym']
                
                messages.success(request, 'The Group was changed successfully')
            
            url = reverse('groups_view', kwargs={'acronym':acronym})
            return HttpResponseRedirect(url)
            
    else:
        form = GroupModelForm(instance=group)
        awp_formset = AWPFormSet(instance=group)

    return render_to_response('groups/edit.html', {
        'group': group,
        'awp_formset': awp_formset,
        'form': form},
        RequestContext(request, {}),
    )
Exemple #30
0
def edit(request, acronym):
    """
    Edit Group details

    **Templates:**

    * ``groups/edit.html``

    **Template Variables:**

    * group, form, awp_formset

    """

    group = get_object_or_404(Group, acronym=acronym)
    AWPFormSet = inlineformset_factory(Group, GroupURL, form=AWPForm, max_num=2)

    if request.method == 'POST':
        button_text = request.POST.get('submit', '')
        if button_text == 'Cancel':
            return redirect('groups_view', acronym=acronym)

        form = GroupModelForm(request.POST, instance=group)
        awp_formset = AWPFormSet(request.POST, instance=group)
        if form.is_valid() and awp_formset.is_valid():

            awp_formset.save()
            if form.changed_data:
                state = form.cleaned_data['state']

                # save group
                save_group_in_history(group)

                form.save()

                # create appropriate GroupEvent
                if 'state' in form.changed_data:
                    if state.name == 'Active':
                        desc = 'Started group'
                    else:
                        desc = state.name + ' group'
                    ChangeStateGroupEvent.objects.create(group=group,
                                                         type='changed_state',
                                                         by=request.user.person,
                                                         state=state,
                                                         desc=desc)
                    form.changed_data.remove('state')

                # if anything else was changed
                if form.changed_data:
                    GroupEvent.objects.create(group=group,
                                              type='info_changed',
                                              by=request.user.person,
                                              desc='Info Changed')

                # if the acronym was changed we'll want to redirect using the new acronym below
                if 'acronym' in form.changed_data:
                    acronym = form.cleaned_data['acronym']

                messages.success(request, 'The Group was changed successfully')

            return redirect('groups_view', acronym=acronym)

    else:
        form = GroupModelForm(instance=group)
        awp_formset = AWPFormSet(instance=group)

    messages.warning(request, "WARNING: don't use this tool to change group names.  Use Datatracker when possible.")

    return render_to_response('groups/edit.html', {
        'group': group,
        'awp_formset': awp_formset,
        'form': form},
        RequestContext(request, {}),
    )
Exemple #31
0
def edit(request, acronym=None, action="edit"):
    """Edit or create a WG, notifying parties as
    necessary and logging changes as group events."""
    if action == "edit":
        wg = get_object_or_404(Group, acronym=acronym)
        new_wg = False
    elif action in ("create","charter"):
        wg = None
        new_wg = True
    else:
        raise Http404

    login = request.user.get_profile()

    if request.method == 'POST':
        form = WGForm(request.POST, wg=wg, confirmed=request.POST.get("confirmed", False))
        if form.is_valid():
            clean = form.cleaned_data
            if new_wg:
                try:
                    wg = Group.objects.get(acronym=clean["acronym"])
                    save_group_in_history(wg)
                    wg.time = datetime.datetime.now()
                    wg.save()
                except Group.DoesNotExist:
                    wg = Group.objects.create(name=clean["name"],
                                              acronym=clean["acronym"],
                                              type=GroupTypeName.objects.get(slug="wg"),
                                              state=clean["state"]
                                              )

                e = ChangeStateGroupEvent(group=wg, type="changed_state")
                e.time = wg.time
                e.by = login
                e.state_id = clean["state"].slug
                e.desc = "Group created in state %s" % clean["state"].name
                e.save()
            else:
                save_group_in_history(wg)


            if action=="charter" and not wg.charter:  # make sure we have a charter
                wg.charter = get_or_create_initial_charter(wg)

            changes = []
                
            def desc(attr, new, old):
                entry = "%(attr)s changed to <b>%(new)s</b> from %(old)s"
                if new_wg:
                    entry = "%(attr)s changed to <b>%(new)s</b>"
                    
                return entry % dict(attr=attr, new=new, old=old)

            def diff(attr, name):
                v = getattr(wg, attr)
                if clean[attr] != v:
                    changes.append(desc(name, clean[attr], v))
                    setattr(wg, attr, clean[attr])

            prev_acronym = wg.acronym

            # update the attributes, keeping track of what we're doing
            diff('name', "Name")
            diff('acronym', "Acronym")
            diff('state', "State")
            diff('ad', "Shepherding AD")
            diff('parent', "IETF Area")
            diff('list_email', "Mailing list email")
            diff('list_subscribe', "Mailing list subscribe address")
            diff('list_archive', "Mailing list archive")

            if not new_wg and wg.acronym != prev_acronym and wg.charter:
                save_document_in_history(wg.charter)
                DocAlias.objects.get_or_create(
                    name="charter-ietf-%s" % wg.acronym,
                    document=wg.charter,
                    )
                old = os.path.join(wg.charter.get_file_path(), 'charter-ietf-%s-%s.txt' % (prev_acronym, wg.charter.rev))
                if os.path.exists(old):
                    new = os.path.join(wg.charter.get_file_path(), 'charter-ietf-%s-%s.txt' % (wg.acronym, wg.charter.rev))
                    shutil.copy(old, new)

            # update roles
            for attr, slug, title in [('chairs', 'chair', "Chairs"), ('secretaries', 'secr', "Secretaries"), ('techadv', 'techadv', "Tech Advisors")]:
                new = clean[attr]
                old = Email.objects.filter(role__group=wg, role__name=slug).select_related("person")
                if set(new) != set(old):
                    changes.append(desc(title,
                                        ", ".join(x.get_name() for x in new),
                                        ", ".join(x.get_name() for x in old)))
                    wg.role_set.filter(name=slug).delete()
                    for e in new:
                        Role.objects.get_or_create(name_id=slug, email=e, group=wg, person=e.person)

            # update urls
            new_urls = clean['urls']
            old_urls = format_urls(wg.groupurl_set.order_by('url'), ", ")
            if ", ".join(sorted(new_urls)) != old_urls:
                changes.append(desc('Urls', ", ".join(sorted(new_urls)), old_urls))
                wg.groupurl_set.all().delete()
                # Add new ones
                for u in new_urls:
                    m = re.search('(?P<url>[\w\d:#@%/;$()~_?\+-=\\\.&]+)( \((?P<name>.+)\))?', u)
                    if m:
                        if m.group('name'):
                            url = GroupURL(url=m.group('url'), name=m.group('name'), group=wg)
                        else:
                            url = GroupURL(url=m.group('url'), name='', group=wg)
                        url.save()

            wg.time = datetime.datetime.now()

            if changes and not new_wg:
                for c in changes:
                    GroupEvent.objects.create(group=wg, by=login, type="info_changed", desc=c)

            wg.save()

            if action=="charter":
                return redirect('charter_submit', name=wg.charter.name, option="initcharter")

            return redirect('wg_charter', acronym=wg.acronym)
    else: # form.is_valid()
        if not new_wg:
            from ietf.person.forms import json_emails
            init = dict(name=wg.name,
                        acronym=wg.acronym,
                        state=wg.state,
                        chairs=Email.objects.filter(role__group=wg, role__name="chair"),
                        secretaries=Email.objects.filter(role__group=wg, role__name="secr"),
                        techadv=Email.objects.filter(role__group=wg, role__name="techadv"),
                        ad=wg.ad_id if wg.ad else None,
                        parent=wg.parent.id if wg.parent else None,
                        list_email=wg.list_email if wg.list_email else None,
                        list_subscribe=wg.list_subscribe if wg.list_subscribe else None,
                        list_archive=wg.list_archive if wg.list_archive else None,
                        urls=format_urls(wg.groupurl_set.all()),
                        )
        else:
            init = dict(ad=login.id if has_role(request.user, "Area Director") else None,
                        )
        form = WGForm(initial=init, wg=wg)

    return render_to_response('wginfo/edit.html',
                              dict(wg=wg,
                                   form=form,
                                   action=action,
                                   user=request.user,
                                   login=login),
                              context_instance=RequestContext(request))
Exemple #32
0
def submit(request, name, option=None):
    if not name.startswith('charter-'):
        raise Http404

    charter = Document.objects.filter(type="charter", name=name).first()
    if charter:
        group = charter.group
        charter_canonical_name = charter.canonical_name()
        charter_rev = charter.rev
    else:
        top_org, group_acronym = split_charter_name(name)
        group = get_object_or_404(Group, acronym=group_acronym)
        charter_canonical_name = name
        charter_rev = "00-00"

    if not can_manage_group_type(
            request.user, group) or not group.features.has_chartering_process:
        return HttpResponseForbidden(
            "You don't have permission to access this view")

    path = os.path.join(settings.CHARTER_PATH,
                        '%s-%s.txt' % (charter_canonical_name, charter_rev))
    not_uploaded_yet = charter_rev.endswith("-00") and not os.path.exists(path)

    if not_uploaded_yet or not charter:
        # this case is special - we recently chartered or rechartered and have no file yet
        next_rev = charter_rev
    else:
        # search history for possible collisions with abandoned efforts
        prev_revs = list(
            charter.history_set.order_by('-time').values_list('rev',
                                                              flat=True))
        next_rev = next_revision(charter.rev)
        while next_rev in prev_revs:
            next_rev = next_revision(next_rev)

    if request.method == 'POST':
        form = UploadForm(request.POST, request.FILES)
        if form.is_valid():
            # Also save group history so we can search for it
            save_group_in_history(group)

            if not charter:
                charter = Document.objects.create(
                    name=name,
                    type_id="charter",
                    title=group.name,
                    group=group,
                    abstract=group.name,
                    rev=next_rev,
                )
                DocAlias.objects.create(name=charter.name, document=charter)

                charter.set_state(
                    State.objects.get(used=True, type="charter",
                                      slug="notrev"))

                group.charter = charter
                group.save()
            else:
                charter.rev = next_rev

            events = []
            e = NewRevisionDocEvent(doc=charter,
                                    by=request.user.person,
                                    type="new_revision")
            e.desc = "New version available: <b>%s-%s.txt</b>" % (
                charter.canonical_name(), charter.rev)
            e.rev = charter.rev
            e.save()
            events.append(e)

            # Save file on disk
            filename = os.path.join(
                settings.CHARTER_PATH,
                '%s-%s.txt' % (charter.canonical_name(), charter.rev))
            with open(filename, 'wb') as destination:
                if form.cleaned_data['txt']:
                    destination.write(form.cleaned_data['txt'])
                else:
                    destination.write(
                        form.cleaned_data['content'].encode("utf-8"))

            if option in ['initcharter', 'recharter'] and charter.ad == None:
                charter.ad = getattr(group.ad_role(), 'person', None)

            charter.save_with_history(events)

            if option:
                return redirect('ietf.doc.views_charter.change_state',
                                name=charter.name,
                                option=option)
            else:
                return redirect("ietf.doc.views_doc.document_main",
                                name=charter.name)
    else:
        init = {"content": ""}

        if not_uploaded_yet and charter:
            # use text from last approved revision
            last_approved = charter.rev.split("-")[0]
            h = charter.history_set.filter(rev=last_approved).order_by(
                "-time", "-id").first()
            if h:
                charter_canonical_name = h.canonical_name()
                charter_rev = h.rev

        filename = os.path.join(
            settings.CHARTER_PATH,
            '%s-%s.txt' % (charter_canonical_name, charter_rev))

        try:
            with open(filename, 'r') as f:
                init["content"] = f.read()
        except IOError:
            pass
        form = UploadForm(initial=init)
        fill_in_charter_info(group)

    return render(request, 'doc/charter/submit.html', {
        'form': form,
        'next_rev': next_rev,
        'group': group,
        'name': name,
    })
Exemple #33
0
def edit(request, acronym):
    """
    Edit Group details

    **Templates:**

    * ``groups/edit.html``

    **Template Variables:**

    * group, form, awp_formset

    """

    group = get_object_or_404(Group, acronym=acronym)
    AWPFormSet = inlineformset_factory(Group,
                                       GroupURL,
                                       form=AWPForm,
                                       max_num=2)

    if request.method == 'POST':
        button_text = request.POST.get('submit', '')
        if button_text == 'Cancel':
            return redirect('ietf.secr.groups.views.view', acronym=acronym)

        form = GroupModelForm(request.POST, instance=group)
        awp_formset = AWPFormSet(request.POST, instance=group)
        if form.is_valid() and awp_formset.is_valid():

            awp_formset.save()
            if form.changed_data:
                state = form.cleaned_data['state']

                # save group
                save_group_in_history(group)

                form.save()

                # create appropriate GroupEvent
                if 'state' in form.changed_data:
                    if state.name == 'Active':
                        desc = 'Started group'
                    else:
                        desc = state.name + ' group'
                    ChangeStateGroupEvent.objects.create(
                        group=group,
                        type='changed_state',
                        by=request.user.person,
                        state=state,
                        desc=desc)
                    form.changed_data.remove('state')

                # if anything else was changed
                if form.changed_data:
                    GroupEvent.objects.create(group=group,
                                              type='info_changed',
                                              by=request.user.person,
                                              desc='Info Changed')

                # if the acronym was changed we'll want to redirect using the new acronym below
                if 'acronym' in form.changed_data:
                    acronym = form.cleaned_data['acronym']

                messages.success(request, 'The Group was changed successfully')

            return redirect('ietf.secr.groups.views.view', acronym=acronym)

    else:
        form = GroupModelForm(instance=group)
        awp_formset = AWPFormSet(instance=group)

    messages.warning(
        request,
        "WARNING: don't use this tool to change group names.  Use Datatracker when possible."
    )

    return render(
        request,
        'groups/edit.html',
        {
            'group': group,
            'awp_formset': awp_formset,
            'form': form
        },
    )
Exemple #34
0
def edit(request, acronym=None, action="edit"):
    """Edit or create a WG, notifying parties as
    necessary and logging changes as group events."""
    if action == "edit":
        wg = get_object_or_404(Group, acronym=acronym)
        new_wg = False
    elif action in ("create", "charter"):
        wg = None
        new_wg = True
    else:
        raise Http404

    login = request.user.get_profile()

    if request.method == 'POST':
        form = WGForm(request.POST,
                      wg=wg,
                      confirmed=request.POST.get("confirmed", False))
        if form.is_valid():
            clean = form.cleaned_data
            if new_wg:
                try:
                    wg = Group.objects.get(acronym=clean["acronym"])
                    save_group_in_history(wg)
                    wg.time = datetime.datetime.now()
                    wg.save()
                except Group.DoesNotExist:
                    wg = Group.objects.create(
                        name=clean["name"],
                        acronym=clean["acronym"],
                        type=GroupTypeName.objects.get(slug="wg"),
                        state=clean["state"])

                e = ChangeStateGroupEvent(group=wg, type="changed_state")
                e.time = wg.time
                e.by = login
                e.state_id = clean["state"].slug
                e.desc = "Group created in state %s" % clean["state"].name
                e.save()
            else:
                save_group_in_history(wg)

            if action == "charter" and not wg.charter:  # make sure we have a charter
                wg.charter = get_or_create_initial_charter(wg)

            changes = []

            def desc(attr, new, old):
                entry = "%(attr)s changed to <b>%(new)s</b> from %(old)s"
                if new_wg:
                    entry = "%(attr)s changed to <b>%(new)s</b>"

                return entry % dict(attr=attr, new=new, old=old)

            def diff(attr, name):
                v = getattr(wg, attr)
                if clean[attr] != v:
                    changes.append(desc(name, clean[attr], v))
                    setattr(wg, attr, clean[attr])

            prev_acronym = wg.acronym

            # update the attributes, keeping track of what we're doing
            diff('name', "Name")
            diff('acronym', "Acronym")
            diff('state', "State")
            diff('ad', "Shepherding AD")
            diff('parent', "IETF Area")
            diff('list_email', "Mailing list email")
            diff('list_subscribe', "Mailing list subscribe address")
            diff('list_archive', "Mailing list archive")

            if not new_wg and wg.acronym != prev_acronym and wg.charter:
                save_document_in_history(wg.charter)
                DocAlias.objects.get_or_create(
                    name="charter-ietf-%s" % wg.acronym,
                    document=wg.charter,
                )
                old = os.path.join(
                    wg.charter.get_file_path(),
                    'charter-ietf-%s-%s.txt' % (prev_acronym, wg.charter.rev))
                if os.path.exists(old):
                    new = os.path.join(
                        wg.charter.get_file_path(), 'charter-ietf-%s-%s.txt' %
                        (wg.acronym, wg.charter.rev))
                    shutil.copy(old, new)

            # update roles
            for attr, slug, title in [('chairs', 'chair', "Chairs"),
                                      ('secretaries', 'secr', "Secretaries"),
                                      ('techadv', 'techadv', "Tech Advisors")]:
                new = clean[attr]
                old = Email.objects.filter(
                    role__group=wg, role__name=slug).select_related("person")
                if set(new) != set(old):
                    changes.append(
                        desc(title, ", ".join(x.get_name() for x in new),
                             ", ".join(x.get_name() for x in old)))
                    wg.role_set.filter(name=slug).delete()
                    for e in new:
                        Role.objects.get_or_create(name_id=slug,
                                                   email=e,
                                                   group=wg,
                                                   person=e.person)

            # update urls
            new_urls = clean['urls']
            old_urls = format_urls(wg.groupurl_set.order_by('url'), ", ")
            if ", ".join(sorted(new_urls)) != old_urls:
                changes.append(
                    desc('Urls', ", ".join(sorted(new_urls)), old_urls))
                wg.groupurl_set.all().delete()
                # Add new ones
                for u in new_urls:
                    m = re.search(
                        '(?P<url>[\w\d:#@%/;$()~_?\+-=\\\.&]+)( \((?P<name>.+)\))?',
                        u)
                    if m:
                        if m.group('name'):
                            url = GroupURL(url=m.group('url'),
                                           name=m.group('name'),
                                           group=wg)
                        else:
                            url = GroupURL(url=m.group('url'),
                                           name='',
                                           group=wg)
                        url.save()

            wg.time = datetime.datetime.now()

            if changes and not new_wg:
                for c in changes:
                    GroupEvent.objects.create(group=wg,
                                              by=login,
                                              type="info_changed",
                                              desc=c)

            wg.save()

            if action == "charter":
                return redirect('charter_submit',
                                name=wg.charter.name,
                                option="initcharter")

            return redirect('wg_charter', acronym=wg.acronym)
    else:  # form.is_valid()
        if not new_wg:
            from ietf.person.forms import json_emails
            init = dict(
                name=wg.name,
                acronym=wg.acronym,
                state=wg.state,
                chairs=Email.objects.filter(role__group=wg,
                                            role__name="chair"),
                secretaries=Email.objects.filter(role__group=wg,
                                                 role__name="secr"),
                techadv=Email.objects.filter(role__group=wg,
                                             role__name="techadv"),
                ad=wg.ad_id if wg.ad else None,
                parent=wg.parent.id if wg.parent else None,
                list_email=wg.list_email if wg.list_email else None,
                list_subscribe=wg.list_subscribe
                if wg.list_subscribe else None,
                list_archive=wg.list_archive if wg.list_archive else None,
                urls=format_urls(wg.groupurl_set.all()),
            )
        else:
            init = dict(ad=login.id
                        if has_role(request.user, "Area Director") else None, )
        form = WGForm(initial=init, wg=wg)

    return render_to_response('wginfo/edit.html',
                              dict(wg=wg,
                                   form=form,
                                   action=action,
                                   user=request.user,
                                   login=login),
                              context_instance=RequestContext(request))
Exemple #35
0
 def save(self):
     delegates = self.cleaned_data.get('delete')
     save_group_in_history(Group.objects.get(pk=self.wg.pk))
     WGDelegate.objects.filter(pk__in=delegates).delete()
     self.set_message('success', 'Delegates removed')
Exemple #36
0
def edit(request, group_type=None, acronym=None, action="edit"):
    """Edit or create a group, notifying parties as
    necessary and logging changes as group events."""
    if not can_manage_group_type(request.user, group_type):
        return HttpResponseForbidden("You don't have permission to access this view")

    if action == "edit":
        group = get_object_or_404(Group, acronym=acronym)
        new_group = False
    elif action in ("create","charter"):
        group = None
        new_group = True
    else:
        raise Http404

    if not group_type and group:
        group_type = group.type_id

    if request.method == 'POST':
        form = GroupForm(request.POST, group=group, group_type=group_type)
        if form.is_valid():
            clean = form.cleaned_data
            if new_group:
                try:
                    group = Group.objects.get(acronym=clean["acronym"])
                    save_group_in_history(group)
                    group.time = datetime.datetime.now()
                    group.save()
                except Group.DoesNotExist:
                    group = Group.objects.create(name=clean["name"],
                                              acronym=clean["acronym"],
                                              type=GroupTypeName.objects.get(slug=group_type),
                                              state=clean["state"]
                                              )

                e = ChangeStateGroupEvent(group=group, type="changed_state")
                e.time = group.time
                e.by = request.user.person
                e.state_id = clean["state"].slug
                e.desc = "Group created in state %s" % clean["state"].name
                e.save()
            else:
                save_group_in_history(group)


            if action == "charter" and not group.charter:  # make sure we have a charter
                group.charter = get_or_create_initial_charter(group, group_type)

            changes = []

            def desc(attr, new, old):
                entry = "%(attr)s changed to <b>%(new)s</b> from %(old)s"
                if new_group:
                    entry = "%(attr)s changed to <b>%(new)s</b>"

                return entry % dict(attr=attr, new=new, old=old)

            def diff(attr, name):
                v = getattr(group, attr)
                if clean[attr] != v:
                    changes.append((attr, clean[attr], desc(name, clean[attr], v)))
                    setattr(group, attr, clean[attr])

            # update the attributes, keeping track of what we're doing
            diff('name', "Name")
            diff('acronym', "Acronym")
            diff('state', "State")
            diff('parent', "IETF Area" if group.type=="wg" else "Group parent")
            diff('list_email', "Mailing list email")
            diff('list_subscribe', "Mailing list subscribe address")
            diff('list_archive', "Mailing list archive")

            personnel_change_text=""
            changed_personnel = set()
            # update roles
            for attr, slug, title in [('ad','ad','Shepherding AD'), ('chairs', 'chair', "Chairs"), ('secretaries', 'secr', "Secretaries"), ('techadv', 'techadv', "Tech Advisors"), ('delegates', 'delegate', "Delegates")]:
                new = clean[attr]
                if attr == 'ad':
                    new = [ new.role_email('ad'),] if new else []
                old = Email.objects.filter(role__group=group, role__name=slug).select_related("person")
                if set(new) != set(old):
                    changes.append((attr, new, desc(title,
                                        ", ".join(x.get_name() for x in new),
                                        ", ".join(x.get_name() for x in old))))
                    group.role_set.filter(name=slug).delete()
                    for e in new:
                        Role.objects.get_or_create(name_id=slug, email=e, group=group, person=e.person)
                    added = set(new) - set(old)
                    deleted = set(old) - set(new)
                    if added:
                        change_text=title + ' added: ' + ", ".join(x.formatted_email() for x in added)
                        personnel_change_text+=change_text+"\n"
                    if deleted:
                        change_text=title + ' deleted: ' + ", ".join(x.formatted_email() for x in deleted)
                        personnel_change_text+=change_text+"\n"
                    changed_personnel.update(set(old)^set(new))

            if personnel_change_text!="":
                email_personnel_change(request, group, personnel_change_text, changed_personnel)

            # update urls
            new_urls = clean['urls']
            old_urls = format_urls(group.groupurl_set.order_by('url'), ", ")
            if ", ".join(sorted(new_urls)) != old_urls:
                changes.append(('urls', new_urls, desc('Urls', ", ".join(sorted(new_urls)), old_urls)))
                group.groupurl_set.all().delete()
                # Add new ones
                for u in new_urls:
                    m = re.search('(?P<url>[\w\d:#@%/;$()~_?\+-=\\\.&]+)( \((?P<name>.+)\))?', u)
                    if m:
                        if m.group('name'):
                            url = GroupURL(url=m.group('url'), name=m.group('name'), group=group)
                        else:
                            url = GroupURL(url=m.group('url'), name='', group=group)
                        url.save()

            group.time = datetime.datetime.now()

            if changes and not new_group:
                for attr, new, desc in changes:
                    if attr == 'state':
                        ChangeStateGroupEvent.objects.create(group=group, time=group.time, state=new, by=request.user.person, type="changed_state", desc=desc)
                    else:
                        GroupEvent.objects.create(group=group, time=group.time, by=request.user.person, type="info_changed", desc=desc)

            group.save()

            if action=="charter":
                return redirect('charter_submit', name=group.charter.name, option="initcharter")

            return HttpResponseRedirect(group.about_url())
    else: # form.is_valid()
        if not new_group:
            ad_role = group.ad_role()
            init = dict(name=group.name,
                        acronym=group.acronym,
                        state=group.state,
                        chairs=Email.objects.filter(role__group=group, role__name="chair"),
                        secretaries=Email.objects.filter(role__group=group, role__name="secr"),
                        techadv=Email.objects.filter(role__group=group, role__name="techadv"),
                        delegates=Email.objects.filter(role__group=group, role__name="delegate"),
                        ad=ad_role and ad_role.person and ad_role.person.id,
                        parent=group.parent.id if group.parent else None,
                        list_email=group.list_email if group.list_email else None,
                        list_subscribe=group.list_subscribe if group.list_subscribe else None,
                        list_archive=group.list_archive if group.list_archive else None,
                        urls=format_urls(group.groupurl_set.all()),
                        )
        else:
            init = dict(ad=request.user.person.id if group_type == "wg" and has_role(request.user, "Area Director") else None,
                        )
        form = GroupForm(initial=init, group=group, group_type=group_type)

    return render(request, 'group/edit.html',
                  dict(group=group,
                       form=form,
                       action=action))
Exemple #37
0
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))