changeset 207:6fef32fad596

Browse project mailing lists
author Sylvain Beucler <beuc@beuc.net>
date Sat, 31 Jul 2010 00:15:25 +0200
parents e58b71703438
children cc3105877a0e
files savane/svmain/admin.py savane/svmain/fixtures/demo/mailinglist.yaml savane/svmain/fixtures/demo/users_groups.yaml savane/svmain/models.py savane/svmain/templatetags/svtopmenu.py savane/svmain/tests.py savane/svmain/urls.py savane/svmain/views.py templates/svmain/group_mailinglist.html
diffstat 9 files changed, 154 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/savane/svmain/admin.py
+++ b/savane/svmain/admin.py
@@ -64,8 +64,7 @@
         (_('Mailing List'),
          {'fields': ('can_use_mailing_list', 'mailing_list_virtual_host',
                      'mailing_list_address', 'mailing_list_format',
-                     'url_mailing_list_listinfo', 'url_mailing_list_subscribe',
-                     'url_mailing_list_unsubscribe', 'url_mailing_list_archives',
+                     'url_mailing_list_listinfo', 'url_mailing_list_archives',
                      'url_mailing_list_archives_private', 'url_mailing_list_admin')}),
         # TODO: finish
         (_('News Manager'), {'fields': ('can_use_news',)}),
@@ -89,8 +88,15 @@
     list_display  = ('pk', 'full_name', 'type', 'license',)
     list_filter = ('type', 'license', 'devel_status',)
 
+class MailingListAdmin(admin.ModelAdmin):
+    search_fields = ('list_name',)
+    ordering = ('list_name',)
+    list_display  = ('pk', 'list_name', 'status', 'is_public', 'description',)
+    list_filter = ('status', 'is_public', )
+
 admin.site.register(svmain_models.SvUserInfo, SvUserInfoAdmin)
 admin.site.register(svmain_models.SvGroupInfo, SvGroupInfoAdmin)
 admin.site.register(svmain_models.GroupConfiguration, GroupConfigurationAdmin)
 admin.site.register(svmain_models.License, LicenseAdmin)
 admin.site.register(svmain_models.DevelopmentStatus, DevelopmentStatusAdmin)
+admin.site.register(svmain_models.MailingList, MailingListAdmin)
new file mode 100644
--- /dev/null
+++ b/savane/svmain/fixtures/demo/mailinglist.yaml
@@ -0,0 +1,7 @@
+- model: svmain.mailinglist
+  pk: 1
+  fields:
+    group: 1
+    list_name: bug-gnu-emacs
+    description: "Bug reports and feature requests"
+    status: 5
--- a/savane/svmain/fixtures/demo/users_groups.yaml
+++ b/savane/svmain/fixtures/demo/users_groups.yaml
@@ -5,6 +5,13 @@
     description: "This project is part of the GNU Project."
     url_homepage: "http://www.gnu.org/software/%PROJECT/"
     url_download: "http://ftp.gnu.org/gnu/%PROJECT/"
+    mailing_list_address: "%LIST@gnu.org"
+    mailing_list_virtual_host: lists.gnu.org
+    mailing_list_format: "%PROJECT-%NAME,%PROJECT,bug-%PROJECT,help-%PROJECT,info-%PROJECT"
+    url_mailing_list_listinfo: "http://lists.gnu.org/mailman/listinfo/%LIST"
+    url_mailing_list_archives: "http://lists.gnu.org/archive/html/%LIST/"
+    url_mailing_list_archives_private: "http://lists.gnu.org/mailman/private/%LIST/"
+    url_mailing_list_admin: "http://lists.gnu.org/mailman/admin/%LIST"
 - model: auth.group
   pk: 1
   fields:
--- a/savane/svmain/models.py
+++ b/savane/svmain/models.py
@@ -326,21 +326,22 @@
     dir_download = models.CharField(max_length=255, default='/')
 
     # Default URLs
