Bhavesh Goyal has proposed merging 
lp:~bhavesh-goyal093/postorius/feature-implemented-mass-removal into 
lp:postorius.

Requested reviews:
  Mailman Coders (mailman-coders)

For more details, see:
https://code.launchpad.net/~bhavesh-goyal093/postorius/feature-implemented-mass-removal/+merge/253775

Implemented the feature : Mass Unsubscription of list members from a list. 
Earlier there was no such option to unsubscribe all / set of members from the 
list and the list maintainer had to manually unsubscribe each member going 
through their email addresses searching for each one of them manually in the 
entire list.

Now Mass Removal feature to remove a set of email addresses is present as an 
option in the list nav bar to selectively unsubscribe a set of email addresses. 
The user can simply input the emails in each lines similar to mass subscribe 
and unsubscribe those members.

Also, a feature to unsubscribe all members has also been added as a button 
under the same tab itself to empty the list at once, unsubscribing all members 
from the list keeping list settings / configs the same. This feature was also 
missing earlier and is now supported with a confirmation page too to prevent 
the user from accidentally pressing the button and emptying the list.
-- 
Your team Mailman Coders is requested to review the proposed merge of 
lp:~bhavesh-goyal093/postorius/feature-implemented-mass-removal into 
lp:postorius.
=== modified file 'src/postorius/forms.py'
--- src/postorius/forms.py	2015-02-09 14:35:44 +0000
+++ src/postorius/forms.py	2015-03-22 22:00:51 +0000
@@ -717,6 +717,24 @@
         layout = [["Mass subscription", "emails"]]
 
 
