Merge pull request #3 from SleepyLili/improved-help

Improved help function
This commit is contained in:
Lin (Lili) Pavelů 2022-11-14 12:31:04 +01:00 committed by GitHub
commit 0182d323d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 303 additions and 98 deletions

View File

@ -2,7 +2,7 @@ from setuptools import find_packages, setup
setup( setup(
name='tlapbot', name='tlapbot',
version='0.6.0', version='0.6.1',
packages=find_packages(), packages=find_packages(),
include_package_data=True, include_package_data=True,
install_requires=[ install_requires=[

View File

@ -21,8 +21,8 @@ def create_app(test_config=None):
) )
app.config.from_object('tlapbot.default_config') app.config.from_object('tlapbot.default_config')
app.config.from_object('tlapbot.default_redeems') app.config.from_object('tlapbot.default_redeems')
app.config.from_pyfile('config.py') app.config.from_pyfile('config.py', silent=True)
app.config.from_pyfile('redeems.py') app.config.from_pyfile('redeems.py', silent=True)
# prepare webhooks and redeem dashboard blueprints # prepare webhooks and redeem dashboard blueprints
from . import owncast_webhooks from . import owncast_webhooks
@ -30,13 +30,11 @@ def create_app(test_config=None):
app.register_blueprint(owncast_webhooks.bp) app.register_blueprint(owncast_webhooks.bp)
app.register_blueprint(owncast_redeem_dashboard.bp) app.register_blueprint(owncast_redeem_dashboard.bp)
# add db initialization CLI command # add db CLI commands
from . import db from . import db
db.init_app(app) db.init_app(app)
app.cli.add_command(db.clear_queue_command)
# add clear queue CLI command app.cli.add_command(db.refresh_counters_command)
from . import owncast_helpers
app.cli.add_command(owncast_helpers.clear_queue_command)
# scheduler job for giving points to users # scheduler job for giving points to users
def proxy_job(): def proxy_job():

View File

@ -27,7 +27,7 @@ def insert_counters(db):
for redeem, redeem_info in current_app.config['REDEEMS'].items(): for redeem, redeem_info in current_app.config['REDEEMS'].items():
if redeem_info["type"] == "counter": if redeem_info["type"] == "counter":
try: try:
cursor = db.execute( db.execute(
"INSERT INTO counters(name, count) VALUES(?, 0)", "INSERT INTO counters(name, count) VALUES(?, 0)",
(redeem,) (redeem,)
) )
@ -45,6 +45,42 @@ def init_db():
insert_counters(db) insert_counters(db)
def clear_redeem_queue():
db = get_db()
try:
cursor = db.execute(
"DELETE FROM redeem_queue"
)
cursor.execute(
"""UPDATE counters SET count = 0"""
)
db.commit()
except Error as e:
print("Error occured deleting redeem queue:", e.args[0])
def refresh_counters():
db = get_db()
try:
db.execute("DELETE FROM counters")
db.commit()
except Error as e:
print("Error occured deleting old counters:", e.args[0])
for redeem, redeem_info in current_app.config['REDEEMS'].items():
if redeem_info["type"] == "counter":
try:
cursor = db.execute(
"INSERT INTO counters(name, count) VALUES(?, 0)",
(redeem,)
)
db.commit()
except Error as e:
print("Failed inserting counters to db:", e.args[0])
@click.command('init-db') @click.command('init-db')
@with_appcontext @with_appcontext
def init_db_command(): def init_db_command():
@ -53,6 +89,22 @@ def init_db_command():
click.echo('Initialized the database.') click.echo('Initialized the database.')
@click.command('clear-queue')
@with_appcontext
def clear_queue_command():
"""Remove all redeems from the redeem queue."""
clear_redeem_queue()
click.echo('Cleared redeem queue.')
@click.command('refresh-counters')
@with_appcontext
def refresh_counters_command():
"""Refresh counters from current config file. (Remove old ones, add new ones.)"""
refresh_counters()
click.echo('Counters refreshed.')
def init_app(app): def init_app(app):
app.teardown_appcontext(close_db) app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command) app.cli.add_command(init_db_command)

View File

@ -3,3 +3,4 @@ OWNCAST_ACCESS_TOKEN=''
OWNCAST_INSTANCE_URL='http://localhost:8080' OWNCAST_INSTANCE_URL='http://localhost:8080'
POINTS_CYCLE_TIME=600 POINTS_CYCLE_TIME=600
POINTS_AMOUNT_GIVEN=10 POINTS_AMOUNT_GIVEN=10
LIST_REDEEMS=False

View File

@ -1,6 +1,6 @@
REDEEMS={ REDEEMS={
"hydrate": {"price": 60, "type": "list"}, "hydrate": {"price": 60, "type": "list"},
"lurk": {"price": 1, "type": "counter"}, "lurk": {"price": 1, "type": "counter", "info": "Let us know you're going to lurk."},
"react": {"price": 200, "type": "note"}, "react": {"price": 200, "type": "note", "info": "Attach link to a video for me to react to."},
"request": {"price": 100, "type": "note"} "request": {"price": 100, "type": "note", "info": "Request a level, gamemode, skin, etc."}
} }

23
tlapbot/help_message.py Normal file
View File

@ -0,0 +1,23 @@
from flask import current_app
from tlapbot.owncast_helpers import send_chat
def send_help():
message = []
message.append("Tlapbot gives you points for being in chat, and then allows you to spend those points.\n")
message.append(f"People connected to chat receive {current_app.config['POINTS_AMOUNT_GIVEN']} points every {current_app.config['POINTS_CYCLE_TIME']} seconds.\n")
message.append("You can see your points and recent redeems in the Tlapbot dashboard. Look for a button to click under the stream window.\n")
message.append("""Tlapbot commands:
!help to see this help message.
!points to see your points.\n"""
)
if current_app.config['LIST_REDEEMS']:
message.append("Active redeems:\n")
for redeem, redeem_info in current_app.config['REDEEMS'].items():
if 'info' in redeem_info:
message.append(f"!{redeem} for {redeem_info['price']} points. {redeem_info['info']}\n")
else:
message.append(f"!{redeem} for {redeem_info['price']} points.\n")
else:
message.append("Check the dashboard for a list of currently active redeems.")
send_chat(''.join(message))

View File

@ -1,7 +1,6 @@
from flask import current_app from flask import current_app
import requests import requests
from sqlite3 import Error from sqlite3 import Error
import click
from flask.cli import with_appcontext from flask.cli import with_appcontext
from tlapbot.db import get_db from tlapbot.db import get_db
@ -160,17 +159,6 @@ def add_to_redeem_queue(db, user_id, redeem_name, note=None):
print("To user:", user_id, " with redeem:", redeem_name, "with note:", note) print("To user:", user_id, " with redeem:", redeem_name, "with note:", note)
def clear_redeem_queue(db):
try:
cursor = db.execute(
"DELETE FROM redeem_queue"
)
cursor.execute(
"""UPDATE counters SET count = 0"""
)
db.commit()
except Error as e:
print("Error occured deleting redeem queue:", e.args[0])
def all_counters(db): def all_counters(db):
@ -217,11 +205,3 @@ def remove_duplicate_usernames(db, user_id, username):
db.commit() db.commit()
except Error as e: except Error as e:
print("Error occured removing duplicate usernames:", e.args[0]) print("Error occured removing duplicate usernames:", e.args[0])
@click.command('clear-queue')
@with_appcontext
def clear_queue_command():
"""Remove all redeems from the redeem queue."""
clear_redeem_queue(get_db())
click.echo('Cleared redeem queue.')

View File

@ -1,4 +1,4 @@
from flask import render_template, Blueprint, request from flask import render_template, Blueprint, request, current_app
from tlapbot.db import get_db from tlapbot.db import get_db
from tlapbot.owncast_helpers import (pretty_redeem_queue, all_counters, from tlapbot.owncast_helpers import (pretty_redeem_queue, all_counters,
read_all_users_with_username) read_all_users_with_username)
@ -12,6 +12,7 @@ def dashboard():
db = get_db() db = get_db()
queue = pretty_redeem_queue(db) queue = pretty_redeem_queue(db)
counters = all_counters(db) counters = all_counters(db)
redeems = current_app.config['REDEEMS']
username = request.args.get("username") username = request.args.get("username")
if username is not None: if username is not None:
users = read_all_users_with_username(db, username) users = read_all_users_with_username(db, username)
@ -21,6 +22,7 @@ def dashboard():
return render_template('dashboard.html', return render_template('dashboard.html',
queue=queue, queue=queue,
counters=counters, counters=counters,
redeems=redeems,
username=username, username=username,
users=users, users=users,
utc_timezone=utc_timezone) utc_timezone=utc_timezone)

View File

@ -3,8 +3,10 @@ from sqlite3 import Error
from tlapbot.db import get_db from tlapbot.db import get_db
from tlapbot.owncast_helpers import (add_user_to_database, change_display_name, from tlapbot.owncast_helpers import (add_user_to_database, change_display_name,
user_exists, send_chat, read_users_points, remove_duplicate_usernames) user_exists, send_chat, read_users_points, remove_duplicate_usernames)
from tlapbot.help_message import send_help
from tlapbot.redeems_handler import handle_redeem from tlapbot.redeems_handler import handle_redeem
bp = Blueprint('owncast_webhooks', __name__) bp = Blueprint('owncast_webhooks', __name__)
@ -31,15 +33,7 @@ def owncast_webhook():
print(f'New chat message from {display_name}:') print(f'New chat message from {display_name}:')
print(f'{data["eventData"]["body"]}') print(f'{data["eventData"]["body"]}')
if "!help" in data["eventData"]["body"]: if "!help" in data["eventData"]["body"]:
message = """Tlapbot commands: send_help()
!help to see this help message.
!points to see your points.
!name_update to force name update if tlapbot didn't catch it.
Tlapbot redeems:\n"""
for redeem, redeem_info in current_app.config['REDEEMS'].items():
message += (f"!{redeem} for {redeem_info['price']} points.\n")
# TODO: also make this customizable
send_chat(message)
elif "!points" in data["eventData"]["body"]: elif "!points" in data["eventData"]["body"]:
if not user_exists(db, user_id): if not user_exists(db, user_id):
add_user_to_database(db, user_id, display_name) add_user_to_database(db, user_id, display_name)

View File

@ -0,0 +1,19 @@
function openTab(event, tabName) {
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(tabName).style.display = "block";
evt.currentTarget.className += " active";
}

View File

@ -38,6 +38,51 @@ th:last-child {
padding-right: 0 padding-right: 0
} }
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 300;
letter-spacing:-.1rem;
margin-bottom:2.0rem;
margin-top:1.5rem
}
h1 {
font-size:4.6rem;
line-height:1.2
}
h2 {
font-size:3.6rem;
line-height:1.25
}
h3 {
font-size:2.8rem;
line-height:1.3
}
h4 {
font-size:2.2rem;
letter-spacing:-.08rem;
line-height:1.35
}
h5 {
font-size:1.8rem;
letter-spacing:-.05rem;
line-height:1.5
}
h6 {
font-size:1.6rem;
letter-spacing:0;
line-height:1.4
}
/* General style */ /* General style */
h1{font-size: 3.6rem; line-height: 1.25} h1{font-size: 3.6rem; line-height: 1.25}
h2{font-size: 2.8rem; line-height: 1.3} h2{font-size: 2.8rem; line-height: 1.3}
@ -57,3 +102,38 @@ pre{padding: 1em;}
select { select {
width: auto; width: auto;
} }
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
/* Style the buttons that are used to open the tab content */
.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
}
/* Change background color of buttons on hover */
.tab button:hover {
background-color: #ddd;
}
/* Create an active/current tablink class */
.tab button.active {
background-color: #ccc;
}
/* Style the tab content */
.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}

