from django import forms from django.contrib.auth.mixins import LoginRequiredMixin from django.http import HttpResponseRedirect from django.shortcuts import render, get_object_or_404 # Create your views here. from django.urls import reverse_lazy, reverse from django.views.generic import CreateView, UpdateView, RedirectView, DetailView, ListView from writingtogether.models import Story, StoryPart, StoryRound class IndexView(LoginRequiredMixin, ListView): template_name = 'writingtogether/index.html' context_object_name = 'open_story_round_list' def get_queryset(self): # TODO: show open & finished rounds return StoryRound.objects.order_by('-created')[:5] class StoryRoundDetailView(LoginRequiredMixin, DetailView): model = StoryRound template_name = 'writingtogether/detail.html' class StoryRoundCreate(LoginRequiredMixin, CreateView): model = StoryRound fields = ['name', 'participants', 'number_of_rounds'] success_url = reverse_lazy('writing:index') def form_valid(self, form): self.object = form.save() sorted_participants = sorted([user.pk for user in form.cleaned_data['participants']]) number_of_participants = len(sorted_participants) for user_index, user_id in enumerate(sorted_participants): story = Story.objects.create( part_of_round=self.object, started_by_id=user_id ) previous_part=None for i in range(form.cleaned_data['number_of_rounds']): current_part = StoryPart.objects.create( user_id=sorted_participants[(user_index + i) % number_of_participants], previous_part=previous_part, part_of=story, turn_number=i, ) previous_part = current_part return HttpResponseRedirect(self.get_success_url()) class StoryUpdate(LoginRequiredMixin, UpdateView): model = Story fields = ['name'] class StoryPartUpdate(LoginRequiredMixin, UpdateView): model = StoryPart fields = ['text'] template_name = 'writingtogether/story_part.html' success_url = reverse_lazy('writing:index') def get_context_data(self, **kwargs): context = super(StoryPartUpdate, self).get_context_data(**kwargs) context.update({ 'current_round': self.object.turn_number + 1, 'total_rounds': self.object.part_of.part_of_round.number_of_rounds, 'previous_part': self.object.previous_part, }) context.update(self.kwargs) return context #def form_valid(self, form): # form.instance.created_by = self.request.user # form.instance.previous_part_id = self.kwargs['previous'] # form.instance.part_of_id = self.kwargs['story_pk'] # return super().form_valid(form) class RedirectToNextOpenPart(LoginRequiredMixin, RedirectView): permanent = False query_string = True pattern_name = 'writing:update_story_part' def get_redirect_url(self, *args, **kwargs): story_round = get_object_or_404(StoryRound, pk=kwargs['story_round_pk']) if story_round.next_round_ready(): status, turn_number = story_round.advance_to_next_turn_and_get_status_and_round_number() if status == 'finished': self.pattern_name = 'writing:finished' kwargs['pk'] = kwargs.pop('story_round_pk') return super().get_redirect_url(*args, **kwargs) story_part = story_round.get_next_story_part(user=self.request.user) if story_part.finished: self.pattern_name = 'writing:wait_for_others' kwargs['pk'] = kwargs.pop('story_round_pk') else: kwargs['story_pk'] = story_part.part_of.pk kwargs['pk'] = story_part.pk return super().get_redirect_url(*args, **kwargs) class WaitForOthersView(LoginRequiredMixin, DetailView): model = StoryRound template_name = 'writingtogether/wait_for_others.html' class RoundFinishedView(LoginRequiredMixin, ListView): model = Story context_object_name = 'stories' template_name = 'writingtogether/finished.html' def get_queryset(self): return Story.objects.filter(part_of_round_id=self.kwargs['pk']).prefetch_related('parts')