Example #1
0
    def wrapper(request, slug, **kwargs):
        tlk = get_object_or_404(models.Talk, slug=slug)
        if request.user.is_anonymous():
            full_access = False
        elif request.user.is_staff:
            full_access = True
        else:
            try:
                tlk.get_all_speakers().get(user__id=request.user.id)
            except (models.Speaker.DoesNotExist,
                    models.Speaker.MultipleObjectsReturned):
                # The MultipleObjectsReturned can happen if the user is not logged on and .id is None
                full_access = False
            else:
                full_access = True

        # if the talk is unconfirmed can access:
        #   * superusers or speakers (full access = True)
        #   * if the community voting is in progress who has the right to vote
        if tlk.status == 'proposed' and not full_access:
            conf = models.Conference.objects.current()
            if not settings.VOTING_OPENED(conf, request.user):
                return http.HttpResponseForbidden()
            if not settings.VOTING_ALLOWED(request.user):
                if settings.VOTING_DISALLOWED:
                    return redirect(settings.VOTING_DISALLOWED)
                else:
                    return http.HttpResponseForbidden()

        return f(request, slug, talk=tlk, full_access=full_access, **kwargs)
Example #2
0
    def wrapper(request, slug, **kwargs):
        try:
            profile = models.AttendeeProfile.objects\
                .select_related('user')\
                .get(slug=slug)
        except models.AttendeeProfile.DoesNotExist:
            raise http.Http404()

        if request.user.is_staff or request.user == profile.user:
            full_access = True
        else:
            full_access = False
            # if the profile belongs to a speaker with talk of "accepted" is visible
            # whatever you say the same profile.
            accepted = models.TalkSpeaker.objects\
                .filter(speaker__user=profile.user)\
                .filter(talk__status='accepted')\
                .count()
            if not accepted:
                # if the community voting is open and the profile belongs to a speaker
                # with the talk in the race page is visible
                conf = models.Conference.objects.current()
                if not (settings.VOTING_OPENED(conf, request.user)
                        and settings.VOTING_ALLOWED(request.user)):
                    if profile.visibility == 'x':
                        return http.HttpResponseForbidden()
                    elif profile.visibility == 'm' and request.user.is_anonymous(
                    ):
                        return http.HttpResponseForbidden()
        return f(request,
                 slug,
                 profile=profile,
                 full_access=full_access,
                 **kwargs)
Example #3
0
    def wrapper(request, slug, **kwargs):
        spk = get_object_or_404(models.Speaker, slug=slug)
        if request.user.is_staff or request.user == spk.user:
            full_access = True
            talks = spk.talks()
        else:
            full_access = False
            conf = models.Conference.objects.current()
            if settings.VOTING_OPENED(conf, request.user):
                if settings.VOTING_ALLOWED(request.user):
                    talks = spk.talks()
                else:
                    if settings.VOTING_DISALLOWED:
                        return redirect(settings.VOTING_DISALLOWED)
                    else:
                        raise http.Http404()
            else:
                talks = spk.talks(status='accepted')
                if talks.count() == 0:
                    raise http.Http404()

        return f(request,
                 slug,
                 speaker=spk,
                 talks=talks,
                 full_access=full_access,
                 **kwargs)
Example #4
0
    def wrapper(request, slug, **kwargs):
        try:
            profile = models.AttendeeProfile.objects\
                .select_related('user')\
                .get(slug=slug)
        except models.AttendeeProfile.DoesNotExist:
            raise http.Http404()

        if request.user.is_staff or request.user == profile.user:
            full_access = True
        else:
            full_access = False
            # se il profilo appartiene ad uno speaker con dei talk "accepted" è
            # visibile qualunque cosa dica il profilo stesso
            accepted = models.TalkSpeaker.objects\
                .filter(speaker__user=profile.user)\
                .filter(talk__status='accepted')\
                .count()
            if not accepted:
                # Se la votazione comunitaria à aperta e il profilo appartiene
                # ad uno speaker con dei talk in gara la pagina è visibile
                conf = models.Conference.objects.current()
                if not (settings.VOTING_OPENED(conf, request.user)
                        and settings.VOTING_ALLOWED(request.user)):
                    if profile.visibility == 'x':
                        return http.HttpResponseForbidden()
                    elif profile.visibility == 'm' and request.user.is_anonymous(
                    ):
                        return http.HttpResponseForbidden()
        return f(request,
                 slug,
                 profile=profile,
                 full_access=full_access,
                 **kwargs)
