summaryrefslogtreecommitdiff
path: root/pgcommitfest/commitfest/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'pgcommitfest/commitfest/views.py')
-rw-r--r--pgcommitfest/commitfest/views.py1270
1 files changed, 635 insertions, 635 deletions
diff --git a/pgcommitfest/commitfest/views.py b/pgcommitfest/commitfest/views.py
index 5f68895..705b172 100644
--- a/pgcommitfest/commitfest/views.py
+++ b/pgcommitfest/commitfest/views.py
@@ -27,170 +27,170 @@ 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)
- inprogresscf = next((c for c in commitfests if c.status == CommitFest.STATUS_INPROGRESS), None)
+ commitfests = list(CommitFest.objects.all())
+ opencf = next((c for c in commitfests if c.status == CommitFest.STATUS_OPEN), None)
+ inprogresscf = next((c for c in commitfests if c.status == CommitFest.STATUS_INPROGRESS), None)
- return render(request, 'home.html', {
- 'commitfests': commitfests,
- 'opencf': opencf,
- 'inprogresscf': inprogresscf,
- 'title': 'Commitfests',
- 'header_activity': 'Activity log',
- 'header_activity_link': '/activity/',
- })
+ return render(request, 'home.html', {
+ 'commitfests': commitfests,
+ 'opencf': opencf,
+ 'inprogresscf': inprogresscf,
+ 'title': 'Commitfests',
+ 'header_activity': 'Activity log',
+ 'header_activity_link': '/activity/',
+ })
def activity(request, cfid=None, rss=None):
- # Number of notes to fetch
- if rss:
- num = 50
- else:
- num = 100
-
- if cfid:
- cf = get_object_or_404(CommitFest, pk=cfid)
-
- # Yes, we do string concatenation of the were clause. Because
- # we're evil. And also because the number has been verified
- # when looking up the cf itself, so nothing can be injected
- # there.
- extrafields = ''
- where = 'WHERE poc.commitfest_id={0}'.format(cf.id)
- else:
- cf = 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)
-
- curs = connection.cursor()
- curs.execute(sql)
- activity = [dict(zip([c[0] for c in curs.description],r)) for r in curs.fetchall()]
-
- if rss:
- # Return RSS feed with these objects
- return ActivityFeed(activity, cf)(request)
- else:
- # Return regular webpage
- return render(request, 'activity.html', {
- 'commitfest': cf,
- 'activity': activity,
- '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,
- })
+ # Number of notes to fetch
+ if rss:
+ num = 50
+ else:
+ num = 100
+
+ if cfid:
+ cf = get_object_or_404(CommitFest, pk=cfid)
+
+ # Yes, we do string concatenation of the were clause. Because
+ # we're evil. And also because the number has been verified
+ # when looking up the cf itself, so nothing can be injected
+ # there.
+ extrafields = ''
+ where = 'WHERE poc.commitfest_id={0}'.format(cf.id)
+ else:
+ cf = 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)
+
+ curs = connection.cursor()
+ curs.execute(sql)
+ activity = [dict(zip([c[0] for c in curs.description],r)) for r in curs.fetchall()]
+
+ if rss:
+ # Return RSS feed with these objects
+ return ActivityFeed(activity, cf)(request)
+ else:
+ # Return regular webpage
+ return render(request, 'activity.html', {
+ 'commitfest': cf,
+ 'activity': activity,
+ '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,
+ })
def redir(request, what):
- if what == 'open':
- cfs = list(CommitFest.objects.filter(status=CommitFest.STATUS_OPEN))
- elif what == 'inprogress':
- cfs = list(CommitFest.objects.filter(status=CommitFest.STATUS_INPROGRESS))
- else:
- raise Http404()
-
- if len(cfs) == 0:
- messages.warning(request, "No {0} commitfests exist, redirecting to startpage.".format(what))
- return HttpResponseRedirect("/")
- if len(cfs) != 1:
- messages.warning(request, "More than one {0} commitfest exists, redirecting to startpage instead.".format(what))
- return HttpResponseRedirect("/")
-
- return HttpResponseRedirect("/%s/" % cfs[0].id)
+ if what == 'open':
+ cfs = list(CommitFest.objects.filter(status=CommitFest.STATUS_OPEN))
+ elif what == 'inprogress':
+ cfs = list(CommitFest.objects.filter(status=CommitFest.STATUS_INPROGRESS))
+ else:
+ raise Http404()
+
+ if len(cfs) == 0:
+ messages.warning(request, "No {0} commitfests exist, redirecting to startpage.".format(what))
+ return HttpResponseRedirect("/")
+ if len(cfs) != 1:
+ messages.warning(request, "More than one {0} commitfest exists, redirecting to startpage instead.".format(what))
+ return HttpResponseRedirect("/")
+
+ return HttpResponseRedirect("/%s/" % cfs[0].id)
def commitfest(request, cfid):
- # Find ourselves
- cf = get_object_or_404(CommitFest, pk=cfid)
-
- # Build a dynamic filter based on the filtering options entered
- whereclauses = []
- whereparams = {}
- if request.GET.has_key('status') and request.GET['status'] != "-1":
- try:
- whereparams['status'] = int(request.GET['status'])
- whereclauses.append("poc.status=%(status)s")
- except ValueError:
- # int() failed -- so just ignore this filter
- pass
-
- if request.GET.has_key('author') and request.GET['author'] != "-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':
- # Checking for "yourself" requires the user to be logged in!
- if not request.user.is_authenticated():
- return HttpResponseRedirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
- whereclauses.append("EXISTS (SELECT 1 FROM commitfest_patch_authors cpa WHERE cpa.patch_id=p.id AND cpa.user_id=%(self)s)")
- whereparams['self'] = request.user.id
- else:
- try:
- whereparams['author'] = int(request.GET['author'])
- whereclauses.append("EXISTS (SELECT 1 FROM commitfest_patch_authors cpa WHERE cpa.patch_id=p.id AND cpa.user_id=%(author)s)")
- except ValueError:
- # int() failed -- so just ignore this filter
- pass
-
- if request.GET.has_key('reviewer') and request.GET['reviewer'] != "-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':
- # Checking for "yourself" requires the user to be logged in!
- if not request.user.is_authenticated():
- return HttpResponseRedirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
- whereclauses.append("EXISTS (SELECT 1 FROM commitfest_patch_reviewers cpr WHERE cpr.patch_id=p.id AND cpr.user_id=%(self)s)")
- whereparams['self'] = request.user.id
- else:
- try:
- whereparams['reviewer'] = int(request.GET['reviewer'])
- whereclauses.append("EXISTS (SELECT 1 FROM commitfest_patch_reviewers cpr WHERE cpr.patch_id=p.id AND cpr.user_id=%(reviewer)s)")
- except ValueError:
- # int() failed -- so just ignore this filter
- pass
-
- if request.GET.has_key('text') and request.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']!='':
- try:
- sortkey=int(request.GET['sortkey'])
- except ValueError:
- sortkey=0
-
- if sortkey==1:
- orderby_str = 'modified, created'
- elif sortkey==2:
- orderby_str = 'lastmail, created'
- elif sortkey==3:
- orderby_str = 'num_cfs DESC, modified, created'
- else:
- orderby_str = 'p.id'
- sortkey=0
- else:
- orderby_str = 'topic, created'
- sortkey = 0
-
- if not has_filter and sortkey==0 and request.GET:
- # Redirect to get rid of the ugly url
- return HttpResponseRedirect('/%s/' % cf.id)
-
- if whereclauses:
- where_str = 'AND ({0})'.format(' AND '.join(whereclauses))
- else:
- where_str = ''
- params = {
- 'cid': cf.id,
- 'openstatuses': PatchOnCommitFest.OPEN_STATUSES,
- }
- params.update(whereparams)
-
- # Let's not overload the poor django ORM
- curs = connection.cursor()
- curs.execute("""SELECT p.id, p.name, poc.status, p.created, p.modified, p.lastmail, committer.username AS committer, t.topic,
+ # Find ourselves
+ cf = get_object_or_404(CommitFest, pk=cfid)
+
+ # Build a dynamic filter based on the filtering options entered
+ whereclauses = []
+ whereparams = {}
+ if request.GET.has_key('status') and request.GET['status'] != "-1":
+ try:
+ whereparams['status'] = int(request.GET['status'])
+ whereclauses.append("poc.status=%(status)s")
+ except ValueError:
+ # int() failed -- so just ignore this filter
+ pass
+
+ if request.GET.has_key('author') and request.GET['author'] != "-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':
+ # Checking for "yourself" requires the user to be logged in!
+ if not request.user.is_authenticated():
+ return HttpResponseRedirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
+ whereclauses.append("EXISTS (SELECT 1 FROM commitfest_patch_authors cpa WHERE cpa.patch_id=p.id AND cpa.user_id=%(self)s)")
+ whereparams['self'] = request.user.id
+ else:
+ try:
+ whereparams['author'] = int(request.GET['author'])
+ whereclauses.append("EXISTS (SELECT 1 FROM commitfest_patch_authors cpa WHERE cpa.patch_id=p.id AND cpa.user_id=%(author)s)")
+ except ValueError:
+ # int() failed -- so just ignore this filter
+ pass
+
+ if request.GET.has_key('reviewer') and request.GET['reviewer'] != "-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':
+ # Checking for "yourself" requires the user to be logged in!
+ if not request.user.is_authenticated():
+ return HttpResponseRedirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
+ whereclauses.append("EXISTS (SELECT 1 FROM commitfest_patch_reviewers cpr WHERE cpr.patch_id=p.id AND cpr.user_id=%(self)s)")
+ whereparams['self'] = request.user.id
+ else:
+ try:
+ whereparams['reviewer'] = int(request.GET['reviewer'])
+ whereclauses.append("EXISTS (SELECT 1 FROM commitfest_patch_reviewers cpr WHERE cpr.patch_id=p.id AND cpr.user_id=%(reviewer)s)")
+ except ValueError:
+ # int() failed -- so just ignore this filter
+ pass
+
+ if request.GET.has_key('text') and request.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']!='':
+ try:
+ sortkey=int(request.GET['sortkey'])
+ except ValueError:
+ sortkey=0
+
+ if sortkey==1:
+ orderby_str = 'modified, created'
+ elif sortkey==2:
+ orderby_str = 'lastmail, created'
+ elif sortkey==3:
+ orderby_str = 'num_cfs DESC, modified, created'
+ else:
+ orderby_str = 'p.id'
+ sortkey=0
+ else:
+ orderby_str = 'topic, created'
+ sortkey = 0
+
+ if not has_filter and sortkey==0 and request.GET:
+ # Redirect to get rid of the ugly url
+ return HttpResponseRedirect('/%s/' % cf.id)
+
+ if whereclauses:
+ where_str = 'AND ({0})'.format(' AND '.join(whereclauses))
+ else:
+ where_str = ''
+ params = {
+ 'cid': cf.id,
+ 'openstatuses': PatchOnCommitFest.OPEN_STATUSES,
+ }
+ params.update(whereparams)
+
+ # Let's not overload the poor django ORM
+ curs = connection.cursor()
+ curs.execute("""SELECT p.id, p.name, poc.status, p.created, p.modified, p.lastmail, committer.username AS committer, t.topic,
(poc.status=ANY(%(openstatuses)s)) AS is_open,
(SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_authors cpa ON cpa.user_id=auth_user.id WHERE cpa.patch_id=p.id) AS author_names,
(SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_reviewers cpr ON cpr.user_id=auth_user.id WHERE cpr.patch_id=p.id) AS reviewer_names,
@@ -202,533 +202,533 @@ LEFT JOIN auth_user committer ON committer.id=p.committer_id
WHERE poc.commitfest_id=%(cid)s {0}
GROUP BY p.id, poc.id, committer.id, t.id
ORDER BY is_open DESC, {1}""".format(where_str, orderby_str), params)
- patches = [dict(zip([col[0] for col in curs.description], row)) for row in curs.fetchall()]
-
- # Generate patch status summary.
- 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))])
-
- # Generates a fairly expensive query, which we shouldn't do unless
- # the user is logged in. XXX: Figure out how to avoid doing that..
- form = CommitFestFilterForm(cf, request.GET)
-
- return render(request, 'commitfest.html', {
- 'cf': cf,
- 'form': form,
- 'patches': patches,
- 'statussummary': statussummary,
- 'has_filter': has_filter,
- 'title': cf.title,
- 'grouping': sortkey==0,
- 'sortkey': sortkey,
- 'openpatchids': [p['id'] for p in patches if p['is_open']],
- 'header_activity': 'Activity log',
- 'header_activity_link': 'activity/',
- })
+ patches = [dict(zip([col[0] for col in curs.description], row)) for row in curs.fetchall()]
+
+ # Generate patch status summary.
+ 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))])
+
+ # Generates a fairly expensive query, which we shouldn't do unless
+ # the user is logged in. XXX: Figure out how to avoid doing that..
+ form = CommitFestFilterForm(cf, request.GET)
+
+ return render(request, 'commitfest.html', {
+ 'cf': cf,
+ 'form': form,
+ 'patches': patches,
+ 'statussummary': statussummary,
+ 'has_filter': has_filter,
+ 'title': cf.title,
+ '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'):
- return HttpResponseRedirect('/')
- searchterm = request.GET['searchterm']
+ if not request.GET.has_key('searchterm'):
+ return HttpResponseRedirect('/')
+ searchterm = request.GET['searchterm']
- patches = Patch.objects.select_related().filter(name__icontains=searchterm).order_by('created',)
+ patches = Patch.objects.select_related().filter(name__icontains=searchterm).order_by('created',)
- return render(request, 'patchsearch.html', {
- 'patches': patches,
- 'title': 'Patch search results',
- })
+ return render(request, 'patchsearch.html', {
+ 'patches': patches,
+ 'title': 'Patch search results',
+ })
def patch(request, cfid, patchid):
- cf = get_object_or_404(CommitFest, pk=cfid)
- patch = get_object_or_404(Patch.objects.select_related(), pk=patchid, commitfests=cf)
- 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?
- if request.user.is_authenticated():
- committer = [c for c in committers if c.user==request.user]
- if len(committer) > 0:
- is_committer= True
- is_this_committer = committer[0] == patch.committer
- else:
- is_committer = is_this_committer = False
-
- is_reviewer = request.user in patch.reviewers.all()
- is_subscribed = patch.subscribers.filter(id=request.user.id).exists()
- else:
- is_committer = False
- is_this_committer = False
- is_reviewer = False
- is_subscribed = False
-
- return render(request, 'patch.html', {
- 'cf': cf,
- 'patch': patch,
- 'patch_commitfests': patch_commitfests,
- 'is_committer': is_committer,
- 'is_this_committer': is_this_committer,
- 'is_reviewer': is_reviewer,
- 'is_subscribed': is_subscribed,
- 'committers': committers,
- 'attachnow': request.GET.has_key('attachthreadnow'),
- 'title': patch.name,
- 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},],
- })
+ cf = get_object_or_404(CommitFest, pk=cfid)
+ patch = get_object_or_404(Patch.objects.select_related(), pk=patchid, commitfests=cf)
+ 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?
+ if request.user.is_authenticated():
+ committer = [c for c in committers if c.user==request.user]
+ if len(committer) > 0:
+ is_committer= True
+ is_this_committer = committer[0] == patch.committer
+ else:
+ is_committer = is_this_committer = False
+
+ is_reviewer = request.user in patch.reviewers.all()
+ is_subscribed = patch.subscribers.filter(id=request.user.id).exists()
+ else:
+ is_committer = False
+ is_this_committer = False
+ is_reviewer = False
+ is_subscribed = False
+
+ return render(request, 'patch.html', {
+ 'cf': cf,
+ 'patch': patch,
+ 'patch_commitfests': patch_commitfests,
+ 'is_committer': is_committer,
+ 'is_this_committer': is_this_committer,
+ 'is_reviewer': is_reviewer,
+ 'is_subscribed': is_subscribed,
+ 'committers': committers,
+ 'attachnow': request.GET.has_key('attachthreadnow'),
+ 'title': patch.name,
+ 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},],
+ })
@login_required
@transaction.atomic
def patchform(request, cfid, patchid):
- cf = get_object_or_404(CommitFest, pk=cfid)
- patch = get_object_or_404(Patch, pk=patchid, commitfests=cf)
-
- prevreviewers = list(patch.reviewers.all())
- prevauthors = list(patch.authors.all())
- prevcommitter = patch.committer
-
- if request.method == 'POST':
- form = PatchForm(data=request.POST, instance=patch)
- if form.is_valid():
- # Some fields need to be set when creating a new one
- r = form.save(commit=False)
- # Fill out any locked fields here
-
- form.save_m2m()
-
- # Track all changes
- for field, values in r.diff.items():
- PatchHistory(patch=patch, by=request.user, what='Changed %s to %s' % (field, values[1])).save_and_notify(prevcommitter=prevcommitter, prevreviewers=prevreviewers, prevauthors=prevauthors)
- r.set_modified()
- r.save()
- return HttpResponseRedirect('../../%s/' % r.pk)
- # Else fall through and render the page again
- else:
- form = PatchForm(instance=patch)
-
- return render(request, 'base_form.html', {
- 'cf': cf,
- 'form': form,
- 'patch': patch,
- 'title': 'Edit patch',
- 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},
- {'title': 'View patch', 'href': '/%s/%s/' % (cf.pk, patch.pk)}],
- })
+ cf = get_object_or_404(CommitFest, pk=cfid)
+ patch = get_object_or_404(Patch, pk=patchid, commitfests=cf)
+
+ prevreviewers = list(patch.reviewers.all())
+ prevauthors = list(patch.authors.all())
+ prevcommitter = patch.committer
+
+ if request.method == 'POST':
+ form = PatchForm(data=request.POST, instance=patch)
+ if form.is_valid():
+ # Some fields need to be set when creating a new one
+ r = form.save(commit=False)
+ # Fill out any locked fields here
+
+ form.save_m2m()
+
+ # Track all changes
+ for field, values in r.diff.items():
+ PatchHistory(patch=patch, by=request.user, what='Changed %s to %s' % (field, values[1])).save_and_notify(prevcommitter=prevcommitter, prevreviewers=prevreviewers, prevauthors=prevauthors)
+ r.set_modified()
+ r.save()
+ return HttpResponseRedirect('../../%s/' % r.pk)
+ # Else fall through and render the page again
+ else:
+ form = PatchForm(instance=patch)
+
+ return render(request, 'base_form.html', {
+ 'cf': cf,
+ 'form': form,
+ 'patch': patch,
+ 'title': 'Edit patch',
+ 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},
+ {'title': 'View patch', 'href': '/%s/%s/' % (cf.pk, patch.pk)}],
+ })
@login_required
@transaction.atomic
def newpatch(request, cfid):
- cf = get_object_or_404(CommitFest, pk=cfid)
- if not cf.status == CommitFest.STATUS_OPEN and not request.user.is_staff:
- raise Http404("This commitfest is not open!")
-
- if request.method == 'POST':
- form = NewPatchForm(data=request.POST)
- if form.is_valid():
- patch = Patch(name=form.cleaned_data['name'],
- topic=form.cleaned_data['topic'])
- patch.set_modified()
- patch.save()
- poc = PatchOnCommitFest(patch=patch, commitfest=cf, enterdate=datetime.now())
- poc.save()
- PatchHistory(patch=patch, by=request.user, what='Created patch record').save()
- # Now add the thread
- try:
- doAttachThread(cf, patch, form.cleaned_data['threadmsgid'], request.user)
- return HttpResponseRedirect("/%s/%s/edit/" % (cf.id, patch.id))
- except Http404:
- # Thread not found!
- # This is a horrible breakage of API layers
- form._errors['threadmsgid'] = form.error_class(('Selected thread did not exist in the archives',))
- except Exception:
- form._errors['threadmsgid'] = form.error_class(('An error occurred looking up the thread in the archives.',))
- # In this case, we have created a patch - delete it. This causes a agp in id's, but it should
- # not happen very often. If we successfully attached to it, we will have already returned.
- patch.delete()
- else:
- form = NewPatchForm()
-
- return render(request, 'base_form.html', {
- 'form': form,
- 'title': 'New patch',
- 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},],
- 'savebutton': 'Create patch',
- 'threadbrowse': True,
- })
+ cf = get_object_or_404(CommitFest, pk=cfid)
+ if not cf.status == CommitFest.STATUS_OPEN and not request.user.is_staff:
+ raise Http404("This commitfest is not open!")
+
+ if request.method == 'POST':
+ form = NewPatchForm(data=request.POST)
+ if form.is_valid():
+ patch = Patch(name=form.cleaned_data['name'],
+ topic=form.cleaned_data['topic'])
+ patch.set_modified()
+ patch.save()
+ poc = PatchOnCommitFest(patch=patch, commitfest=cf, enterdate=datetime.now())
+ poc.save()
+ PatchHistory(patch=patch, by=request.user, what='Created patch record').save()
+ # Now add the thread
+ try:
+ doAttachThread(cf, patch, form.cleaned_data['threadmsgid'], request.user)
+ return HttpResponseRedirect("/%s/%s/edit/" % (cf.id, patch.id))
+ except Http404:
+ # Thread not found!
+ # This is a horrible breakage of API layers
+ form._errors['threadmsgid'] = form.error_class(('Selected thread did not exist in the archives',))
+ except Exception:
+ form._errors['threadmsgid'] = form.error_class(('An error occurred looking up the thread in the archives.',))
+ # In this case, we have created a patch - delete it. This causes a agp in id's, but it should
+ # not happen very often. If we successfully attached to it, we will have already returned.
+ patch.delete()
+ else:
+ form = NewPatchForm()
+
+ return render(request, 'base_form.html', {
+ 'form': form,
+ 'title': 'New patch',
+ '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:
- return "tested, passed"
- else:
- return "tested, failed"
- else:
- return "not tested"
+ if '0' in reviewstatus:
+ if '1' in reviewstatus:
+ return "tested, passed"
+ else:
+ return "tested, failed"
+ 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')
-
- if poc.is_closed:
- # We allow modification of patches in closed CFs *only* if it's the
- # last CF that the patch is part of. If it's part of another CF, that
- # is later than this one, tell the user to go there instead.
- lastcf = PatchOnCommitFest.objects.filter(patch=patch).order_by('-commitfest__startdate')[0]
- if poc != lastcf:
- messages.add_message(request, messages.INFO, "The status of this patch cannot be changed in this commitfest. You must modify it in the one where it's open!")
- return HttpResponseRedirect('..')
-
- if request.method == 'POST':
- try:
- form = CommentForm(patch, poc, is_review, data=request.POST)
- except Exception, e:
- messages.add_message(request, messages.ERROR, "Failed to build list of response options from the archives: %s" % e)
- return HttpResponseRedirect('/%s/%s/' % (cf.id, patch.id))
-
- if form.is_valid():
- if is_review:
- txt = "The following review has been posted through the commitfest application:\n%s\n\n%s" % (
- "\n".join(["%-25s %s" % (f.label + ':', _review_status_string(form.cleaned_data[fn])) for (fn, f) in form.fields.items() if fn.startswith('review_')]),
- form.cleaned_data['message']
- )
- else:
- txt = form.cleaned_data['message']
-
- if int(form.cleaned_data['newstatus']) != poc.status:
- poc.status = int(form.cleaned_data['newstatus'])
- poc.save()
- PatchHistory(patch=poc.patch, by=request.user, what='New status: %s' % poc.statusstring).save_and_notify()
- txt += "\n\nThe new status of this patch is: %s\n" % poc.statusstring
-
- msg = MIMEText(txt, _charset='utf-8')
-
- if form.thread.subject.startswith('Re:'):
- msg['Subject'] = form.thread.subject
- else:
- msg['Subject'] = 'Re: %s' % form.thread.subject
-
- msg['To'] = settings.HACKERS_EMAIL
- msg['From'] = UserWrapper(request.user).encoded_email_header
-
- # CC the authors of a patch, if there are any
- authors = list(patch.authors.all())
- if len(authors):
- msg['Cc'] = ", ".join([UserWrapper(a).encoded_email_header for a in authors])
-
- msg['Date'] = formatdate(localtime=True)
- msg['User-Agent'] = 'pgcommitfest'
- msg['X-cfsender'] = request.user.username
- msg['In-Reply-To'] = '<%s>' % form.respid
- # We just add the "top" messageid and the one we're responding to.
- # This along with in-reply-to should indicate clearly enough where
- # in the thread the message belongs.
- msg['References'] = '<%s> <%s>' % (form.thread.messageid, form.respid)
- msg['Message-ID'] = make_msgid('pgcf')
-
- uw = UserWrapper(request.user)
- msgstring = msg.as_string()
- send_mail(uw.email, settings.HACKERS_EMAIL, msgstring)
- for a in authors:
- # Actually send a copy directly to the author. Just setting the Cc field doesn't
- # make it deliver the email...
- send_mail(uw.email, UserWrapper(a).email, msgstring)
-
- PatchHistory(patch=patch, by=request.user, what='Posted %s with messageid %s' % (what, msg['Message-ID'])).save()
-
- messages.add_message(request, messages.INFO, "Your email has been queued for %s, and will be sent within a few minutes." % (settings.HACKERS_EMAIL))
-
- return HttpResponseRedirect('/%s/%s/' % (cf.id, patch.id))
- else:
- try:
- form = CommentForm(patch, poc, is_review)
- except Exception, e:
- messages.add_message(request, messages.ERROR, "Failed to build list of response options from the archives: %s" % e)
- return HttpResponseRedirect('/%s/%s/' % (cf.id, patch.id))
-
- return render(request, 'base_form.html', {
- 'cf': cf,
- 'form': form,
- 'patch': patch,
- 'extraformclass': 'patchcommentform',
- 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},
- {'title': 'View patch', 'href': '/%s/%s/' % (cf.pk, patch.pk)}],
- 'title': "Add %s" % what,
- 'note': '<b>Note!</b> This form will generate an email to the public mailinglist <i>%s</i>, with sender set to <i>%s</i>!<br/>Please ensure that the email settings for your domain (<a href="https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail" target="_blank">DKIM</a>, <a href="https://en.wikipedia.org/wiki/SPF" target="_blank">SPF</a>) allow emails from external sources.' % (settings.HACKERS_EMAIL, UserWrapper(request.user).email),
- 'savebutton': 'Send %s' % 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')
+
+ if poc.is_closed:
+ # We allow modification of patches in closed CFs *only* if it's the
+ # last CF that the patch is part of. If it's part of another CF, that
+ # is later than this one, tell the user to go there instead.
+ lastcf = PatchOnCommitFest.objects.filter(patch=patch).order_by('-commitfest__startdate')[0]
+ if poc != lastcf:
+ messages.add_message(request, messages.INFO, "The status of this patch cannot be changed in this commitfest. You must modify it in the one where it's open!")
+ return HttpResponseRedirect('..')
+
+ if request.method == 'POST':
+ try:
+ form = CommentForm(patch, poc, is_review, data=request.POST)
+ except Exception, e:
+ messages.add_message(request, messages.ERROR, "Failed to build list of response options from the archives: %s" % e)
+ return HttpResponseRedirect('/%s/%s/' % (cf.id, patch.id))
+
+ if form.is_valid():
+ if is_review:
+ txt = "The following review has been posted through the commitfest application:\n%s\n\n%s" % (
+ "\n".join(["%-25s %s" % (f.label + ':', _review_status_string(form.cleaned_data[fn])) for (fn, f) in form.fields.items() if fn.startswith('review_')]),
+ form.cleaned_data['message']
+ )
+ else:
+ txt = form.cleaned_data['message']
+
+ if int(form.cleaned_data['newstatus']) != poc.status:
+ poc.status = int(form.cleaned_data['newstatus'])
+ poc.save()
+ PatchHistory(patch=poc.patch, by=request.user, what='New status: %s' % poc.statusstring).save_and_notify()
+ txt += "\n\nThe new status of this patch is: %s\n" % poc.statusstring
+
+ msg = MIMEText(txt, _charset='utf-8')
+
+ if form.thread.subject.startswith('Re:'):
+ msg['Subject'] = form.thread.subject
+ else:
+ msg['Subject'] = 'Re: %s' % form.thread.subject
+
+ msg['To'] = settings.HACKERS_EMAIL
+ msg['From'] = UserWrapper(request.user).encoded_email_header
+
+ # CC the authors of a patch, if there are any
+ authors = list(patch.authors.all())
+ if len(authors):
+ msg['Cc'] = ", ".join([UserWrapper(a).encoded_email_header for a in authors])
+
+ msg['Date'] = formatdate(localtime=True)
+ msg['User-Agent'] = 'pgcommitfest'
+ msg['X-cfsender'] = request.user.username
+ msg['In-Reply-To'] = '<%s>' % form.respid
+ # We just add the "top" messageid and the one we're responding to.
+ # This along with in-reply-to should indicate clearly enough where
+ # in the thread the message belongs.
+ msg['References'] = '<%s> <%s>' % (form.thread.messageid, form.respid)
+ msg['Message-ID'] = make_msgid('pgcf')
+
+ uw = UserWrapper(request.user)
+ msgstring = msg.as_string()
+ send_mail(uw.email, settings.HACKERS_EMAIL, msgstring)
+ for a in authors:
+ # Actually send a copy directly to the author. Just setting the Cc field doesn't
+ # make it deliver the email...
+ send_mail(uw.email, UserWrapper(a).email, msgstring)
+
+ PatchHistory(patch=patch, by=request.user, what='Posted %s with messageid %s' % (what, msg['Message-ID'])).save()
+
+ messages.add_message(request, messages.INFO, "Your email has been queued for %s, and will be sent within a few minutes." % (settings.HACKERS_EMAIL))
+
+ return HttpResponseRedirect('/%s/%s/' % (cf.id, patch.id))
+ else:
+ try:
+ form = CommentForm(patch, poc, is_review)
+ except Exception, e:
+ messages.add_message(request, messages.ERROR, "Failed to build list of response options from the archives: %s" % e)
+ return HttpResponseRedirect('/%s/%s/' % (cf.id, patch.id))
+
+ return render(request, 'base_form.html', {
+ 'cf': cf,
+ 'form': form,
+ 'patch': patch,
+ 'extraformclass': 'patchcommentform',
+ 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},
+ {'title': 'View patch', 'href': '/%s/%s/' % (cf.pk, patch.pk)}],
+ 'title': "Add %s" % what,
+ 'note': '<b>Note!</b> This form will generate an email to the public mailinglist <i>%s</i>, with sender set to <i>%s</i>!<br/>Please ensure that the email settings for your domain (<a href="https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail" target="_blank">DKIM</a>, <a href="https://en.wikipedia.org/wiki/SPF" target="_blank">SPF</a>) allow emails from external sources.' % (settings.HACKERS_EMAIL, UserWrapper(request.user).email),
+ 'savebutton': 'Send %s' % what,
+ })
@login_required
@transaction.atomic
def status(request, cfid, patchid, status):
- poc = get_object_or_404(PatchOnCommitFest.objects.select_related(), commitfest__id=cfid, patch__id=patchid)
-
- if poc.is_closed:
- # We allow modification of patches in closed CFs *only* if it's the
- # last CF that the patch is part of. If it's part of another CF, that
- # is later than this one, tell the user to go there instead.
- lastcf = PatchOnCommitFest.objects.filter(patch__id=patchid).order_by('-commitfest__startdate')[0]
- if poc != lastcf:
- messages.add_message(request, messages.INFO, "The status of this patch cannot be changed in this commitfest. You must modify it in the one where it's open!")
- return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
-
- if status == 'review':
- newstatus = PatchOnCommitFest.STATUS_REVIEW
- elif status == 'author':
- newstatus = PatchOnCommitFest.STATUS_AUTHOR
- elif status == 'committer':
- newstatus = PatchOnCommitFest.STATUS_COMMITTER
- else:
- raise Exception("Can't happen")
-
- if newstatus != poc.status:
- # Only save it if something actually changed
- poc.status = newstatus
- poc.patch.set_modified()
- poc.patch.save()
- poc.save()
-
- PatchHistory(patch=poc.patch, by=request.user, what='New status: %s' % poc.statusstring).save_and_notify()
-
- return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
+ poc = get_object_or_404(PatchOnCommitFest.objects.select_related(), commitfest__id=cfid, patch__id=patchid)
+
+ if poc.is_closed:
+ # We allow modification of patches in closed CFs *only* if it's the
+ # last CF that the patch is part of. If it's part of another CF, that
+ # is later than this one, tell the user to go there instead.
+ lastcf = PatchOnCommitFest.objects.filter(patch__id=patchid).order_by('-commitfest__startdate')[0]
+ if poc != lastcf:
+ messages.add_message(request, messages.INFO, "The status of this patch cannot be changed in this commitfest. You must modify it in the one where it's open!")
+ return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
+
+ if status == 'review':
+ newstatus = PatchOnCommitFest.STATUS_REVIEW
+ elif status == 'author':
+ newstatus = PatchOnCommitFest.STATUS_AUTHOR
+ elif status == 'committer':
+ newstatus = PatchOnCommitFest.STATUS_COMMITTER
+ else:
+ raise Exception("Can't happen")
+
+ if newstatus != poc.status:
+ # Only save it if something actually changed
+ poc.status = newstatus
+ poc.patch.set_modified()
+ poc.patch.save()
+ poc.save()
+
+ PatchHistory(patch=poc.patch, by=request.user, what='New status: %s' % poc.statusstring).save_and_notify()
+
+ return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
@login_required
@transaction.atomic
def close(request, cfid, patchid, status):
- poc = get_object_or_404(PatchOnCommitFest.objects.select_related(), commitfest__id=cfid, patch__id=patchid)
-
- if poc.is_closed:
- # We allow modification of patches in closed CFs *only* if it's the
- # last CF that the patch is part of. If it's part of another CF, that
- # is later than this one, tell the user to go there instead.
- lastcf = PatchOnCommitFest.objects.filter(patch__id=patchid).order_by('-commitfest__startdate')[0]
- if poc != lastcf:
- messages.add_message(request, messages.INFO, "The status of this patch cannot be changed in this commitfest. You must modify it in the one where it's open!")
- return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
-
- poc.leavedate = datetime.now()
-
- # We know the status can't be one of the ones below, since we
- # have checked that we're not closed yet. Therefor, we don't
- # need to check if the individual status has changed.
- if status == 'reject':
- poc.status = PatchOnCommitFest.STATUS_REJECTED
- elif status == 'withdrawn':
- poc.status = PatchOnCommitFest.STATUS_WITHDRAWN
- elif status == 'feedback':
- poc.status = PatchOnCommitFest.STATUS_RETURNED
- elif status == 'next':
- # Only some patch statuses can actually be moved.
- if poc.status in (PatchOnCommitFest.STATUS_AUTHOR,
- PatchOnCommitFest.STATUS_COMMITTED,
- PatchOnCommitFest.STATUS_NEXT,
- PatchOnCommitFest.STATUS_RETURNED,
- PatchOnCommitFest.STATUS_REJECTED):
- # Can't be moved!
- messages.error(request, "A patch in status {0} cannot be moved to next commitfest.".format(poc.statusstring))
- return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
- elif poc.status in (PatchOnCommitFest.STATUS_REVIEW,
- PatchOnCommitFest.STATUS_COMMITTER):
- # This one can be moved
- pass
- else:
- messages.error(request, "Invalid existing patch status")
-
- oldstatus = poc.status
-
- poc.status = PatchOnCommitFest.STATUS_NEXT
- # Figure out the commitfest to actually put it on
- newcf = CommitFest.objects.filter(status=CommitFest.STATUS_OPEN)
- if len(newcf) == 0:
- # Ok, there is no open CF at all. Let's see if there is a
- # future one.
- newcf = CommitFest.objects.filter(status=CommitFest.STATUS_FUTURE)
- if len(newcf) == 0:
- 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!")
- return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
- elif len(newcf) != 1:
- messages.error(request, "Multiple open commitfests exists!")
- return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
- elif newcf[0] == poc.commitfest:
- # The current open CF is the same one that we are already on.
- # In this case, try to see if there is a future CF we can
- # move it to.
- newcf = CommitFest.objects.filter(status=CommitFest.STATUS_FUTURE)
- if len(newcf) == 0:
- messages.error(request, "Cannot move patch to the same commitfest, and no future commitfests exist!")
- return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
- elif len(newcf) != 1:
- messages.error(request, "Cannot move patch to the same commitfest, and multiple future commitfests exist!")
- return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
- # Create a mapping to the new commitfest that we are bouncing
- # this patch to.
- newpoc = PatchOnCommitFest(patch=poc.patch,
- commitfest=newcf[0],
- status=oldstatus,
- enterdate=datetime.now())
- newpoc.save()
- elif status == 'committed':
- committer = get_object_or_404(Committer, user__username=request.GET['c'])
- if committer != poc.patch.committer:
- # Committer changed!
- prevcommitter = poc.patch.committer
- poc.patch.committer = committer
- PatchHistory(patch=poc.patch, by=request.user, what='Changed committer to %s' % committer).save_and_notify(prevcommitter=prevcommitter)
- poc.status = PatchOnCommitFest.STATUS_COMMITTED
- else:
- raise Exception("Can't happen")
-
- poc.patch.set_modified()
- poc.patch.save()
- poc.save()
-
- PatchHistory(patch=poc.patch, by=request.user, what='Closed in commitfest %s with status: %s' % (poc.commitfest, poc.statusstring)).save_and_notify()
-
- return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
+ poc = get_object_or_404(PatchOnCommitFest.objects.select_related(), commitfest__id=cfid, patch__id=patchid)
+
+ if poc.is_closed:
+ # We allow modification of patches in closed CFs *only* if it's the
+ # last CF that the patch is part of. If it's part of another CF, that
+ # is later than this one, tell the user to go there instead.
+ lastcf = PatchOnCommitFest.objects.filter(patch__id=patchid).order_by('-commitfest__startdate')[0]
+ if poc != lastcf:
+ messages.add_message(request, messages.INFO, "The status of this patch cannot be changed in this commitfest. You must modify it in the one where it's open!")
+ return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
+
+ poc.leavedate = datetime.now()
+
+ # We know the status can't be one of the ones below, since we
+ # have checked that we're not closed yet. Therefor, we don't
+ # need to check if the individual status has changed.
+ if status == 'reject':
+ poc.status = PatchOnCommitFest.STATUS_REJECTED
+ elif status == 'withdrawn':
+ poc.status = PatchOnCommitFest.STATUS_WITHDRAWN
+ elif status == 'feedback':
+ poc.status = PatchOnCommitFest.STATUS_RETURNED
+ elif status == 'next':
+ # Only some patch statuses can actually be moved.
+ if poc.status in (PatchOnCommitFest.STATUS_AUTHOR,
+ PatchOnCommitFest.STATUS_COMMITTED,
+ PatchOnCommitFest.STATUS_NEXT,
+ PatchOnCommitFest.STATUS_RETURNED,
+ PatchOnCommitFest.STATUS_REJECTED):
+ # Can't be moved!
+ messages.error(request, "A patch in status {0} cannot be moved to next commitfest.".format(poc.statusstring))
+ return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
+ elif poc.status in (PatchOnCommitFest.STATUS_REVIEW,
+ PatchOnCommitFest.STATUS_COMMITTER):
+ # This one can be moved
+ pass
+ else:
+ messages.error(request, "Invalid existing patch status")
+
+ oldstatus = poc.status
+
+ poc.status = PatchOnCommitFest.STATUS_NEXT
+ # Figure out the commitfest to actually put it on
+ newcf = CommitFest.objects.filter(status=CommitFest.STATUS_OPEN)
+ if len(newcf) == 0:
+ # Ok, there is no open CF at all. Let's see if there is a
+ # future one.
+ newcf = CommitFest.objects.filter(status=CommitFest.STATUS_FUTURE)
+ if len(newcf) == 0:
+ 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!")
+ return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
+ elif len(newcf) != 1:
+ messages.error(request, "Multiple open commitfests exists!")
+ return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
+ elif newcf[0] == poc.commitfest:
+ # The current open CF is the same one that we are already on.
+ # In this case, try to see if there is a future CF we can
+ # move it to.
+ newcf = CommitFest.objects.filter(status=CommitFest.STATUS_FUTURE)
+ if len(newcf) == 0:
+ messages.error(request, "Cannot move patch to the same commitfest, and no future commitfests exist!")
+ return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
+ elif len(newcf) != 1:
+ messages.error(request, "Cannot move patch to the same commitfest, and multiple future commitfests exist!")
+ return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
+ # Create a mapping to the new commitfest that we are bouncing
+ # this patch to.
+ newpoc = PatchOnCommitFest(patch=poc.patch,
+ commitfest=newcf[0],
+ status=oldstatus,
+ enterdate=datetime.now())
+ newpoc.save()
+ elif status == 'committed':
+ committer = get_object_or_404(Committer, user__username=request.GET['c'])
+ if committer != poc.patch.committer:
+ # Committer changed!
+ prevcommitter = poc.patch.committer
+ poc.patch.committer = committer
+ PatchHistory(patch=poc.patch, by=request.user, what='Changed committer to %s' % committer).save_and_notify(prevcommitter=prevcommitter)
+ poc.status = PatchOnCommitFest.STATUS_COMMITTED
+ else:
+ raise Exception("Can't happen")
+
+ poc.patch.set_modified()
+ poc.patch.save()
+ poc.save()
+
+ PatchHistory(patch=poc.patch, by=request.user, what='Closed in commitfest %s with status: %s' % (poc.commitfest, poc.statusstring)).save_and_notify()
+
+ return HttpResponseRedirect('/%s/%s/' % (poc.commitfest.id, poc.patch.id))
@login_required
@transaction.atomic
def reviewer(request, cfid, patchid, status):
- get_object_or_404(CommitFest, pk=cfid)
- patch = get_object_or_404(Patch, pk=patchid)
+ get_object_or_404(CommitFest, pk=cfid)
+ patch = get_object_or_404(Patch, pk=patchid)
- is_reviewer = request.user in patch.reviewers.all()
+ is_reviewer = request.user in patch.reviewers.all()
- 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:
- 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('../../')
+ 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:
+ 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):
- get_object_or_404(CommitFest, pk=cfid)
- patch = get_object_or_404(Patch, pk=patchid)
-
- committer = list(Committer.objects.filter(user=request.user, active=True))
- if len(committer) == 0:
- return HttpResponseForbidden('Only committers can do that!')
- committer = committer[0]
-
- is_committer = committer == patch.committer
-
- prevcommitter = patch.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:
- 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('../../')
+ get_object_or_404(CommitFest, pk=cfid)
+ patch = get_object_or_404(Patch, pk=patchid)
+
+ committer = list(Committer.objects.filter(user=request.user, active=True))
+ if len(committer) == 0:
+ return HttpResponseForbidden('Only committers can do that!')
+ committer = committer[0]
+
+ is_committer = committer == patch.committer
+
+ prevcommitter = patch.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:
+ 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):
- get_object_or_404(CommitFest, pk=cfid)
- patch = get_object_or_404(Patch, pk=patchid)
-
- if sub == 'un':
- patch.subscribers.remove(request.user)
- messages.info(request, "You have been unsubscribed from updates on this patch")
- else:
- patch.subscribers.add(request.user)
- messages.info(request, "You have been subscribed to updates on this patch")
- patch.save()
- return HttpResponseRedirect("../")
+ get_object_or_404(CommitFest, pk=cfid)
+ patch = get_object_or_404(Patch, pk=patchid)
+
+ if sub == 'un':
+ patch.subscribers.remove(request.user)
+ messages.info(request, "You have been unsubscribed from updates on this patch")
+ else:
+ patch.subscribers.add(request.user)
+ messages.info(request, "You have been subscribed to updates on this patch")
+ patch.save()
+ return HttpResponseRedirect("../")
@login_required
@transaction.atomic
def send_email(request, cfid):
- cf = get_object_or_404(CommitFest, pk=cfid)
- if not request.user.is_staff:
- raise Http404("Only CF managers can do that.")
-
- if request.method == 'POST':
- authoridstring = request.POST['authors']
- revieweridstring = request.POST['reviewers']
- form = BulkEmailForm(data=request.POST)
- if form.is_valid():
- q = Q()
- if authoridstring:
- q = q | Q(patch_author__in=[int(x) for x in authoridstring.split(',')])
- if revieweridstring:
- q = q | Q(patch_reviewer__in=[int(x) for x in revieweridstring.split(',')])
-
- recipients = User.objects.filter(q).distinct()
-
- for r in recipients:
- send_simple_mail(UserWrapper(request.user).email, r.email, form.cleaned_data['subject'], form.cleaned_data['body'], request.user.username)
- messages.add_message(request, messages.INFO, "Sent email to %s" % r.email)
- return HttpResponseRedirect('..')
- else:
- authoridstring = request.GET.get('authors', None)
- revieweridstring = request.GET.get('reviewers', None)
- form = BulkEmailForm(initial={'authors': authoridstring, 'reviewers': revieweridstring})
-
- if authoridstring:
- authors = list(User.objects.filter(patch_author__in=[int(x) for x in authoridstring.split(',')]).distinct())
- else:
- authors = []
- if revieweridstring:
- reviewers = list(User.objects.filter(patch_reviewer__in=[int(x) for x in revieweridstring.split(',')]).distinct())
- else:
- reviewers = []
-
- 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)
-
- if len(authors):
- messages.add_message(request, messages.INFO, "The email will be sent to the following authors: %s" % ", ".join([_user_and_mail(u) for u in authors]))
- if len(reviewers):
- messages.add_message(request, messages.INFO, "The email will be sent to the following reviewers: %s" % ", ".join([_user_and_mail(u) for u in reviewers]))
-
- return render(request, 'base_form.html', {
- 'cf': cf,
- 'form': form,
- 'title': 'Send email',
- 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},],
- 'savebutton': 'Send email',
- })
+ cf = get_object_or_404(CommitFest, pk=cfid)
+ if not request.user.is_staff:
+ raise Http404("Only CF managers can do that.")
+
+ if request.method == 'POST':
+ authoridstring = request.POST['authors']
+ revieweridstring = request.POST['reviewers']
+ form = BulkEmailForm(data=request.POST)
+ if form.is_valid():
+ q = Q()
+ if authoridstring:
+ q = q | Q(patch_author__in=[int(x) for x in authoridstring.split(',')])
+ if revieweridstring:
+ q = q | Q(patch_reviewer__in=[int(x) for x in revieweridstring.split(',')])
+
+ recipients = User.objects.filter(q).distinct()
+
+ for r in recipients:
+ send_simple_mail(UserWrapper(request.user).email, r.email, form.cleaned_data['subject'], form.cleaned_data['body'], request.user.username)
+ messages.add_message(request, messages.INFO, "Sent email to %s" % r.email)
+ return HttpResponseRedirect('..')
+ else:
+ authoridstring = request.GET.get('authors', None)
+ revieweridstring = request.GET.get('reviewers', None)
+ form = BulkEmailForm(initial={'authors': authoridstring, 'reviewers': revieweridstring})
+
+ if authoridstring:
+ authors = list(User.objects.filter(patch_author__in=[int(x) for x in authoridstring.split(',')]).distinct())
+ else:
+ authors = []
+ if revieweridstring:
+ reviewers = list(User.objects.filter(patch_reviewer__in=[int(x) for x in revieweridstring.split(',')]).distinct())
+ else:
+ reviewers = []
+
+ 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)
+
+ if len(authors):
+ messages.add_message(request, messages.INFO, "The email will be sent to the following authors: %s" % ", ".join([_user_and_mail(u) for u in authors]))
+ if len(reviewers):
+ messages.add_message(request, messages.INFO, "The email will be sent to the following reviewers: %s" % ", ".join([_user_and_mail(u) for u in reviewers]))
+
+ return render(request, 'base_form.html', {
+ 'cf': cf,
+ 'form': form,
+ 'title': 'Send email',
+ 'breadcrumbs': [{'title': cf.title, 'href': '/%s/' % cf.pk},],
+ 'savebutton': 'Send email',
+ })
@csrf_exempt
def thread_notify(request):
- if request.method != 'POST':
- return HttpResponseForbidden("Invalid method")
-
- j = json.loads(request.body)
- if j['apikey'] != settings.ARCHIVES_APIKEY:
- return HttpResponseForbidden("Invalid API key")
-
- for m in j['messageids']:
- try:
- t = MailThread.objects.get(messageid=m)
- refresh_single_thread(t)
- except Exception, e:
- # Just ignore it, we'll check again later
- pass
-
- return HttpResponse(status=200)
+ if request.method != 'POST':
+ return HttpResponseForbidden("Invalid method")
+
+ j = json.loads(request.body)
+ if j['apikey'] != settings.ARCHIVES_APIKEY:
+ return HttpResponseForbidden("Invalid API key")
+
+ for m in j['messageids']:
+ try:
+ t = MailThread.objects.get(messageid=m)
+ refresh_single_thread(t)
+ except Exception, e:
+ # Just ignore it, we'll check again later
+ pass
+
+ return HttpResponse(status=200)