-    url_homepage             = models.CharField(max_length=255, default='http://')
-    url_cvs_viewcvs_homepage = models.CharField(max_length=255, default='http://')
-    url_cvs_viewcvs          = models.CharField(max_length=255, default='http://')
-    url_arch_viewcvs         = models.CharField(max_length=255, default='http://')
-    url_svn_viewcvs          = models.CharField(max_length=255, default='http://')
-    url_git_viewcvs          = models.CharField(max_length=255, default='http://')
-    url_hg_viewcvs           = models.CharField(max_length=255, default='http://')
-    url_bzr_viewcvs          = models.CharField(max_length=255, default='http://')
-    url_download             = models.CharField(max_length=255, default='http://')
-    url_mailing_list_listinfo         = models.CharField(max_length=255, default='http://')
-    url_mailing_list_subscribe        = models.CharField(max_length=255, default='http://')
-    url_mailing_list_unsubscribe      = models.CharField(max_length=255, default='http://')
-    url_mailing_list_archives         = models.CharField(max_length=255, default='http://')
-    url_mailing_list_archives_private = models.CharField(max_length=255, default='http://')
-    url_mailing_list_admin            = models.CharField(max_length=255, default='http://')
+    url_homepage             = models.CharField(max_length=255)
+    url_cvs_viewcvs_homepage = models.CharField(max_length=255)
+    url_cvs_viewcvs          = models.CharField(max_length=255)
+    url_arch_viewcvs         = models.CharField(max_length=255)
+    url_svn_viewcvs          = models.CharField(max_length=255)
+    url_git_viewcvs          = models.CharField(max_length=255)
+    url_hg_viewcvs           = models.CharField(max_length=255)
+    url_bzr_viewcvs          = models.CharField(max_length=255)
+    url_download             = models.CharField(max_length=255)
+    url_mailing_list_listinfo         = models.CharField(max_length=255)
+    url_mailing_list_archives         = models.CharField(max_length=255)
+    url_mailing_list_archives_private = models.CharField(max_length=255)
+    url_mailing_list_admin            = models.CharField(max_length=255)
+    # Old majordomo
+    #url_mailing_list_subscribe        = models.CharField(max_length=255)
+    #url_mailing_list_unsubscribe      = models.CharField(max_length=255)
     url_extralink_documentation = models.CharField(max_length=255, blank=True)
 
     # Deprecated
@@ -631,3 +632,30 @@
 
     def __unicode__(self):
         return "[%s is a member of %s]" % (self.user.username, self.group.name)
+
+
+class MailingList(models.Model):
+    status_CHOICES = (
+        ('0', 'Deleted'),
+        ('1', 'To be created'),
+        ('2', 'To be reconfigured'),
+        ('5', 'Created'),
+        )
+    group = models.ForeignKey(auth_models.Group)
+    list_name = models.CharField(max_length=255)
+    is_public = models.BooleanField(default=True)
+    # password
+    # list_admin
+    status = models.CharField(max_length=1, choices=status_CHOICES, default='1')
+    description = models.CharField(max_length=255)
+
+    def get_address(self):
+        return (self.group.svgroupinfo.type.mailing_list_address.replace('%LIST', self.list_name))
+    def get_url_listinfo(self):
+        return (self.group.svgroupinfo.type.url_mailing_list_listinfo.replace('%LIST', self.list_name))
+    def get_url_archives(self):
+        return (self.group.svgroupinfo.type.url_mailing_list_archives.replace('%LIST', self.list_name))
+    def get_url_archives_private(self):
+        return (self.group.svgroupinfo.type.url_mailing_list_archives_private.replace('%LIST', self.list_name))
+    def get_url_admin(self):
+        return (self.group.svgroupinfo.type.url_mailing_list_admin.replace('%LIST', self.list_name))
--- a/savane/svmain/templatetags/svtopmenu.py
+++ b/savane/svmain/templatetags/svtopmenu.py
@@ -68,15 +68,15 @@
                           'href' : group.svgroupinfo.get_url_download(),
                           'title': _("Download area: files released")}
 
