summaryrefslogtreecommitdiff
path: root/pgcommitfest/commitfest/forms.py
blob: 6d4c115e9dee099ffa88ce6ec3ac87b702547340 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from django import forms
from django.forms import ValidationError
from django.db.models import Q
from django.contrib.auth.models import User

from selectable.forms.widgets import AutoCompleteSelectMultipleWidget

from models import Patch, MailThread, PatchOnCommitFest
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)
	author = forms.ChoiceField(required=False)
	reviewer = forms.ChoiceField(required=False)
	sortkey = forms.IntegerField(required=False)

	def __init__(self, cf, *args, **kwargs):
		super(CommitFestFilterForm, self).__init__(*args, **kwargs)

		self.fields['sortkey'].widget = forms.HiddenInput()

		c = [(-1, '* All')] + list(PatchOnCommitFest._STATUS_CHOICES)
		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'), ] + [(u.id, '%s %s (%s)' % (u.first_name, u.last_name, u.username)) for u in User.objects.filter(q).distinct()]
		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
		exclude = ('commitfests', 'mailthreads', 'modified', 'lastmail', )
		widgets = {
			'authors': AutoCompleteSelectMultipleWidget(lookup_class=UserLookup, position='top'),
			'reviewers': AutoCompleteSelectMultipleWidget(lookup_class=UserLookup, position='top'),
		}

	def __init__(self, *args, **kwargs):
		super(PatchForm, self).__init__(*args, **kwargs)
		self.fields['authors'].help_text = 'Enter part of name to see list'
		self.fields['reviewers'].help_text = 'Enter part of name to see list'
		self.fields['committer'].label_from_instance = lambda x: '%s %s (%s)' % (x.user.first_name, x.user.last_name, x.user.username)


class NewPatchForm(forms.ModelForm):
	threadmsgid = forms.CharField(max_length=200, required=True, label='Specify thread msgid', widget=ThreadPickWidget)
#	patchfile = forms.FileField(allow_empty_file=False, max_length=50000, label='or upload patch file', required=False, help_text='This may be supported sometime in the future, and would then autogenerate a mail to the hackers list. At such a time, the threadmsgid would no longer be required.')

	class Meta:
		model = Patch
		exclude = ('commitfests', 'mailthreads', 'modified', 'authors', 'reviewers', 'committer', 'wikilink', 'gitlink', 'lastmail', )

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]]


review_state_choices = (
	(0, 'Tested'),
	(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')

	# Specific checkbox fields for reviews
	review_installcheck = reviewfield('make installcheck')
	review_implements = reviewfield('Implements feature')
	review_spec = reviewfield('Spec compliant')
	review_doc = reviewfield('Documentation')

	message = forms.CharField(required=True, widget=forms.Textarea)

	def __init__(self, patch, is_review, *args, **kwargs):
		super(CommentForm, self).__init__(*args, **kwargs)
		self.is_review = is_review

		self.fields['responseto'].choices = _fetch_thread_choices(patch)
		if not is_review:
			del self.fields['review_installcheck']
			del self.fields['review_implements']
			del self.fields['review_spec']
			del self.fields['review_doc']

	def clean_responseto(self):
		try:
			(threadid, respid) = self.cleaned_data['responseto'].split(',')
			self.thread = MailThread.objects.get(messageid=threadid)
			self.respid = respid
		except MailThread.DoesNotExist:
			raise ValidationError('Selected thread appears to no longer exist')
		except:
			raise ValidationError('Invalid message selected')
		return self.cleaned_data['responseto']

	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]:
						self.errors[fn] = (('Cannot pass a test without performing it!'),)
		return self.cleaned_data