def resetpw(request): """Send a password reset e-mail to a user's e-mail addresses. We support recovery in two modes: * By username, in which we e-mail all the e-mail addresses associated with an account. * By e-mail, in which we e-mail the given e-mail address, once for each username associated with an account. """ if request.method != 'POST': return redirect(login_page) username_email = request.POST.get('username_email') if not username_email: return redirect_to_login('No username/email supplied!') if '@' in username_email: users = User.objects.filter( emailaddress__address=username_email ).distinct() addresses = [username_email] else: users = User.objects.filter(username__exact=username_email) try: user = users.get() except User.DoesNotExist: return redirect_to_login('No such user {}!'.format(username_email)) addresses = [a.address for a in user.emailaddress_set.all()] for u in users: secret = SIGNER.sign(rot13(u.username)) sending.send_template( subject='Account recovery', template_name='account-recovery', recipients=addresses, params={ 'username': u.username, 'secret': secret, }, priority=sending.PRIORITY_IMMEDIATE, reason='because someone, possibly you, requested account ' + 'recovery at pyweek.org.', ) return redirect_to_login( "Please check your inbox for an account recovery e-mail." )
def request_verification(self): """Send an e-mail address verification code.""" from pyweek.mail import sending if self.verified: return self.verification_key = default_verification_key() self.save() sending.send_template( subject='E-mail verification', template_name='email-verification', recipients=[self.address], params={ 'user': self.user, 'address': self.address, 'verification_key': self.verification_key, }, priority=sending.PRIORITY_IMMEDIATE, reason='because someone, possibly you, entered ' + 'your e-mail address at pyweek.org.', )
def diary_display(request, diary_id): """Display a message thread.""" diary = get_object_or_404(models.DiaryEntry, pk=diary_id) entry = diary.entry challenge = diary.challenge is_member = entry and request.user in entry.users.all() is_anon = request.user.is_anonymous previewed = False if request.POST: form = CommentForm(request.POST) if form.is_valid(): previewed = True # do the save comment = models.DiaryComment(content=form.cleaned_data['content'], challenge=challenge, user=request.user, diary_entry=diary) comment.save() diary.activity = datetime.datetime.utcnow() diary.actor = request.user diary.last_comment = comment diary.reply_count = diary.reply_count + 1 diary.save() messages.success(request, 'Comment added!') # Send notifies addresses = EmailAddress.objects.filter( user__settings__email_replies=True, ).filter( # TODO: filter by users who want to receive notifications Q(user__diarycomment__diary_entry=diary) | Q(user=diary.user)).exclude( user=request.user).distinct().select_related('user') sending.send_template( subject= f'New comment from {request.user.username} on "{diary.title}"', template_name='diary-reply', recipients=addresses, params={ 'diary': diary, 'comment': comment, }, reason=sending.REASON_COMMENTS) return HttpResponseRedirect(f'/d/{diary_id}/#{comment.id}') else: form = CommentForm() return render( request, 'challenge/diary.html', { 'challenge': challenge, 'entry': entry, 'diary': diary, 'is_user': not request.user.is_anonymous, 'previewed': previewed, 'content': diary.content, 'form': form, 'comments': diary.diarycomment_set.all(), 'is_member': is_member, 'is_owner': entry and entry.user == request.user, })
def entry_requests(request, entry_id): """Approve or reject join requests for a team.""" back_to_entry = HttpResponseRedirect(f'/e/{entry_id}/') if request.user.is_anonymous: return back_to_entry entry = get_object_or_404(models.Entry, pk=entry_id) if not entry.is_open: messages.error(request, "This is not an open team.") return back_to_entry if entry.user != request.user: messages.error( request, "Only the team owner can accept membership requests." ) return back_to_entry if request.method == 'POST': data = request.POST added = set() rejected = set() for u in list(entry.join_requests.all()): action = request.POST.get('user:'******'approve': # TODO: send e-mail entry.users.add(u) entry.join_requests.remove(u) added.add(u) elif action == 'reject': # TODO: send e-mail entry.join_requests.remove(u) rejected.add(u) team_name = entry.title or entry.name if added: addresses = [ a.address for a in EmailAddress.objects.filter(user__in=added) ] sending.send_template( subject=f'{team_name} team membership accepted', template_name='team-request-accepted', recipients=addresses, params={ 'entry': entry, }, reason='because you requested to join this team.', ) if added or rejected: msgs = [] if added: msgs.append(f'added {len(added)} new team members') if rejected: msgs.append( f'rejected {len(rejected)} membership requests' ) messages.success(request, ' and '.join(msgs).capitalize()) return back_to_entry else: messages.error(request, 'No changes made.') return render( request, 'challenge/entry_requests.html', { 'entry': entry, 'requesters': entry.join_requests.all() } )
def entry_display(request, entry_id): entry = get_object_or_404(models.Entry, pk=entry_id) challenge = entry.challenge user_list = entry.users.all() is_member = request.user in list(user_list) files = entry.file_set.filter(is_screenshot__exact=True).order_by("-created")[:1] thumb = None if files: thumb = files[0] # handle adding the ratings form and accepting ratings submissions f = None if entry.may_rate(request.user, challenge) and challenge.isRatingOpen(): errors = {} # get existing scores rating = None for rating in entry.rating_set.filter(user__id__exact=request.user.id): break # fields for rating editing if request.method == 'POST': f = RatingForm(request.POST) if f.is_valid(): if rating is not None: # edit existing rating.disqualify = f.cleaned_data['disqualify'] rating.nonworking = f.cleaned_data['nonworking'] rating.fun = f.cleaned_data['fun'] rating.innovation = f.cleaned_data['innovation'] rating.production = f.cleaned_data['production'] rating.comment = f.cleaned_data['comment'] else: # create new rating = models.Rating( entry=entry, user=request.user, disqualify=f.cleaned_data['disqualify'], nonworking=f.cleaned_data['nonworking'], fun=f.cleaned_data['fun'], innovation=f.cleaned_data['innovation'], production=f.cleaned_data['production'], comment=f.cleaned_data['comment'], ) rating.save() messages.info( request, 'Rating saved!   <a href="/{}/rating-dashboard">' 'Return to rating dashboard</a>'.format( entry.challenge.number, ) ) return HttpResponseRedirect(f"/e/{entry.name}/") elif rating is not None: data = dict( disqualify=rating.disqualify, nonworking=rating.nonworking, fun=rating.fun, innovation=rating.innovation, production=rating.production, comment=rating.comment ) f = RatingForm(data) else: f = RatingForm() rating_results = False if challenge.isAllDone() and entry.has_final: # display ratings d = rating_results = entry.tally_ratings() d['dp'] = f"{int(d.get('disqualify', 0) * 100)}%" d['dnwp'] = f"{int(d.get('nonworking', 0) * 100)}%" join_requested = False if request.user.is_authenticated: if request.POST.get('action') == 'join': if not entry.is_open: messages.error(request, "Sorry, {} is no longer accepting join requests.".format( entry.title or entry.name ) ) elif not entry.challenge.isRegoOpen(): messages.error(request, "You cannot join {} as the respective PyWeek challenge has ended.".format( entry.title or entry.name ) ) elif is_member: messages.error( request, "You are already a member of this team." ) else: owner = entry.user addresses = [a.address for a in owner.emailaddress_set.all()] entry.join_requests.add(request.user) sending.send_template( subject='Team membership request', template_name='team-request', recipients=addresses, params={ 'user': request.user, 'entry': entry, }, reason='because you created an open team on pyweek.org.', ) messages.success(request, "Request sent!") return HttpResponseRedirect(entry.get_absolute_url()) join_requested = ( entry.is_open and request.user in entry.join_requests.all() ) return render(request, 'challenge/entry.html', { 'challenge': challenge, 'entry': entry, 'files': entry.file_set.all(), 'thumb': thumb, 'diary_entries': entry.diary_entries(), 'is_user': not request.user.is_anonymous, 'is_member': is_member, 'is_team': len(user_list) > 1, 'is_owner': entry.user == request.user, 'join_requested': join_requested, 'form': f, 'rating': rating_results, 'awards': entry.entryaward_set.all(), } )