Compare commits

..

No commits in common. "2284fb3a00c204d5e53c42c1c5cb99f5a0cdb5a8" and "8c19088640635c804bfe349b89a86ccfc63d3c2e" have entirely different histories.

12 changed files with 71 additions and 98 deletions

View File

@ -329,8 +329,7 @@ REDEEMS={
```
#### File format
`redeems.py` is a config file with just a `REDEEMS` key, that assigns a dictionary of redeems to it.
Each dictionary entry is a redeem, and the dictionary keys are strings that decide the chat command for the redeem.
The redeem names shouldn't have spaces in them.
Each dictionary entry is a redeem, and the dictionary keys are strings that decides the chat command for the redeem.
The value is another dictionary that needs to have an entry for `"type"` and
an entry for `"price"` for non-milestones or `"goal"` for milestones.
Optionally, each redeem can also have `"info"` and `"category"` entries.

View File

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

View File

@ -4,7 +4,7 @@ from flask import Flask
from apscheduler.schedulers.background import BackgroundScheduler
from tlapbot.db import get_db
from tlapbot.owncast_requests import is_stream_live, give_points_to_chat
from tlapbot.redeems import remove_inactive_redeems
def create_app(test_config=None):
app = Flask(__name__, instance_relative_config=True)
@ -36,12 +36,6 @@ def create_app(test_config=None):
raise RuntimeError("Prefix is >1 character. "
"Change your config to set 1-character prefix.")
# Check for spaces in redeems (they won't work)
for redeem in app.config['REDEEMS']:
if ' ' in redeem:
app.logger.warning(f"Redeem '{redeem}' has spaces in its name.")
app.logger.warning("Redeems with spaces are impossible to redeem.")
# prepare webhooks and redeem dashboard blueprints
from . import owncast_webhooks
from . import tlapbot_dashboard

View File

@ -6,7 +6,6 @@ from flask.cli import with_appcontext
from tlapbot.redeems import milestone_complete
def get_db():
if 'db' not in g:
g.db = sqlite3.connect(
@ -128,7 +127,7 @@ def refresh_milestones():
def reset_milestone(milestone):
if milestone not in current_app.config['REDEEMS']:
if not milestone in current_app.config['REDEEMS']:
print(f"Failed resetting milestone, {milestone} not in redeems file.")
return False
try:
@ -148,6 +147,7 @@ def reset_milestone(milestone):
return False
@click.command('init-db')
@with_appcontext
def init_db_command():

View File

@ -4,27 +4,20 @@ from tlapbot.owncast_requests 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. <br>")
message.append(f"People connected to chat receive {current_app.config['POINTS_AMOUNT_GIVEN']} points every {current_app.config['POINTS_CYCLE_TIME']} seconds. <br>")
message.append("You can see your points and recent redeems in the Tlapbot dashboard. Look for a button to click under the stream window. <br>")
message.append("""Tlapbot commands: <br>
!help to see this help message. <br>
!points to see your points. <br>"""
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: <br>")
message.append("Active redeems:\n")
for redeem, redeem_info in current_app.config['REDEEMS'].items():
if redeem_info.get('category', None):
if not set(redeem_info['category']).intersection(set(current_app.config['ACTIVE_CATEGORIES'])):
continue
if 'type' in redeem_info and redeem_info['type'] == 'milestone':
message.append(f"!{redeem} milestone with goal of {redeem_info['goal']}.")
else:
message.append(f"!{redeem} for {redeem_info['price']} points.")
if 'info' in redeem_info:
message.append(f" {redeem_info['info']} <br>")
message.append(f"!{redeem} for {redeem_info['price']} points. {redeem_info['info']}\n")
else:
message.append("<br>")
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

@ -2,7 +2,6 @@ from flask import current_app
from sqlite3 import Error
from re import sub
# # # db stuff # # #
def read_users_points(db, user_id):
"""Errors out if user doesn't exist."""
@ -98,7 +97,7 @@ def add_user_to_database(db, user_id, display_name):
def change_display_name(db, user_id, new_name):
try:
db.execute(
cursor = db.execute(
"UPDATE points SET name = ? WHERE id = ?",
(new_name, user_id)
)
@ -110,7 +109,7 @@ def change_display_name(db, user_id, new_name):
def remove_duplicate_usernames(db, user_id, username):
try:
db.execute(
cursor = db.execute(
"""UPDATE points
SET name = NULL
WHERE name = ? AND NOT id = ?""",
@ -122,7 +121,6 @@ def remove_duplicate_usernames(db, user_id, username):
# # # misc. stuff # # #
# This is now unused since rawBody attribute of the webhook now returns cleaned-up emotes.
def remove_emoji(message):
return sub(
r'<img class="emoji" alt="(:.*?:)" title=":.*?:" src="/img/emoji/.*?">',

View File

@ -45,3 +45,4 @@ def send_chat(message):
current_app.logger.error(f"Check owncast instance url and access key.")
return
return r.json()

View File

@ -36,22 +36,22 @@ def owncast_webhook():
user_id = data["eventData"]["user"]["id"]
display_name = data["eventData"]["user"]["displayName"]
current_app.logger.debug(f'New chat message from {display_name}:')
current_app.logger.debug(f'{data["eventData"]["rawBody"]}')
if data["eventData"]["rawBody"].startswith(f"{prefix}help"):
current_app.logger.debug(f'{data["eventData"]["body"]}')
if data["eventData"]["body"].startswith(f"{prefix}help"):
send_help()
elif data["eventData"]["rawBody"].startswith(f"{prefix}points"):
elif data["eventData"]["body"].startswith(f"{prefix}points"):
points = read_users_points(db, user_id)
if points is None:
send_chat("Error reading points.")
else:
send_chat(f"{display_name}'s points: {points}")
elif data["eventData"]["rawBody"].startswith(f"{prefix}name_update"):
elif data["eventData"]["body"].startswith(f"{prefix}name_update"):
# Forces name update in case bot didn't catch the NAME_CHANGE
# event. Also removes saved usernames from users with same name
# if user is authenticated.
change_display_name(db, user_id, display_name)
if data["eventData"]["user"]["authenticated"]:
remove_duplicate_usernames(db, user_id, display_name)
elif data["eventData"]["rawBody"].startswith(prefix):
handle_redeem(data["eventData"]["rawBody"], user_id)
elif data["eventData"]["body"].startswith(prefix):
handle_redeem(data["eventData"]["body"], user_id)
return data

View File

@ -23,7 +23,7 @@ def counter_exists(db, counter_name):
def add_to_counter(db, counter_name):
if counter_exists(db, counter_name):
try:
db.execute(
cursor = db.execute(
"UPDATE counters SET count = count + 1 WHERE name = ?",
(counter_name,)
)
@ -37,7 +37,7 @@ def add_to_counter(db, counter_name):
def add_to_redeem_queue(db, user_id, redeem_name, note=None):
try:
db.execute(
cursor = db.execute(
"INSERT INTO redeem_queue(redeem, redeemer_id, note) VALUES(?, ?, ?)",
(redeem_name, user_id, note)
)
@ -159,7 +159,7 @@ def all_active_milestones(db):
return all_active_milestones
def all_active_redeems():
def all_active_redeems(db):
redeems = current_app.config['REDEEMS']
all_active_redeems = {}
for redeem_name, redeem_dict in redeems.items():

View File

@ -3,7 +3,7 @@ from tlapbot.db import get_db
from tlapbot.owncast_requests import send_chat
from tlapbot.redeems import (add_to_redeem_queue, add_to_counter, add_to_milestone,
check_apply_milestone_completion, milestone_complete, is_redeem_active)
from tlapbot.owncast_helpers import use_points, read_users_points
from tlapbot.owncast_helpers import use_points, read_users_points, remove_emoji
def handle_redeem(message, user_id):
@ -32,11 +32,9 @@ def handle_redeem(message, user_id):
elif not note:
send_chat(f"Cannot redeem {redeem}, no amount of points specified.")
elif not note.isdigit():
send_chat(f"Cannot redeem {redeem}, amount of points is not a positive integer.")
send_chat(f"Cannot redeem {redeem}, amount of points is not an integer.")
elif int(note) > points:
send_chat(f"Can't redeem {redeem}, you're donating more points than you have.")
elif int(note) == 0:
send_chat(f"Can't donate zero points.")
elif add_to_milestone(db, user_id, redeem, int(note)):
send_chat(f"Succesfully donated to {redeem} milestone!")
if check_apply_milestone_completion(db, redeem):
@ -66,7 +64,7 @@ def handle_redeem(message, user_id):
if not note:
send_chat(f"Cannot redeem {redeem}, no note included.")
return
if (add_to_redeem_queue(db, user_id, redeem, note) and
if (add_to_redeem_queue(db, user_id, redeem, remove_emoji(note)) and
use_points(db, user_id, price)):
send_chat(f"{redeem} redeemed for {price} points.")
else:

View File

@ -30,14 +30,12 @@
<th>Your points balance</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<tbody>
<td> {{ user[0] }} </td>
<td> {{ user[1] }} </td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% endif %}
@ -54,14 +52,12 @@
<th>Active counters</th>
</tr>
</thead>
<tbody>
{% for counter in counters %}
<tr>
<tbody>
<td> {{ counter[0] }} </td>
<td> {{ counter[1] }} </td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% endif %}
{% if milestones %}
@ -72,15 +68,13 @@
<th>Progress</th>
</tr>
</thead>
<tbody>
{% for milestone in milestones %}
<tr>
<tbody>
<td> {{ milestone[0] }} </td>
<td> <progress id="file" max={{ milestone[2] }} value={{ milestone[1] }}></progress></td>
<td> {{ milestone[1] }} / {{ milestone[2] }}</td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% endif %}
{% endif %}
@ -105,18 +99,16 @@
<th>Note</th>
</tr>
</thead>
<tbody>
{% for row in queue %}
<tr>
<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 %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% endif %}
</body>
@ -144,9 +136,8 @@
<th>Description</th>
</tr>
</thead>
<tbody>
{% for redeem, redeem_info in redeems.items() %}
<tr>
<tbody>
<td>{{ prefix }}{{ redeem }}</td>
{% if redeem_info["type"] == "milestone" %}
<td></td>
@ -157,9 +148,8 @@
{% if redeem_info["info"] %}
<td>{{ redeem_info["info"] }}</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
{% endif %}
</body>

View File

@ -2,7 +2,7 @@ from flask import render_template, Blueprint, request, current_app
from tlapbot.db import get_db
from tlapbot.redeems import all_active_counters, all_active_milestones, all_active_redeems, pretty_redeem_queue
from tlapbot.owncast_helpers import read_all_users_with_username
from datetime import timezone
from datetime import datetime, timezone
bp = Blueprint('redeem_dashboard', __name__)
@ -20,7 +20,7 @@ def dashboard():
queue=pretty_redeem_queue(db),
counters=all_active_counters(db),
milestones=all_active_milestones(db),
redeems=all_active_redeems(),
redeems=all_active_redeems(db),
prefix=current_app.config['PREFIX'],
passive=current_app.config['PASSIVE'],
username=username,