File diff ac57053ecf58 → 252697b842c0
vendor/symposion/reviews/views.py
Show inline comments
...
 
@@ -175,204 +175,207 @@ def review_proposals_csv(request, section_slug=None):
 
    for proposal in proposals:
 

	
 
        proposal.speaker_name = proposal.speaker.name
 
        section_slug = proposal.kind.section.slug
 
        kind_slug = proposal.kind.slug
 
        proposal.proposal_type = kind_slug
 

	
 
        if hasattr(proposal, "target_audience"):
 
            proposal.audience = proposal.get_target_audience_display()
 
        else:
 
            proposal.audience = "Unknown"
 

	
 
        proposal.other_speakers = ", ".join(
 
            speaker.name
 
            for speaker in proposal.additional_speakers.all()
 
        )
 

	
 
        proposal.speaker_travel = ", ".join(
 
            str(bool(speaker.travel_assistance))
 
            for speaker in proposal.speakers()
 
        )
 

	
 
        proposal.speaker_accommodation = ", ".join(
 
            str(bool(speaker.accommodation_assistance))
 
            for speaker in proposal.speakers()
 
        )
 

	
 
        suggested_status = proposal.status
 
        if suggested_status == "undecided":
 
            if proposal.score >= 1.5:
 
                suggested_status = "auto-accept"
 
            elif proposal.score <= -1.5:
 
                suggested_status = "auto-reject"
 
        proposal.suggested_status = suggested_status
 

	
 
        if not request.user.has_perm("reviews.can_review_%s" % section_slug):
 
            continue
 

	
 
        csv_line = [getattr(proposal, field) for field in fields]
 

	
 
        writer.writerow(csv_line)
 

	
 
    return response
 

	
 

	
 
@login_required
 
def review_random_proposal(request, section_slug):
 
    # lca2017 #16 view for random proposal
 

	
 
    if not request.user.has_perm("reviews.can_review_%s" % section_slug):
 
        return access_not_permitted(request)
 

	
 
    section = get_object_or_404(ProposalSection, section__slug=section_slug)
 
    queryset = ProposalBase.objects.filter(kind__section=section.section)
 
    # Remove ones already reviewed
 
    queryset = queryset.exclude(reviews__user=request.user)
 
    # Remove withdrawn talks
 
    queryset = queryset.exclude(cancelled=True)
 
    # Remove talks the reviewer can't vote on -- their own.
 
    queryset = queryset.exclude(speaker__user=request.user)
 
    queryset = queryset.exclude(additional_speakers__user=request.user)
 

	
 
    if len(queryset) == 0:
 
        return redirect("review_section", section_slug=section_slug, reviewed="all")
 

	
 
    # Direct reviewers to underreviewed proposals
 
    too_few_set = REVIEW_STATUS_FILTERS[TOO_FEW](queryset)
 
    controversial_set = REVIEW_STATUS_FILTERS[CONTROVERSIAL](queryset)
 

	
 
    if len(too_few_set) > 0:
 
        proposals = too_few_set.all()
 
    elif len(controversial_set) > 0 and random.random() < 0.2:
 
        proposals = controversial_set.all()
 
    else:
 
        # Select a proposal with less than the median number of total votes
 
        proposals = proposals_generator(request, queryset, check_speaker=False)
 
        proposals = list(proposals)
 
        proposals.sort(key=lambda proposal: proposal.total_votes)
 
        # The first half is the median or less.
 
        proposals = proposals[:math.ceil(len(proposals) / 2)]
 

	
 
    # Realistically, there shouldn't be all that many proposals to choose
 
    # from, so this should be cheap.
 
    chosen = random.choice(proposals)
 
    return redirect("review_detail", pk=chosen.pk)
 

	
 

	
 
@login_required
 
