示例#1
0
文件: views.py 项目: fdenzer/Bitpoll
def edit_dt_choice_combinations(request, poll_url):
    current_poll = get_object_or_404(Poll, url=poll_url)
    if not current_poll.can_edit(request.user):
        messages.error(request, _("You are not allowed to edit this Poll."))
        return redirect('poll', poll_url)

    tz_activate(current_poll.timezone_name)
    if request.method == 'POST':
        # getlist does not raise an exception if datetimes[] is not in request.POST
        chosen_combinations = request.POST.getlist('datetimes[]')

        chosen_times = []
        new_choices = []
        old_choices = []
        choices = current_poll.choice_set.all()
        # List of the Old Ids, used for detection what has to be deleted
        old_choices_ids = [c.pk for c in choices]
        # parse datetime objects of chosen combinations
        for combination in chosen_combinations:
            try:
                tz = timezone(current_poll.timezone_name)
                timestamp = parse_datetime(combination)
                if timestamp:
                    chosen_times.append(tz.localize(timestamp))
                else:
                    messages.error(
                        request,
                        _("There was en error interpreting the provided dates and times"
                          ))
                    return redirect('poll_editDTChoiceDate', current_poll.url)
            except ValueError:
                # at least one invalid time/date has been specified. Redirect to first step # TODO: error message spezifizierne
                messages.error(
                    request,
                    _("There was en error interpreting the provided dates and times"
                      ))
                return redirect('poll_editDTChoiceDate', current_poll.url)
        # Search for already existing Choices
        for i, date_time in enumerate(sorted(chosen_times)):
            choice_obj = current_poll.choice_set.filter(date=date_time)
            if choice_obj:
                old_choices_ids.remove(choice_obj[0].pk)
                choice_obj[0].sort_key = i
                choice_obj[0].deleted = False  # Mark as not deleted
                old_choices.append(choice_obj[0])
            else:
                new_choices.append(
                    Choice(date=date_time, poll=current_poll, sort_key=i))
        # Save new choices to database, Update/Delete old ones
        with transaction.atomic():
            # Save the new Choices
            Choice.objects.bulk_create(new_choices)
            for choice in old_choices:
                choice.save()
            Choice.objects.filter(pk__in=old_choices_ids).update(deleted=True)
        return redirect('poll', current_poll.url)
    return redirect('poll_editDTChoiceDate', current_poll.url)
示例#2
0
文件: views.py 项目: fdenzer/Bitpoll
def edit_dt_choice_time(request, poll_url):
    """
    :param request:
    :param poll_url: url of poll

    Takes several times as the user's input and checks the validity.
    If the data is valid, the user is directed to the combinations-site, to which all possible combinations of
        dates and times are passed on.
    If the dates are missing, the user is directed back to the date-input-site.
    If the times are missing, the user is directed back to the time-input-site.
    """
    current_poll = get_object_or_404(Poll, url=poll_url)
    if not current_poll.can_edit(request.user):
        messages.error(request, _("You are not allowed to edit this Poll."))
        return redirect('poll', poll_url)

    tz_activate(current_poll.timezone_name)
    initial = {
        'dates':
        ','.join(
            date_format(localtime(c.date), format='Y-m-d')
            for c in current_poll.choice_set.order_by('sort_key')),
        'times':
        ','.join(
            set(
                list(
                    date_format(localtime(c.date), format='H:i')
                    for c in current_poll.choice_set.order_by('sort_key')))),
    }
    if request.method == 'POST':
        form = DTChoiceCreationTimeForm(request.POST, initial=initial)
        if form.is_valid():
            times = form.cleaned_data['times'].split(',')
            dates = form.cleaned_data['dates'].split(',')

            return TemplateResponse(
                request, "poll/dt_choice_creation_combinations.html", {
                    'times': times,
                    'dates': dates,
                    'poll': current_poll,
                    'page': 'Choices',
                    'step': 3,
                })
        elif form.cleaned_data['dates'] != "":
            return TemplateResponse(request,
                                    "poll/dt_choice_creation_time.html", {
                                        'time': form,
                                        'poll': current_poll,
                                        'page': 'Choices',
                                        'step': 2,
                                    })
    return redirect('poll_editDTChoiceDate', current_poll.url)
