summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.BRANDING2
-rw-r--r--devel/admin.py8
-rw-r--r--devel/migrations/0002_staffgroup.py31
-rw-r--r--devel/models.py37
-rw-r--r--main/templatetags/flags.py2
-rw-r--r--mirrors/admin.py2
-rw-r--r--mirrors/migrations/0002_mirrorurl_bandwidth.py20
-rw-r--r--mirrors/models.py3
-rw-r--r--mirrors/views.py37
-rw-r--r--public/views.py38
-rw-r--r--settings.py5
-rw-r--r--sitemaps.py3
-rw-r--r--templates/mirrors/mirrors.html8
-rw-r--r--templates/public/developer_list.html4
-rw-r--r--templates/public/index.html5
-rw-r--r--templates/public/userlist.html8
-rw-r--r--urls.py10
17 files changed, 150 insertions, 73 deletions
diff --git a/README.BRANDING b/README.BRANDING
index e75eaeb9..55ef9d91 100644
--- a/README.BRANDING
+++ b/README.BRANDING
@@ -7,7 +7,7 @@ Files used to configure branding/url stuff
------------------------------------------
* `settings.py`
- * `templates/templatetags/package_extras.py`
+ * `templates/templatetags/jinja2.py`
* `main/templatetags/wiki.py`
* `main/templatetags/bugs.py`
diff --git a/devel/admin.py b/devel/admin.py
index c8f80f95..d1729fe3 100644
--- a/devel/admin.py
+++ b/devel/admin.py
@@ -2,7 +2,7 @@ from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
-from .models import UserProfile, MasterKey, DeveloperKey, PGPSignature
+from .models import UserProfile, StaffGroup, MasterKey, DeveloperKey, PGPSignature
class UserProfileInline(admin.StackedInline):
@@ -15,6 +15,11 @@ class UserProfileAdmin(UserAdmin):
list_filter = ('is_staff', 'is_superuser', 'is_active')
+class StaffGroupAdmin(admin.ModelAdmin):
+ list_display = ('name', 'group', 'sort_order', 'member_title', 'slug')
+ prepopulated_fields = {'slug': ('name',)}
+
+
class MasterKeyAdmin(admin.ModelAdmin):
list_display = ('pgp_key', 'owner', 'created', 'revoker', 'revoked')
search_fields = ('pgp_key', 'owner__username', 'revoker__username')
@@ -36,6 +41,7 @@ class PGPSignatureAdmin(admin.ModelAdmin):
admin.site.unregister(User)
admin.site.register(User, UserProfileAdmin)
+admin.site.register(StaffGroup, StaffGroupAdmin)
admin.site.register(MasterKey, MasterKeyAdmin)
admin.site.register(DeveloperKey, DeveloperKeyAdmin)
diff --git a/devel/migrations/0002_staffgroup.py b/devel/migrations/0002_staffgroup.py
new file mode 100644
index 00000000..5679e6a3
--- /dev/null
+++ b/devel/migrations/0002_staffgroup.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('auth', '0001_initial'),
+ ('devel', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='StaffGroup',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('name', models.CharField(max_length=100)),
+ ('slug', models.SlugField(unique=True, max_length=100)),
+ ('sort_order', models.PositiveIntegerField()),
+ ('member_title', models.CharField(max_length=100)),
+ ('description', models.TextField(blank=True)),
+ ('group', models.OneToOneField(to='auth.Group')),
+ ],
+ options={
+ 'ordering': ('sort_order',),
+ },
+ bases=(models.Model,),
+ ),
+ ]
diff --git a/devel/models.py b/devel/models.py
index 5c4d4fe7..b05800a5 100644
--- a/devel/models.py
+++ b/devel/models.py
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
import pytz
+from django.core.urlresolvers import reverse
from django.db import models
from django.db.models.signals import pre_save
-from django.contrib.auth.models import User
+from django.contrib.auth.models import User, Group
from django_countries.fields import CountryField
from .fields import PGPKeyField
@@ -54,17 +55,29 @@ class UserProfile(models.Model):
verbose_name_plural = 'additional profile data'
def get_absolute_url(self):
- # TODO: this is disgusting. find a way to consolidate this logic with
- # public.views.userlist among other places, and make some constants or
- # something so we aren't using copies of string names everywhere.
- group_names = self.user.groups.values_list('name', flat=True)
- if "Developers" in group_names:
- prefix = "developers"
- elif "Trusted Users" in group_names:
- prefix = "trustedusers"
- else:
- prefix = "fellows"
- return '/%s/#%s' % (prefix, self.user.username)
+ user = self.user
+ group = StaffGroup.objects.filter(group=user.groups.all()).first()
+ if group:
+ return '%s#%s' % (group.get_absolute_url(), user.username)
+ return None
+
+
+class StaffGroup(models.Model):
+ name = models.CharField(max_length=100)
+ slug = models.SlugField(max_length=100, unique=True)
+ group = models.OneToOneField(Group)
+ sort_order = models.PositiveIntegerField()
+ member_title = models.CharField(max_length=100)
+ description = models.TextField(blank=True)
+
+ class Meta:
+ ordering = ('sort_order',)
+
+ def __unicode__(self):
+ return self.name
+
+ def get_absolute_url(self):
+ return reverse('people', args=[self.slug])
class MasterKey(models.Model):
diff --git a/main/templatetags/flags.py b/main/templatetags/flags.py
index 22f524ca..5b356561 100644
--- a/main/templatetags/flags.py
+++ b/main/templatetags/flags.py
@@ -8,6 +8,6 @@ def country_flag(country):
if not country:
return ''
return '<span class="fam-flag fam-flag-%s" title="%s"></span> ' % (
- country.code.lower(), country.name)
+ unicode(country.code).lower(), unicode(country.name))
# vim: set ts=4 sw=4 et:
diff --git a/mirrors/admin.py b/mirrors/admin.py
index d5c89c2a..16a97ea2 100644
--- a/mirrors/admin.py
+++ b/mirrors/admin.py
@@ -11,7 +11,7 @@ from .models import (Mirror, MirrorProtocol, MirrorUrl, MirrorRsync,
class MirrorUrlForm(forms.ModelForm):
class Meta:
model = MirrorUrl
- fields = ('url', 'country', 'active')
+ fields = ('url', 'country', 'bandwidth', 'active')
def clean_url(self):
# is this a valid-looking URL?
diff --git a/mirrors/migrations/0002_mirrorurl_bandwidth.py b/mirrors/migrations/0002_mirrorurl_bandwidth.py
new file mode 100644
index 00000000..f0118199
--- /dev/null
+++ b/mirrors/migrations/0002_mirrorurl_bandwidth.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('mirrors', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='mirrorurl',
+ name='bandwidth',
+ field=models.FloatField(null=True, verbose_name=b'bandwidth (mbits)', blank=True),
+ preserve_default=True,
+ ),
+ ]
diff --git a/mirrors/models.py b/mirrors/models.py
index 641a6b97..820f3328 100644
--- a/mirrors/models.py
+++ b/mirrors/models.py
@@ -72,8 +72,9 @@ class MirrorUrl(models.Model):
editable=False)
has_ipv6 = models.BooleanField("IPv6 capable", default=False,
editable=False)
- created = models.DateTimeField(editable=False)
active = models.BooleanField(default=True)
+ bandwidth = models.FloatField("bandwidth (mbits)", null=True, blank=True)
+ created = models.DateTimeField(editable=False)
class Meta:
verbose_name = 'mirror URL'
diff --git a/mirrors/views.py b/mirrors/views.py
index cffafbf5..65fa0123 100644
--- a/mirrors/views.py
+++ b/mirrors/views.py
@@ -4,7 +4,7 @@ import json
from operator import attrgetter, itemgetter
from django import forms
-from django.forms.widgets import CheckboxSelectMultiple
+from django.forms.widgets import SelectMultiple, CheckboxSelectMultiple
from django.core.serializers.json import DjangoJSONEncoder
from django.db import connection
from django.db.models import Q
@@ -14,7 +14,8 @@ from django.utils.timezone import now
from django.views.decorators.cache import cache_page
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import condition
-from django_countries.data import COUNTRIES
+from django_countries import countries
+from django_countries.fields import Country
from .models import (Mirror, MirrorUrl, MirrorProtocol, MirrorLog,
CheckLocation)
@@ -22,7 +23,8 @@ from .utils import get_mirror_statuses, get_mirror_errors, DEFAULT_CUTOFF
class MirrorlistForm(forms.Form):
- country = forms.MultipleChoiceField(required=False)
+ country = forms.MultipleChoiceField(required=False,
+ widget=SelectMultiple(attrs={'size': '12'}))
protocol = forms.MultipleChoiceField(required=False,
widget=CheckboxSelectMultiple)
ip_version = forms.MultipleChoiceField(required=False,
@@ -30,8 +32,6 @@ class MirrorlistForm(forms.Form):
widget=CheckboxSelectMultiple)
use_mirror_status = forms.BooleanField(required=False)
- countries = dict(COUNTRIES)
-
def __init__(self, *args, **kwargs):
super(MirrorlistForm, self).__init__(*args, **kwargs)
fields = self.fields
@@ -49,8 +49,8 @@ class MirrorlistForm(forms.Form):
country_codes.update(MirrorUrl.objects.filter(active=True,
mirror__active=True).exclude(country='').values_list(
'country', flat=True).order_by().distinct())
- countries = [(code, self.countries[code]) for code in country_codes]
- return sorted(countries, key=itemgetter(1))
+ code_list = [(code, countries.name(code)) for code in country_codes]
+ return sorted(code_list, key=itemgetter(1))
def as_div(self):
"Returns this form rendered as HTML <divs>s."
@@ -142,14 +142,29 @@ def mirrors(request):
mirror_list = Mirror.objects.select_related().order_by('tier', 'name')
protos = MirrorUrl.objects.values_list(
'mirror_id', 'protocol__protocol').order_by(
- 'mirror__id', 'protocol__protocol').distinct()
+ 'mirror_id', 'protocol__protocol').distinct()
+ countries = MirrorUrl.objects.values_list(
+ 'mirror_id', 'country').order_by(
+ 'mirror_id', 'country').distinct()
+
if not request.user.is_authenticated():
mirror_list = mirror_list.filter(public=True, active=True)
- protos = protos.filter(mirror__public=True, mirror__active=True)
+ protos = protos.filter(
+ mirror__public=True, mirror__active=True, active=True)
+ countries = countries.filter(
+ mirror__public=True, mirror__active=True, active=True)
+
protos = {k: list(v) for k, v in groupby(protos, key=itemgetter(0))}
+ countries = {k: list(v) for k, v in groupby(countries, key=itemgetter(0))}
+
for mirror in mirror_list:
- items = protos.get(mirror.id, [])
- mirror.protocols = [item[1] for item in items]
+ item_protos = protos.get(mirror.id, [])
+ mirror.protocols = [item[1] for item in item_protos]
+ mirror.country = None
+ item_countries = countries.get(mirror.id, [])
+ if len(item_countries) == 1:
+ mirror.country = Country(item_countries[0][1])
+
return render(request, 'mirrors/mirrors.html',
{'mirror_list': mirror_list})
diff --git a/public/views.py b/public/views.py
index 57634983..1b79e7c8 100644
--- a/public/views.py
+++ b/public/views.py
@@ -5,11 +5,11 @@ from operator import attrgetter
from django.conf import settings
from django.contrib.auth.models import User
from django.db.models import Count, Q
-from django.http import Http404, HttpResponse
-from django.shortcuts import render
+from django.http import HttpResponse
+from django.shortcuts import get_object_or_404, render
from django.views.decorators.cache import cache_control, cache_page
-from devel.models import MasterKey, PGPSignature
+from devel.models import MasterKey, PGPSignature, StaffGroup
from main.models import Arch, Repo, Donor
from mirrors.models import MirrorUrl
from news.models import News
@@ -28,38 +28,18 @@ def index(request):
context = {
'news_updates': News.objects.order_by('-postdate', '-id')[:15],
'pkg_updates': updates,
+ 'staff_groups': StaffGroup.objects.all(),
}
return render(request, 'public/index.html', context)
-USER_LISTS = {
- 'hackers': {
- 'user_type': 'Hackers',
- 'user_title': 'Hacker',
- 'description': "This is a list of the current "+settings.BRANDING_SHORTNAME+" Hackers. They maintain the [libre] package repository and keep the [core], [extra] and [community] repositories clean of unfree software, in addition to doing any other developer duties.",
- },
- 'fellows': {
- 'user_type': 'Fellows',
- 'user_title': 'Fellow',
- 'description': "Below you can find a list of ex-hackers (aka project fellows). These folks helped make "+settings.BRANDING_SHORTNAME+" what it is today. Thanks!",
- },
-}
-
@cache_control(max_age=307)
-def userlist(request, user_type='hackers'):
- users = User.objects.order_by(
- 'username').select_related('userprofile')
- if user_type == 'hackers':
- users = users.filter(is_active=True, groups__name="Hackers")
- elif user_type == 'fellows':
- users = users.filter(is_active=False,
- groups__name__in=["Hackers"])
- else:
- raise Http404
+def people(request, slug):
+ group = get_object_or_404(StaffGroup, slug=slug)
+ users = User.objects.filter(groups=group.group).order_by(
+ 'first_name', 'last_name').select_related('userprofile')
- users = users.distinct()
- context = USER_LISTS[user_type].copy()
- context['users'] = users
+ context = {'group': group, 'users': users}
return render(request, 'public/userlist.html', context)
diff --git a/settings.py b/settings.py
index 5ee17af3..fa27b2f2 100644
--- a/settings.py
+++ b/settings.py
@@ -199,6 +199,11 @@ BRANDING_WIKINAME = 'ParabolaWiki'
BRANDING_EMAIL = 'Parabola Website Notification <nobody@parabola.nu>'
BRANDING_OSEARCH_TAGS = 'gnu linuxlibre parabola package software'
+# Country name overrides for display purposes
+COUNTRIES_OVERRIDE = {
+ 'MK': 'Macedonia',
+}
+
## Import local settings
from local_settings import *
diff --git a/sitemaps.py b/sitemaps.py
index d79b00b5..eb4e05d9 100644
--- a/sitemaps.py
+++ b/sitemaps.py
@@ -127,9 +127,6 @@ class BaseSitemap(Sitemap):
'page-about',
'page-art',
'page-svn',
- 'page-devs',
- 'page-tus',
- 'page-fellows',
'page-donate',
'feeds-list',
'mirror-list',
diff --git a/templates/mirrors/mirrors.html b/templates/mirrors/mirrors.html
index 13701e5a..3450d439 100644
--- a/templates/mirrors/mirrors.html
+++ b/templates/mirrors/mirrors.html
@@ -1,8 +1,12 @@
{% extends "base.html" %}
{% load cycle from future %}
{% load static from staticfiles %}
+{% load flags %}
+
{% block title %}{{ BRANDING_DISTRONAME }} - Mirror Overview{% endblock %}
+{% block head %}<link rel="stylesheet" type="text/css" href="{% static "flags/fam.css" %}" media="screen, projection" />{% endblock %}
+
{% block content %}
<div id="dev-mirrorlist" class="box">
<h2>Mirror Overview</h2>
@@ -10,6 +14,7 @@
<thead>
<tr>
<th>Server</th>
+ <th>Country</th>
<th>Tier</th>
<th>ISOs</th>
<th>Protocols</th>
@@ -26,6 +31,7 @@
<tr class="{% cycle 'odd' 'even' %}">
<td><a href="{{ mirror.get_absolute_url }}"
title="Mirror details for {{ mirror.name }}">{{ mirror.name }}</a></td>
+ <td class="country">{% if mirror.country %}{% country_flag mirror.country %}{{ mirror.country.name }}{% else %}Various{% endif %}</td>
<td>{{ mirror.get_tier_display }}</td>
<td>{{ mirror.isos|yesno|capfirst }}</td>
<td class="wrap">{{ mirror.protocols|join:", " }}</td>
@@ -44,7 +50,7 @@
<script type="text/javascript" src="{% static "archweb.js" %}"></script>
<script type="text/javascript">
$(document).ready(function() {
- $(".results").tablesorter({widgets: ['zebra'], sortList: [[1,0], [0,0]]});
+ $(".results").tablesorter({widgets: ['zebra'], sortList: [[2,0], [0,0]]});
});
</script>
{% endblock %}
diff --git a/templates/public/developer_list.html b/templates/public/developer_list.html
index 15a6c8bb..041780d7 100644
--- a/templates/public/developer_list.html
+++ b/templates/public/developer_list.html
@@ -21,7 +21,7 @@
<meta itemprop="name" content="{{ dev.get_full_name|escape }}"/>
<meta itemprop="givenName" content="{{ dev.first_name|escape }}"/>
<meta itemprop="familyName" content="{{ dev.last_name|escape }}"/>
- <meta itemprop="jobTitle" content="{{ user_title|escape }}"/>
+ <meta itemprop="jobTitle" content="{{ group.member_title|escape }}"/>
<div style="display:none" itemprop="memberOf" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="{{ BRANDING_DISTRONAME }}"/>
</div>
@@ -53,7 +53,7 @@
<th>Occupation:</th>
<td>{{ prof.occupation }}</td>
</tr><tr>
- <th>YOB:</th>
+ <th>Birth Year:</th>
<td itemprop="birthDate">{% if prof.yob %}{{ prof.yob }}{% endif %}</td>
</tr><tr>
<th>Location:</th>
diff --git a/templates/public/index.html b/templates/public/index.html
index e7174b45..f30b00f8 100644
--- a/templates/public/index.html
+++ b/templates/public/index.html
@@ -171,8 +171,9 @@
<h4>People</h4>
<ul>
- <li><a href="{% url 'page-devs' %}" title="Active hackers">Hackers</a></li>
- <li><a href="{% url 'page-fellows' %}" title="Retired hackers">Fellows</a></li>
+ {% for group in staff_groups %}
+ <li><a href="{% url 'people' group.slug %}" title="More info about {{ group.name }}">{{ group.name }}</a></li>
+ {% endfor %}
<li><a href="{% url 'page-keys' %}"
title="Package/Database signing master keys">Signing Master Keys</a></li>
</ul>
diff --git a/templates/public/userlist.html b/templates/public/userlist.html
index 6292af83..d49a1539 100644
--- a/templates/public/userlist.html
+++ b/templates/public/userlist.html
@@ -2,16 +2,16 @@
{% load static from staticfiles %}
{% load cache %}
-{% block title %}{{ BRANDING_DISTRONAME }} - {{ user_type }}{% endblock %}
+{% block title %}{{ BRANDING_DISTRONAME }} - {{ group.name }}{% endblock %}
{% block head %}<link rel="stylesheet" type="text/css" href="{% static "flags/fam.css" %}" media="screen, projection" />{% endblock %}
{% block content %}
-{% cache 600 dev-tu-profiles user_type %}
+{% cache 600 dev-tu-profiles group.name %}
<div id="dev-tu-profiles" class="box">
- <h2>{{BRANDING_DISTRONAME}} {{user_type}}</h2>
+ <h2>{{BRANDING_DISTRONAME}} {{ group.name }}</h2>
- <p>{{description}}</p>
+ <p>{{ group.description }}</p>
{% with users as dev_list %}
{% include 'public/developer_list.html' %}
diff --git a/urls.py b/urls.py
index e7a2cbc3..81b45627 100644
--- a/urls.py
+++ b/urls.py
@@ -29,14 +29,13 @@ urlpatterns += patterns('public.views',
{}, 'page-art'),
(r'^https/$', TemplateView.as_view(template_name='public/https.html'),
{}, 'page-https'),
- (r'^hackers/$', 'userlist', { 'user_type':'hackers' }, 'page-devs'),
- (r'^fellows/$', 'userlist', { 'user_type':'fellows' }, 'page-fellows'),
(r'^donate/$', RedirectView.as_view('https://wiki.parabola.nu/Donations'),
{}, 'page-donate'),
(r'^download/$', RedirectView.as_view('https://wiki.parabola.nu/Get_Parabola'),
{}, 'page-download'),
(r'^master-keys/$', 'keys', {}, 'page-keys'),
(r'^master-keys/json/$', 'keys_json', {}, 'pgp-keys-json'),
+ (r'^people/(?P<slug>[-\w]+)/$', 'people', {}, 'people'),
)
# Feeds patterns, used below
@@ -94,15 +93,18 @@ urlpatterns += patterns('django.contrib.auth.views',
legacy_urls = (
('^about.php', '/about/'),
('^changelog.php', '/packages/?sort=-last_update'),
- ('^devs.php', '/developers/'),
+ ('^devs.php', '/people/developers/'),
('^donations.php', '/donate/'),
('^download.php', '/download/'),
('^index.php', '/'),
('^logos.php', '/art/'),
('^news.php', '/news/'),
('^packages.php', '/packages/'),
- ('^people.php', '/developers/'),
+ ('^people.php', '/people/developers/'),
('^todolists/$', '/todo/'),
+ ('^developers/$', '/people/developers/'),
+ ('^fellows/$', '/people/developer-fellows/'),
+ ('^trustedusers/$', '/people/trusted-users/'),
('^docs/en/guide/install/arch-install-guide.html',
'https://wiki.parabola.nu/Installation_Guide'),