Example #5
0
    def wrapper(request, slug, **kwargs):
        tlk = get_object_or_404(models.Talk, slug=slug)
        if request.user.is_anonymous():
            full_access = False
        elif request.user.is_staff:
            full_access = True
        else:
            try:
                tlk.get_all_speakers().get(user__id=request.user.id)
            except (models.Speaker.DoesNotExist,
                    models.Speaker.MultipleObjectsReturned):
                # Il MultipleObjectsReturned può capitare se l'utente non è loggato
                # e .id vale None
                full_access = False
            else:
                full_access = True

        # Se il talk non è confermato possono accedere:
        #   * i super user o gli speaker (full_access = True)
        #   * se la votazione comunitarià è in corso chi ha il diritto di votare
        if tlk.status == 'proposed' and not full_access:
            conf = models.Conference.objects.current()
            if not settings.VOTING_OPENED(conf, request.user):
                return http.HttpResponseForbidden()
            if not settings.VOTING_ALLOWED(request.user):
                if settings.VOTING_DISALLOWED:
                    return redirect(settings.VOTING_DISALLOWED)
                else:
                    return http.HttpResponseForbidden()

        return f(request, slug, talk=tlk, full_access=full_access, **kwargs)
Example #6
0
def subcommunity_talk_voting(request):
    """
    View Callback used for community talk voting.
    This view wraps the conference voting view,
    and adds a talk filter based on sub_communities.
    """

    if request.method == 'POST':
        return voting(request)
    else:
        conf, talks, voting_allowed = get_data_for_context(request)

        if not csettings.VOTING_OPENED(conf, request.user):
            if csettings.VOTING_CLOSED:
                return redirect(csettings.VOTING_CLOSED)
            else:
                raise http.Http404()

        ctx = filter_talks_in_context(request, talks, voting_allowed)
        filtered_talks = ctx['talks']

        sub_community_choices = [list(v) for v in TALK_SUBCOMMUNITY]
        sub_community_choices[0][1] = _('All')

        class SubCommunityOptionForm(OptionForm):
            sub_community = forms.ChoiceField(
                choices=sub_community_choices,
                required=False,
                initial='',
                widget=forms.RadioSelect(renderer=PseudoRadioRenderer),
            )

        if request.GET:
            form = SubCommunityOptionForm(data=request.GET)
            form.is_valid()
            options = form.cleaned_data
        else:
            form = SubCommunityOptionForm()
            options = {
                'abstracts': 'not-voted',
                'talk_type': '',
                'language': '',
                'tags': '',
                'order': 'vote',
                'sub_community': '',
            }

        if options['sub_community'] != '':
            sub_community_talks = P3Talk.objects.filter(
                sub_community=options['sub_community'])
            sub_community_talks = [p3talk.pk for p3talk in sub_community_talks]
            talks_id = [t['id'] for t in filtered_talks]
            talks = list()
            for idx, tid in enumerate(talks_id):
                if tid in sub_community_talks:
                    talks.append(filtered_talks[idx])
            ctx.update({'talks': talks})
        ctx.update({'form': form})

        if request.is_ajax():
            tpl = 'conference/ajax/voting.html'
        else:
            tpl = 'conference/voting.html'
        return render(request, tpl, ctx)