示例#3
0
文件: views.py 项目: fdenzer/Bitpoll
def edit_dt_choice_date(request, poll_url):
    """
    :param request:
    :param poll_url: url of poll

    Takes several dates as the user's input and checks if it's valid.
    If the data is valid, the user is directed to the time-input-site. (The date is passed on as an argument)

    If the data is not valid, the user is directed back for correction.
    """
    current_poll = get_object_or_404(Poll, url=poll_url)
    if not current_poll.can_edit(request.user):
        messages.error(request, _("You are not allowed to edit this Poll."))
        return redirect('poll', poll_url)

    tz_activate(current_poll.timezone_name)
    initial = {
        'dates':
        ','.join(
            set(
                list(
                    date_format(localtime(c.date), format='Y-m-d')
                    for c in current_poll.choice_set.order_by('sort_key')))),
        'times':
        ','.join(
            set(
                list(
                    date_format(localtime(c.date), format='H:i')
                    for c in current_poll.choice_set.order_by('sort_key')))),
    }
    form = DTChoiceCreationDateForm(initial=initial)
    if request.method == 'POST':
        form = DTChoiceCreationDateForm(request.POST, initial=initial)
        if form.is_valid():
            initial['dates'] = form.cleaned_data.get('dates')
            time = DTChoiceCreationTimeForm(initial=initial)
            return TemplateResponse(request,
                                    "poll/dt_choice_creation_time.html", {
                                        'time': time,
                                        'poll': current_poll,
                                        'page': 'Choices',
                                        'step': 2,
                                    })
    return TemplateResponse(
        request, "poll/choice_creation_date.html", {
            'new_choice': form,
            'poll': current_poll,
            'step': 1,
            'page': 'Choices',
            'is_dt_choice': True,
        })
示例#4
0
def timetable(request, organization, project_id):
    organization = get_object_or_404(Organization, name=organization)
    project = get_object_or_404(Project, id=project_id)

    setting, _ = Setting.objects.get_or_create(user=request.user)
    timezone = pytz.timezone(str(setting.timezone))

    if not project.is_member(request.user):
        return HttpResponseForbidden()

    tl_activate(setting.locale)
    tz_activate(timezone)

    time_records = TimeRecordTable(project.timerecord_set.all(),
                                   request=request)
    request.session['timetable.sort'] = request.GET.get(
        'sort') or request.session.get('timetable.sort')
    time_records.order_by = request.session.get(
        'timetable.sort') or '-end_time'
    RequestConfig(request, paginate={'per_page': 15}).configure(time_records)

    current_time = TimeRecord.round_time(
        datetime.now(timezone), timedelta(minutes=setting.timestamp_rounding))
    form_add_record = TimeRecordForm(
        initial={"start_time": current_time.strftime('%Y-%m-%dT%H:%M')})
    form_edit_record = TimeRecordForm(
        initial={"end_time": current_time.strftime('%Y-%m-%dT%H:%M')})

    step_in_seconds = setting.timestamp_rounding * 60
    form_add_record.fields['start_time'].widget.attrs.update(
        step=step_in_seconds)
    form_add_record.fields['end_time'].widget.attrs.update(
        step=step_in_seconds)
    form_edit_record.fields['start_time'].widget.attrs.update(
        step=step_in_seconds)
    form_edit_record.fields['end_time'].widget.attrs.update(
        step=step_in_seconds)

    context = dict(organization=organization,
                   project=project,
                   time_records=time_records,
                   form_add_record=form_add_record,
                   form_edit_record=form_edit_record)
    return render(request, 'tracker/timetable.html', context)
示例#5
0
def details(request, organization, project_id):
    organization = get_object_or_404(Organization, name=organization)
    project = get_object_or_404(Project, id=project_id)

    setting, _ = Setting.objects.get_or_create(user=request.user)
    timezone = pytz.timezone(str(setting.timezone))

    if not project.is_member(request.user):
        return HttpResponseForbidden()

    tl_activate(setting.locale)
    tz_activate(timezone)

    members = set(set(project.admins.all()) | set(project.editors.all()))

    recent_query = project.timerecord_set.order_by('-end_time')[:5]
    recent_changes = RecentRecordTable(recent_query, request=request)
    RequestConfig(request, paginate=False).configure(recent_changes)

    context = dict(organization=organization,
                   project=project,
                   members=members,
                   recent_changes=recent_changes)
    return render(request, 'tracker/project/details.html', context)
