Exemple #1
0
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."
    )
Exemple #2
0
    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.',
        )
Exemple #3
0
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,
        })
Exemple #4
0
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()
        }
    )
Exemple #5
0
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! &emsp; <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(),
        }
    )