+class ListMassRemoval(FieldsetForm):
+
+    """Form fields to remove multiple list users.
+    """
+    emails = forms.CharField(
+        label=_('Emails to Unsubscribe'),
+        widget=forms.Textarea,
+    )
+
+    class Meta:
+
+        """
+        Class to define the name of the fieldsets and what should be
+        included in each.
+        """
+        layout = [["Mass Removal", "emails"]]
+
+
 class UserPreferences(FieldsetForm):
 
     """

=== modified file 'src/postorius/static/postorius/js/script.js'
--- src/postorius/static/postorius/js/script.js	2012-08-29 11:19:08 +0000
+++ src/postorius/static/postorius/js/script.js	2015-03-22 22:00:51 +0000
@@ -1,5 +1,4 @@
 $(document).ready(function(){
     $('.collapse').collapse({
-        toggle: false,
-    });
+toggle: false,
 });

=== modified file 'src/postorius/templates/postorius/base.html'
--- src/postorius/templates/postorius/base.html	2014-10-15 20:32:39 +0000
+++ src/postorius/templates/postorius/base.html	2015-03-22 22:00:51 +0000
@@ -6,11 +6,9 @@
 	<title></title>
 	<meta name="description" content="">
 	<meta name="author" content="">
-
 	<meta name="viewport" content="width=device-width, initial-scale=1.0">
 	<link rel="shortcut icon" href="{% static 'postorius/img/favicon.ico' %}">
 	<link rel="apple-touch-icon" href="{% static 'postorius/img/apple-touch-icon.png' %}">
-
 	<link rel="stylesheet" href="{% static 'postorius/css/bootstrap.css' %}">
 	<link rel="stylesheet" href="{% static 'postorius/css/style.css' %}">
 
@@ -65,7 +63,6 @@
     <script src="{% static 'postorius/js/libs/jquery-1.8.3.min.js' %}"></script>
     <script src="{% static 'postorius/js/libs/bootstrap.js' %}"></script>
     <script src="{% static 'postorius/js/plugins.js' %}"></script>
-    <script src="{% static 'postorius/js/script.js' %}"></script>
-
+    <script src="{% static 'postorius/js/script.js' %}"></script> 
     {% block additionaljs %}{% endblock %}
 </body>

=== added file 'src/postorius/templates/postorius/lists/confirm_removeall_subscribers.html'
--- src/postorius/templates/postorius/lists/confirm_removeall_subscribers.html	1970-01-01 00:00:00 +0000
+++ src/postorius/templates/postorius/lists/confirm_removeall_subscribers.html	2015-03-22 22:00:51 +0000
@@ -0,0 +1,14 @@
+{% extends "postorius/base.html" %}
+{% load url from future %}
+{% load i18n %}
+{% load nav_helpers %}
+
+{% block main %}
+    <h1>{% trans 'Confirm Removal of All Members' %}</h1>
+    <p>{% trans "Are you sure you want to unsubscribe all members from "  %}{{list_id}}{% trans " ?"%}</p>
+    <hr />
+   <form method="post" action="{% url 'unsubscribe_all' list_id %}">
+          {% csrf_token %}
+        <button class="btn btn-danger" type="submit" >{% trans "Unsubscribe All " %}</button>
+        <a class="btn" href="{% url 'list_members' list_id %}">{% trans "Cancel" %}</a>
+{% endblock main %}

=== modified file 'src/postorius/templates/postorius/lists/members.html'
--- src/postorius/templates/postorius/lists/members.html	2015-01-17 17:23:59 +0000
+++ src/postorius/templates/postorius/lists/members.html	2015-03-22 22:00:51 +0000
@@ -5,7 +5,6 @@
 
 {% block main %}
     {% list_nav 'list_members' "List Members" %}
-
     <h2>{% trans "Owners" %}</h2>
 
     {{ owner_form.email.errors }}
@@ -61,7 +60,6 @@
     </table>
 
     <h2>{% trans "Members" %}</h2>
-
     <table class="table table-bordered table-striped">
         <thead>
     		<tr>

=== modified file 'src/postorius/templates/postorius/menu/list_nav.html'
--- src/postorius/templates/postorius/menu/list_nav.html	2015-01-19 15:03:09 +0000
+++ src/postorius/templates/postorius/menu/list_nav.html	2015-03-22 22:00:51 +0000
@@ -18,6 +18,9 @@
         {% if user.is_superuser or user.is_list_moderator %}
             <li class="mm_nav_item"><a class="{% nav_active_class current 'mass_subscribe' %}" href="{% url 'mass_subscribe' list.list_id %}">{% trans "Mass Subscribe" %}</a></li>
         {% endif %}
+        {% if user.is_superuser or user.is_list_moderator %} 
+	    <li class="mm_nav_item"><a class="{% nav_active_class current 'mass_removal' %}" href="{% url 'mass_removal' list.list_id %}">{% trans "Mass Removal" %}</a></li>
+        {% endif %}
         {% if user.is_superuser or user.is_list_owner %}
             <li class="mm_nav_item"><a class="{% nav_active_class current 'list_delete' %}" href="{% url 'list_delete' list.list_id %}">{% trans "Delete List" %}</a></li>
         {% endif %}

=== modified file 'src/postorius/urls.py'
--- src/postorius/urls.py	2015-02-09 14:35:44 +0000
+++ src/postorius/urls.py	2015-03-22 22:00:51 +0000
@@ -47,13 +47,16 @@
                                 url(r'^unsubscribe/(?P<email>[^/]+)$',
                                     ListUnsubscribeView.as_view(
                                     ), name='list_unsubscribe'),
-                                url(r'^subscriptions$',
+				url(r'^subscriptions$',
                                     'list_subscriptions',
                                     name='list_subscriptions'),
                                 url(r'^mass_subscribe/$',
                                     ListMassSubsribeView.as_view(
                                     ), name='mass_subscribe'),
-                                url(r'^delete$',
+                                url(r'^mass_removal/$',
+				    ListMassRemovalView.as_view(
+			            ), name='mass_removal'),
+				url(r'^delete$',
                                     'list_delete', name='list_delete'),
                                 url(r'^held_messages/(?P<msg_id>[^/]+)/'
                                     'accept$', 'accept_held_message',
@@ -77,6 +80,8 @@
                                     '(?:/(?P<visible_option>.*))?$',
                                     'list_settings',
                                     name='list_settings'),
+                                url(r'^unsubscribe_all$',
+				    'remove_all_subscribers', name='unsubscribe_all'),
                                 )
 
 urlpatterns = patterns(

=== modified file 'src/postorius/views/list.py'
--- src/postorius/views/list.py	2015-02-09 14:35:44 +0000
+++ src/postorius/views/list.py	2015-03-22 22:00:51 +0000
@@ -230,7 +230,6 @@
             messages.error(request, e)
         return redirect('list_summary', self.mailing_list.list_id)
 
-
 class ListMassSubsribeView(MailingListView):
 
     """Mass subscription."""
@@ -267,6 +266,43 @@
                         messages.error(request, e)
         return redirect('mass_subscribe', self.mailing_list.list_id)
 
+class ListMassRemovalView(MailingListView):
+
+    """Class For Mass Removal"""
+
+    @method_decorator(list_owner_required)
+    def get(self, request, *args, **kwargs):
+        form = ListMassRemoval()
+        return render_to_response('postorius/lists/mass_removal.html',
+                                  {'form': form, 'list': self.mailing_list},
+                                  context_instance=RequestContext(request))
+
+    def post(self, request, *args, **kwargs):
+        form = ListMassRemoval(request.POST)
+        if not form.is_valid():
+            messages.error(request, 'Please fill out the form correctly.')
+        else:
+            emails = request.POST["emails"].splitlines()
+            for email in emails:
+                parts = email.split('@')
+                if len(parts) != 2 or '.' not in parts[1]:
+                    messages.error(request,
+                                   'The email address %s is not valid.' %
+                                   email)
+                else:
+                    try:
+                        self.mailing_list.unsubscribe(email.lower())
+                        messages.success(
+                            request,
+                            'The address %s has been unsubscribed from %s.' %
+                            (email, self.mailing_list.fqdn_listname))
+                    except MailmanApiError:
+                        return utils.render_api_error(request)
+                    except HTTPError, e:
+                        messages.error(request, e)
+		    except ValueError, e:
+                        messages.error(request, e)
+        return redirect('mass_removal', self.mailing_list.list_id)
 
 def _get_choosable_domains(request):
     try:
@@ -659,3 +695,29 @@
                               {'role': role, 'address': address,
                                'list_id': the_list.list_id},
                               context_instance=RequestContext(request))
+
+@list_owner_required
+def remove_all_subscribers(request, list_id):
+   
+    """Empty the list by unsubscribing all members."""
+    
+    try:
+	mlist = List.objects.get_or_404(fqdn_listname=list_id)
+	if len(mlist.members) == 0:
+	    messages.error(request, 'No member is subscribed to the list currently.')
+	    return redirect('mass_removal', mlist.list_id)
+    except MailmanApiError:
+        return utils.render_api_error(request)
+	
+    if request.method == 'POST':
+	try:
+	    for names in mlist.members:
+                mlist.unsubscribe(names.email)
+	    messages.success(request,
+			    'All members have been unsubscribed from the list.')
+	except Exception, e:
+	    messages.error(request, e)
+	return redirect('list_members', mlist.list_id)
+    return render_to_response('postorius/lists/confirm_removeall_subscribers.html', 
+			     {'list_id' : mlist.list_id},
+			     context_instance=RequestContext(request))

_______________________________________________
Mailman-coders mailing list
[email protected]
https://mail.python.org/mailman/listinfo/mailman-coders

Reply via email to