示例#6
0
文件: views.py 项目: tanzir71/Bitpoll
def vote(request, poll_url, vote_id=None):
    """
    :param request:
    :param poll_url: Url of poll
    :param vote_id: Optional the voteID to edit
    :return:

    Takes vote with comments as input and saves the vote along with all comments.
    """
    current_poll = get_object_or_404(Poll, url=poll_url)
    error_msg = False
    deleted_choicevals = False

    if current_poll.due_date and current_poll.due_date < now():
        messages.error(
            request,
            _("This Poll is past the due date, voting is no longer possible"))
        return redirect('poll', poll_url)

    if not current_poll.can_vote(request.user, request, vote_id is not None):
        if current_poll.require_login and not request.user.is_authenticated:
            return redirect_to_login(reverse('poll_vote', args=[poll_url]))
        else:
            return redirect('poll', poll_url)

    tz_activate(current_poll.get_tz_name(request.user))

    if request.method == 'POST':
        vote_id = request.POST.get('vote_id', None)
        if vote_id:
            current_vote = get_object_or_404(Vote,
                                             pk=vote_id,
                                             poll=current_poll)
            if not current_vote.can_edit(request.user):
                # the vote belongs to an user and it is not the authenticated user
                return HttpResponseForbidden()  # todo: better errorpage?
        else:
            current_vote = Vote(poll=current_poll)
        current_vote.date_created = now()
        current_vote.comment = request.POST.get('comment')
        if vote_id:
            # leave the name as it was
            pass
        elif 'anonymous' in request.POST:
            current_vote.name = 'Anonymous'
        elif request.user.is_authenticated:
            current_vote.name = request.user.get_displayname()
            current_vote.user = request.user

            if request.user.auto_watch:
                try:
                    poll_watch = PollWatch(poll=current_poll,
                                           user=request.user)
                    poll_watch.save()
                except IntegrityError:
                    pass
        else:
            current_vote.name = request.POST.get('name').strip()

        if len(current_vote.name) > 80:
            messages.error(
                request,
                _("The Name is longer than the allowed name length of 80 characters"
                  ))
            return redirect(
                'poll', poll_url
            )  #todo: das macht keinen sinn, warum nicht verbessern?

        current_vote.anonymous = 'anonymous' in request.POST

        if not current_poll.anonymous_allowed and current_vote.anonymous:
            messages.error(request,
                           _("Anonymous votes are not allowed for this poll."))
        else:
            if current_vote.anonymous or current_vote.name:
                # prevent non-anonymous vote without name
                try:
                    with transaction.atomic():
                        new_choices = []

                        current_vote.save()

                        if request.user.is_authenticated:
                            # check if this user was invited
                            invitation = current_poll.invitation_set.filter(
                                user=request.user)
                            if invitation:
                                invitation = invitation[0]
                                invitation.vote = current_vote
                                invitation.save()

                        for choice in current_poll.choice_set.all():
                            if str(choice.id) in request.POST and request.POST[
                                    str(choice.id)].isdecimal():
                                choice_value = get_object_or_404(
                                    ChoiceValue,
                                    id=request.POST[str(choice.id)])
                                if not choice_value.deleted:
                                    new_choices.append(
                                        VoteChoice(
                                            value=choice_value,
                                            vote=current_vote,
                                            choice=choice,
                                            comment=request.POST.get(
                                                'comment_{}'.format(choice.id))
                                            or ''))
                                else:
                                    deleted_choicevals = True
                            else:
                                if current_poll.vote_all and not choice.deleted:
                                    if not error_msg:  # TODO: error_msg is used in other places here to, maybe use
                                        # deduplication for messages?
                                        # https://stackoverflow.com/questions/23249807/django-remove-duplicate
                                        # -messages-from-storage
                                        messages.error(
                                            request,
                                            _('Due to the the configuration of this poll, '
                                              'you have to fill all choices.'))
                                    error_msg = True

                        if deleted_choicevals:
                            error_msg = True
                            messages.error(
                                request,
                                _('Value for choice does not exist. This is probably due to '
                                  'changes in the poll. Please correct your vote.'
                                  ))

                        if not error_msg:
                            if vote_id:
                                VoteChoice.objects.filter(
                                    vote=current_vote).delete()
                                # todo: nochmal prüfen ob das wirjklich das tut was es soll, also erst alles löschen und dann neu anlegen
                                # todo eventuell eine transaktion drum machen? wegen falls das eventuell dazwischen abbricht?
                            else:
                                for current_watch in current_poll.pollwatch_set.all(
                                ):
                                    current_watch.send(request=request,
                                                       vote=current_vote)

                            VoteChoice.objects.bulk_create(new_choices)
                            messages.success(request,
                                             _('Vote has been recorded'))
                            return redirect('poll', poll_url)
                        else:
                            raise IntegrityError(
                                "An Error while saving the Vote occurred, see message"
                            )
                except IntegrityError as e:
                    # Nothing todo as the main point in this exception is the database rollback
                    pass
            else:
                messages.error(
                    request,
                    _('You need to either provide a name or post an anonymous vote.'
                      ))

    # no/invalid POST: show the dialog
    matrix = current_poll.get_choice_group_matrix(get_current_timezone())
    choices = []
    comments = []
    choice_votes = []
    if vote_id:
        current_vote = get_object_or_404(Vote, pk=vote_id)
    else:
        current_vote = Vote()
    choices_orig = current_poll.choice_set.filter(
        deleted=False).order_by('sort_key')
    for choice in choices_orig:
        cur_comment = ""
        value = None
        if request.method == 'POST':
            if str(choice.id) in request.POST:
                value = get_object_or_404(ChoiceValue,
                                          id=request.POST[str(choice.id)])
            else:
                value = None
            cur_comment = request.POST.get('comment_{}'.format(
                choice.id)) or ''
        elif vote_id:  # If we want to edit an vote find the selected fields
            vote_choice = VoteChoice.objects.filter(vote=vote_id,
                                                    choice=choice.id)
            if vote_choice:  # append the found values
                cur_comment = vote_choice[0].comment
                value = vote_choice[0].value
        choices.append(choice)
        comments.append(cur_comment)
        choice_votes.append(value)
    return TemplateResponse(
        request, 'poll/vote_creation.html', {
            'poll':
            current_poll,
            'matrix':
            matrix,
            'matrix_len':
            len(matrix[0]),
            'choices_matrix':
            zip(matrix, choices, comments, choice_votes),
            'choices':
            current_poll.choice_set.all(),
            'choices_matrix_len':
            len(choices),
            'values':
            current_poll.choicevalue_set.filter(deleted=False).all(),
            'page':
            'Vote',
            'current_vote':
            current_vote,
            'timezone_warning':
            (request.user.is_authenticated and
             current_poll.get_tz_name(request.user) != request.user.timezone),
            'choice_values':
            ChoiceValue.objects.filter(poll=current_poll)
        })
