Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(5)

Delta Between Two Patch Sets: rietveld/views.py

Issue 776: Allow reviewers to change the reviewers list (Closed) SVN Base: http://rietveld.googlecode.com/svn/trunk/
Left Patch Set: Automatically add current non-owner to reviewer list, remove duplicates in reviewer list Created 5 months ago
Right Patch Set: Stop emailing the current user if she remove herself from the reviewers list Created 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
1 # Copyright 2008 Google Inc. 1 # Copyright 2008 Google Inc.
2 # 2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); 3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License. 4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at 5 # You may obtain a copy of the License at
6 # 6 #
7 # http://www.apache.org/licenses/LICENSE-2.0 7 # http://www.apache.org/licenses/LICENSE-2.0
8 # 8 #
9 # Unless required by applicable law or agreed to in writing, software 9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, 10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and 12 # See the License for the specific language governing permissions and
13 # limitations under the License. 13 # limitations under the License.
14 14
15 """Views for Rietveld. 15 """Views for Rietveld.
16 16
17 This requires Django 0.97.pre. 17 This requires Django 0.97.pre.
18 """ 18 """
19 19
20 20
21 ### Imports ### 21 ### Imports ###
22 22
23 23
24 # Python imports 24 # Python imports
25 import os 25 import os
26 import cgi 26 import cgi
27 import random 27 import random
28 import logging 28 import logging
29 import binascii 29 import binascii
30 import sets
GvR 2008/05/11 19:20:49 This is Python 2.5, it has a built-in set type. (E
31 30
32 # AppEngine imports 31 # AppEngine imports
33 from google.appengine.api import mail 32 from google.appengine.api import mail
34 from google.appengine.api import users 33 from google.appengine.api import users
35 from google.appengine.api import urlfetch 34 from google.appengine.api import urlfetch
36 from google.appengine.ext import db 35 from google.appengine.ext import db
37 from google.appengine.ext.db import djangoforms 36 from google.appengine.ext.db import djangoforms
38 37
39 # DeadlineExceededError can live in two different places 38 # DeadlineExceededError can live in two different places
40 # TODO(guido): simplify once this is fixed. 39 # TODO(guido): simplify once this is fixed.
(...skipping 139 matching lines...) Show 10 above Show 10 below
180 max_length=1000, 179 max_length=1000,
181 widget=forms.TextInput(attrs={'size': 60})) 180 widget=forms.TextInput(attrs={'size': 60}))
182 send_mail = forms.BooleanField() 181 send_mail = forms.BooleanField()
183 message = forms.CharField(required=False, 182 message = forms.CharField(required=False,
184 max_length=10000, 183 max_length=10000,
185 widget=forms.Textarea(attrs={'cols': 60})) 184 widget=forms.Textarea(attrs={'cols': 60}))
186 185
187 186
188 class MiniPublishForm(forms.Form): 187 class MiniPublishForm(forms.Form):
189 188
190 send_mail = forms.BooleanField()
191 reviewers = forms.CharField(required=False, 189 reviewers = forms.CharField(required=False,
192 max_length=1000, 190 max_length=1000,
193 widget=forms.TextInput(attrs={'size': 60})) 191 widget=forms.TextInput(attrs={'size': 60}))
192 send_mail = forms.BooleanField()
194 message = forms.CharField(required=False, 193 message = forms.CharField(required=False,
195 max_length=10000, 194 max_length=10000,
196 widget=forms.Textarea(attrs={'cols': 60})) 195 widget=forms.Textarea(attrs={'cols': 60}))
197 196
198 197
199 class SettingsForm(forms.Form): 198 class SettingsForm(forms.Form):
200 199
201 nickname = forms.CharField(max_length=30) 200 nickname = forms.CharField(max_length=30)
202 201
203 202
(...skipping 360 matching lines...) Show 10 above Show 10 below
564 errkey = url and 'url' or 'data' 563 errkey = url and 'url' or 'data'
565 form.errors[errkey] = ['Patch set contains no recognizable patches'] 564 form.errors[errkey] = ['Patch set contains no recognizable patches']
566 return False 565 return False
567 db.put(patches) 566 db.put(patches)
568 issue.put() # To update last modified time 567 issue.put() # To update last modified time
569 return True 568 return True
570 569
571 570
572 def _get_reviewers(form): 571 def _get_reviewers(form):
573 """Helper to return the list of reviewers, or None for error.""" 572 """Helper to return the list of reviewers, or None for error."""
574 reviewers = sets.Set() 573 reviewers = []
575 raw_reviewers = form.cleaned_data.get('reviewers') 574 raw_reviewers = form.cleaned_data.get('reviewers')
576 if raw_reviewers: 575 if raw_reviewers:
577 for reviewer in raw_reviewers.split(','): 576 for reviewer in raw_reviewers.split(','):
578 reviewer = reviewer.strip() 577 reviewer = reviewer.strip()
579 if reviewer: 578 if reviewer and reviewer not in reviewers:
580 try: 579 try:
581 reviewer = db.Email(reviewer) 580 reviewer = db.Email(reviewer)
582 if reviewer.count('@') != 1: 581 if reviewer.count('@') != 1:
583 raise db.BadValueError('Invalid email address: %s' % reviewer) 582 raise db.BadValueError('Invalid email address: %s' % reviewer)
584 head, tail = reviewer.split('@') 583 head, tail = reviewer.split('@')
585 if '.' not in tail: 584 if '.' not in tail:
586 raise db.BadValueError('Invalid email address: %s' % reviewer) 585 raise db.BadValueError('Invalid email address: %s' % reviewer)
587 except db.BadValueError, err: 586 except db.BadValueError, err:
588 form.errors['reviewers'] = [unicode(err)] 587 form.errors['reviewers'] = [unicode(err)]
589 return None 588 return None
590 reviewers.add(reviewer) 589 reviewers.append(reviewer)
591 return list(reviewers) 590 return reviewers
GvR 2008/05/11 19:20:49 I'd prefer to keep reviewers in the order that the
592 591
593 592
594 593
595 @issue_required 594 @issue_required
596 def show(request, form=AddForm()): 595 def show(request, form=AddForm()):
597 """/<issue> - Show an issue.""" 596 """/<issue> - Show an issue."""
598 issue = request.issue 597 issue = request.issue
599 patchsets = list(issue.patchset_set.order('created')) 598 patchsets = list(issue.patchset_set.order('created'))
600 issue.draft_count = 0 599 issue.draft_count = 0
601 issue.comment_count = 0 600 issue.comment_count = 0
(...skipping 337 matching lines...) Show 10 above Show 10 below
939 @issue_required 938 @issue_required
940 @login_required 939 @login_required
941 def publish(request): 940 def publish(request):
942 """ /<issue>/publish - Publish draft comments and send mail.""" 941 """ /<issue>/publish - Publish draft comments and send mail."""
943 issue = request.issue 942 issue = request.issue
944 if request.user == issue.owner: 943 if request.user == issue.owner:
945 form_class = PublishForm 944 form_class = PublishForm
946 else: 945 else:
947 form_class = MiniPublishForm 946 form_class = MiniPublishForm
948 if request.method != 'POST': 947 if request.method != 'POST':
949 if request.user != issue.owner and (not request.user.email() 948 reviewers = issue.reviewers[:]
950 in issue.reviewers): 949 if request.user != issue.owner and (request.user.email()
GvR 2008/05/11 19:20:49 You can use 'not in' for the latter test.
951 issue.reviewers.append(request.user.email()) 950 not in issue.reviewers):
GvR 2008/05/11 19:20:49 I wouldn't assign to issue.reviewers here, since y
951 reviewers.append(request.user.email())
952 form = form_class(initial={'subject': issue.subject, 952 form = form_class(initial={'subject': issue.subject,
953 'reviewers': ', '.join(issue.reviewers), 953 'reviewers': ', '.join(reviewers),
954 'send_mail': True, 954 'send_mail': True,
955 }) 955 })
956 return respond(request, 'publish.html', {'form': form, 'issue': issue}) 956 return respond(request, 'publish.html', {'form': form, 'issue': issue})
957 957
958 form = form_class(request.POST) 958 form = form_class(request.POST)
959 if form.is_valid(): 959 if form.is_valid():
960 reviewers = _get_reviewers(form) 960 reviewers = _get_reviewers(form)
961 if not form.is_valid(): 961 if not form.is_valid():
962 return respond(request, 'publish.html', {'form': form, 'issue': issue}) 962 return respond(request, 'publish.html', {'form': form, 'issue': issue})
963 tbd = [] # List of things to put() after all is said and done 963 tbd = [] # List of things to put() after all is said and done
(...skipping 39 matching lines...) Show 10 above Show 10 below
1003 if comments: 1003 if comments:
1004 logging.warn('Publishing %d comments', len(comments)) 1004 logging.warn('Publishing %d comments', len(comments))
1005 # Decide who should receive mail 1005 # Decide who should receive mail
1006 my_email = db.Email(request.user.email()) 1006 my_email = db.Email(request.user.email())
1007 addressees = [db.Email(issue.owner.email())] + issue.reviewers 1007 addressees = [db.Email(issue.owner.email())] + issue.reviewers
1008 if my_email in addressees: 1008 if my_email in addressees:
1009 everyone = addressees[:] 1009 everyone = addressees[:]
1010 if len(addressees) > 1: # Keep it if sending only to yourself 1010 if len(addressees) > 1: # Keep it if sending only to yourself
1011 addressees.remove(my_email) 1011 addressees.remove(my_email)
1012 else: 1012 else:
1013 everyone = addressees + [my_email] 1013 everyone = addressees
1014 details = _get_draft_details(request, comments) 1014 details = _get_draft_details(request, comments)
1015 text = ((message.strip() + '\n\n' + details.strip())).strip() 1015 text = ((message.strip() + '\n\n' + details.strip())).strip()
1016 msg = models.Message(issue=issue, 1016 msg = models.Message(issue=issue,
1017 subject=issue.subject, 1017 subject=issue.subject,
1018 sender=my_email, 1018 sender=my_email,
1019 recipients=everyone, 1019 recipients=everyone,
1020 text=db.Text(text), 1020 text=db.Text(text),
1021 parent=issue) 1021 parent=issue)
1022 tbd.append(msg) 1022 tbd.append(msg)
1023 1023
(...skipping 220 matching lines...) Show 10 above Show 10 below
1244 else: 1244 else:
1245 accounts = models.Account.get_accounts_for_nickname(nickname) 1245 accounts = models.Account.get_accounts_for_nickname(nickname)
1246 if nickname != account.nickname and accounts: 1246 if nickname != account.nickname and accounts:
1247 form.errors['nickname'] = ['This nickname is already in use.'] 1247 form.errors['nickname'] = ['This nickname is already in use.']
1248 else: 1248 else:
1249 account.nickname = nickname 1249 account.nickname = nickname
1250 account.put() 1250 account.put()
1251 if not form.is_valid(): 1251 if not form.is_valid():
1252 return respond(request, 'settings.html', {'form': form}) 1252 return respond(request, 'settings.html', {'form': form})
1253 return HttpResponseRedirect('/settings') 1253 return HttpResponseRedirect('/settings')
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld r338