def review_list(request, section_slug, user_pk):
 

	
 
    # if they're not a reviewer admin and they aren't the person whose
 
    # review list is being asked for, don't let them in
 
    if not request.user.has_perm("reviews.can_manage_%s" % section_slug):
 
        if not request.user.pk == user_pk:
 
            return access_not_permitted(request)
 

	
 
    section = get_object_or_404(ProposalSection, section__slug=section_slug)
 

	
 
    queryset = ProposalBase.objects.select_related("speaker__user", "result")
 
    reviewed = LatestVote.objects.filter(user__pk=user_pk).values_list("proposal", flat=True)
 
    queryset = queryset.filter(kind__section__slug=section_slug)
 
    queryset = queryset.filter(pk__in=reviewed)
 
    proposals = queryset.order_by("submitted")
 

	
 
    admin = request.user.has_perm("reviews.can_manage_%s" % section_slug)
 

	
 
    proposals = proposals_generator(request, proposals, user_pk=user_pk, check_speaker=not admin)
 

	
 
    ctx = {
 
        "proposals": proposals,
 
        "section": section,
 
    }
 
    return render(request, "symposion/reviews/review_list.html", ctx)
 

	
 

	
 
@login_required
 
def review_admin(request, section_slug):
 

	
 
    if not request.user.has_perm("reviews.can_manage_%s" % section_slug):
 
        return access_not_permitted(request)
 

	
 
    def reviewers():
 
        already_seen = set()
 

	
 
        for team in Team.objects.filter(permissions__codename="can_review_%s" % section_slug):
 
            for membership in team.memberships.filter(Q(state="member") | Q(state="manager")):
 
                user = membership.user
 
                if user.pk in already_seen:
 
                    continue
 
                already_seen.add(user.pk)
 

	
 
                user.comment_count = Review.objects.filter(
 
                    user=user,
 
                    proposal__kind__section__slug=section_slug,
 
                ).count()
 

	
 
                user_votes = LatestVote.objects.filter(
 
                    user=user,
 
                    proposal__kind__section__slug=section_slug,
 
                )
 
                user.total_votes = user_votes.exclude(
 
                    vote=LatestVote.VOTES.ABSTAIN,
 
                ).count()
 
                user.plus_two = user_votes.filter(
 
                    vote=LatestVote.VOTES.PLUS_TWO,
 
                ).count()
 
                user.plus_one = user_votes.filter(
 
                    vote=LatestVote.VOTES.PLUS_ONE,
 
                ).count()
 
                user.minus_one = user_votes.filter(
 
                    vote=LatestVote.VOTES.MINUS_ONE,
 
                ).count()
 
                user.minus_two = user_votes.filter(
 
                    vote=LatestVote.VOTES.MINUS_TWO,
 
                ).count()
 
                user.abstain = user_votes.filter(
 
                    vote=LatestVote.VOTES.ABSTAIN,
 
                ).count()
 
                if user.total_votes == 0:
 
                    user.average = "-"
 
                else:
 
                    user.average = (
 
                        ((user.plus_two * 2) + user.plus_one) -
 
                        ((user.minus_two * 2) + user.minus_one)
 
                    ) / (user.total_votes * 1.0)
 

	
 
                yield user
 

	
 
    reviewers_sorted = list(reviewers())
 
    reviewers_sorted.sort(key=lambda reviewer: 0 - reviewer.total_votes)
 

	
 
    ctx = {
 
        "section_slug": section_slug,
 
        "reviewers": reviewers_sorted,
 
    }
 
    return render(request, "symposion/reviews/review_admin.html", ctx)
 

	
 

	
 
# FIXME: This view is too complex according to flake8
 
@login_required
 
@transaction.atomic
 
def review_detail(request, pk):
 

	
 
    proposals = ProposalBase.objects.select_related("result").select_subclasses()
 
    proposal = get_object_or_404(proposals, pk=pk)
 

	
 
    if not request.user.has_perm("reviews.can_review_%s" % proposal.kind.section.slug):
 
        return access_not_permitted(request)
 

	
 
    speakers = [s.user for s in proposal.speakers()]
 

	
 
    if not request.user.is_superuser and request.user in speakers:
 
        return access_not_permitted(request)
 

	
 
    admin = request.user.has_perm("reviews.can_manage_%s" % proposal.kind.section.slug)
 

	
 
    try:
 
        latest_vote = LatestVote.objects.get(proposal=proposal, user=request.user)
 
    except LatestVote.DoesNotExist:
 
        latest_vote = None
 

	
 
    if request.method == "POST":
 
        if not admin and request.user in speakers:
 
            return access_not_permitted(request)
 

	
 
        if "vote_submit" in request.POST or "vote_submit_and_random" in request.POST:
 
            review_form = ReviewForm(request.POST)