Example #7
0
def voting(request):

    conf, talks, voting_allowed = get_data_for_context(request)

    if not settings.VOTING_OPENED(conf, request.user):
        if settings.VOTING_CLOSED:
            return redirect(settings.VOTING_CLOSED)
        else:
            raise http.Http404()

    if request.method == 'POST':
        if not voting_allowed:
            return http.HttpResponseBadRequest('anonymous user not allowed')

        data = dict((x.id, x) for x in talks)
        for k, v in filter(lambda x: x[0].startswith('vote-'),
                           request.POST.items()):
            try:
                talk = data[int(k[5:])]
            except KeyError:
                return http.HttpResponseBadRequest('invalid talk')
            except ValueError:
                return http.HttpResponseBadRequest('id malformed')
            if not v:
                models.VotoTalk.objects.filter(user=request.user,
                                               talk=talk).delete()
            else:
                try:
                    vote = Decimal(v)
                except ValueError:
                    return http.HttpResponseBadRequest('vote malformed')
                try:
                    o = models.VotoTalk.objects.get(user=request.user,
                                                    talk=talk)
                except models.VotoTalk.DoesNotExist:
                    o = models.VotoTalk(user=request.user, talk=talk)
                if not vote:
                    if o.id:
                        o.delete()
                else:
                    o.vote = vote
                    o.save()
        if request.is_ajax():
            return http.HttpResponse('')
        else:
            return HttpResponseRedirectSeeOther(
                reverse('conference-voting') + '?' + request.GET.urlencode())
    else:
        from conference.forms import TagField, ReadonlyTagWidget, PseudoRadioRenderer

        class OptionForm(forms.Form):
            abstracts = forms.ChoiceField(
                choices=(
                    ('not-voted', 'Not yet voted'),
                    ('all', 'All'),
                ),
                required=False,
                initial='not-voted',
                widget=forms.RadioSelect(renderer=PseudoRadioRenderer),
            )
            talk_type = forms.ChoiceField(
                label=u'Session type',
                choices=(('all', 'All'), ) +
                tuple(settings.TALK_TYPES_TO_BE_VOTED),
                required=False,
                initial='all',
                widget=forms.RadioSelect(renderer=PseudoRadioRenderer),
            )
            language = forms.ChoiceField(
                choices=(('all', 'All'), ) +
                tuple(settings.TALK_SUBMISSION_LANGUAGES),
                required=False,
                initial='all',
                widget=forms.RadioSelect(renderer=PseudoRadioRenderer),
            )
            order = forms.ChoiceField(
                choices=(
                    ('random', 'Random order'),
                    ('vote', 'Vote'),
                    ('speaker', 'Speaker name'),
                ),
                required=False,
                initial='random',
                widget=forms.RadioSelect(renderer=PseudoRadioRenderer),
            )
            tags = TagField(
                required=False,
                widget=ReadonlyTagWidget(),
            )

        # I want to associate with each talk a "unique" number to display next to the title to be able to easily find.
        ordinal = dict()
        for ix, t in enumerate(
                talks.order_by('created').values_list('id', flat=True)):
            ordinal[t] = ix

        user_votes = models.VotoTalk.objects.filter(user=request.user.id)

        # Start by sorting talks by name
        talks = talks.order_by('speakers__user__first_name',
                               'speakers__user__last_name')

        if request.GET:
            form = OptionForm(data=request.GET)
            form.is_valid()
            options = form.cleaned_data
        else:
            form = OptionForm()
            options = {
                'abstracts': 'not-voted',
                'talk_type': 'all',
                'language': 'all',
                'tags': '',
                'order': 'random',
            }
        # if options['abstracts'] == 'not-voted':
        #     talks = talks.exclude(id__in=user_votes.values('talk_id'))
        if options['talk_type'] in (
                tchar for (tchar, tdef) in settings.TALK_TYPES_TO_BE_VOTED):
            talks = talks.filter(type__startswith=options['talk_type'])

        if options['language'] in (
                lcode for (lcode, ldef) in settings.TALK_SUBMISSION_LANGUAGES):
            talks = talks.filter(language=options['language'])

        if options['tags']:
            # if options['tags'] ends us a tag not associated with any talk I results
            # in a query that results from scratch; to avoid this limit the usable tag
            # as a filter to those associated with talk.
            allowed = set()
            ctt = ContentType.objects.get_for_model(models.Talk)
            for t, usage in dataaccess.tags().items():
                for cid, oid in usage:
                    if cid == ctt.id:
                        allowed.add(t.name)
                        break
            tags = set(options['tags']) & allowed
            if tags:
                talks = talks.filter(id__in=models.ConferenceTaggedItem.objects\
                    .filter(
                        content_type__app_label='conference', content_type__model='talk',
                        tag__name__in=tags)\
                    .values('object_id')
                )

        talk_order = options['order']
        votes = dict((x.talk_id, x) for x in user_votes)

        # As talks are sorted by a model connected via a m2m can I have repeated the talk, and
        # distinct does not apply in these case.
        #
        # It can only filtered in python, at this point I take this opportunity to engage
        # votes user using a single loop.
        dups = set()

        def filter_vote(t):
            if t['id'] in dups:
                return False
            dups.add(t['id'])
            t['user_vote'] = votes.get(t['id'])
            t['ordinal'] = ordinal[t['id']]
            return True

        talks = filter(filter_vote, talks.values('id'))

        # Fix talk order, if necessary
        if talk_order == 'vote':

            def key(x):
                if x['user_vote']:
                    return x['user_vote'].vote
                else:
                    return Decimal('-99.99')

            talks = reversed(sorted(reversed(talks), key=key))
        elif talk_order == 'random':
            random.shuffle(talks)
        elif talk_order == 'speaker':
            # Already sorted
            pass

        ctx = {
            'voting_allowed': voting_allowed,
            'talks': list(talks),
            'form': form,
        }
        if request.is_ajax():
            tpl = 'conference/ajax/voting.html'
        else:
            tpl = 'conference/voting.html'
        return render(request, tpl, ctx)