示例#7
0
文件: views.py 项目: tanzir71/Bitpoll
def edit_date_choice(request, poll_url):
    """
    :param request:
    :param poll_url: url of poll

    Takes several dates as the user's input und checks the validity.
    If the input is valid, for every given date a choice is created and saved. The user is directed to the poll's site.

    If the input is not valid, the user is directed back for correction.
    """
    current_poll = get_object_or_404(Poll, url=poll_url)
    if not current_poll.can_edit(request.user, request):
        return redirect('poll', poll_url)

    tz_activate('UTC')
    initial = {
        'dates':
        ','.join(
            set(
                list(
                    date_format(localtime(c.date), format='Y-m-d')
                    for c in current_poll.choice_set.order_by('sort_key')))),
    }
    if request.method == 'POST':
        form = DateChoiceCreationForm(request.POST, initial=initial)
        if form.is_valid():
            choices = current_poll.choice_set.all()
            # List of the Old Ids, used for detection what has to be deleted
            old_choices_ids = [c.pk for c in choices]
            new_choices = []
            old_choices = []
            dates = []
            error = False
            # clean the data
            for choice in form.cleaned_data['dates'].split(","):
                try:
                    tz = timezone('UTC')
                    parsed_date = parse_datetime('{} 0:0'.format(choice))
                    if parsed_date:
                        date = tz.localize(parsed_date)
                        dates.append(date)
                    else:
                        error = True
                        messages.error(
                            _("There was en error interpreting the provided dates and times"
                              ))
                except ValueError:
                    # This will most likely only happen with users turning of JS
                    error = True
                    messages.error(
                        _("There was en error interpreting the provided dates and times"
                          ))
            if not error:
                for i, datum in enumerate(sorted(dates)):
                    choice_objs = Choice.objects.filter(poll=current_poll,
                                                        date=datum)
                    if choice_objs:
                        choice_obj = choice_objs[0]
                        old_choices_ids.remove(choice_obj.pk)
                        choice_obj.sort_key = i
                        choice_obj.deleted = False
                        old_choices.append(choice_obj)
                    else:
                        new_choices.append(
                            Choice(text="",
                                   date=datum,
                                   poll=current_poll,
                                   sort_key=i))
                with transaction.atomic():
                    Choice.objects.bulk_create(new_choices)
                    for choice in old_choices:
                        choice.save()
                    Choice.objects.filter(pk__in=old_choices_ids).update(
                        deleted=True)
                return redirect('poll', poll_url)
    else:
        form = DateChoiceCreationForm(initial=initial)
    return TemplateResponse(
        request, "poll/choice_creation_date.html", {
            'poll': current_poll,
            'new_choice': form,
            'page': 'Choices',
            'is_dt_choice': False,
        })
