2018-08-15 17:41:51 -04:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
"""
|
|
|
|
Individual functions for handling WebSocket events. Gets called by the
|
|
|
|
QuestConsumer object in consumers.py.
|
|
|
|
"""
|
2018-08-20 07:23:33 -04:00
|
|
|
import re
|
2018-08-16 15:43:43 -04:00
|
|
|
import time
|
2018-08-15 17:41:51 -04:00
|
|
|
import types
|
2018-08-21 07:18:03 -04:00
|
|
|
import random
|
2018-08-15 17:41:51 -04:00
|
|
|
|
2018-08-16 15:43:43 -04:00
|
|
|
import bleach
|
2018-08-21 09:01:16 -04:00
|
|
|
from django.utils.timezone import localtime
|
2018-08-16 15:43:43 -04:00
|
|
|
|
2018-08-23 11:57:37 -04:00
|
|
|
from quest.models import Message, Quest, Post, DiceCall
|
2018-08-23 07:40:28 -04:00
|
|
|
from quest.forms import DiceCallForm
|
2018-08-20 06:57:36 -04:00
|
|
|
|
2018-08-15 17:41:51 -04:00
|
|
|
def message(socket, data):
|
|
|
|
"""
|
|
|
|
Gets called when the server receives a 'message' event.
|
|
|
|
"""
|
2018-08-20 06:57:36 -04:00
|
|
|
# TODO: validation
|
2018-08-15 17:41:51 -04:00
|
|
|
message = data.get('message')
|
2018-08-20 06:57:36 -04:00
|
|
|
quest_id = data.get('quest_id')
|
2018-08-16 15:43:43 -04:00
|
|
|
|
2018-08-21 07:18:03 -04:00
|
|
|
# cleaning
|
2018-08-16 15:43:43 -04:00
|
|
|
message = message.strip()
|
|
|
|
if not message:
|
|
|
|
return
|
|
|
|
tags = ["b", "code", "i", "s"]
|
|
|
|
message = bleach.clean(message, tags=tags)
|
2018-08-20 07:23:33 -04:00
|
|
|
|
2018-08-21 07:18:03 -04:00
|
|
|
# greentext
|
2018-08-20 07:23:33 -04:00
|
|
|
lines = []
|
|
|
|
for line in message.splitlines():
|
|
|
|
if line.startswith(">") and not line.startswith(">>"):
|
|
|
|
line = '<span class="greenText">' + line + '</span>'
|
|
|
|
lines.append(line)
|
|
|
|
message = "<br>".join(lines)
|
|
|
|
|
2018-08-21 07:18:03 -04:00
|
|
|
# quote links
|
2018-08-20 07:23:33 -04:00
|
|
|
quotes = re.findall(r">>\d+", message)
|
|
|
|
for quote in quotes:
|
|
|
|
msg_id = quote.replace(">>", "")
|
|
|
|
msg = '<a class="quotelink" '
|
|
|
|
msg += 'href="javascript:scrollToMsg(\'' + msg_id + '\')" '
|
|
|
|
msg += 'onmousemove="showPreview(event, \'' + msg_id + '\')" '
|
|
|
|
msg += 'onmouseout="clearPreview()">' + quote + '</a>'
|
|
|
|
message = message.replace(quote, msg)
|
|
|
|
|
2018-08-21 07:18:03 -04:00
|
|
|
# handle image
|
|
|
|
|
|
|
|
# dice rolling
|
|
|
|
if any(map(message.startswith, ["/dice", "/roll"])):
|
|
|
|
reg = re.search(r"(\d+)d(\d+)([+-]\d+)?", data["message"])
|
|
|
|
if not reg:
|
|
|
|
return
|
|
|
|
try:
|
|
|
|
groups = [0 if d is None else int(d) for d in reg.groups()]
|
|
|
|
dice_num, dice_sides, dice_mod = groups
|
|
|
|
assert 0 < dice_num < 100
|
|
|
|
assert 0 < dice_sides < 100
|
|
|
|
assert -1000 < dice_mod < 1000
|
|
|
|
except (ValueError, AssertionError):
|
|
|
|
return
|
|
|
|
dice = [random.randint(1, dice_sides) for _ in range(dice_num)]
|
|
|
|
total = sum(dice) + dice_mod
|
|
|
|
roll_msg = f"Rolled {', '.join(map(str, dice))}"
|
|
|
|
if dice_mod:
|
|
|
|
if dice_mod > 0:
|
|
|
|
roll_msg += " + " + str(dice_mod)
|
|
|
|
else:
|
|
|
|
roll_msg += " - " + str(dice_mod)[1:]
|
|
|
|
roll_msg += " = " + str(total)
|
|
|
|
message += '<hr class="msgSrvHr" /><b>' + roll_msg + "</b>"
|
|
|
|
|
2018-08-20 06:57:36 -04:00
|
|
|
user = socket.scope['user']
|
|
|
|
|
|
|
|
m = Message(
|
|
|
|
quest=Quest.objects.get(id=quest_id),
|
|
|
|
message=message)
|
|
|
|
if user.username:
|
|
|
|
m.user = user
|
|
|
|
m.save()
|
2018-08-15 17:41:51 -04:00
|
|
|
|
|
|
|
data = {}
|
2018-08-20 06:57:36 -04:00
|
|
|
data['message_id'] = m.id
|
2018-08-16 15:43:43 -04:00
|
|
|
data['message'] = message
|
2018-08-20 06:57:36 -04:00
|
|
|
data['date'] = int(time.time())
|
|
|
|
data['name'] = user.username
|
2018-08-15 17:41:51 -04:00
|
|
|
socket.send('message', data)
|
|
|
|
|
|
|
|
|
2018-08-21 09:01:16 -04:00
|
|
|
def text_post(socket, data):
|
|
|
|
"""
|
|
|
|
Called when the QM creates a new text post.
|
|
|
|
"""
|
2018-08-23 07:40:28 -04:00
|
|
|
# TODO: security
|
2018-08-21 09:01:16 -04:00
|
|
|
quest_id = data.get('quest_id')
|
2018-08-23 07:40:28 -04:00
|
|
|
post_text = data.get('text')
|
2018-08-21 09:01:16 -04:00
|
|
|
page_num = data.get('page_num')
|
|
|
|
|
|
|
|
# cleaning
|
2018-08-23 07:40:28 -04:00
|
|
|
post_text = bleach.clean(post_text.strip())
|
|
|
|
post_text = text.replace("\n", "<br>")
|
2018-08-21 09:01:16 -04:00
|
|
|
|
|
|
|
# handle image
|
|
|
|
|
|
|
|
p = Post(
|
|
|
|
quest=Quest.objects.get(id=quest_id),
|
|
|
|
page_num=page_num,
|
|
|
|
post_type='text',
|
2018-08-23 07:40:28 -04:00
|
|
|
post_text=post_text)
|
2018-08-21 09:01:16 -04:00
|
|
|
p.save()
|
|
|
|
|
|
|
|
data = {}
|
2018-08-23 07:40:28 -04:00
|
|
|
data['post_text'] = post_text
|
2018-08-21 09:01:16 -04:00
|
|
|
data['post_type'] = 'text'
|
|
|
|
data['date'] = localtime(p.timestamp).strftime('%Y-%m-%d %H:%M')
|
|
|
|
data['post_id'] = p.id
|
|
|
|
socket.send('new_post', data)
|
|
|
|
|
|
|
|
|
2018-08-23 07:40:28 -04:00
|
|
|
def dice_post(socket, data):
|
|
|
|
"""
|
|
|
|
Called when the QM makes a new dice post.
|
|
|
|
"""
|
|
|
|
quest_id = data.get('quest_id')
|
|
|
|
page_num = data.get('page_num')
|
|
|
|
form = DiceCallForm(data)
|
|
|
|
if not form.is_valid():
|
|
|
|
return # error message?
|
2018-08-23 11:57:37 -04:00
|
|
|
form = form.cleaned_data
|
2018-08-23 07:40:28 -04:00
|
|
|
|
2018-08-23 11:57:37 -04:00
|
|
|
dice_roll = str(form['diceNum']) + "d"
|
|
|
|
dice_roll += str(form['diceSides'])
|
|
|
|
if form['diceMod']:
|
|
|
|
if form['diceMod'] > 0:
|
2018-08-23 07:40:28 -04:00
|
|
|
dice_roll += "+"
|
2018-08-23 11:57:37 -04:00
|
|
|
dice_roll += str(form['diceMod'])
|
2018-08-23 07:40:28 -04:00
|
|
|
|
|
|
|
post_text = "Roll " + dice_roll
|
2018-08-23 11:57:37 -04:00
|
|
|
if form['diceChal']:
|
|
|
|
post_text += " vs DC" + str(form['diceChal'])
|
|
|
|
|
|
|
|
p = Post(
|
|
|
|
quest=Quest.objects.get(id=quest_id),
|
|
|
|
page_num=page_num,
|
|
|
|
post_type='dice',
|
|
|
|
post_text=post_text
|
|
|
|
)
|
|
|
|
p.save()
|
|
|
|
d = DiceCall(
|
|
|
|
post=p,
|
|
|
|
dice_roll=dice_roll,
|
|
|
|
strict=form['diceStrict'],
|
|
|
|
dice_challenge=form['diceChal'],
|
2018-08-24 17:45:18 -04:00
|
|
|
rolls_taken=form['diceRollsTaken'],
|
|
|
|
open=True,
|
2018-08-23 11:57:37 -04:00
|
|
|
)
|
|
|
|
d.save()
|
2018-08-23 07:40:28 -04:00
|
|
|
|
2018-08-24 17:45:18 -04:00
|
|
|
socket.send('close_all_posts')
|
|
|
|
|
2018-08-23 07:40:28 -04:00
|
|
|
data = {}
|
|
|
|
data['post_text'] = post_text
|
|
|
|
data['post_type'] = 'dice'
|
2018-08-23 11:57:37 -04:00
|
|
|
data['date'] = localtime(p.timestamp).strftime('%Y-%m-%d %H:%M')
|
|
|
|
data['post_id'] = p.id
|
2018-08-23 07:40:28 -04:00
|
|
|
socket.send('new_post', data)
|
|
|
|
|
|
|
|
|
2018-08-24 17:45:18 -04:00
|
|
|
def close_post(socket, data):
|
|
|
|
"""
|
|
|
|
Called when the QM closes an open post.
|
|
|
|
"""
|
|
|
|
post_id = data.get('post_id')
|
|
|
|
p = Post.objects.get(id=post_id)
|
|
|
|
if data.get('post_type') == 'dice':
|
|
|
|
p.dicecall.open = False
|
|
|
|
p.dicecall.save()
|
|
|
|
elif data.get('post_type') == 'poll':
|
|
|
|
p.poll.open = False
|
|
|
|
p.poll.save()
|
|
|
|
|
|
|
|
data = {}
|
|
|
|
data['post_id'] = post_id
|
|
|
|
socket.send('close_post', data)
|
|
|
|
|
|
|
|
|
|
|
|
def open_post(socket, data):
|
|
|
|
"""
|
|
|
|
Called when the QM opens a closed post.
|
|
|
|
"""
|
2018-08-24 18:24:25 -04:00
|
|
|
# TODO: only posts on last page can be opened
|
2018-08-24 17:45:18 -04:00
|
|
|
post_id = data.get('post_id')
|
|
|
|
p = Post.objects.get(id=post_id)
|
|
|
|
if data.get('post_type') == 'dice':
|
2018-08-24 18:24:25 -04:00
|
|
|
posts = Post.objects.filter(post_type='dice', dicecall__open=True)
|
|
|
|
for post in posts:
|
|
|
|
post.dicecall.open = False
|
|
|
|
post.dicecall.save()
|
|
|
|
socket.send('close_all_posts', {'post_type': 'dice'})
|
|
|
|
|
2018-08-24 17:45:18 -04:00
|
|
|
p.dicecall.open = True
|
|
|
|
p.dicecall.save()
|
|
|
|
elif data.get('post_type') == 'poll':
|
|
|
|
p.poll.open = True
|
|
|
|
p.poll.save()
|
|
|
|
|
|
|
|
data = {}
|
|
|
|
data['post_id'] = post_id
|
|
|
|
socket.send('open_post', data)
|
|
|
|
|
|
|
|
|
2018-08-15 17:41:51 -04:00
|
|
|
events = {}
|
|
|
|
for obj in dir():
|
|
|
|
if type(locals()[obj]) == types.FunctionType:
|
|
|
|
events[locals()[obj].__name__] = locals()[obj]
|