added auto messages for stream and a smart stream offline checker
authorGeorgios Atheridis <atheridis@tutamail.com>
Fri, 1 Apr 2022 16:22:54 +0000 (19:22 +0300)
committerGeorgios Atheridis <atheridis@tutamail.com>
Fri, 1 Apr 2022 16:22:54 +0000 (19:22 +0300)
skgyorugo/README.md
skgyorugo/analyze_auto_message.py [new file with mode: 0644]
skgyorugo/analyze_command.py
skgyorugo/auto_messages/latege.py [new file with mode: 0644]
skgyorugo/auto_messages/youtube.py [new file with mode: 0644]
skgyorugo/commands/youtube.py
skgyorugo/database_manager.py [new file with mode: 0644]
skgyorugo/main.py
skgyorugo/tools/smart_start_stream_time.py [new file with mode: 0644]

index dd1f015c4b7afc2afa3df84cafdff9722f618dd3..b601724a15c801a5964583eaae8f6b72c28078dd 100644 (file)
@@ -18,6 +18,7 @@
 - [ ] 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
diff --git a/skgyorugo/analyze_auto_message.py b/skgyorugo/analyze_auto_message.py
new file mode 100644 (file)
index 0000000..5031b03
--- /dev/null
@@ -0,0 +1,57 @@
+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()
index 559070f3262762c721593238bbf57245c651f1d7..d071dd774e0e4d8c3a6e45bb261435f4a19ac033 100644 (file)
@@ -55,6 +55,7 @@ def do_command(bot: Bot, message: Message, command_modules: dict):
     fetched = c.fetchall()
     print(fetched)
     if not fetched:
+        conn.close()
         return
 
     (_, value,
@@ -68,6 +69,7 @@ def do_command(bot: Bot, message: Message, command_modules: dict):
             f"The command '{prefix}{command}' is on cooldown. \
             Please wait {int(avail_time - message_timestamp) + 1} seconds."
         )
+        conn.close()
         return
 
     c.execute(
@@ -86,6 +88,7 @@ def do_command(bot: Bot, message: Message, command_modules: dict):
         )
     )
     conn.commit()
+    conn.close()
     if value is None:
         command_modules[command].main(bot, message)
     else:
diff --git a/skgyorugo/auto_messages/latege.py b/skgyorugo/auto_messages/latege.py
new file mode 100644 (file)
index 0000000..b56a29d
--- /dev/null
@@ -0,0 +1,30 @@
+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)
diff --git a/skgyorugo/auto_messages/youtube.py b/skgyorugo/auto_messages/youtube.py
new file mode 100644 (file)
index 0000000..c898490
--- /dev/null
@@ -0,0 +1,17 @@
+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)
index 1829fa1ef766453b556d4c26b992a974fb471130..b034c2915fe01d2d726b73dcce3a3c28f0e569f6 100644 (file)
@@ -14,7 +14,7 @@ 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 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)
diff --git a/skgyorugo/database_manager.py b/skgyorugo/database_manager.py
new file mode 100644 (file)
index 0000000..98dbae9
--- /dev/null
@@ -0,0 +1,169 @@
+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()
index de62fb69a363580719ed0d2afe11b80b901a5c2c..0908c85a844dd8eca5626bf9eca04225490ea0df 100644 (file)
@@ -2,26 +2,29 @@ from aptbot.bot import Bot, Message, Commands
 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))
@@ -29,7 +32,6 @@ commands = [
 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(
@@ -38,122 +40,37 @@ for command in commands:
         )
     )
 
-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):
diff --git a/skgyorugo/tools/smart_start_stream_time.py b/skgyorugo/tools/smart_start_stream_time.py
new file mode 100644 (file)
index 0000000..5218936
--- /dev/null
@@ -0,0 +1,91 @@
+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