示例#8
0
文件: views.py 项目: tanzir71/Bitpoll
def poll(request, poll_url):
    """
    :param request
    :param poll_url: url of poll

    Displays for a given poll its fields along with all possible choices, all votes and all its comments.
    """
    current_poll = get_object_or_404(Poll, url=poll_url)

    tz_activate(current_poll.get_tz_name(request.user))

    poll_votes = Vote.objects.filter(poll=current_poll).select_related('user')
    if current_poll.sorting == Poll.ResultSorting.NAME:
        poll_votes = poll_votes.order_by('name')
    elif current_poll.sorting == Poll.ResultSorting.DATE:
        poll_votes = poll_votes.order_by('date_created')
    # prefetch_related('votechoice_set').select_releated() #TODO (Prefetch objekt nötig, wie ist der reverse join name wirklich?

    matrix = transpose(
        current_poll.get_choice_group_matrix(get_current_timezone()))

    # aggregate stats for all columns
    stats = Choice.objects.filter(
        poll=current_poll, deleted=False).order_by('sort_key').annotate(
            score=Sum('votechoice__value__weight')).values(
                'score', 'id', 'text')
    votes_count = poll_votes.count()

    invitations = current_poll.invitation_set.filter(vote=None)
    # The next block is limiting the visibility of the results
    summary = True
    if current_poll.current_user_is_owner(
            request) and current_poll.show_results != "complete":
        messages.info(
            request,
            _("You can see the results because you are the owner of the Poll"))
    else:
        if current_poll.show_results in ("summary", "never"):
            if request.user.is_authenticated:
                poll_votes = poll_votes.filter(user=request.user)
                invitations = invitations.filter(user=request.user)
            else:
                poll_votes = []
                invitations = []
            messages.info(
                request,
                _("No individual results are shown due to Poll settings"))
        elif current_poll.show_results in ("summary after vote", "complete after vote") \
                and (request.user.is_anonymous or not poll_votes.filter(Q(user=request.user))):
            poll_votes = []
            messages.info(
                request,
                _("Results are only sown after (authenticated) Voting"))
            summary = False
        elif current_poll.show_results == "summary after vote":
            poll_votes = poll_votes.filter(user=request.user)
            messages.info(
                request,
                _("Only the Summary is shown due to the Poll settings"))
        if current_poll.show_results == "never":
            summary = False

    if not summary:
        messages.info(
            request,
            _("The summary is not shown due to the config of the Poll"))

    choices = Choice.objects.filter(
        poll=current_poll,
        deleted=0).select_related('poll').order_by('sort_key')
    vote_idx = {vote.id: i for (i, vote) in enumerate(poll_votes)}
    choice_idx = {choice.id: (i, choice) for (i, choice) in enumerate(choices)}

    vote_choice_matrix = [[None] * len(choice_idx) for bla in vote_idx]
    for vote_choice in VoteChoice.objects.filter(
            vote__poll=current_poll,
            choice__deleted=0).select_related('value'):
        if vote_choice.vote_id in vote_idx:
            x = vote_idx[vote_choice.vote_id]
            y, choice = choice_idx[vote_choice.choice_id]
            vote_choice_matrix[x][y] = {
                'comment': vote_choice.comment,
                'value': vote_choice.value,
                'choice': choice
            }

    # aggregate stats for the different Choice_Values per column
    stats2 = Choice.objects.filter(
        poll=current_poll, deleted=False).order_by('sort_key').annotate(
            count=Count('votechoice__value__color')).values(
                'count', 'id', 'votechoice__value__icon',
                'votechoice__value__color', 'votechoice__value__title',
                'votechoice__value__deleted')
    #
    # use average for stats
    stats = [{
        'score':
        (stat['score'] / Decimal(votes_count) if votes_count > 0 else 0)
        if stat['score'] is not None else None,
        'count':
        stat['score'],
        'text':
        stat,
        'choices': [{
            'count': stat2['count'],
            'color': stat2['votechoice__value__color'],
            'icon': stat2['votechoice__value__icon'],
            'deleted': stat2['votechoice__value__deleted'],
            'title': stat2['votechoice__value__title']
        } for stat2 in stats2 if stat2['id'] == stat['id']
                    and stat2['votechoice__value__color'] != None],
    } for stat in stats]

    if request.user.is_authenticated:
        # warn the user if the Timezone is not the same on the Poll and in his settings
        different_timezone = current_poll.timezone_name != request.user.timezone
        if current_poll.use_user_timezone and different_timezone:
            messages.info(
                request,
                _("This poll was transferred from {} to your local timezone {}"
                  .format(current_poll.timezone_name, request.user.timezone)))
        elif different_timezone:
            messages.warning(
                request,
                _("This poll has a different timezone ({}) than you.".format(
                    current_poll.timezone_name)))

    deleted_choicevals_count = VoteChoice.objects.filter(
        choice__poll=current_poll, value__deleted=True).count()
    if deleted_choicevals_count > 0:
        messages.warning(
            request,
            _('Some votes contain deleted values. If you have already voted, please check your '
              'vote.'))

    max_score = None
    if stats and votes_count > 0:
        max_score_list = [
            val['score'] for val in stats if val['score'] is not None
        ]
        if max_score_list:
            max_score = max(max_score_list)

    return TemplateResponse(
        request, "poll/poll.html", {
            'poll': current_poll,
            'matrix': matrix,
            'choices_matrix': zip(matrix, current_poll.choice_set.all()),
            'page': '',
            'votes': zip(poll_votes, vote_choice_matrix),
            'stats': stats,
            'max_score': max_score,
            'invitations':
            invitations if current_poll.show_invitations else [],
            'summary': summary,
            'comment_form': CommentForm(),
            'choice_values': ChoiceValue.objects.filter(poll=current_poll),
        })
