Mercurial > hg > savane-forge
changeset 206:e58b71703438
Manage 'homepage' and 'download' project links
author | Sylvain Beucler <beuc@beuc.net> |
---|---|
date | Fri, 30 Jul 2010 15:54:41 +0200 |
parents | 93815ee7cef7 |
children | 6fef32fad596 |
files | 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/svtopmenu.html |
diffstat | 7 files changed, 95 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/savane/svmain/fixtures/demo/users_groups.yaml +++ b/savane/svmain/fixtures/demo/users_groups.yaml @@ -3,6 +3,8 @@ fields: name: "Official GNU software" 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/" - model: auth.group pk: 1 fields:
--- a/savane/svmain/models.py +++ b/savane/svmain/models.py @@ -58,11 +58,25 @@ similar to extending a model class (at the SQL tables level), and AutoOneToOneField is a trick from django-annoying to automatically create the extended data on first access. + +However this means all SvGroupInfo fields have a default value or can +be NULL, which means the rest of the code will have to handle NULL +cases :/ + +There are also reports of issues when used with the South framework. + +Also this code: + group.svgroupinfo.type = ... + group.svgroupinfo.save() +Currently fails: type remains NULL, probably because the result of the +first invocation of 'group.svgroupinfo' return a different result +thant the second one. We may need to do things differently... """ from django.db import models from django.contrib.auth import models as auth_models from django.utils.translation import ugettext, ugettext_lazy as _ +import datetime class SshKey(models.Model): @@ -374,7 +388,8 @@ group = AutoOneToOneField(auth_models.Group, primary_key=True) - type = models.ForeignKey(GroupConfiguration) + type = models.ForeignKey(GroupConfiguration, + null=True) # NULL when object initially created by AutoOneToOneField full_name = models.CharField(max_length=255, blank=True, help_text="Full project name (not Unix system name)") is_public = models.BooleanField(default=False) @@ -393,14 +408,15 @@ license = models.ForeignKey(License, blank=True, null=True) license_other = models.TextField(blank=True) - devel_status = models.ForeignKey(DevelopmentStatus) + devel_status = models.ForeignKey(DevelopmentStatus, + null=True) # NULL when object initially created by AutoOneToOneField # Registration-specific register_purpose = models.TextField(blank=True) required_software = models.TextField(blank=True) other_comments = models.TextField(blank=True) - register_time = models.DateTimeField() + register_time = models.DateTimeField(default=datetime.datetime.now) #rand_hash text, registered_gpg_keys = models.TextField(blank=True) @@ -501,6 +517,14 @@ def get_active_memberships(self): return self.group.membership_set.exclude(admin_flags='P') + def get_url_homepage(self): + return (self.url_homepage + or self.type.url_homepage.replace('%PROJECT', self.group.name)) + + def get_url_download(self): + return (self.url_download + or self.type.url_download.replace('%PROJECT', self.group.name)) + @staticmethod def query_active_groups_raw(conn, fields): """ @@ -581,13 +605,15 @@ def is_member(user, group): return (user.is_superuser or user.is_staff or - group.user_set.filter(pk=user.pk).count() > 0) + (not user.is_anonymous() + and group.user_set.filter(pk=user.pk).count() > 0)) @staticmethod def is_admin(user, group): return (user.is_superuser or user.is_staff or - (Membership.is_member(user, group) + (not user.is_anonymous() + and Membership.is_member(user, group) and Membership.objects .filter(user=user, group=group, admin_flags='A').count() > 0))
--- a/savane/svmain/templatetags/svtopmenu.py +++ b/savane/svmain/templatetags/svtopmenu.py @@ -39,7 +39,7 @@ group = context['group'] if menu_name == 'group': - entry_home = { 'text' : 'Home', + entry_home = { 'text' : 'Main', 'href' : reverse('savane:svmain:group_detail', args=[group.name]), 'title': "Project Main Page at %s" % 'this website'} entry_home['children'] = [] @@ -60,15 +60,38 @@ entry_home['children'].append({'text' : _("Manage members"), 'href' : reverse('savane:svmain:group_admin_members', args=[group.name]) }) - entry_test = { - 'text' : 2, 'href' : 2, 'title': 2, 'children': - [ - {'text' : 2.1, 'href' : 2.1, 'title': 2.1 }, - ] - } + entry_homepage = {'text' : _("Homepage"), + 'href' : group.svgroupinfo.get_url_homepage(), + 'title': _("Browse project homepage (outside of Savane)")} + + entry_download = {'text' : _("Download"), + 'href' : group.svgroupinfo.get_url_download(), + 'title': _("Download area: files released")} + + entry_mailinglists = {'text' : _("Mailing lists") + " (TODO)", + 'href' : '', + 'title': _("List existing mailing lists")} + entry_mailinglists['children'] = [] + entry_mailinglists['children'].append({'text' : _("Browse") + " (TODO)", + 'href' : '' }) + if (svmain_models.Membership.is_admin(context['user'], group)): + entry_mailinglists['children'].append({'separator' : True }) + entry_mailinglists['children'].append({'text' : _("Configure:") + " (TODO)", 'strong': True, + 'href' : '' }) + + entry_sourcecode = {'text' : _("Source code") + " (TODO)", + 'href' : '', + 'title': _("Source Code Management")} + entry_sourcecode['children'] = [] + entry_sourcecode['children'].append({'text' : _("Use X") + " (TODO)", + 'href' : '' }) + entries.append(entry_home) - entries.append(entry_test) + entries.append(entry_homepage) + entries.append(entry_download) + entries.append(entry_mailinglists) + entries.append(entry_sourcecode) elif menu_name == 'my': pass
--- a/savane/svmain/tests.py +++ b/savane/svmain/tests.py @@ -20,6 +20,7 @@ from django.test import TestCase from django.core.urlresolvers import reverse import django.contrib.auth.models as auth_models +import savane.svmain.models as svmain_models import re class SimpleTest(TestCase): @@ -49,3 +50,28 @@ response = self.client.get(reverse('registration_activate', args=[hash])) self.assertRedirects(response, reverse('registration_activation_complete')) self.assertTrue(self.client.login(username='test', password='test')) + + def test_020_group_url(self): + """ + Create a new group and check the page menu + """ + conf = svmain_models.GroupConfiguration(name='testconf', + url_homepage='http://www.test.tld/homepage/%PROJECT/', + url_download='http://www.test.tld/download/%PROJECT/') + conf.save() + + group = auth_models.Group(name='test') + group.save() + # Work-around AutoOneToOneField bug + group.svgroupinfo + group.svgroupinfo.type = conf + group.svgroupinfo.save() + + 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/') + + group.svgroupinfo.url_homepage = 'http://www.mysite.tld/%PROJECT/' + group.svgroupinfo.save() + response = self.client.get(reverse('savane:svmain:group_detail', args=[group.name])) + self.assertContains(response, 'http://www.mysite.tld/%PROJECT/')
--- a/savane/svmain/urls.py +++ b/savane/svmain/urls.py @@ -107,7 +107,8 @@ 'extra_context' : { 'title' : 'Editing public info' }, }, name='group_admin_info'), url(r'^p/(?P<slug>[-\w]+)/admin/features/$', views.group_admin_features, - { 'extra_context' : { 'title' : 'Select features' }, }, + { 'extra_context' : { 'title' : 'Select features' }, + 'post_save_redirect': ''}, name='group_admin_features'), url(r'^p/(?P<slug>[-\w]+)/admin/members/$', views.group_admin_members, { 'extra_context' : { 'title' : 'Manage members' }, },
--- a/savane/svmain/views.py +++ b/savane/svmain/views.py @@ -157,7 +157,7 @@ return context @render_to("svmain/group_admin_features.html", mimetype=None) -def group_admin_features(request, slug, extra_context={}): +def group_admin_features(request, slug, extra_context={}, post_save_redirect=None): group = get_object_or_404(auth_models.Group, name=slug) object = group.svgroupinfo
--- a/templates/svmain/svtopmenu.html +++ b/templates/svmain/svtopmenu.html @@ -2,6 +2,7 @@ {% for l1 in entries %} <li class="topmenuitemmainitem"> <a class="tabs" href="{{l1.href}}" title="{{l1.title}}">{{ l1.text }}</a> + {% if l1.children %} <ul id="submenu{{forloop.counter}}" class="topmenuitemsubmenu"> {% for l2 in l1.children %} {% if l2.separator %} @@ -13,6 +14,7 @@ {% endif %} {% endfor %} </ul> + {% endif %} </li> {% endfor %} </ul>