added fundamental message and channel interpreter
authorGeorgios Atheridis <atheridis@tutamail.com>
Tue, 22 Mar 2022 20:12:26 +0000 (22:12 +0200)
committerGeorgios Atheridis <atheridis@tutamail.com>
Tue, 22 Mar 2022 20:12:26 +0000 (22:12 +0200)
aptbot/__main__.py
aptbot/args.py
aptbot/bot.py

index d01dfbd461758793c78b528a05d441caa165187d..9227412fa8e62b20dd12c0864ca72b2f3e7966a7 100644 (file)
@@ -4,9 +4,22 @@ import time
 import aptbot.bot
 import os
 import sys
+import importlib
+import importlib.util
 from threading import Thread
 from dotenv import load_dotenv
 
+
+if "XDG_CONFIG_HOME" in os.environ:
+    CONFIG_HOME = os.environ["XDG_CONFIG_HOME"]
+elif "APPDATA" in os.environ:
+    CONFIG_HOME = os.environ["APPDATA"]
+else:
+    CONFIG_HOME = os.path.join(os.environ["HOME"], ".config")
+
+CONFIG_PATH = os.path.join(CONFIG_HOME, f"aptbot")
+
+
 load_dotenv()
 
 PORT = 26538
@@ -17,50 +30,123 @@ def loop(bot: aptbot.bot.Bot):
     while True:
         messages = bot.receive_messages()
         for message in messages:
-            pass
+            if message.channel:
+                account_path = os.path.join(CONFIG_PATH, f"{message.channel}")
+                module_path = os.path.join(
+                    account_path, f"message_interpreter.py")
+                spec = importlib.util.spec_from_file_location(
+                    "message_interpreter",
+                    module_path,
+                )
+                if spec and spec.loader:
+                    foo = importlib.util.module_from_spec(spec)
+                    spec.loader.exec_module(foo)
+                    method = Thread(target=foo.main, args=(bot, message, ))
+                    method.daemon = True
+                    method.start()
+                    # foo.main(bot, message)
+                print(message)
         time.sleep(0.001)
 
 
+def initialize(bot: aptbot.bot.Bot):
+    channels = os.listdir(CONFIG_PATH)
+    for channel in channels:
+        bot.join_channel(channel)
+
+
 def listener():
     NICK = os.getenv("APTBOT_NICK")
     OAUTH = os.getenv("APTBOT_OAUTH")
     CLIENT_ID = os.getenv("APTBOT_CLIENT_ID")
-    print(NICK)
-    print(OAUTH)
-    print(CLIENT_ID)
     if NICK and OAUTH and CLIENT_ID:
         bot = aptbot.bot.Bot(NICK, OAUTH, CLIENT_ID)
     else:
         sys.exit(1)
     bot.connect()
-    bot.join_channel("skgyorugo")
-    Thread(target=loop, args=(bot,)).start()
+    message_loop = Thread(target=loop, args=(bot,))
+    message_loop.daemon = True
+    message_loop.start()
     s = socket.socket()
-    s.bind(("", PORT))
+    s.bind((LOCALHOST, PORT))
     s.listen(5)
+    initialize(bot)
 
     while True:
-        c, addr = s.accept()
+        c, _ = s.accept()
         msg = c.recv(1024).decode()
-        bot.send_privmsg("skgyorugo", msg)
+        msg = msg.split("===")
+        try:
+            command = msg[0]
+            channel = msg[1]
+            msg = msg[2]
+        except IndexError:
+            pass
+        else:
+            if "JOIN" in command:
+                bot.join_channel(channel)
+            elif "SEND" in command:
+                bot.send_privmsg(channel, msg)
+            elif "KILL" in command:
+                sys.exit()
         time.sleep(1)
 
 