示例#9
0
文件: views.py 项目: tanzir71/Bitpoll
def settings(request, poll_url):
    """

    :param request:
    :param poll_url:
    :return:
    """
    current_poll = get_object_or_404(Poll, url=poll_url)
    groups = None

    if request.user.is_authenticated:
        groups = Group.objects.filter(user=request.user)

    if not current_poll.can_edit(request.user, request):
        return redirect('poll', poll_url)

    user_error = ""
    user = current_poll.user.username if current_poll.user else ""
    if request.method == 'POST':
        old_timezone_name = current_poll.timezone_name
        form = PollSettingsForm(request.POST, instance=current_poll)
        if form.is_valid():
            new_poll = form.save(commit=False)
            user = form.data.get('user', '')
            with transaction.atomic():
                if user:
                    try:
                        user_obj = BitpollUser.objects.get(username=user)
                        new_poll.user = user_obj
                    except ObjectDoesNotExist:
                        user_error = _("User {} not Found".format(user))
                else:
                    new_poll.user = None
                    current_poll.choice_set.all()
                if not user_error:
                    # change the Timezone in the Choices, date-polls are in UTC regardles of the timezone
                    if old_timezone_name != new_poll.timezone_name and current_poll.type == 'datetime':
                        new_timezone = timezone(new_poll.timezone_name)
                        old_timezone = timezone(old_timezone_name)
                        for choice in current_poll.choice_set.all():
                            choice.date = make_aware(
                                make_naive(choice.date, old_timezone),
                                new_timezone)
                            choice.save()
                    new_poll.save()
                    messages.success(request, _('Settings have been changed'))
                    return redirect('poll_settings', current_poll.url)
        else:
            user = form.cleaned_data.get('user', '')
    else:
        form = PollSettingsForm(instance=current_poll)

    # we activate the base timezone of this poll so the due date etc is showed in the correct way.
    tz_activate(current_poll.timezone_name)

    return TemplateResponse(
        request, 'poll/settings.html', {
            'form': form,
            'poll': current_poll,
            'page': 'Settings',
            'groups': groups,
            'results': POLL_RESULTS,
            'timezones': all_timezones,
            'user_error': user_error,
            'user_select': user,
        })