View File

@ -4,60 +4,116 @@
<head> <head>
<title>Redeems Dashboard</title> <title>Redeems Dashboard</title>
</head> </head>
<body> <div id="script">
{% if (username and users ) %}
<table>
<thead>
<tr>
<th>Points balance:</th>
</tr>
</thead>
{% for user in users %}
<tbody>
<td> {{ user[0] }} </td>
<td> {{ user[1] }} </td>
</tbody>
{% endfor %}
</table>
{% endif %}
{% if counters %} <script src="/static/dashboard.js"></script>
<table>
<thead>
<tr>
<th>Counters</th>
</tr>
</thead>
{% for counter in counters %}
<tbody>
<td> {{ counter[0] }} </td>
<td> {{ counter[1] }} </td>
</tbody>
{% endfor %}
</table>
{% endif %}
{% if queue %} <div class="tab">
<table> <button class="tablinks" onclick="openTab(event, 'dashboard')", id="defaultOpen">Tlapbot dashboard</button>
<thead> <button class="tablinks" onclick="openTab(event, 'redeems-list')">Redeems help</button>
<tr> </div>
<th>time</th>
<th>redeem</th> <div id='dashboard' class="tabcontent">
<th>redeemer</th> <body>
<th>note</th> <h3>Redeems Dashboard</h3>
</tr> {% if (username and users ) %}
</thead> <table>
{% for row in queue %} <thead>
<tbody> <tr>
<td>{{ row[0].replace(tzinfo=utc_timezone).astimezone().strftime("%H:%M") }}</td> <th>Your points balance</th>
<td>{{ row[1] }}</td> </tr>
<td>{{ row[3] }}</td> </thead>
{% if row[2] %} {% for user in users %}
<td>{{ row[2] }}</td> <tbody>
<td> {{ user[0] }} </td>
<td> {{ user[1] }} </td>
</tbody>
{% endfor %}
</table>
{% endif %} {% endif %}
</tbody>
{% endfor %} {% if counters %}
</table> <table>
{% endif %} <thead>
</body> <tr>
<th>Active counters</th>
</tr>
</thead>
{% for counter in counters %}
<tbody>
<td> {{ counter[0] }} </td>
<td> {{ counter[1] }} </td>
</tbody>
{% endfor %}
</table>
{% endif %}
{% if queue %}
<table>
<thead>
<tr>
<th>Recent redeems</th>
</tr>
<tr>
<th>Time</th>
<th>Redeem</th>
<th>Redeemer</th>
<th>Note</th>
</tr>
</thead>
{% for row in queue %}
<tbody>
<td>{{ row[0].replace(tzinfo=utc_timezone).astimezone().strftime("%H:%M") }}</td>
<td>{{ row[1] }}</td>
<td>{{ row[3] }}</td>
{% if row[2] %}
<td>{{ row[2] }}</td>
{% endif %}
</tbody>
{% endfor %}
</table>
{% endif %}
</body>
</div>
<div id='redeems-list' class="tabcontent">
<h3>Currently active redeems</h3>
<p>If you have enough points, you can redeem those redeems by typing the command in chat.</p>
<ul>
<li><strong>Counter</strong> redeems add +1 to their counter.</li>
<li><strong>List</strong> redeems get added to the list of recent redeems (without a note).</li>
<li><strong>Note</strong> redeems require you to send a message together with the redeem.</li>
</ul>
<body>
{% if redeems %}
<table>
<thead>
<tr>
<th>Redeem</th>
<th>Price</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
{% for redeem, redeem_info in redeems.items() %}
<tbody>
<td>!{{ redeem }}</td>
<td>{{ redeem_info["price"] }}</td>
<td>{{ redeem_info["type"] }}</td>
{% if redeem_info["info"] %}
<td>{{ redeem_info["info"] }}</td>
{% endif %}
</tbody>
{% endfor %}
</table>
{% endif %}
</body>
</div>
</div>
<script>
document.getElementById("defaultOpen").click();
</script>
</html> </html>