200 lines
6.1 KiB
Python
200 lines
6.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Quest and quest accessory views.
|
|
"""
|
|
from datetime import timedelta, datetime, timezone
|
|
|
|
import bleach
|
|
from user_messages import api
|
|
from django.views.decorators.http import require_POST
|
|
from django.contrib import messages
|
|
from django.shortcuts import render, redirect
|
|
from django.db.models import F
|
|
from django.conf import settings
|
|
|
|
from .models import Quest, DiceRoll, PollOption, PollVote, Page, Post
|
|
from .forms import EditQuestForm, QuestForm, PostForm
|
|
from user.models import User
|
|
from .tools import download_img, send_to_websocket
|
|
|
|
def index(request):
|
|
"""The quest page index."""
|
|
search_terms = request.GET.get('search_terms')
|
|
search_type = request.GET.get('search_type')
|
|
tags = request.GET.get('tags')
|
|
order_by = request.GET.get('order_by')
|
|
order_way = request.GET.get('order_way', 'desc')
|
|
|
|
order_keys = {
|
|
'ceation_date': 'id',
|
|
'last_post': 'latest_post_date',
|
|
'next_live': 'live_time',
|
|
}
|
|
order_by = order_keys.get(order_by, 'id')
|
|
|
|
results = Quest.objects.all()
|
|
if search_terms:
|
|
if search_type == 'title':
|
|
results = results.filter(title__unaccent__icontains=search_terms)
|
|
elif search_type == 'author':
|
|
results = results.filter(
|
|
owner__username__unaccent__icontains=search_terms)
|
|
if tags:
|
|
results = results.filter(tags__name__in=tags.split()).distinct()
|
|
|
|
if order_way == 'asc':
|
|
results = results.order_by(F(order_by).asc(nulls_last=True))
|
|
elif order_way == 'desc':
|
|
results = results.order_by(F(order_by).desc(nulls_last=True))
|
|
|
|
context = locals()
|
|
return render(request, 'quest/index.html', context)
|
|
|
|
|
|
def quest(request, quest_id, page_num='0'):
|
|
"""
|
|
Arbituary quest page view.
|
|
"""
|
|
# TODO: 404 quest not found
|
|
quest = Quest.objects.get(id=quest_id)
|
|
pages = Page.objects.filter(
|
|
quest=quest, appendix=False).order_by('page_num')
|
|
appendices = Page.objects.filter(
|
|
quest=quest, appendix=True).order_by('title')
|
|
chat_messages = reversed(quest.message_set.all().order_by('-id')[:50])
|
|
try:
|
|
page = Page.objects.get(quest=quest, page_num=page_num)
|
|
except Page.DoesNotExist:
|
|
messages.error(request, "Page not found, redirecting you.")
|
|
return redirect('quest:quest', quest_id=quest.id, page_num='0')
|
|
posts = quest.post_set.filter(page=page)
|
|
# TODO: filter by page_num as well
|
|
dice_rolls = DiceRoll.objects.filter(dicecall__post__quest=quest)
|
|
poll_options = PollOption.objects.filter(poll__post__quest=quest)
|
|
poll_votes = PollVote.objects.filter(option__poll__post__quest=quest)
|
|
ip_address = request.META['REMOTE_ADDR']
|
|
server_user_id = settings.SERVER_USER_ID
|
|
context = locals()
|
|
if page_num == '0':
|
|
return render(request, 'quest/quest_homepage.html', context)
|
|
else:
|
|
return render(request, 'quest/quest.html', context)
|
|
|
|
|
|
def edit_quest(request, quest_id, page_num='0'):
|
|
"""
|
|
Edit quest page. Only available to the QM.
|
|
"""
|
|
quest = Quest.objects.get(id=quest_id)
|
|
prev_live = quest.live
|
|
if quest.owner != request.user:
|
|
return redirect('quest:quest', quest_id=quest_id, page_num=page_num)
|
|
if request.method == 'POST':
|
|
form = EditQuestForm(request.POST)
|
|
if form.is_valid():
|
|
quest.title = form.cleaned_data['quest_title']
|
|
quest.anon_name = form.cleaned_data['anon_name']
|
|
quest.live = form.cleaned_data['live']
|
|
quest.description = form.cleaned_data['description']
|
|
quest.banner_url = download_img(form.cleaned_data['banner_url'])
|
|
if not quest.banner_url.startswith('http'):
|
|
quest.banner_url = None
|
|
|
|
live_date = form.cleaned_data['live_date']
|
|
live_time = form.cleaned_data['live_time']
|
|
if live_date and live_time:
|
|
live_datetime = datetime.combine(
|
|
live_date,
|
|
live_time,
|
|
timezone.utc
|
|
)
|
|
tz_delta = timedelta(minutes=form.cleaned_data['timezone'])
|
|
live_datetime = live_datetime + tz_delta
|
|
quest.live_time = live_datetime
|
|
else:
|
|
quest.live_time = None
|
|
quest.save()
|
|
data = {
|
|
'live': quest.live,
|
|
'live_time': quest.live_time,
|
|
}
|
|
if data['live_time']:
|
|
data['live_time'] =data['live_time'].strftime('%Y-%m-%d %H:%M')
|
|
send_to_websocket('live', quest_id, data)
|
|
if prev_live == False and quest.live == True:
|
|
subscribers = quest.user_set.all()
|
|
for subscriber in subscribers:
|
|
api.info(
|
|
subscriber,
|
|
f"{quest.title} has gone live!",
|
|
extra_tags='subscription',
|
|
deliver_once=False
|
|
)
|
|
return redirect('quest:quest',quest_id=quest.id, page_num=page_num)
|
|
else:
|
|
messages.error(request, "Error")
|
|
else:
|
|
pass
|
|
context = locals()
|
|
return render(request, 'quest/edit_quest.html', context)
|
|
|
|
|
|
def new_quest(request):
|
|
"""
|
|
The page for creating new quests.
|
|
"""
|
|
if not request.user.is_authenticated:
|
|
return redirect('login:index')
|
|
if request.method == 'POST':
|
|
# TODO: clean the post body
|
|
quest_form = QuestForm(request.POST)
|
|
if quest_form.is_valid():
|
|
quest = quest_form.save(commit=False)
|
|
quest.owner = request.user
|
|
quest.banner_url = download_img(quest.banner_url)
|
|
if not quest.banner_url.startswith('http'):
|
|
quest.banner_url = None
|
|
quest.save()
|
|
quest_form.save_m2m()
|
|
print(quest.tags.names())
|
|
page = Page(
|
|
quest=quest,
|
|
page_num=0,
|
|
title="Homepage",
|
|
appendix=False,
|
|
)
|
|
page.save()
|
|
return redirect('quest:quest', quest_id=quest.id)
|
|
else:
|
|
quest_form = QuestForm()
|
|
context = locals()
|
|
return render(request, 'quest/new_quest.html', context)
|
|
|
|
|
|
@require_POST
|
|
def new_tag(request, quest_id):
|
|
"""Endpoint for adding new tags to a quest."""
|
|
if not request.user.is_authenticated:
|
|
return redirect('login:index')
|
|
tag = request.POST.get('tag', '').strip()
|
|
if not tag:
|
|
return redirect('quest:quest', quest_id=quest_id, page_num='0')
|
|
|
|
quest = Quest.objects.get(id=quest_id)
|
|
tag = bleach.clean(tag)
|
|
if tag in quest.tags.names():
|
|
return redirect('quest:quest', quest_id=quest_id, page_num='0')
|
|
|
|
quest.tags.add(tag)
|
|
return redirect('quest:quest', quest_id=quest_id, page_num='0')
|
|
|
|
|
|
@require_POST
|
|
def subscribe(request, quest_id):
|
|
"""Endpoint for users to subscribe to a quest."""
|
|
if not request.user.is_authenticated:
|
|
return redirect('login:index')
|
|
request.user.subscriptions.add(Quest.objects.get(id=quest_id))
|
|
messages.success(request, "Subscribed")
|
|
return redirect('quest:quest', quest_id=quest_id, page_num='0')
|