Example #8
0
def voting(request):

    conf, talks, voting_allowed = get_data_for_context(request)

    if not settings.VOTING_OPENED(conf, request.user):
        if settings.VOTING_CLOSED:
            return redirect(settings.VOTING_CLOSED)
        else:
            raise http.Http404()

    if request.method == 'POST':
        if not voting_allowed:
            return http.HttpResponseBadRequest('anonymous user not allowed')

        data = dict((x.id, x) for x in talks)
        for k, v in filter(lambda x: x[0].startswith('vote-'),
                           request.POST.items()):
            try:
                talk = data[int(k[5:])]
            except KeyError:
                return http.HttpResponseBadRequest('invalid talk')
            except ValueError:
                return http.HttpResponseBadRequest('id malformed')
            if not v:
                models.VotoTalk.objects.filter(user=request.user,
                                               talk=talk).delete()
            else:
                try:
                    vote = Decimal(v)
                except ValueError:
                    return http.HttpResponseBadRequest('vote malformed')
                try:
                    o = models.VotoTalk.objects.get(user=request.user,
                                                    talk=talk)
                except models.VotoTalk.DoesNotExist:
                    o = models.VotoTalk(user=request.user, talk=talk)
                if not vote:
                    if o.id:
                        o.delete()
                else:
                    o.vote = vote
                    o.save()
        if request.is_ajax():
            return http.HttpResponse('')
        else:
            return HttpResponseRedirectSeeOther(
                reverse('conference-voting') + '?' + request.GET.urlencode())
    else:
        from conference.forms import TagField, ReadonlyTagWidget, PseudoRadioRenderer

        class OptionForm(forms.Form):
            abstracts = forms.ChoiceField(
                choices=(
                    ('not-voted', 'To be voted'),
                    ('all', 'All'),
                ),
                required=False,
                initial='not-voted',
                widget=forms.RadioSelect(renderer=PseudoRadioRenderer),
            )
            talk_type = forms.ChoiceField(
                choices=settings.TALK_TYPES_TO_BE_VOTED,
                required=False,
                initial='all',
                widget=forms.RadioSelect(renderer=PseudoRadioRenderer),
            )
            language = forms.ChoiceField(
                choices=(
                    ('all', 'All'),
                    ('en', 'English'),
                    ('it', 'Italian'),
                ),
                required=False,
                initial='all',
                widget=forms.RadioSelect(renderer=PseudoRadioRenderer),
            )
            order = forms.ChoiceField(
                choices=(
                    ('vote', 'Vote'),
                    ('speaker', 'Speaker name'),
                ),
                required=False,
                initial='vote',
                widget=forms.RadioSelect(renderer=PseudoRadioRenderer),
            )
            tags = TagField(
                required=False,
                widget=ReadonlyTagWidget(),
            )

        # voglio poter associare ad ogni talk un numero "univoco" da mostrare
        # accanto al titolo per poterlo individuare facilmente.
        ordinal = dict()
        for ix, t in enumerate(
                talks.order_by('created').values_list('id', flat=True)):
            ordinal[t] = ix

        user_votes = models.VotoTalk.objects.filter(user=request.user.id)
        talks = talks.order_by('speakers__user__first_name',
                               'speakers__user__last_name')

        if request.GET:
            form = OptionForm(data=request.GET)
            form.is_valid()
            options = form.cleaned_data
        else:
            form = OptionForm()
            options = {
                'abstracts': 'not-voted',
                'talk_type': '',
                'language': '',
                'tags': '',
                'order': 'vote',
            }
        if options['abstracts'] != 'all':
            talks = talks.exclude(id__in=user_votes.values('talk_id'))
        if options['talk_type'] in ('s', 't', 'p'):
            talks = talks.filter(type=options['talk_type'])

        if options['language'] in ('en', 'it'):
            talks = talks.filter(language=options['language'])

        if options['tags']:
            # se in options['tags'] ci finisce un tag non associato ad alcun
            # talk ho come risultato una query che da zero risultati; per
            # evitare questo limito i tag usabili come filtro a quelli
            # associati ai talk.
            allowed = set()
            ctt = ContentType.objects.get_for_model(models.Talk)
            for t, usage in dataaccess.tags().items():
                for cid, oid in usage:
                    if cid == ctt.id:
                        allowed.add(t.name)
                        break
            tags = set(options['tags']) & allowed
            if tags:
                talks = talks.filter(id__in=models.ConferenceTaggedItem.objects\
                    .filter(
                        content_type__app_label='conference', content_type__model='talk',
                        tag__name__in=tags)\
                    .values('object_id')
                )

        talk_order = options['order']

        votes = dict((x.talk_id, x) for x in user_votes)

        # Poichè talks è ordinato per un modello collegato tramite una
        # ManyToMany posso avere dei talk ripetuti, e il distinct non si
        # applica in questi casi.
        #
        # Non mi rimane che filtrare in python, a questo punto ne approfitto
        # per agganciare i voti dell'utente utilizzando un unico loop.
        dups = set()

        def filter_vote(t):
            if t['id'] in dups:
                return False
            dups.add(t['id'])
            t['user_vote'] = votes.get(t['id'])
            t['ordinal'] = ordinal[t['id']]
            return True

        talks = filter(filter_vote, talks.values('id'))

        if talk_order != 'speaker':

            def key(x):
                if x['user_vote']:
                    return x['user_vote'].vote
                else:
                    return Decimal('-99.99')

            talks = reversed(sorted(reversed(talks), key=key))

        ctx = {
            'voting_allowed': voting_allowed,
            'talks': list(talks),
            'form': form,
        }
        if request.is_ajax():
            tpl = 'conference/ajax/voting.html'
        else:
            tpl = 'conference/voting.html'
        return render(request, tpl, ctx)