Add managers to teams
authorMagnus Hagander <magnus@hagander.net>
Thu, 11 Feb 2016 14:18:59 +0000 (15:18 +0100)
committerMagnus Hagander <magnus@hagander.net>
Thu, 11 Feb 2016 14:18:59 +0000 (15:18 +0100)
This is a single user that's in charge of a team. The manager will get an
email whenever somebody tries to join a team. The team will also show up
on the managers /register/ page with the ability to remove people from it.

hamnadmin/hamnadmin/register/migrations/0005_add_team_manager.py [new file with mode: 0644]
hamnadmin/hamnadmin/register/models.py
hamnadmin/hamnadmin/register/templates/index.html
hamnadmin/hamnadmin/register/urls.py
hamnadmin/hamnadmin/register/views.py

diff --git a/hamnadmin/hamnadmin/register/migrations/0005_add_team_manager.py b/hamnadmin/hamnadmin/register/migrations/0005_add_team_manager.py
new file mode 100644 (file)
index 0000000..7728e38
--- /dev/null
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+from django.conf import settings
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('register', '0004_archived_blogs'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='team',
+            name='manager',
+            field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True),
+        ),
+    ]
index f01643b6749741cd1c267d93d43c7b3ec4c91215..ee63b7a84ecc0af74085153b1ee562cf78b5e313 100644 (file)
@@ -7,6 +7,7 @@ from hamnadmin.util.shortlink import urlvalmap
 class Team(models.Model):
        teamurl = models.CharField(max_length=255, blank=False)
        name = models.CharField(max_length=255, blank=False)
+       manager = models.ForeignKey(User, null=True, blank=True)
 
        def __unicode__(self):
                return "%s (%s)" % (self.name, self.teamurl)
index bdef79e5125fb43b6b8cf04931df4b92eaa82dcc..ed5256bf5621f0a18e14cf7e47d4e9c4eddebcf2 100644 (file)
@@ -75,4 +75,49 @@ Note that your blog will have to be approved before it appears
 on the planet.
 </p>
 <a class="btn btn-default" href="new/">Register new blog</a>
+
+{%if teams%}
+<h1>Your teams</h1>
+<p>
+You are listed as a manager for the following teams:
+</p>
+{%for team in teams%}
+<div class="panel panel-info">
+  <div class="panel-heading"><a href="{{team.teamurl}}">{{team.name}}</a></div>
+  <div class="panel-body">
+    <div class="row">
+      <div class="col-sm-12">
+       The following accounts are members of your team. You can remove any member you want.
+       New membership is requested by the blog owner, and you will receive a notification
+       email when they do.
+      </div>
+    </div>
+    <table class="table table-condensed table-striped">
+      <tr>
+       <th>Name</th>
+       <th>Feed</th>
+       <th>Actions</th>
+      </tr>
+      {%for m in team.blog_set.all%}
+      <tr>
+       <td><a href="{{m.blogurl}}">{{m.name|default:m.feedurl}}</a></td>
+       <td>{{m.feedurl}}</td>
+       <td><a class="btn btn-default btn-sm" onClick="confirmRemoveFromTeam({{team.id}},{{m.id}})">Remove from team</a></td>
+      </tr>
+      {%endfor%}
+    </table>
+  </div>
+</div>
+{%endfor%}
+{%endif%}
+{%endblock%}
+
+{%block extrahead%}
+<script language="javascript">
+function confirmRemoveFromTeam(teamid, feedid) {
+  if (confirm('Are you sure you want to remove this blog from the team?\n\n(A notification will be sent to the blog owner.)\n')) {
+    document.location.href = 'teamremove/' + teamid + '/' + feedid + '/';
+  }
+}
+</script>
 {%endblock%}