-def send(acc: str):
-    s = socket.socket()
-    s.connect(("", PORT))
-    print("Socket connected")
-    s.send(acc.encode())
-    s.close()
+def send(func,):
+    def inner(*args, **kwargs):
+        s = socket.socket()
+        s.connect((LOCALHOST, PORT))
+        func(s, *args, **kwargs)
+        s.close()
+    return inner
+
+
+def add_account(s: socket.socket, acc: str):
+    account_path = os.path.join(CONFIG_PATH, f"{acc}")
+
+    os.makedirs(account_path, exist_ok=True)
+
+    f = open(os.path.join(account_path, "message_interpreter.py"), "a")
+    f.write("""from aptbot.bot import Bot, Message, Commands
+def main(bot, message: Message):
+    pass""")
+    f.close()
+
+    command = "JOIN"
+    channel = acc
+    msg = ""
+    s.send(bytes(f"{command}==={channel}==={msg}", "utf-8"))
+
+
+def send_msg(s: socket.socket, msg: str):
+    command = "SEND"
+    channel = "skgyorugo"
+    msg = msg
+    s.send(bytes(f"{command}==={channel}==={msg}", "utf-8"))
+
+
+def disable(s: socket.socket):
+    command = "KILL"
+    channel = ""
+    msg = ""
+    s.send(bytes(f"{command}==={channel}==={msg}", "utf-8"))
 
 
 def main():
     argsv = aptbot.args.parse_arguments()
     if argsv.enable:
         listener()
+
+    s = socket.socket()
+    s.connect((LOCALHOST, PORT))
+
     if argsv.add_account:
-        send(argsv.add_account)
-    print("hi")
+        add_account(s, argsv.add_account)
+    if argsv.send_message:
+        send_msg(s, argsv.send_message)
+    if argsv.disable:
+        disable(s)
+    s.close()
 
 
 if __name__ == "__main__":
index c2928194a40eb0fdb7b31a04eabf4894906079c4..78f5f5163388e69e1bcd7f40544aa5a74de5283c 100644 (file)
@@ -14,6 +14,13 @@ def parse_arguments() -> argparse.Namespace:
         help=f"Add an account to connect with the bot"
     )
 
+    arg_parser.add_argument(
+        "-s",
+        "--send-message",
+        type=str,
+        help=f"Send a message to skgyorugo"
+    )
+
     arg_parser.add_argument(
         "--enable",
         default=False,
@@ -21,4 +28,11 @@ def parse_arguments() -> argparse.Namespace:
         help=f"Enable the bot"
     )
 
+    arg_parser.add_argument(
+        "--disable",
+        default=False,
+        action="store_true",
+        help=f"Disable the bot"
+    )
+
     return arg_parser.parse_args()
index 71f59ed5aa6433fb280ec527f5968bd5ed4eb4cf..3c609a0c875c8ede25557a733f9d051dd185024b 100644 (file)
@@ -1,4 +1,6 @@
 import socket
+import time
+import sys
 from enum import Enum
 from dataclasses import dataclass
 from typing import Optional
@@ -36,8 +38,10 @@ class Bot:
         self.nick = nick
         self.oauth_token = oauth_token
         self.client_id = client_id
+        self.connected_channels = []
 
     def send_command(self, command: str):
+        print(f"< {command}")
         self.irc.send((command + "\r\n").encode())
 
     def connect(self):
@@ -50,9 +54,15 @@ class Bot:
 
     def join_channel(self, channel: str):
         self.send_command(f"{Commands.JOIN.value} #{channel}")
+        self.connected_channels.append(channel)
+
+    def join_channels(self, channels: list[str]):
+        for channel in channels:
+            self.join_channel(channel)
 
     def leave_channel(self, channel: str):
         self.send_command(f"{Commands.PART.value} #{channel}")
+        self.connected_channels.remove(channel)
 
     def send_privmsg(self, channel: str, text: str):
         self.send_command(f"{Commands.PRIVMSG.value} #{channel} :{text}")
@@ -100,9 +110,23 @@ class Bot:
             return Message({}, "", None, "", "")
         return Bot.parse_message(received_msg)
 
-    def receive_messages(self) -> list:
+    def receive_messages(self) -> list[Message]:
         messages = []
-        received_msgs = self.irc.recv(2048).decode()
+        i = 0
+        while i < 5:
+            try:
+                received_msgs = self.irc.recv(2048).decode()
+            except ConnectionResetError as e:
+                print(f"There was an error connecting with error {e}")
+                print("Trying to connect again")
+                time.sleep(2**i)
+                self.connect()
+                self.join_channels(self.connected_channels)
+                i += 1
+            else:
+                break
+        else:
+            sys.exit(1)
         for received_msgs in received_msgs.split("\r\n"):
             messages.append(self._handle_message(received_msgs))
         return messages