- [ ] specific word in message {message.0}, {message.1}, etc.
- [ ] replied variable {reply.nick} {reply.message} {reply.message.0}
- [ ] sub sellout bot
+- [ ] schedule
## Basic Commands
- [ ] int
--- /dev/null
+from aptbot.bot import Bot, Message, Commands
+import os
+import sqlite3
+import time
+import tools.smart_privmsg
+from tools.smart_start_stream_time import start_stream_timestamp as stream_ts
+
+PATH = os.path.dirname(os.path.realpath(__file__))
+
+
+def do_auto_message(bot: Bot, message: Message, auto_message_modules: dict):
+ conn = sqlite3.connect(os.path.join(PATH, "database.db"))
+ c = conn.cursor()
+
+ start_stream_ts = stream_ts()
+ if not start_stream_ts:
+ return
+
+ c.execute(
+ """
+ SELECT
+ name,
+ cooldown,
+ end_time,
+ last_used,
+ value
+ FROM
+ auto_messages
+ LEFT JOIN auto_message_values USING (name)
+ """
+ )
+ fetched = c.fetchall()
+ if not fetched:
+ conn.close()
+ return
+
+ for auto_message in fetched:
+ name, cooldown, end_time, last_used, value = auto_message
+ if time.time() < last_used + cooldown:
+ continue
+ if time.time() > start_stream_ts + end_time and end_time != 0:
+ continue
+ if value:
+ tools.smart_privmsg.send(bot, message, value)
+ else:
+ auto_message_modules[name].main(bot, message)
+ c.execute(
+ "REPLACE INTO auto_messages VALUES (?, ?, ?, ?)",
+ (
+ name,
+ cooldown,
+ end_time,
+ int(time.time()),
+ )
+ )
+ conn.commit()
+ conn.close()
fetched = c.fetchall()
print(fetched)
if not fetched:
+ conn.close()
return
(_, value,
f"The command '{prefix}{command}' is on cooldown. \
Please wait {int(avail_time - message_timestamp) + 1} seconds."
)
+ conn.close()
return
c.execute(
)
)
conn.commit()
+ conn.close()
if value is None:
command_modules[command].main(bot, message)
else:
--- /dev/null
+from aptbot.bot import Message, Commands, Bot
+import datetime as dt
+from datetime import datetime
+import tools.smart_start_stream_time
+
+COOLDOWN = 120
+END_TIME = COOLDOWN * 6
+
+STREAM_SCHEDULE = dt.time(17, 30)
+
+
+def main(bot: Bot, message: Message):
+ start_stream_ts = tools.smart_start_stream_time.start_stream_timestamp()
+ if not start_stream_ts:
+ return
+ start_stream_dt = datetime.utcfromtimestamp(start_stream_ts)
+ stream_schedule_dt = datetime.combine(datetime.now(), STREAM_SCHEDULE)
+ latege_amount = (start_stream_dt - stream_schedule_dt).total_seconds()
+ if latege_amount > 45 * 60:
+ msg = f"{message.channel} is so Latege he might as well have not \
+ streamed today. At least he's early for tomorrow COPIUM . \
+ {message.channel} is Latege by {latege_amount} seconds Madge"
+ elif latege_amount > 0:
+ msg = f"{message.channel} is Latege by {latege_amount} seconds again Madge"
+ elif latege_amount == 0:
+ msg = f"Amazing!!! {message.channel} is EXACTLY on time today ihaspeHappy"
+ else:
+ msg = f"UNBELIEVABLE!!!!! {message.channel} is EARLY by {-latege_amount} seconds!!!!\
+ This has NEVER happened before POGGERS"
+ bot.send_privmsg(message.channel, msg)
--- /dev/null
+from aptbot.bot import Message, Commands, Bot
+import yt_api.videos
+
+COOLDOWN = 20 * 60
+END_TIME = 0
+
+CHANNEL_ID = "UCQ7C3NUKY6TSkURdUdVoYFw"
+
+
+def main(bot: Bot, message: Message):
+ video = yt_api.videos.get_newest_video(CHANNEL_ID)
+ if video:
+ video_link = f"https://www.youtube.com/watch?v={video.video_id}"
+ msg = f"Watch Peks' latest video \" {video.video_name} \" here: {video_link}"
+ else:
+ msg = f"Check out my youtube channel here -> https://www.youtube.com/channel/{CHANNEL_ID}"
+ bot.send_privmsg(message.channel, msg)
video = yt_api.videos.get_newest_video(CHANNEL_ID)
if video:
video_link = f"https://www.youtube.com/watch?v={video.video_id}"
- msg = f"Watch my latest video \"{video.video_name}\" here -> {video_link}"
- bot.send_privmsg(message.channel, msg)
+ msg = f"Watch Peks' latest video \" {video.video_name} \" here: {video_link}"
else:
msg = f"Check out my youtube channel here -> https://www.youtube.com/channel/{CHANNEL_ID}"
+ bot.send_privmsg(message.channel, msg)
--- /dev/null
+import sqlite3
+import os
+import ttv_api.users
+
+PATH = os.path.dirname(os.path.realpath(__file__))
+
+
+def create_database():
+ conn = sqlite3.connect(os.path.join(PATH, "database.db"))
+ c = conn.cursor()
+ try:
+ c.execute(
+ """
+ CREATE TABLE commands (
+ command TEXT NOT NULL,
+ prefix TEXT NOT NULL,
+ permission INTEGER NOT NULL,
+ description TEXT,
+ user_cooldown INTEGER NOT NULL,
+ global_cooldown INTEGER NOT NULL,
+ last_used INTEGER NOT NULL,
+ PRIMARY KEY (command)
+ )
+ """
+ )
+ except sqlite3.OperationalError:
+ print("Table commands exists")
+
+ try:
+ c.execute(
+ """
+ CREATE TABLE users (
+ user_id text NOT NULL,
+ permission INTEGER NOT NULL,
+ PRIMARY KEY (user_id)
+ )
+ """
+ )
+ except sqlite3.OperationalError as e:
+ print(f"Table users exists: {e}")
+ else:
+ admin_id = ttv_api.users.get_users(user_logins=["skgyorugo"])
+ if admin_id:
+ c.execute("INSERT INTO users VALUES (?, ?)",
+ (admin_id[0].user_id, 0))
+
+ try:
+ c.execute(
+ """
+ CREATE TABLE cooldowns (
+ user_id TEXT NOT NULL,
+ command TEXT NOT NULL,
+ user_cooldown INTEGER NOT NULL,
+ FOREIGN KEY(user_id) REFERENCES users(user_id)
+ FOREIGN KEY(command) REFERENCES commands(command)
+ PRIMARY KEY (user_id, command)
+ )
+ """
+ )
+ except sqlite3.OperationalError:
+ print("Table cooldowns exists")
+
+ try:
+ c.execute(
+ """
+ CREATE TABLE command_values (
+ command TEXT NOT NULL,
+ value TEXT NOT NULL,
+ FOREIGN KEY(command) REFERENCES commands(command)
+ )
+ """
+ )
+ except sqlite3.OperationalError:
+ print("Table cooldowns exists")
+
+ try:
+ c.execute(
+ """
+ CREATE TABLE auto_messages (
+ name TEXT NOT NULL,
+ cooldown INTEGER NOT NULL,
+ end_time INTEGER NOT NULL,
+ last_used INTEGER NOT NULL,
+ PRIMARY KEY (name)
+ )
+ """
+ )
+ except sqlite3.OperationalError:
+ print("Table commands exists")
+
+ try:
+ c.execute(
+ """
+ CREATE TABLE auto_message_values (
+ name TEXT NOT NULL,
+ value TEXT NOT NULL,
+ FOREIGN KEY(name) REFERENCES auto_messages(name)
+ )
+ """
+ )
+ except sqlite3.OperationalError:
+ print("Table cooldowns exists")
+
+ try:
+ c.execute(
+ """
+ CREATE TABLE streamer_info (
+ start_stream_ts INTEGER NOT NULL,
+ last_checked INTEGER NOT NULL,
+ ended INTEGER NOT NULL,
+ PRIMARY KEY (start_stream_ts)
+ )
+ """
+ )
+ except sqlite3.OperationalError as e:
+ print(f"Table users exists: {e}")
+
+ conn.commit()
+ conn.close()
+
+
+def update_commands_in_database(modules, commands):
+ conn = sqlite3.connect(os.path.join(PATH, "database.db"))
+ c = conn.cursor()
+
+ for command in commands:
+ command_name = command.split('.')[0]
+ command_permission = modules[command_name].PERMISSION
+ command_prefix = modules[command_name].PREFIX
+ command_description = modules[command_name].DESCRIPTION
+ command_user_cooldown = modules[command_name].USER_COOLDOWN
+ command_global_cooldown = modules[command_name].GLOBAL_COOLDOWN
+ command_last_used = 0
+ c.execute(
+ "REPLACE INTO commands VALUES (?, ?, ?, ?, ?, ?, ?)",
+ (
+ command_name,
+ command_prefix,
+ command_permission,
+ command_description,
+ command_user_cooldown,
+ command_global_cooldown,
+ command_last_used,
+ )
+ )
+ conn.commit()
+ conn.close()
+
+
+def update_auto_messages_in_database(modules, auto_messages):
+ conn = sqlite3.connect(os.path.join(PATH, "database.db"))
+ c = conn.cursor()
+
+ for auto_message in auto_messages:
+ auto_message_name = auto_message.split('.')[0]
+ auto_message_cooldown = modules[auto_message_name].COOLDOWN
+ auto_message_end_time = modules[auto_message_name].END_TIME
+ auto_message_last_used = 0
+ c.execute(
+ "REPLACE INTO commands VALUES (?, ?, ?, ?)",
+ (
+ auto_message_name,
+ auto_message_cooldown,
+ auto_message_end_time,
+ auto_message_last_used,
+ )
+ )
+ conn.commit()
+ conn.close()
import os
import importlib
import importlib.util
-import sqlite3
-from importlib import reload
import traceback
-import ttv_api.users
import tools.raid
import tools.smart_privmsg
import tools.permissions
import analyze_command
import scripts.unit_converter
-import yt_api.videos
+import database_manager
+from importlib import reload
reload(tools.raid)
reload(tools.smart_privmsg)
reload(tools.permissions)
reload(analyze_command)
reload(scripts.unit_converter)
+reload(database_manager)
+
PATH = os.path.dirname(os.path.realpath(__file__))
COMMANDS_PATH = os.path.join(PATH, "commands")
+AUTO_MESSAGES_PATH = os.path.join(PATH, "auto_messages")
+specs = {}
+modules = {}
commands = [
c for c in os.listdir(COMMANDS_PATH) if os.path.isfile(os.path.join(COMMANDS_PATH, c))
commands = filter(lambda x: not x.startswith('.'), commands)
commands = filter(lambda x: os.path.splitext(x)[1] == ".py", commands)
commands = list(commands)
-specs = {}
for command in commands:
specs[command.split('.')[0]] = (
importlib.util.spec_from_file_location(
)
)
-modules = {}
-for command in specs:
- modules[command] = importlib.util.module_from_spec(specs[command])
- if not specs[command]:
+auto_messages = [
+ c for c in os.listdir(COMMANDS_PATH) if os.path.isfile(os.path.join(COMMANDS_PATH, c))
+]
+auto_messages = filter(lambda x: not x.startswith('.'), auto_messages)
+auto_messages = filter(
+ lambda x: os.path.splitext(x)[1] == ".py",
+ auto_messages
+)
+auto_messages = list(auto_messages)
+for auto_message in auto_messages:
+ specs[auto_message.split('.')[0]] = (
+ importlib.util.spec_from_file_location(
+ f"{auto_message.split('.')[0]}",
+ os.path.join(COMMANDS_PATH, auto_message)
+ )
+ )
+
+for spec in specs:
+ modules[spec] = importlib.util.module_from_spec(specs[spec])
+ if not specs[spec]:
continue
try:
- specs[command].loader.exec_module(modules[command])
+ specs[spec].loader.exec_module(modules[spec])
except Exception as e:
print()
print(traceback.format_exc())
print(f"Problem Loading Module: {e}")
-def create_database():
- conn = sqlite3.connect(os.path.join(PATH, "database.db"))
- c = conn.cursor()
- try:
- c.execute(
- """
- CREATE TABLE commands (
- command TEXT NOT NULL,
- prefix TEXT NOT NULL,
- permission INTEGER NOT NULL,
- description TEXT,
- user_cooldown INTEGER NOT NULL,
- global_cooldown INTEGER NOT NULL,
- last_used INTEGER NOT NULL,
- PRIMARY KEY (command)
- )
- """
- )
- except sqlite3.OperationalError:
- print("Table commands exists")
-
- try:
- c.execute(
- """
- CREATE TABLE users (
- user_id text NOT NULL,
- permission INTEGER NOT NULL,
- PRIMARY KEY (user_id)
- )
- """
- )
- except sqlite3.OperationalError as e:
- print(f"Table users exists: {e}")
- else:
- aptbot_id = ttv_api.users.get_users(user_logins=["skgyorugo"])
- if aptbot_id:
- c.execute("INSERT INTO users VALUES (?, ?)",
- (aptbot_id[0].user_id, 0))
-
- try:
- c.execute(
- """
- CREATE TABLE cooldowns (
- user_id TEXT NOT NULL,
- command TEXT NOT NULL,
- user_cooldown INTEGER NOT NULL,
- FOREIGN KEY(user_id) REFERENCES users(user_id)
- FOREIGN KEY(command) REFERENCES commands(command)
- PRIMARY KEY (user_id, command)
- )
- """
- )
- except sqlite3.OperationalError:
- print("Table cooldowns exists")
-
- try:
- c.execute(
- """
- CREATE TABLE command_values (
- command TEXT NOT NULL,
- value TEXT NOT NULL,
- FOREIGN KEY(command) REFERENCES commands(command)
- )
- """
- )
- except sqlite3.OperationalError:
- print("Table cooldowns exists")
-
- conn.commit()
- conn.close()
-
-
-def update_commands_in_database():
- conn = sqlite3.connect(os.path.join(PATH, "database.db"))
- c = conn.cursor()
-
- for command in commands:
- command_name = command.split('.')[0]
- command_permission = modules[command_name].PERMISSION
- command_prefix = modules[command_name].PREFIX
- command_description = modules[command_name].DESCRIPTION
- command_user_cooldown = modules[command_name].USER_COOLDOWN
- command_global_cooldown = modules[command_name].GLOBAL_COOLDOWN
- command_last_used = 0
- # try:
- c.execute(
- "REPLACE INTO commands VALUES (?, ?, ?, ?, ?, ?, ?)",
- (
- command_name,
- command_prefix,
- command_permission,
- command_description,
- command_user_cooldown,
- command_global_cooldown,
- 0,
- )
- )
- conn.commit()
- conn.close()
-
-
-create_database()
-update_commands_in_database()
+database_manager.create_database()
+database_manager.update_commands_in_database(modules, commands)
def main(bot: Bot, message: Message):
--- /dev/null
+import time
+import os
+import ttv_api.users
+import ttv_api.stream
+import ttv_api.channel
+import sqlite3
+from typing import Optional
+
+STREAMER_PATH = os.path.abspath(os.path.join(__file__, "../.."))
+TOOLS_PATH = os.path.dirname(os.path.realpath(__file__))
+PATH = os.path.join(TOOLS_PATH, "..")
+
+
+CHECK_STREAMTIME_CD = 5 * 60
+MAX_OFF_STREAM_MARGIN = 60 * 60
+
+
+def start_stream_timestamp() -> Optional[int]:
+ streamer_login = os.path.split(STREAMER_PATH)[1]
+
+ conn = sqlite3.connect(os.path.join(PATH, "database.db"))
+ c = conn.cursor()
+
+ c.execute(
+ """
+ SELECT
+ start_stream_ts,
+ last_checked,
+ ended
+ FROM
+ stream_info
+ WHERE
+ last_checked = (SELECT MAX(last_checked) FROM stream_info);
+ AND ended = 0
+ """
+ )
+
+ fetched = c.fetchone()
+ if fetched:
+ start_stream_ts, last_checked, _ = fetched
+ if last_checked + CHECK_STREAMTIME_CD < time.time():
+ return start_stream_ts
+
+ stream_info = ttv_api.stream.get_streams(user_logins=[streamer_login])
+ if not stream_info and not fetched:
+ return
+
+ if not stream_info:
+ start_stream_ts, last_checked, _ = fetched
+ if last_checked + MAX_OFF_STREAM_MARGIN < time.time():
+ conn.close()
+ return
+
+ c.execute(
+ "REPLACE INTO commands VALUES (?, ?, ?)",
+ (
+ start_stream_ts,
+ last_checked,
+ 1,
+ )
+ )
+ conn.commit()
+ conn.close()
+ return
+
+ if not fetched:
+ start_stream_ts = int(stream_info[0].started_at.timestamp())
+ c.execute(
+ "REPLACE INTO commands VALUES (?, ?, ?)",
+ (
+ start_stream_ts,
+ int(time.time()),
+ 0,
+ )
+ )
+ conn.commit()
+ conn.close()
+ return start_stream_ts
+
+ start_stream_ts, last_checked, _ = fetched
+ c.execute(
+ "REPLACE INTO commands VALUES (?, ?, ?)",
+ (
+ start_stream_ts,
+ int(time.time()),
+ 0,
+ )
+ )
+ conn.commit()
+ conn.close()
+ return start_stream_ts