diff --git a/setup.py b/setup.py
index 5b34277..d089bc7 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import find_packages, setup
setup(
name='tlapbot',
- version='0.6.0',
+ version='0.6.1',
packages=find_packages(),
include_package_data=True,
install_requires=[
diff --git a/tlapbot/__init__.py b/tlapbot/__init__.py
index c5a9368..9b75963 100644
--- a/tlapbot/__init__.py
+++ b/tlapbot/__init__.py
@@ -21,8 +21,8 @@ def create_app(test_config=None):
)
app.config.from_object('tlapbot.default_config')
app.config.from_object('tlapbot.default_redeems')
- app.config.from_pyfile('config.py')
- app.config.from_pyfile('redeems.py')
+ app.config.from_pyfile('config.py', silent=True)
+ app.config.from_pyfile('redeems.py', silent=True)
# prepare webhooks and redeem dashboard blueprints
from . import owncast_webhooks
@@ -30,14 +30,12 @@ def create_app(test_config=None):
app.register_blueprint(owncast_webhooks.bp)
app.register_blueprint(owncast_redeem_dashboard.bp)
- # add db initialization CLI command
+ # add db CLI commands
from . import db
db.init_app(app)
-
- # add clear queue CLI command
- from . import owncast_helpers
- app.cli.add_command(owncast_helpers.clear_queue_command)
-
+ app.cli.add_command(db.clear_queue_command)
+ app.cli.add_command(db.refresh_counters_command)
+
# scheduler job for giving points to users
def proxy_job():
with app.app_context():
diff --git a/tlapbot/db.py b/tlapbot/db.py
index 8bb5b68..e9890f7 100644
--- a/tlapbot/db.py
+++ b/tlapbot/db.py
@@ -27,7 +27,7 @@ def insert_counters(db):
for redeem, redeem_info in current_app.config['REDEEMS'].items():
if redeem_info["type"] == "counter":
try:
- cursor = db.execute(
+ db.execute(
"INSERT INTO counters(name, count) VALUES(?, 0)",
(redeem,)
)
@@ -45,6 +45,42 @@ def init_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')
@with_appcontext
def init_db_command():
@@ -53,6 +89,22 @@ def init_db_command():
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):
app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command)
diff --git a/tlapbot/default_config.py b/tlapbot/default_config.py
index 57f4d85..2871227 100644
--- a/tlapbot/default_config.py
+++ b/tlapbot/default_config.py
@@ -2,4 +2,5 @@ SECRET_KEY='dev'
OWNCAST_ACCESS_TOKEN=''
OWNCAST_INSTANCE_URL='http://localhost:8080'
POINTS_CYCLE_TIME=600
-POINTS_AMOUNT_GIVEN=10
\ No newline at end of file
+POINTS_AMOUNT_GIVEN=10
+LIST_REDEEMS=False
\ No newline at end of file
diff --git a/tlapbot/default_redeems.py b/tlapbot/default_redeems.py
index 6956e1c..6210a04 100644
--- a/tlapbot/default_redeems.py
+++ b/tlapbot/default_redeems.py
@@ -1,6 +1,6 @@
REDEEMS={
"hydrate": {"price": 60, "type": "list"},
- "lurk": {"price": 1, "type": "counter"},
- "react": {"price": 200, "type": "note"},
- "request": {"price": 100, "type": "note"}
+ "lurk": {"price": 1, "type": "counter", "info": "Let us know you're going to lurk."},
+ "react": {"price": 200, "type": "note", "info": "Attach link to a video for me to react to."},
+ "request": {"price": 100, "type": "note", "info": "Request a level, gamemode, skin, etc."}
}
\ No newline at end of file
diff --git a/tlapbot/help_message.py b/tlapbot/help_message.py
new file mode 100644
index 0000000..af2d4cd
--- /dev/null
+++ b/tlapbot/help_message.py
@@ -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))
\ No newline at end of file
diff --git a/tlapbot/owncast_helpers.py b/tlapbot/owncast_helpers.py
index f766627..17367d4 100644
--- a/tlapbot/owncast_helpers.py
+++ b/tlapbot/owncast_helpers.py
@@ -1,7 +1,6 @@
from flask import current_app
import requests
from sqlite3 import Error
-import click
from flask.cli import with_appcontext
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)
-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):
@@ -217,11 +205,3 @@ def remove_duplicate_usernames(db, user_id, username):
db.commit()
except Error as e:
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.')
diff --git a/tlapbot/owncast_redeem_dashboard.py b/tlapbot/owncast_redeem_dashboard.py
index 263f301..b5de116 100644
--- a/tlapbot/owncast_redeem_dashboard.py
+++ b/tlapbot/owncast_redeem_dashboard.py
@@ -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.owncast_helpers import (pretty_redeem_queue, all_counters,
read_all_users_with_username)
@@ -12,6 +12,7 @@ def dashboard():
db = get_db()
queue = pretty_redeem_queue(db)
counters = all_counters(db)
+ redeems = current_app.config['REDEEMS']
username = request.args.get("username")
if username is not None:
users = read_all_users_with_username(db, username)
@@ -21,6 +22,7 @@ def dashboard():
return render_template('dashboard.html',
queue=queue,
counters=counters,
+ redeems=redeems,
username=username,
users=users,
utc_timezone=utc_timezone)
diff --git a/tlapbot/owncast_webhooks.py b/tlapbot/owncast_webhooks.py
index 64f8cd2..e83f9ec 100644
--- a/tlapbot/owncast_webhooks.py
+++ b/tlapbot/owncast_webhooks.py
@@ -3,8 +3,10 @@ from sqlite3 import Error
from tlapbot.db import get_db
from tlapbot.owncast_helpers import (add_user_to_database, change_display_name,
user_exists, send_chat, read_users_points, remove_duplicate_usernames)
+from tlapbot.help_message import send_help
from tlapbot.redeems_handler import handle_redeem
+
bp = Blueprint('owncast_webhooks', __name__)
@@ -31,15 +33,7 @@ def owncast_webhook():
print(f'New chat message from {display_name}:')
print(f'{data["eventData"]["body"]}')
if "!help" in data["eventData"]["body"]:
- message = """Tlapbot commands:
- !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)
+ send_help()
elif "!points" in data["eventData"]["body"]:
if not user_exists(db, user_id):
add_user_to_database(db, user_id, display_name)
diff --git a/tlapbot/static/dashboard.js b/tlapbot/static/dashboard.js
new file mode 100644
index 0000000..193529b
--- /dev/null
+++ b/tlapbot/static/dashboard.js
@@ -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";
+ }
\ No newline at end of file
diff --git a/tlapbot/static/style.css b/tlapbot/static/style.css
index 3d5068f..9ea94a6 100644
--- a/tlapbot/static/style.css
+++ b/tlapbot/static/style.css
@@ -38,6 +38,51 @@ th:last-child {
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 */
h1{font-size: 3.6rem; line-height: 1.25}
h2{font-size: 2.8rem; line-height: 1.3}
@@ -56,4 +101,39 @@ pre{padding: 1em;}
}
select {
width: auto;
-}
\ No newline at end of file
+}
+
+.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;
+ }
\ No newline at end of file
diff --git a/tlapbot/templates/dashboard.html b/tlapbot/templates/dashboard.html
index bebbc1d..785b9cd 100644
--- a/tlapbot/templates/dashboard.html
+++ b/tlapbot/templates/dashboard.html
@@ -4,60 +4,116 @@
Redeems Dashboard
-
- {% if (username and users ) %}
-
-
-
- Points balance: |
-
-
- {% for user in users %}
-
- {{ user[0] }} |
- {{ user[1] }} |
-
- {% endfor %}
-
- {% endif %}
+
- {% if counters %}
-
-
-
- Counters |
-
-
- {% for counter in counters %}
-
- {{ counter[0] }} |
- {{ counter[1] }} |
-
- {% endfor %}
-
- {% endif %}
+
- {% if queue %}
-
-
-
- time |
- redeem |
- redeemer |
- note |
-
-
- {% for row in queue %}
-
- {{ row[0].replace(tzinfo=utc_timezone).astimezone().strftime("%H:%M") }} |
- {{ row[1] }} |
- {{ row[3] }} |
- {% if row[2] %}
- {{ row[2] }} |
+
+
+
+
+
+
+
+
Redeems Dashboard
+ {% if (username and users ) %}
+
+
+
+ Your points balance |
+
+
+ {% for user in users %}
+
+ {{ user[0] }} |
+ {{ user[1] }} |
+
+ {% endfor %}
+
{% endif %}
-
- {% endfor %}
-
- {% endif %}
-
+
+ {% if counters %}
+
+
+
+ Active counters |
+
+
+ {% for counter in counters %}
+
+ {{ counter[0] }} |
+ {{ counter[1] }} |
+
+ {% endfor %}
+
+ {% endif %}
+
+ {% if queue %}
+
+
+
+ Recent redeems |
+
+
+ Time |
+ Redeem |
+ Redeemer |
+ Note |
+
+
+ {% for row in queue %}
+
+ {{ row[0].replace(tzinfo=utc_timezone).astimezone().strftime("%H:%M") }} |
+ {{ row[1] }} |
+ {{ row[3] }} |
+ {% if row[2] %}
+ {{ row[2] }} |
+ {% endif %}
+
+ {% endfor %}
+
+ {% endif %}
+
+
+
+
+
Currently active redeems
+
If you have enough points, you can redeem those redeems by typing the command in chat.
+
+ - Counter redeems add +1 to their counter.
+ - List redeems get added to the list of recent redeems (without a note).
+ - Note redeems require you to send a message together with the redeem.
+
+
+ {% if redeems %}
+
+
+
+ Redeem |
+ Price |
+ Type |
+ Description |
+
+
+ {% for redeem, redeem_info in redeems.items() %}
+
+ !{{ redeem }} |
+ {{ redeem_info["price"] }} |
+ {{ redeem_info["type"] }} |
+ {% if redeem_info["info"] %}
+ {{ redeem_info["info"] }} |
+ {% endif %}
+
+ {% endfor %}
+
+ {% endif %}
+
+
+
+
+
+
+