index 74aaef84809ef98fb0daa7b299bd298f698c1624..08232ca77935e964078ea23c46bbe6d2d4c72295 100644 (file)
@@ -10,6 +10,7 @@ urlpatterns = patterns('',
     (r'^edit/(?P<id>\d+)/$', 'hamnadmin.register.views.edit'),
     (r'^delete/(?P<id>\d+)/$', 'hamnadmin.register.views.delete'),
     (r'^archive/(?P<id>\d+)/$', 'hamnadmin.register.views.archive'),
+    (r'^teamremove/(?P<teamid>\d+)/(?P<blogid>\d+)/$', 'hamnadmin.register.views.remove_from_team'),
 
     (r'^blogposts/(\d+)/hide/(\d+)/$', 'hamnadmin.register.views.blogpost_hide'),
     (r'^blogposts/(\d+)/unhide/(\d+)/$', 'hamnadmin.register.views.blogpost_unhide'),
index 7818c4f3b9289347135eb464c57242b7bd5f9862..3cab054921e421af3e84bad6f38ed0f0334fd796 100644 (file)
@@ -55,7 +55,7 @@ def root(request):
                blogs = Blog.objects.filter(user=request.user).order_by('archived', 'approved', 'name')
        return render_to_response('index.html',{
                'blogs': blogs,
-               'teams': Team.objects.all().order_by('name'),
+               'teams': Team.objects.filter(manager=request.user).order_by('name'),
        }, context_instance=RequestContext(request))
 
 @login_required
@@ -72,6 +72,7 @@ def edit(request, id=None):
        if request.method == 'POST':
                saved_url = blog.feedurl
                saved_filter = blog.authorfilter
+               saved_team = blog.team
                form = BlogEditForm(request, data=request.POST, instance=blog)
                if form.is_valid():
                        if id:
@@ -101,6 +102,21 @@ def edit(request, id=None):
                                                messages.info(request, "did not change")
 
                        obj = form.save()
+
+                       if obj.team and obj.team != saved_team:
+                               # We allow anybody to join a team by default, and will just send a notice
+                               # so the team manager can undo it.
+                               send_simple_mail(settings.EMAIL_SENDER,
+                                                                obj.team.manager.email,
+                                                                "A blog joined your team on Planet PostgreSQL",
+                                                                u"The blog at {0} by {1} {2}\nhas been added to yor team {3} on Planet PostgreSQL\n\nIf this is correct, you do not need to do anything.\n\nIf this is incorrect, please go to\n\nhttps://planet.postgresql.org/register/\n\nand click the button to remove the blog from your team.\nWe apologize if this causes work for you.\n\n".format(
+                                                                        obj.feedurl,
+                                                                        obj.user.first_name, obj.user.last_name,
+                                                                        obj.team.name),
+                                                                sendername="Planet PostgreSQL",
+                                                                receivername=u"{0} {1}".format(obj.team.manager.first_name, obj.team.manager.last_name),
+                                                                )
+
                        return HttpResponseRedirect("/register/edit/{0}/".format(obj.id))
        else:
                form =  BlogEditForm(request, instance=blog)
@@ -154,6 +170,41 @@ def archive(request, id):
        messages.info(request, "Blog archived.")
        return HttpResponseRedirect("/register/")
 
+@login_required
+@transaction.atomic
+def remove_from_team(request, teamid, blogid):
+       team = get_object_or_404(Team, id=teamid, manager=request.user)
+       blog = get_object_or_404(Blog, id=blogid)
+
+       if blog.team != team:
+               messages.error(request, "The blog at {0} does not (any more?) belong to the team {1}!".format(
+                       blog.feedurl,
+                       team.name))
+               return HttpResponseRedirect("/register/")
+
+       blog.team = None
+       blog.save()
+
+       send_simple_mail(settings.EMAIL_SENDER,
+                                        settings.NOTIFICATION_RECEIVER,
+                                        "A blog was removed from a team on Planet PostgreSQL",
+                                        u"The blog at {0} by {1} {2}\nwas removed from team {3} by {4}.\n".format(
+                                                blog.feedurl, blog.user.first_name, blog.user.last_name, team.name, request.user.username),
+                                        sendername="Planet PostgreSQL",
+                                        receivername="Planet PostgreSQL Moderators",
+                                        )
+
+       send_simple_mail(settings.EMAIL_SENDER,
+                                        blog.user.email,
+                                        "Your blog on Planet PostgreSQL was removed from the team",
+                                        u"Your blog at {0} has been removed\nfrom the team {1} on Planet PostgreSQL.\n\nIf you believe this to be in error, please contact\nthe team administrator.\n\n".format(blog.feedurl, team.name),
+                                        sendername="Planet PostgreSQL",
+                                        receivername=u"{0} {1}".format(blog.user.first_name, blog.user.last_name),
+                                        )
+
+       messages.info(request, "Blog {0} removed from team {1}".format(blog.feedurl, team.name))
+       return HttpResponseRedirect("/register/")
+
 def __getvalidblogpost(request, blogid, postid):
        blog = get_object_or_404(Blog, id=blogid)
        post = get_object_or_404(Post, id=postid)