示例#10
0
def send_notify(command: Command, user: User, repo_tag: RepositoryTag):
    """
    ユーザーに通知を送信する
    """
    if not user.is_active:
        return

    context = {
        "repo": str(repo_tag),
        "last_updated": repo_tag.last_updated,
        "url": repo_tag.get_url(),
    }
    webhook_type = user.get_webhook_type()
    message = None
    if webhook_type == WebhookType.SLACK:
        try:
            lang_activate(str(user.language_code))
            tz_activate(pytz.timezone(user.timezone))
            message = render_to_string(
                'messages/update_notify_slack.txt', context).encode('UTF-8')
        finally:
            lang_activate(SYS_LANGUAGE_CODE)
            tz_deactivate()
    elif webhook_type == WebhookType.IFTTT:
        try:
            lang_activate(str(user.language_code))
            tz_activate(pytz.timezone(user.timezone))
            message = render_to_string(
                'messages/update_notify_slack.txt', context).encode('UTF-8')
        finally:
            lang_activate(SYS_LANGUAGE_CODE)
            tz_deactivate()
    elif webhook_type == WebhookType.UNKNOWN:
        command.stdout.write(command.style.ERROR(
            f'User {user} has UNKNOWN URL.\n{user.webhook_url}'
        ))

    if webhook_type not in [WebhookType.UNKNOWN, WebhookType.NONE]:
        result = False
        try:
            if message:
                result = user.post_webhook(message)
        except Exception:
            command.stdout.write(command.style.ERROR(traceback.format_exc()))
        finally:
            if result:
                command.stdout.write(command.style.SUCCESS(
                    f'Webhook notification was successfully.'
                    f' "{repo_tag}", last_updated: {repo_tag.last_updated}'
                ))
            else:
                command.stdout.write(command.style.ERROR(
                    f'Webhook notification was failed.'
                    f' "{repo_tag}", last_updated: {repo_tag.last_updated}\n'
                    f'message: {message}'
                ))

    if user.is_notify_to_email:
        result = False
        try:
            lang_activate(str(user.language_code))
            tz_activate(pytz.timezone(user.timezone))
            result = user.email_user(
                subject=render_to_string(
                    'messages/update_notify_subject.txt', context),
                message=render_to_string(
                    'messages/update_notify_email.html', context)
            )
        except Exception:
            command.stdout.write(command.style.ERROR(traceback.format_exc()))
        finally:
            lang_activate(SYS_LANGUAGE_CODE)
            tz_deactivate()
            if result:
                command.stdout.write(command.style.SUCCESS(
                    f'E-mail notification was successfully.'
                    f' "{repo_tag}", last_updated: {repo_tag.last_updated}'
                ))
            else:
                command.stdout.write(command.style.ERROR(
                    f'E-mail notification was failed.'
                    f' "{repo_tag}", last_updated: {repo_tag.last_updated}\n'
                    f'message: {message}'
                ))