summaryrefslogtreecommitdiff
path: root/pgcommitfest/commitfest
diff options
context:
space:
mode:
authorMagnus Hagander2019-02-05 22:55:23 +0000
committerMagnus Hagander2019-02-06 09:29:00 +0000
commit463b3c1fe2e5bea061269ed9eea4b876a9eab213 (patch)
treec7f6f057b238434b4865129e2a4f61312be4d274 /pgcommitfest/commitfest
parenta32f4007670330d05a834db1b67687ab8b8c3b34 (diff)
Fixes for pep8 compatibility
Diffstat (limited to 'pgcommitfest/commitfest')
-rw-r--r--pgcommitfest/commitfest/admin.py8
-rw-r--r--pgcommitfest/commitfest/ajax.py62
-rw-r--r--pgcommitfest/commitfest/feeds.py3
-rw-r--r--pgcommitfest/commitfest/forms.py16
-rw-r--r--pgcommitfest/commitfest/lookups.py1
-rw-r--r--pgcommitfest/commitfest/management/commands/send_notifications.py5
-rw-r--r--pgcommitfest/commitfest/models.py59
-rw-r--r--pgcommitfest/commitfest/reports.py13
-rw-r--r--pgcommitfest/commitfest/templatetags/commitfest.py10
-rw-r--r--pgcommitfest/commitfest/util.py7
-rw-r--r--pgcommitfest/commitfest/views.py89
-rw-r--r--pgcommitfest/commitfest/widgets.py1
12 files changed, 167 insertions, 107 deletions
diff --git a/pgcommitfest/commitfest/admin.py b/pgcommitfest/commitfest/admin.py
index 232ba30..3ac72a0 100644
--- a/pgcommitfest/commitfest/admin.py
+++ b/pgcommitfest/commitfest/admin.py
@@ -2,21 +2,25 @@ from django.contrib import admin
from models import *
+
class CommitterAdmin(admin.ModelAdmin):
list_display = ('user', 'active')
+
class PatchOnCommitFestInline(admin.TabularInline):
model = PatchOnCommitFest
- extra=1
+ extra = 1
+
class PatchAdmin(admin.ModelAdmin):
inlines = (PatchOnCommitFestInline,)
list_display = ('name', )
-# list_filter = ('commitfests_set__commitfest__name',)
+
class MailThreadAttachmentAdmin(admin.ModelAdmin):
list_display = ('date', 'author', 'messageid', 'mailthread',)
+
admin.site.register(Committer, CommitterAdmin)
admin.site.register(CommitFest)
admin.site.register(Topic)
diff --git a/pgcommitfest/commitfest/ajax.py b/pgcommitfest/commitfest/ajax.py
index b8317f5..71b3ee8 100644
--- a/pgcommitfest/commitfest/ajax.py
+++ b/pgcommitfest/commitfest/ajax.py
@@ -10,27 +10,30 @@ import requests
import json
from pgcommitfest.auth import user_search
+from models import CommitFest, Patch, MailThread, MailThreadAttachment
+from models import MailThreadAnnotation, PatchHistory
+
-class HttpResponseServiceUnavailable(HttpResponse):
+class HttpResponseServiceUnavailable(HttpResponse):
status_code = 503
+
class Http503(Exception):
pass
-from models import CommitFest, Patch, MailThread, MailThreadAttachment
-from models import MailThreadAnnotation, PatchHistory
def _archivesAPI(suburl, params=None):
try:
- resp = requests.get("http{0}://{1}:{2}{3}".format(settings.ARCHIVES_PORT == 443 and 's' or '',
- settings.ARCHIVES_SERVER,
- settings.ARCHIVES_PORT,
- suburl),
- params=params,
- headers={
- 'Host': settings.ARCHIVES_HOST,
- },
- timeout=settings.ARCHIVES_TIMEOUT,
+ resp = requests.get(
+ "http{0}://{1}:{2}{3}".format(settings.ARCHIVES_PORT == 443 and 's' or '',
+ settings.ARCHIVES_SERVER,
+ settings.ARCHIVES_PORT,
+ suburl),
+ params=params,
+ headers={
+ 'Host': settings.ARCHIVES_HOST,
+ },
+ timeout=settings.ARCHIVES_TIMEOUT,
)
if resp.status_code != 200:
if resp.status_code == 404:
@@ -43,9 +46,10 @@ def _archivesAPI(suburl, params=None):
except Exception as e:
raise Http503("Failed to communicate with archives backend: %s" % e)
+
def getThreads(request):
- search = request.GET.has_key('s') and request.GET['s'] or None
- if request.GET.has_key('a') and request.GET['a'] == "1":
+ search = request.GET.get('s', None)
+ if request.GET.get('a', '0') == '1':
attachonly = 1
else:
attachonly = 0
@@ -58,6 +62,7 @@ def getThreads(request):
r = _archivesAPI('/list/pgsql-hackers/latest.json', params)
return sorted(r, key=lambda x: x['date'], reverse=True)
+
def getMessages(request):
threadid = request.GET['t']
@@ -67,6 +72,7 @@ def getMessages(request):
r = _archivesAPI('/message-id.json/%s' % thread.messageid)
return sorted(r, key=lambda x: x['date'], reverse=True)
+
def refresh_single_thread(thread):
r = sorted(_archivesAPI('/message-id.json/%s' % thread.messageid), key=lambda x: x['date'])
if thread.latestmsgid != r[-1]['msgid']:
@@ -83,6 +89,7 @@ def refresh_single_thread(thread):
p.lastmail = thread.latestmessage
p.save()
+
@transaction.atomic
def annotateMessage(request):
thread = get_object_or_404(MailThread, pk=int(request.POST['t']))
@@ -112,6 +119,7 @@ def annotateMessage(request):
return 'OK'
return 'Message not found in thread!'
+
@transaction.atomic
def deleteAnnotation(request):
annotation = get_object_or_404(MailThreadAnnotation, pk=request.POST['id'])
@@ -125,6 +133,7 @@ def deleteAnnotation(request):
return 'OK'
+
def parse_and_add_attachments(threadinfo, mailthread):
for t in threadinfo:
if len(t['atts']):
@@ -142,6 +151,7 @@ def parse_and_add_attachments(threadinfo, mailthread):
# In theory we should remove objects if they don't have an
# attachment, but how could that ever happen? Ignore for now.
+
@transaction.atomic
def attachThread(request):
cf = get_object_or_404(CommitFest, pk=int(request.POST['cf']))
@@ -150,6 +160,7 @@ def attachThread(request):
return doAttachThread(cf, patch, msgid, request.user)
+
def doAttachThread(cf, patch, msgid, user):
# Note! Must be called in an open transaction!
r = sorted(_archivesAPI('/message-id.json/%s' % msgid), key=lambda x: x['date'])
@@ -166,10 +177,10 @@ def doAttachThread(cf, patch, msgid, user):
# While at it, we update the thread entry with the latest data from the
# archives.
thread.patches.add(patch)
- thread.latestmessage=r[-1]['date']
- thread.latestauthor=r[-1]['from']
- thread.latestsubject=r[-1]['subj']
- thread.latestmsgid=r[-1]['msgid']
+ thread.latestmessage = r[-1]['date']
+ thread.latestauthor = r[-1]['from']
+ thread.latestsubject = r[-1]['subj']
+ thread.latestmsgid = r[-1]['msgid']
thread.save()
else:
# No existing thread existed, so create it
@@ -195,6 +206,7 @@ def doAttachThread(cf, patch, msgid, user):
return 'OK'
+
@transaction.atomic
def detachThread(request):
cf = get_object_or_404(CommitFest, pk=int(request.POST['cf']))
@@ -209,16 +221,18 @@ def detachThread(request):
return 'OK'
+
def searchUsers(request):
- if request.GET.has_key('s') and request.GET['s']:
+ if request.GET.get('s', ''):
return user_search(request.GET['s'])
else:
return []
+
def importUser(request):
- if request.GET.has_key('u') and request.GET['u']:
+ if request.GET.get('u', ''):
u = user_search(userid=request.GET['u'])
- if len (u) != 1:
+ if len(u) != 1:
return "Internal error, duplicate user found"
u = u[0]
@@ -235,7 +249,8 @@ def importUser(request):
else:
raise Http404()
-_ajax_map={
+
+_ajax_map = {
'getThreads': getThreads,
'getMessages': getMessages,
'attachThread': attachThread,
@@ -246,11 +261,12 @@ _ajax_map={
'importUser': importUser,
}
+
# Main entrypoint for /ajax/<command>/
@csrf_exempt
@login_required
def main(request, command):
- if not _ajax_map.has_key(command):
+ if command not in _ajax_map:
raise Http404
try:
resp = HttpResponse(content_type='application/json')
diff --git a/pgcommitfest/commitfest/feeds.py b/pgcommitfest/commitfest/feeds.py
index d858703..cd206ac 100644
--- a/pgcommitfest/commitfest/feeds.py
+++ b/pgcommitfest/commitfest/feeds.py
@@ -1,5 +1,6 @@
from django.contrib.syndication.views import Feed
+
class ActivityFeed(Feed):
title = description = 'Commitfest Activity Log'
link = 'https://commitfest.postgresql.org/'
@@ -30,7 +31,7 @@ class ActivityFeed(Feed):
def item_link(self, item):
if self.cfid:
- return 'https://commitfest.postgresql.org/{cfid}/{patchid}/'.format(cfid=self.cfid,**item)
+ return 'https://commitfest.postgresql.org/{cfid}/{patchid}/'.format(cfid=self.cfid, **item)
else:
return 'https://commitfest.postgresql.org/{cfid}/{patchid}/'.format(**item)
diff --git a/pgcommitfest/commitfest/forms.py b/pgcommitfest/commitfest/forms.py
index a341f99..ab8a14f 100644
--- a/pgcommitfest/commitfest/forms.py
+++ b/pgcommitfest/commitfest/forms.py
@@ -12,6 +12,7 @@ from lookups import UserLookup
from widgets import ThreadPickWidget
from ajax import _archivesAPI
+
class CommitFestFilterForm(forms.Form):
text = forms.CharField(max_length=50, required=False)
status = forms.ChoiceField(required=False)
@@ -28,13 +29,14 @@ class CommitFestFilterForm(forms.Form):
self.fields['status'] = forms.ChoiceField(choices=c, required=False)
q = Q(patch_author__commitfests=cf) | Q(patch_reviewer__commitfests=cf)
- userchoices = [(-1, '* All'), (-2, '* None'), (-3, '* Yourself') ] + [(u.id, '%s %s (%s)' % (u.first_name, u.last_name, u.username)) for u in User.objects.filter(q).distinct().order_by('first_name', 'last_name')]
+ userchoices = [(-1, '* All'), (-2, '* None'), (-3, '* Yourself')] + [(u.id, '%s %s (%s)' % (u.first_name, u.last_name, u.username)) for u in User.objects.filter(q).distinct().order_by('first_name', 'last_name')]
self.fields['author'] = forms.ChoiceField(choices=userchoices, required=False)
self.fields['reviewer'] = forms.ChoiceField(choices=userchoices, required=False)
for f in ('status', 'author', 'reviewer',):
self.fields[f].widget.attrs = {'class': 'input-medium'}
+
class PatchForm(forms.ModelForm):
class Meta:
model = Patch
@@ -68,11 +70,12 @@ class NewPatchForm(forms.ModelForm):
raise ValidationError("Error in API call to validate thread")
return self.cleaned_data['threadmsgid']
+
def _fetch_thread_choices(patch):
for mt in patch.mailthread_set.order_by('-latestmessage'):
ti = sorted(_archivesAPI('/message-id.json/%s' % mt.messageid), key=lambda x: x['date'], reverse=True)
yield [mt.subject,
- [('%s,%s' % (mt.messageid, t['msgid']),'From %s at %s' % (t['from'], t['date'])) for t in ti]]
+ [('%s,%s' % (mt.messageid, t['msgid']), 'From %s at %s' % (t['from'], t['date'])) for t in ti]]
review_state_choices = (
@@ -80,9 +83,11 @@ review_state_choices = (
(1, 'Passed'),
)
+
def reviewfield(label):
return forms.MultipleChoiceField(choices=review_state_choices, label=label, widget=forms.CheckboxSelectMultiple, required=False)
+
class CommentForm(forms.Form):
responseto = forms.ChoiceField(choices=[], required=True, label='In response to')
@@ -120,12 +125,13 @@ class CommentForm(forms.Form):
def clean(self):
if self.is_review:
- for fn,f in self.fields.items():
- if fn.startswith('review_') and self.cleaned_data.has_key(fn):
- if '1' in self.cleaned_data[fn] and not '0' in self.cleaned_data[fn]:
+ for fn, f in self.fields.items():
+ if fn.startswith('review_') and fn in self.cleaned_data:
+ if '1' in self.cleaned_data[fn] and '0' not in self.cleaned_data[fn]:
self.errors[fn] = (('Cannot pass a test without performing it!'),)
return self.cleaned_data
+
class BulkEmailForm(forms.Form):
reviewers = forms.CharField(required=False, widget=HiddenInput())
authors = forms.CharField(required=False, widget=HiddenInput())
diff --git a/pgcommitfest/commitfest/lookups.py b/pgcommitfest/commitfest/lookups.py
index 1cb567f..7297ccc 100644
--- a/pgcommitfest/commitfest/lookups.py
+++ b/pgcommitfest/commitfest/lookups.py
@@ -22,4 +22,5 @@ class UserLookup(ModelLookup):
# Display for choice listings
return u"%s (%s)" % (item.username, item.get_full_name())
+
registry.register(UserLookup)
diff --git a/pgcommitfest/commitfest/management/commands/send_notifications.py b/pgcommitfest/commitfest/management/commands/send_notifications.py
index be8cd90..d181712 100644
--- a/pgcommitfest/commitfest/management/commands/send_notifications.py
+++ b/pgcommitfest/commitfest/management/commands/send_notifications.py
@@ -8,6 +8,7 @@ from pgcommitfest.commitfest.models import PendingNotification
from pgcommitfest.userprofile.models import UserProfile
from pgcommitfest.mailqueue.util import send_template_mail
+
class Command(BaseCommand):
help = "Send queued notifications"
@@ -17,9 +18,9 @@ class Command(BaseCommand):
# build our own.
matches = {}
for n in PendingNotification.objects.all().order_by('user', 'history__patch__id', 'history__id'):
- if not matches.has_key(n.user.id):
+ if n.user.id not in matches:
matches[n.user.id] = {'user': n.user, 'patches': {}}
- if not matches[n.user.id]['patches'].has_key(n.history.patch.id):
+ if n.history.patch.id not in matches[n.user.id]['patches']:
matches[n.user.id]['patches'][n.history.patch.id] = {'patch': n.history.patch, 'entries': []}
matches[n.user.id]['patches'][n.history.patch.id]['entries'].append(n.history)
n.delete()
diff --git a/pgcommitfest/commitfest/models.py b/pgcommitfest/commitfest/models.py
index 1cc694e..5687561 100644
--- a/pgcommitfest/commitfest/models.py
+++ b/pgcommitfest/commitfest/models.py
@@ -7,6 +7,7 @@ from util import DiffableModel
from pgcommitfest.userprofile.models import UserProfile
+
# We have few enough of these, and it's really the only thing we
# need to extend from the user model, so just create a separate
# class.
@@ -24,17 +25,18 @@ class Committer(models.Model):
class Meta:
ordering = ('user__last_name', 'user__first_name')
+
class CommitFest(models.Model):
- STATUS_FUTURE=1
- STATUS_OPEN=2
- STATUS_INPROGRESS=3
- STATUS_CLOSED=4
+ STATUS_FUTURE = 1
+ STATUS_OPEN = 2
+ STATUS_INPROGRESS = 3
+ STATUS_CLOSED = 4
_STATUS_CHOICES = (
(STATUS_FUTURE, 'Future'),
(STATUS_OPEN, 'Open'),
(STATUS_INPROGRESS, 'In Progress'),
(STATUS_CLOSED, 'Closed'),
- )
+ )
name = models.CharField(max_length=100, blank=False, null=False, unique=True)
status = models.IntegerField(null=False, blank=False, default=1, choices=_STATUS_CHOICES)
startdate = models.DateField(blank=True, null=True)
@@ -42,7 +44,7 @@ class CommitFest(models.Model):
@property
def statusstring(self):
- return [v for k,v in self._STATUS_CHOICES if k==self.status][0]
+ return [v for k, v in self._STATUS_CHOICES if k == self.status][0]
@property
def periodstring(self):
@@ -62,9 +64,10 @@ class CommitFest(models.Model):
return self.name
class Meta:
- verbose_name_plural='Commitfests'
+ verbose_name_plural = 'Commitfests'
ordering = ('-startdate',)
+
class Topic(models.Model):
topic = models.CharField(max_length=100, blank=False, null=False)
@@ -85,9 +88,6 @@ class Patch(models.Model, DiffableModel):
# If there is a git repo about this patch
gitlink = models.URLField(blank=True, null=False, default='')
- # Mailthreads are ManyToMany in the other direction
- #mailthreads_set = ...
-
authors = models.ManyToManyField(User, related_name='patch_author', blank=True)
reviewers = models.ManyToManyField(User, related_name='patch_reviewer', blank=True)
@@ -107,7 +107,8 @@ class Patch(models.Model, DiffableModel):
map_manytomany_for_diff = {
'authors': 'authors_string',
'reviewers': 'reviewers_string',
- }
+ }
+
# Some accessors
@property
def authors_string(self):
@@ -139,7 +140,7 @@ class Patch(models.Model, DiffableModel):
if len(threads) == 0:
self.lastmail = None
else:
- self.lastmail = max(threads, key=lambda t:t.latestmessage).latestmessage
+ self.lastmail = max(threads, key=lambda t: t.latestmessage).latestmessage
def __unicode__(self):
return self.name
@@ -147,20 +148,21 @@ class Patch(models.Model, DiffableModel):
class Meta:
verbose_name_plural = 'patches'
+
class PatchOnCommitFest(models.Model):
# NOTE! This is also matched by the commitfest_patchstatus table,
# but we hardcoded it in here simply for performance reasons since
# the data should be entirely static. (Yes, that's something we
# might re-evaluate in the future)
- STATUS_REVIEW=1
- STATUS_AUTHOR=2
- STATUS_COMMITTER=3
- STATUS_COMMITTED=4
- STATUS_NEXT=5
- STATUS_REJECTED=6
- STATUS_RETURNED=7
- STATUS_WITHDRAWN=8
- _STATUS_CHOICES=(
+ STATUS_REVIEW = 1
+ STATUS_AUTHOR = 2
+ STATUS_COMMITTER = 3
+ STATUS_COMMITTED = 4
+ STATUS_NEXT = 5
+ STATUS_REJECTED = 6
+ STATUS_RETURNED = 7
+ STATUS_WITHDRAWN = 8
+ _STATUS_CHOICES = (
(STATUS_REVIEW, 'Needs review'),
(STATUS_AUTHOR, 'Waiting on Author'),
(STATUS_COMMITTER, 'Ready for Committer'),
@@ -170,7 +172,7 @@ class PatchOnCommitFest(models.Model):
(STATUS_RETURNED, 'Returned with feedback'),
(STATUS_WITHDRAWN, 'Withdrawn'),
)
- _STATUS_LABELS=(
+ _STATUS_LABELS = (
(STATUS_REVIEW, 'default'),
(STATUS_AUTHOR, 'primary'),
(STATUS_COMMITTER, 'info'),
@@ -180,8 +182,8 @@ class PatchOnCommitFest(models.Model):
(STATUS_RETURNED, 'danger'),
(STATUS_WITHDRAWN, 'danger'),
)
- OPEN_STATUSES=[STATUS_REVIEW, STATUS_AUTHOR, STATUS_COMMITTER]
- OPEN_STATUS_CHOICES=[x for x in _STATUS_CHOICES if x[0] in OPEN_STATUSES]
+ OPEN_STATUSES = [STATUS_REVIEW, STATUS_AUTHOR, STATUS_COMMITTER]
+ OPEN_STATUS_CHOICES = [x for x in _STATUS_CHOICES if x[0] in OPEN_STATUSES]
patch = models.ForeignKey(Patch, blank=False, null=False)
commitfest = models.ForeignKey(CommitFest, blank=False, null=False)
@@ -196,12 +198,13 @@ class PatchOnCommitFest(models.Model):
@property
def statusstring(self):
- return [v for k,v in self._STATUS_CHOICES if k==self.status][0]
+ return [v for k, v in self._STATUS_CHOICES if k == self.status][0]
class Meta:
unique_together = (('patch', 'commitfest',),)
ordering = ('-commitfest__startdate', )
+
class PatchHistory(models.Model):
patch = models.ForeignKey(Patch, blank=False, null=False)
date = models.DateTimeField(blank=False, null=False, auto_now_add=True)
@@ -250,9 +253,10 @@ class PatchHistory(models.Model):
recipients.extend(self.patch.authors.filter(userprofile__notify_all_author=True))
for u in set(recipients):
- if u != self.by: # Don't notify for changes we make ourselves
+ if u != self.by: # Don't notify for changes we make ourselves
PendingNotification(history=self, user=u).save()
+
class MailThread(models.Model):
# This class tracks mail threads from the main postgresql.org
# mailinglist archives. For each thread, we store *one* messageid.
@@ -279,6 +283,7 @@ class MailThread(models.Model):
class Meta:
ordering = ('firstmessage', )
+
class MailThreadAttachment(models.Model):
mailthread = models.ForeignKey(MailThread, null=False, blank=False)
messageid = models.CharField(max_length=1000, null=False, blank=False)
@@ -292,6 +297,7 @@ class MailThreadAttachment(models.Model):
ordering = ('-date',)
unique_together = (('mailthread', 'messageid',), )
+
class MailThreadAnnotation(models.Model):
mailthread = models.ForeignKey(MailThread, null=False, blank=False)
date = models.DateTimeField(null=False, blank=False, auto_now_add=True)
@@ -309,6 +315,7 @@ class MailThreadAnnotation(models.Model):
class Meta:
ordering = ('date', )
+
class PatchStatus(models.Model):
status = models.IntegerField(null=False, blank=False, primary_key=True)
statusstring = models.TextField(max_length=50, null=False, blank=False)
diff --git a/pgcommitfest/commitfest/reports.py b/pgcommitfest/commitfest/reports.py
index 4645856..aae1bba 100644
--- a/pgcommitfest/commitfest/reports.py
+++ b/pgcommitfest/commitfest/reports.py
@@ -6,6 +6,7 @@ from django.db import connection
from models import CommitFest
+
@login_required
def authorstats(request, cfid):
cf = get_object_or_404(CommitFest, pk=cfid)
@@ -13,7 +14,8 @@ def authorstats(request, cfid):
raise Http404("Only CF Managers can do that.")
cursor = connection.cursor()
- cursor.execute("""WITH patches(id,name) AS (
+ cursor.execute("""
+WITH patches(id,name) AS (
SELECT p.id, name
FROM commitfest_patch p
INNER JOIN commitfest_patchoncommitfest poc ON poc.patch_id=p.id AND poc.commitfest_id=%(cid)s
@@ -34,13 +36,14 @@ SELECT first_name || ' ' || last_name || ' (' || username ||')', authorpatches,
FROM (authors FULL OUTER JOIN reviewers ON authors.userid=reviewers.userid)
INNER JOIN auth_user u ON u.id=COALESCE(authors.userid, reviewers.userid)
ORDER BY last_name, first_name
-""", {
- 'cid': cf.id,
-})
+""",
+ {
+ 'cid': cf.id,
+ })
return render(request, 'report_authors.html', {
'cf': cf,
'report': cursor.fetchall(),
'title': 'Author stats',
- 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},],
+ 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk}, ],
})
diff --git a/pgcommitfest/commitfest/templatetags/commitfest.py b/pgcommitfest/commitfest/templatetags/commitfest.py
index bde7d07..c51765d 100644
--- a/pgcommitfest/commitfest/templatetags/commitfest.py
+++ b/pgcommitfest/commitfest/templatetags/commitfest.py
@@ -5,26 +5,31 @@ from pgcommitfest.commitfest.models import PatchOnCommitFest
register = template.Library()
+
@register.filter(name='patchstatusstring')
@stringfilter
def patchstatusstring(value):
i = int(value)
- return [v for k,v in PatchOnCommitFest._STATUS_CHOICES if k==i][0]
+ return [v for k, v in PatchOnCommitFest._STATUS_CHOICES if k == i][0]
+
@register.filter(name='patchstatuslabel')
@stringfilter
def patchstatuslabel(value):
i = int(value)
- return [v for k,v in PatchOnCommitFest._STATUS_LABELS if k==i][0]
+ return [v for k, v in PatchOnCommitFest._STATUS_LABELS if k == i][0]
+
@register.filter(is_safe=True)
def label_class(value, arg):
return value.label_tag(attrs={'class': arg})
+
@register.filter(is_safe=True)
def field_class(value, arg):
return value.as_widget(attrs={"class": arg})
+
@register.filter(name='alertmap')
@stringfilter
def alertmap(value):
@@ -37,6 +42,7 @@ def alertmap(value):
else:
return 'alert-info'
+
@register.filter(name='hidemail')
@stringfilter
def hidemail(value):
diff --git a/pgcommitfest/commitfest/util.py b/pgcommitfest/commitfest/util.py
index 4698879..94ad3e5 100644
--- a/pgcommitfest/commitfest/util.py
+++ b/pgcommitfest/commitfest/util.py
@@ -18,15 +18,15 @@ class DiffableModel(object):
d2 = self._dict
diffs = dict([(k, (v, d2[k])) for k, v in d1.items() if v != d2[k]])
# Foreign key lookups
- for k,v in diffs.items():
+ for k, v in diffs.items():
if type(self._meta.get_field(k)) is django.db.models.fields.related.ForeignKey:
# If it's a foreign key, look up the name again on ourselves.
# Since we only care about the *new* value, it's easy enough.
diffs[k] = (v[0], getattr(self, k))
# Many to many lookups
if hasattr(self, 'map_manytomany_for_diff'):
- for k,v in diffs.items():
- if k in manytomanyfieldnames and self.map_manytomany_for_diff.has_key(k):
+ for k, v in diffs.items():
+ if k in manytomanyfieldnames and k in self.map_manytomany_for_diff:
# Try to show the display name instead here
newvalue = getattr(self, self.map_manytomany_for_diff[k])
diffs[k] = (v[0], newvalue)
@@ -41,4 +41,3 @@ class DiffableModel(object):
fields = [field.name for field in self._meta.fields]
fields.extend([field.name for field in self._meta.many_to_many])
return model_to_dict(self, fields=fields)
-
diff --git a/pgcommitfest/commitfest/views.py b/pgcommitfest/commitfest/views.py
index 705b172..7835f5e 100644
--- a/pgcommitfest/commitfest/views.py
+++ b/pgcommitfest/commitfest/views.py
@@ -26,6 +26,7 @@ from forms import BulkEmailForm
from ajax import doAttachThread, refresh_single_thread
from feeds import ActivityFeed
+
def home(request):
commitfests = list(CommitFest.objects.all())
opencf = next((c for c in commitfests if c.status == CommitFest.STATUS_OPEN), None)
@@ -38,7 +39,7 @@ def home(request):
'title': 'Commitfests',
'header_activity': 'Activity log',
'header_activity_link': '/activity/',
- })
+ })
def activity(request, cfid=None, rss=None):
@@ -62,11 +63,11 @@ def activity(request, cfid=None, rss=None):
extrafields = ',poc.commitfest_id AS cfid,cf.name AS cfname'
where = ' INNER JOIN commitfest_commitfest cf ON cf.id=poc.commitfest_id'
- sql = "SELECT ph.date, auth_user.username AS by, ph.what, p.id AS patchid, p.name{0} FROM commitfest_patchhistory ph INNER JOIN commitfest_patch p ON ph.patch_id=p.id INNER JOIN auth_user on auth_user.id=ph.by_id INNER JOIN commitfest_patchoncommitfest poc ON poc.patch_id=p.id {1} ORDER BY ph.date DESC LIMIT {2}".format(extrafields,where, num)
+ sql = "SELECT ph.date, auth_user.username AS by, ph.what, p.id AS patchid, p.name{0} FROM commitfest_patchhistory ph INNER JOIN commitfest_patch p ON ph.patch_id=p.id INNER JOIN auth_user on auth_user.id=ph.by_id INNER JOIN commitfest_patchoncommitfest poc ON poc.patch_id=p.id {1} ORDER BY ph.date DESC LIMIT {2}".format(extrafields, where, num)
curs = connection.cursor()
curs.execute(sql)
- activity = [dict(zip([c[0] for c in curs.description],r)) for r in curs.fetchall()]
+ activity = [dict(zip([c[0] for c in curs.description], r)) for r in curs.fetchall()]
if rss:
# Return RSS feed with these objects
@@ -79,9 +80,10 @@ def activity(request, cfid=None, rss=None):
'title': cf and 'Commitfest activity' or 'Global Commitfest activity',
'rss_alternate': cf and '/{0}/activity.rss/'.format(cf.id) or '/activity.rss/',
'rss_alternate_title': 'PostgreSQL Commitfest Activity Log',
- 'breadcrumbs': cf and [{'title': cf.title, 'href': '/%s/' % cf.pk},] or None,
+ 'breadcrumbs': cf and [{'title': cf.title, 'href': '/%s/' % cf.pk}, ] or None,
})
+
def redir(request, what):
if what == 'open':
cfs = list(CommitFest.objects.filter(status=CommitFest.STATUS_OPEN))
@@ -99,6 +101,7 @@ def redir(request, what):
return HttpResponseRedirect("/%s/" % cfs[0].id)
+
def commitfest(request, cfid):
# Find ourselves
cf = get_object_or_404(CommitFest, pk=cfid)
@@ -106,7 +109,7 @@ def commitfest(request, cfid):
# Build a dynamic filter based on the filtering options entered
whereclauses = []
whereparams = {}
- if request.GET.has_key('status') and request.GET['status'] != "-1":
+ if request.GET.get('status', '-1') != '-1':
try:
whereparams['status'] = int(request.GET['status'])
whereclauses.append("poc.status=%(status)s")
@@ -114,7 +117,7 @@ def commitfest(request, cfid):
# int() failed -- so just ignore this filter
pass
- if request.GET.has_key('author') and request.GET['author'] != "-1":
+ if request.GET.get('author', '-1') != '-1':
if request.GET['author'] == '-2':
whereclauses.append("NOT EXISTS (SELECT 1 FROM commitfest_patch_authors cpa WHERE cpa.patch_id=p.id)")
elif request.GET['author'] == '-3':
@@ -131,7 +134,7 @@ def commitfest(request, cfid):
# int() failed -- so just ignore this filter
pass
- if request.GET.has_key('reviewer') and request.GET['reviewer'] != "-1":
+ if request.GET.get('reviewer', '-1') != '-1':
if request.GET['reviewer'] == '-2':
whereclauses.append("NOT EXISTS (SELECT 1 FROM commitfest_patch_reviewers cpr WHERE cpr.patch_id=p.id)")
elif request.GET['reviewer'] == '-3':
@@ -148,33 +151,33 @@ def commitfest(request, cfid):
# int() failed -- so just ignore this filter
pass
- if request.GET.has_key('text') and request.GET['text'] != '':
+ if request.GET.get('text', '') != '':
whereclauses.append("p.name ILIKE '%%' || %(txt)s || '%%'")
whereparams['txt'] = request.GET['text']
has_filter = len(whereclauses) > 0
# Figure out custom ordering
- if request.GET.has_key('sortkey') and request.GET['sortkey']!='':
+ if request.GET.get('sortkey', '') != '':
try:
- sortkey=int(request.GET['sortkey'])
+ sortkey = int(request.GET['sortkey'])
except ValueError:
- sortkey=0
+ sortkey = 0
- if sortkey==1:
+ if sortkey == 1:
orderby_str = 'modified, created'
- elif sortkey==2:
+ elif sortkey == 2:
orderby_str = 'lastmail, created'
- elif sortkey==3:
+ elif sortkey == 3:
orderby_str = 'num_cfs DESC, modified, created'
else:
orderby_str = 'p.id'
- sortkey=0
+ sortkey = 0
else:
orderby_str = 'topic, created'
sortkey = 0
- if not has_filter and sortkey==0 and request.GET:
+ if not has_filter and sortkey == 0 and request.GET:
# Redirect to get rid of the ugly url
return HttpResponseRedirect('/%s/' % cf.id)
@@ -208,7 +211,7 @@ ORDER BY is_open DESC, {1}""".format(where_str, orderby_str), params)
curs = connection.cursor()
curs.execute("SELECT ps.status, ps.statusstring, count(*) FROM commitfest_patchoncommitfest poc INNER JOIN commitfest_patchstatus ps ON ps.status=poc.status WHERE commitfest_id=%(id)s GROUP BY ps.status ORDER BY ps.sortkey", {
'id': cf.id,
- })
+ })
statussummary = curs.fetchall()
statussummary.append([-1, 'Total', sum((r[2] for r in statussummary))])
@@ -223,15 +226,16 @@ ORDER BY is_open DESC, {1}""".format(where_str, orderby_str), params)
'statussummary': statussummary,
'has_filter': has_filter,
'title': cf.title,
- 'grouping': sortkey==0,
+ 'grouping': sortkey == 0,
'sortkey': sortkey,
'openpatchids': [p['id'] for p in patches if p['is_open']],
'header_activity': 'Activity log',
'header_activity_link': 'activity/',
- })
+ })
+
def global_search(request):
- if not request.GET.has_key('searchterm'):
+ if 'searchterm' not in request.GET:
return HttpResponseRedirect('/')
searchterm = request.GET['searchterm']
@@ -240,7 +244,8 @@ def global_search(request):
return render(request, 'patchsearch.html', {
'patches': patches,
'title': 'Patch search results',
- })
+ })
+
def patch(request, cfid, patchid):
cf = get_object_or_404(CommitFest, pk=cfid)
@@ -248,12 +253,12 @@ def patch(request, cfid, patchid):
patch_commitfests = PatchOnCommitFest.objects.select_related('commitfest').filter(patch=patch).order_by('-commitfest__startdate')
committers = Committer.objects.filter(active=True).order_by('user__last_name', 'user__first_name')
- #XXX: this creates a session, so find a smarter way. Probably handle
- #it in the callback and just ask the user then?
+ # XXX: this creates a session, so find a smarter way. Probably handle
+ # it in the callback and just ask the user then?
if request.user.is_authenticated():
- committer = [c for c in committers if c.user==request.user]
+ committer = [c for c in committers if c.user == request.user]
if len(committer) > 0:
- is_committer= True
+ is_committer = True
is_this_committer = committer[0] == patch.committer
else:
is_committer = is_this_committer = False
@@ -275,10 +280,11 @@ def patch(request, cfid, patchid):
'is_reviewer': is_reviewer,
'is_subscribed': is_subscribed,
'committers': committers,
- 'attachnow': request.GET.has_key('attachthreadnow'),
+ 'attachnow': 'attachthreadnow' in request.GET,
'title': patch.name,
- 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},],
- })
+ 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk}, ],
+ })
+
@login_required
@transaction.atomic
@@ -318,6 +324,7 @@ def patchform(request, cfid, patchid):
{'title': 'View patch', 'href': '/%s/%s/' % (cf.pk, patch.pk)}],
})
+
@login_required
@transaction.atomic
def newpatch(request, cfid):
@@ -354,11 +361,12 @@ def newpatch(request, cfid):
return render(request, 'base_form.html', {
'form': form,
'title': 'New patch',
- 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},],
+ 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk}, ],
'savebutton': 'Create patch',
'threadbrowse': True,
})
+
def _review_status_string(reviewstatus):
if '0' in reviewstatus:
if '1' in reviewstatus:
@@ -368,13 +376,14 @@ def _review_status_string(reviewstatus):
else:
return "not tested"
+
@login_required
@transaction.atomic
def comment(request, cfid, patchid, what):
cf = get_object_or_404(CommitFest, pk=cfid)
patch = get_object_or_404(Patch, pk=patchid)
poc = get_object_or_404(PatchOnCommitFest, patch=patch, commitfest=cf)
- is_review = (what=='review')
+ is_review = (what == 'review')
if poc.is_closed:
# We allow modification of patches in closed CFs *only* if it's the
@@ -464,6 +473,7 @@ def comment(request, cfid, patchid, what):
'savebutton': 'Send %s' % what,
})
+
@login_required
@transaction.atomic
def status(request, cfid, patchid, status):
@@ -551,7 +561,7 @@ def close(request, cfid, patchid, status):
# future one.
newcf = CommitFest.objects.filter(status=CommitFest.STATUS_FUTURE)
if len(newcf) == 0:
- messages.error(request,"No open and no future commitfest exists!")
+ messages.error(request, "No open and no future commitfest exists!")
return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
elif len(newcf) != 1:
messages.error(request, "No open and multiple future commitfests exist!")
@@ -596,6 +606,7 @@ def close(request, cfid, patchid, status):
return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
+
@login_required
@transaction.atomic
def reviewer(request, cfid, patchid, status):
@@ -604,16 +615,17 @@ def reviewer(request, cfid, patchid, status):
is_reviewer = request.user in patch.reviewers.all()
- if status=='become' and not is_reviewer:
+ if status == 'become' and not is_reviewer:
patch.reviewers.add(request.user)
patch.set_modified()
PatchHistory(patch=patch, by=request.user, what='Added %s as reviewer' % request.user.username).save_and_notify()
- elif status=='remove' and is_reviewer:
+ elif status == 'remove' and is_reviewer:
patch.reviewers.remove(request.user)
patch.set_modified()
PatchHistory(patch=patch, by=request.user, what='Removed %s from reviewers' % request.user.username).save_and_notify()
return HttpResponseRedirect('../../')
+
@login_required
@transaction.atomic
def committer(request, cfid, patchid, status):
@@ -628,17 +640,18 @@ def committer(request, cfid, patchid, status):
is_committer = committer == patch.committer
prevcommitter = patch.committer
- if status=='become' and not is_committer:
+ if status == 'become' and not is_committer:
patch.committer = committer
patch.set_modified()
PatchHistory(patch=patch, by=request.user, what='Added %s as committer' % request.user.username).save_and_notify(prevcommitter=prevcommitter)
- elif status=='remove' and is_committer:
+ elif status == 'remove' and is_committer:
patch.committer = None
patch.set_modified()
PatchHistory(patch=patch, by=request.user, what='Removed %s from committers' % request.user.username).save_and_notify(prevcommitter=prevcommitter)
patch.save()
return HttpResponseRedirect('../../')
+
@login_required
@transaction.atomic
def subscribe(request, cfid, patchid, sub):
@@ -654,6 +667,7 @@ def subscribe(request, cfid, patchid, sub):
patch.save()
return HttpResponseRedirect("../")
+
@login_required
@transaction.atomic
def send_email(request, cfid):
@@ -692,11 +706,12 @@ def send_email(request, cfid):
else:
reviewers = []
- if len(authors)==0 and len(reviewers)==0:
+ if len(authors) == 0 and len(reviewers) == 0:
messages.add_message(request, messages.WARNING, "No recipients specified, cannot send email")
return HttpResponseRedirect('..')
messages.add_message(request, messages.INFO, "Email will be sent from: %s" % UserWrapper(request.user).email)
+
def _user_and_mail(u):
return "%s %s (%s)" % (u.first_name, u.last_name, u.email)
@@ -709,7 +724,7 @@ def send_email(request, cfid):
'cf': cf,
'form': form,
'title': 'Send email',
- 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},],
+ 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk}, ],
'savebutton': 'Send email',
})
diff --git a/pgcommitfest/commitfest/widgets.py b/pgcommitfest/commitfest/widgets.py
index ee2df3d..fbce50d 100644
--- a/pgcommitfest/commitfest/widgets.py
+++ b/pgcommitfest/commitfest/widgets.py
@@ -1,6 +1,7 @@
from django.forms import TextInput
from django.utils.safestring import mark_safe
+
class ThreadPickWidget(TextInput):
def render(self, name, value, attrs=None):
attrs['class'] += ' threadpick-input'