-        entry_mailinglists = {'text' : _("Mailing lists") + " (TODO)",
-                              'href' : '',
+        entry_mailinglist = {'text' : _("Browse"),
+                              'href' : reverse('savane:svmain:group_mailinglist', args=[group.name]),
                               'title': _("List existing mailing lists")}
-        entry_mailinglists['children'] = []
-        entry_mailinglists['children'].append({'text' : _("Browse") + " (TODO)",
-                                                   'href' : '' })
+        entry_mailinglist['children'] = []
+        entry_mailinglist['children'].append({'text' : _("Browse"),
+                                               'href' : reverse('savane:svmain:group_mailinglist', args=[group.name])})
         if (svmain_models.Membership.is_admin(context['user'], group)):
-            entry_mailinglists['children'].append({'separator' : True })
-            entry_mailinglists['children'].append({'text' : _("Configure:") + " (TODO)", 'strong': True,
+            entry_mailinglist['children'].append({'separator' : True })
+            entry_mailinglist['children'].append({'text' : _("Configure:") + " (TODO)", 'strong': True,
                                                    'href' : '' })
  
         entry_sourcecode = {'text' : _("Source code") + " (TODO)",
@@ -90,7 +90,7 @@
         entries.append(entry_home)
         entries.append(entry_homepage)
         entries.append(entry_download)
-        entries.append(entry_mailinglists)
+        entries.append(entry_mailinglist)
         entries.append(entry_sourcecode)
     elif menu_name == 'my':
         pass
--- a/savane/svmain/tests.py
+++ b/savane/svmain/tests.py
@@ -51,9 +51,9 @@
         self.assertRedirects(response, reverse('registration_activation_complete'))
         self.assertTrue(self.client.login(username='test', password='test'))
 
-    def test_020_group_url(self):
+    def test_020_group(self):
         """
-        Create a new group and check the page menu
+        Create a new group and perform multiple checks
         """
         conf = svmain_models.GroupConfiguration(name='testconf',
                                                 url_homepage='http://www.test.tld/homepage/%PROJECT/',
@@ -67,6 +67,7 @@
         group.svgroupinfo.type = conf
         group.svgroupinfo.save()
 
+        # Check project menu
         response = self.client.get(reverse('savane:svmain:group_detail', args=[group.name]))
         self.assertContains(response, 'http://www.test.tld/homepage/test/')
         self.assertContains(response, 'http://www.test.tld/homepage/test/')
@@ -75,3 +76,8 @@
         group.svgroupinfo.save()
         response = self.client.get(reverse('savane:svmain:group_detail', args=[group.name]))
         self.assertContains(response, 'http://www.mysite.tld/%PROJECT/')
+
+        # Check that the list of mailing lists is displayed correctly
+        svmain_models.MailingList(group=group, list_name='test-commits').save()
+        response = self.client.get(reverse('savane:svmain:group_mailinglist', args=[group.name]))
+        self.assertContains(response, 'test-commits')
--- a/savane/svmain/urls.py
+++ b/savane/svmain/urls.py
@@ -95,6 +95,9 @@
       name='group_gpgkeyring'),
   url(r'^p/(?P<slug>[-\w]+)/gpgkeyring/download/$', views.group_gpgkeyring_download,
       name='group_gpgkeyring_download'),
+  url(r'^p/(?P<slug>[-\w]+)/mailinglist/$', views.group_mailinglist,
+      { 'extra_context' : { 'title' : 'Mailing lists' }, },
+      name='group_mailinglist'),
 )
 urlpatterns += decorated_patterns ('', login_required,
   url(r'^p/(?P<slug>[-\w]+)/join/$', views.group_join),
--- a/savane/svmain/views.py
+++ b/savane/svmain/views.py
@@ -34,6 +34,10 @@
     g = get_object_or_404(auth_models.Group, name=slug)
     return HttpResponseRedirect(reverse('savane.svmain.group_detail', args=(slug,)))
 
+##
+# Main
+##
+
 def group_join(request, slug):
     g = get_object_or_404(auth_models.Group, name=slug)
     if svmain_models.Membership.objects.filter(user=request.user, group=g).count():
@@ -264,3 +268,20 @@
                                model_admin=UserAdmin,
                                extra_context=context,
                                template_name='svmain/group_admin_members_add.html')
+
+##
+# Mailing lists
+##
+
+def group_mailinglist(request, slug, extra_context={}):
+    group = get_object_or_404(auth_models.Group, name=slug)
+
+    from django.views.generic.list_detail import object_list
+    context = {}
+    context.update(extra_context)
+    context.update({'group' : group})
+    queryset = svmain_models.MailingList.objects.filter(group=group).exclude(status=0)
+    return object_list(request,
+                       queryset=queryset,
+                       extra_context=context,
+                       template_name='svmain/group_mailinglist.html')
new file mode 100644
--- /dev/null
+++ b/templates/svmain/group_mailinglist.html
@@ -0,0 +1,49 @@
+{% extends "base.html" %}
+{% load i18n %}
+{% load svtopmenu %}
+
+{% block title %}
+{{group.svgroupinfo.get_full_name_display}} - {{title}}
+{% endblock %}
+
+{% block icon %}mail{% endblock %}
+
+{% block topmenu %}
+  {% svtopmenu "group" %}
+{% endblock %}
+
+{% block content %}
+
+{% if object_list %}
+  {% for object in object_list %}
+  <img src="{{STATIC_MEDIA_URL}}savane/images/common/contexts1/mail.orig.png" width=24 height=24 border="0" alt="" />
+  <a href="{{object.get_url_listinfo}}">{{object.list_name}}</a>
+  &nbsp;&nbsp;<em>{{object.description}}</em>
+  <p class="smaller">
+  {% if object.is_public %}
+  {% blocktrans with '<a href="'|add:object.get_url_archives|add:'">'|safe as begin_link and '</a>.' as end_link and object.list_name as list_name %}To see the collection of prior posting to the list, visit the {{begin_link}}{{list_name}} archives{{end_link}}{% endblocktrans %}
+  {% else %}
+  {% blocktrans with '<a href="'|add:object.get_url_archives_private|add:'">'|safe as begin_link and '</a>' as end_link and object.list_name as list_name %}To see the collection of prior posting to the list, visit the {{begin_link}}{{list_name}} archives{{end_link}} (authorization required).{% endblocktrans %}
+  {% endif %}
+  <br />
+  {% blocktrans with object.get_address|urlize as list_address %}To post a message to all the list members, write to {{list_address}}{% endblocktrans %}
+  <br />
+  {% blocktrans with '<a href="'|add:object.get_url_listinfo|add:'">'|safe as begin_link and '</a>.' as end_link and object.list_name as list_name %}You can (un)subscribe to the list by following instructions on the {{begin_link}}list information page{{end_link}}{% endblocktrans %}
+  <br />
+  {% blocktrans with '<a href="'|add:object.get_url_admin|add:'">'|safe as begin_link and '</a>' as end_link and object.list_name as list_name %}Project administrators can use the {{begin_link}}administrative interface{{end_link}} to manage the list.{% endblocktrans %}
+  </p>
+  {% endfor %}
+{% else %}
+  <h2>{% blocktrans with group.name as group_name %}No Lists found for {{group_name}}{% endblocktrans %}</h2>
+  <p>{% trans "Project administrators can add mailing lists using the admin interface." %}</p>
+{% endif %}
+
+{% endblock %}
+
+{% comment %}
+Local Variables: **
+mode: django-html **
+tab-width: 4 **
+indent-tabs-mode: nil **
+End: **
+{% endcomment %}