From a0e31da8049e8c4c3558b65610d270b6430c9b1f Mon Sep 17 00:00:00 2001 From: dnns01 <github@dnns01.de> Date: Sun, 5 Sep 2021 22:36:42 +0200 Subject: [PATCH] Change settings and fix issues with websocket sessions --- haugebot/asgi.py | 4 +- haugebot/consumers.py | 12 ++--- haugebot/settings.py | 2 +- haugebot_twitch/config.py | 16 +++---- haugebot_twitch/wordcloud.py | 3 +- haugebot_twitch/wusstest_du_schon.py | 4 +- haugebot_web/forms.py | 40 ++-------------- haugebot_web/migrations/0004_setting_label.py | 19 ++++++++ .../migrations/0005_auto_20210727_2314.py | 37 +++++++++++++++ haugebot_web/models.py | 4 +- haugebot_web/templates/card_formset.html | 14 +++--- haugebot_web/templates/form.html | 4 +- haugebot_web/templates/list_formset.html | 2 +- haugebot_web/templates/settings_formset.html | 46 +++++++++++++++++++ haugebot_web/templates/wordcloud.html | 8 ++-- haugebot_web/views.py | 26 ++++++----- requirements.txt | 1 - 17 files changed, 156 insertions(+), 86 deletions(-) create mode 100644 haugebot_web/migrations/0004_setting_label.py create mode 100644 haugebot_web/migrations/0005_auto_20210727_2314.py create mode 100644 haugebot_web/templates/settings_formset.html diff --git a/haugebot/asgi.py b/haugebot/asgi.py index 3d887d5..44b9720 100644 --- a/haugebot/asgi.py +++ b/haugebot/asgi.py @@ -9,7 +9,7 @@ https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/ import os -from channels.auth import AuthMiddlewareStack +from channels.sessions import SessionMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from django.core.asgi import get_asgi_application @@ -19,7 +19,7 @@ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'haugebot.settings') application = ProtocolTypeRouter({ "http": get_asgi_application(), - "websocket": AuthMiddlewareStack( + "websocket": SessionMiddlewareStack( URLRouter( haugebot.routing.websocket_urlpatterns ) diff --git a/haugebot/consumers.py b/haugebot/consumers.py index eaa390e..ce7c24e 100644 --- a/haugebot/consumers.py +++ b/haugebot/consumers.py @@ -1,7 +1,6 @@ import json import os -from django.contrib.sessions.models import Session from asgiref.sync import async_to_sync from channels.generic.websocket import WebsocketConsumer from wordcloud import WordCloud @@ -21,10 +20,6 @@ def make_image(uuid, words, permitted): wc.to_file(f"media/{uuid}.png") -def verify_session_key(session_key): - return len(list(Session.objects.filter(session_key=session_key))) > 0 - - class WordCloudConsumer(WebsocketConsumer): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -62,6 +57,9 @@ class WordCloudConsumer(WebsocketConsumer): } ) + def verify_session_key(self): + return self.scope["session"].session_key is not None + def word_update(self, data): global uuid, words, permitted @@ -78,7 +76,7 @@ class WordCloudConsumer(WebsocketConsumer): make_image(uuid, words, permitted) def permit(self, data): - if not verify_session_key(data.get("session_key")): + if not self.verify_session_key(): return word = data.get("word") if word not in permitted: @@ -86,7 +84,7 @@ class WordCloudConsumer(WebsocketConsumer): make_image(uuid, words, permitted) def deny(self, data): - if not verify_session_key(data.get("session_key")): + if not self.verify_session_key(): return word = data.get("word") if word in permitted: diff --git a/haugebot/settings.py b/haugebot/settings.py index 92ecbb4..0071116 100644 --- a/haugebot/settings.py +++ b/haugebot/settings.py @@ -27,7 +27,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent SECRET_KEY = os.getenv("DJANGO_SECRET") # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = os.getenv("DJANGO_DEBUG") == "True" ALLOWED_HOSTS = [os.getenv("DJANGO_ALLOWED_HOST1"), os.getenv("DJANGO_ALLOWED_HOST2"), "127.0.0.1"] diff --git a/haugebot_twitch/config.py b/haugebot_twitch/config.py index 8e25af0..7895a4a 100644 --- a/haugebot_twitch/config.py +++ b/haugebot_twitch/config.py @@ -1,24 +1,24 @@ import sqlite3 -def get_value(key): +def get_value(column): conn = sqlite3.connect("db.sqlite3") c = conn.cursor() - c.execute('SELECT value from haugebot_web_setting where key = ?', (key,)) + c.execute(f"SELECT {column} FROM haugebot_web_setting") value = c.fetchone()[0] conn.close() return value -def get_int(key): - return int(get_value(key)) +def get_int(column): + return get_value(column) -def get_float(key): - return float(get_value(key)) +def get_float(column): + return get_value(column) -def get_bool(key): - return get_value(key) == "1" +def get_bool(column): + return get_value(column) == "1" diff --git a/haugebot_twitch/wordcloud.py b/haugebot_twitch/wordcloud.py index 5bd037e..feafed1 100644 --- a/haugebot_twitch/wordcloud.py +++ b/haugebot_twitch/wordcloud.py @@ -28,7 +28,8 @@ class Wordcloud(commands.Cog): try: if self.running: if not self.ws or self.ws.closed: - self.ws = await connect(self.ws_url) + self.ws = await connect(self.ws_url, + extra_headers=[("sessionid", "aaaso34ko6goc2wczbfjj1njnqo8k89b")]) if self.ws: js = { diff --git a/haugebot_twitch/wusstest_du_schon.py b/haugebot_twitch/wusstest_du_schon.py index 5f6da17..9559aec 100644 --- a/haugebot_twitch/wusstest_du_schon.py +++ b/haugebot_twitch/wusstest_du_schon.py @@ -9,11 +9,11 @@ class WusstestDuSchon(commands.Cog): def __init__(self, bot): self.bot = bot - @routines.routine(minutes=config.get_int("WusstestDuSchonLoop")) + @routines.routine(minutes=config.get_int("wusstest_du_schon_loop")) async def loop(self): if await self.bot.stream(): channel = self.bot.channel() - prefix = config.get_value("WusstestDuSchonPrefix") + prefix = config.get_value("wusstest_du_schon_prefix") message = self.get_random_message(prefix) await self.bot.send_me(channel, message) diff --git a/haugebot_web/forms.py b/haugebot_web/forms.py index 9441e9e..50bb652 100644 --- a/haugebot_web/forms.py +++ b/haugebot_web/forms.py @@ -15,41 +15,7 @@ class BaseForm(forms.ModelForm): field.widget.attrs['placeholder'] = field.label -class WusstestDuSchonConfigForm(forms.Form): - prefix_field = forms.CharField(max_length=50, initial=Setting.objects.get(key="WusstestDuSchonPrefix").value, - label="Präfix") - loop_field = forms.IntegerField(initial=Setting.objects.get(key="WusstestDuSchonLoop").value, - label="Pause (in Minuten)") - color_field = forms.ChoiceField(choices=[(color.color, color.display_name) for color in TwitchColor.objects.all()], - label="Text Farbe") - +class BaseWusstestDuSchonSettingsFormSet(forms.BaseModelFormSet): def __init__(self, *args, **kwargs): - super(WusstestDuSchonConfigForm, self).__init__(*args, **kwargs) - - self.fields["prefix_field"].initial = Setting.objects.get(key="WusstestDuSchonPrefix").value - self.fields["loop_field"].initial = Setting.objects.get(key="WusstestDuSchonLoop").value - self.fields["color_field"].initial = TwitchColor.objects.get( - twitch_name=Setting.objects.get(key="WusstestDuSchonColor").value).color - - for field_name, field in self.fields.items(): - if type(field) is forms.fields.BooleanField: - field.widget.attrs['class'] = ' w3-check ' - field.label_suffix = "" - else: - field.widget.attrs['class'] = ' w3-input ' - field.widget.attrs['placeholder'] = field.label - - self.fields["color_field"].widget.attrs['class'] += ' color-select ' - - def save(self): - prefix = Setting.objects.get(key="WusstestDuSchonPrefix") - prefix.value = self.cleaned_data["prefix_field"] - prefix.save() - - loop = Setting.objects.get(key="WusstestDuSchonLoop") - loop.value = self.cleaned_data["loop_field"] - loop.save() - - color = Setting.objects.get(key="WusstestDuSchonColor") - color.value = TwitchColor.objects.get(color=self.cleaned_data["color_field"]).twitch_name - color.save() + super().__init__(*args, **kwargs) + self.queryset = Setting.objects.filter(key__in=["WusstestDuSchonPrefix", "WusstestDuSchonLoop"]) diff --git a/haugebot_web/migrations/0004_setting_label.py b/haugebot_web/migrations/0004_setting_label.py new file mode 100644 index 0000000..e978300 --- /dev/null +++ b/haugebot_web/migrations/0004_setting_label.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.5 on 2021-07-24 21:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('haugebot_web', '0003_pipimeter'), + ] + + operations = [ + migrations.AddField( + model_name='setting', + name='label', + field=models.CharField(default='', max_length=50), + preserve_default=False, + ), + ] diff --git a/haugebot_web/migrations/0005_auto_20210727_2314.py b/haugebot_web/migrations/0005_auto_20210727_2314.py new file mode 100644 index 0000000..abc75a5 --- /dev/null +++ b/haugebot_web/migrations/0005_auto_20210727_2314.py @@ -0,0 +1,37 @@ +# Generated by Django 3.2.5 on 2021-07-27 21:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('haugebot_web', '0004_setting_label'), + ] + + operations = [ + migrations.RemoveField( + model_name='setting', + name='key', + ), + migrations.RemoveField( + model_name='setting', + name='label', + ), + migrations.RemoveField( + model_name='setting', + name='value', + ), + migrations.AddField( + model_name='setting', + name='wusstest_du_schon_loop', + field=models.PositiveIntegerField(default=10, verbose_name='Pause (in Minuten)'), + preserve_default=False, + ), + migrations.AddField( + model_name='setting', + name='wusstest_du_schon_prefix', + field=models.CharField(default='Psssst... wusstest du eigentlich schon,', max_length=50, verbose_name='Präfix'), + preserve_default=False, + ), + ] diff --git a/haugebot_web/models.py b/haugebot_web/models.py index 8cd484a..9fca378 100644 --- a/haugebot_web/models.py +++ b/haugebot_web/models.py @@ -7,8 +7,8 @@ from .managers import TwitchUserManager class Setting(models.Model): - key = models.CharField(max_length=50) - value = models.CharField(max_length=50) + wusstest_du_schon_prefix = models.CharField(max_length=50, verbose_name="Präfix") + wusstest_du_schon_loop = models.PositiveIntegerField(verbose_name="Pause (in Minuten)") class TwitchColor(models.Model): diff --git a/haugebot_web/templates/card_formset.html b/haugebot_web/templates/card_formset.html index e426d36..172f623 100644 --- a/haugebot_web/templates/card_formset.html +++ b/haugebot_web/templates/card_formset.html @@ -19,12 +19,12 @@ </p> {% endfor %} </div> - {% if formset_form.fields.id.initial %} - <div class="w3-display-topright"> - <p><a href="{% url form.remove_url formset_form.fields.id.initial %}" - class="w3-button w3-haugepink"><i - class="fas fa-trash-alt"></i></a></p> - </div> - {% endif %} + {% if formset_form.fields.id.initial and form.remove_url%} + <div class="w3-display-topright"> + <p><a href="{% url form.remove_url formset_form.fields.id.initial %}" + class="w3-button w3-haugepink"><i + class="fas fa-trash-alt"></i></a></p> + </div> + {% endif %} </div> {% endfor %} diff --git a/haugebot_web/templates/form.html b/haugebot_web/templates/form.html index e29f1de..1bab465 100644 --- a/haugebot_web/templates/form.html +++ b/haugebot_web/templates/form.html @@ -20,7 +20,9 @@ <form method="post"> <input type="hidden" id="id-active" value="{{ form.name }}" name="form-active"/> {% csrf_token %} - {% if form.display == "list" %} + {% if form.name == "config" %} + {% include 'settings_formset.html' %} + {% elif form.display == "list" %} {% if form.type == "form" %} {% include 'list_form.html' %} {% elif form.type == "formset" %} diff --git a/haugebot_web/templates/list_formset.html b/haugebot_web/templates/list_formset.html index 93ae469..1e448df 100644 --- a/haugebot_web/templates/list_formset.html +++ b/haugebot_web/templates/list_formset.html @@ -3,7 +3,7 @@ {% for formset_form in form.formset %} <li class="w3-bar"> <div class="w3-bar-item w3-form-bar-item" style="width: 100%;"> - {% if formset_form.fields.id.initial %} + {% if formset_form.fields.id.initial and form.remove_url %} <span class="w3-right"> <a href="{% url form.remove_url formset_form.fields.id.initial %}" class="w3-button w3-haugepink"> diff --git a/haugebot_web/templates/settings_formset.html b/haugebot_web/templates/settings_formset.html new file mode 100644 index 0000000..60d2daa --- /dev/null +++ b/haugebot_web/templates/settings_formset.html @@ -0,0 +1,46 @@ +{{ form.formset.management_form }} +<ul class="w3-ul w3-card-4 w3-white"> + {% for formset_form in form.formset %} + <li class="w3-bar"> +{# <div class="w3-bar-item w3-form-bar-item" style="width: 100%;">#} +{# <div class="w3-form-container">#} + {{ formformset_form.non_field_errors }} + {% for field in formset_form %} + {{ field.errors }} + {% if field.widget_type == "checkbox" %} + <label class="switch"> + {{ field }} + <span class="slider"></span> + </label> + {{ field.label_tag }} + {% else %} + {{ field }} + {% endif %} + {% endfor %} +{# </div>#} +{# </div>#} + </li> + {% endfor %} +</ul> + + +<div class="w3-card w3-white w3-display-container"> + <div class="w3-container w3-form-container"> + {{ form.form.non_field_errors }} + {% for field in form.form %} + <p> + {{ field.errors }} + {% if field.widget_type == "checkbox" %} + <label class="switch"> + {{ field }} + <span class="slider"></span> + </label> + {{ field.label_tag }} + {% else %} + {{ field.label_tag }} + {{ field }} + {% endif %} + </p> + {% endfor %} + </div> +</div> diff --git a/haugebot_web/templates/wordcloud.html b/haugebot_web/templates/wordcloud.html index 9307230..83f2655 100644 --- a/haugebot_web/templates/wordcloud.html +++ b/haugebot_web/templates/wordcloud.html @@ -19,10 +19,10 @@ </div> <div class="w3-container w3-card-4 w3-white" id="filter"> - {% if user.is_broadcaster %} - <h3>OBS Browser Source URL: {{ embed_link }}</h3> - <hr> - {% endif %} +{# {% if user.is_broadcaster %}#} +{# <h3>OBS Browser Source URL: {{ embed_link }}</h3>#} +{# <hr>#} +{# {% endif %}#} <h3>Freigegeben</h3> <ul class="w3-ul" id="permitted"> </ul> diff --git a/haugebot_web/views.py b/haugebot_web/views.py index 5d70217..370ee95 100644 --- a/haugebot_web/views.py +++ b/haugebot_web/views.py @@ -3,12 +3,12 @@ import os import requests from django.contrib.auth import authenticate, login as django_login, logout as django_logout from django.contrib.auth.decorators import login_required -from django.forms import modelformset_factory +from django.forms import modelformset_factory, modelform_factory from django.shortcuts import render, redirect from django.urls import reverse -from .forms import BaseForm, WusstestDuSchonConfigForm -from .models import WusstestDuSchon +from .forms import BaseForm +from .models import WusstestDuSchon, Setting # Create your views here. @@ -18,9 +18,10 @@ def home(request): @login_required(login_url="/login") def wusstest_du_schon(request): - WusstestDuSchonFormSet = modelformset_factory(WusstestDuSchon, form=BaseForm, - fields=('advertised_command', 'text', 'use_prefix', 'active'), - field_classes=['']) + wusstest_du_schon_form_set = modelformset_factory(WusstestDuSchon, form=BaseForm, + fields=('advertised_command', 'text', 'use_prefix', 'active')) + settings_form = modelform_factory(Setting, form=BaseForm, + fields=('wusstest_du_schon_prefix', 'wusstest_du_schon_loop')) active = "config" form = None @@ -28,9 +29,9 @@ def wusstest_du_schon(request): active = request.POST["form-active"] if active == "config": - form = WusstestDuSchonConfigForm(request.POST) + form = settings_form(request.POST, instance=Setting.objects.first()) elif active == "wusstestdu": - form = WusstestDuSchonFormSet(request.POST, request.FILES) + form = wusstest_du_schon_form_set(request.POST, request.FILES) if form and form.is_valid(): form.save() @@ -39,12 +40,13 @@ def wusstest_du_schon(request): "display": "card", 'type': 'form', 'name': 'config', - 'form': WusstestDuSchonConfigForm()}, + 'form': settings_form(instance=Setting.objects.first()), + }, "Texte": { 'display': 'card', 'type': 'formset', 'name': 'wusstestdu', - 'formset': WusstestDuSchonFormSet(), + 'formset': wusstest_du_schon_form_set(), 'remove_url': 'wusstest_du_schon_remove', }, } @@ -59,10 +61,10 @@ def wusstest_du_schon_remove(request, id): return redirect("/wusstest_du_schon") -@login_required(login_url="/login") +#@login_required(login_url="/login") def wordcloud(request): id = os.getenv("DJANGO_WORDCLOUD_LIVE_ID") - embed_link = f"{request.scheme}://{request.headers['Host']}{reverse('wordcloud_live', args=(id,))}" if request.user.is_broadcaster else "" + embed_link = "" #f"{request.scheme}://{request.headers['Host']}{reverse('wordcloud_live', args=(id,))}" if request.user.is_broadcaster else "" return render(request, "wordcloud.html", {'title': 'Wordcloud', "ws_url": os.getenv("WORDCLOUD_WS_URL"), "session_key": request.session.session_key, "embed_link": embed_link}) diff --git a/requirements.txt b/requirements.txt index b1ee80a..56944f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -42,7 +42,6 @@ service-identity==21.1.0 six==1.16.0 sqlparse==0.4.1 Twisted==21.2.0 -twisted-iocpsupport==1.0.1 twitchio==2.0.0b7 txaio==21.2.1 typing-extensions==3.7.4.3 -- GitLab