From a3312cffda5cc951145a52907675d4248d28cf0a Mon Sep 17 00:00:00 2001 From: Yuuki Chan Date: Mon, 19 Feb 2024 15:15:58 +0900 Subject: [PATCH 1/2] Remove more (unnecessary) double quotes... --- elitebot.py | 21 ++++++++++++--------- plugins/commands.py | 6 +++--- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/elitebot.py b/elitebot.py index 2ca4067..4f2d53a 100755 --- a/elitebot.py +++ b/elitebot.py @@ -1,34 +1,37 @@ #!/usr/bin/env python3 import sys + from src.bot import Bot + def main(): if len(sys.argv) < 2: - print("Usage: python elitebot.py ") + print('Usage: python elitebot.py ') sys.exit(1) config_file = sys.argv[1] try: bot = Bot(config_file) except FileNotFoundError as e: - print(f"Config file not found: {e}") + print(f'Config file not found: {e}') sys.exit(1) except Exception as e: - print(f"Error loading bot: {e}") + print(f'Error loading bot: {e}') sys.exit(1) try: - print("EliteBot started successfully!") - bot.start() + print('EliteBot started successfully!') + bot.start() except Exception as e: - print(f"Error starting EliteBot: {e}") + print(f'Error starting EliteBot: {e}') sys.exit(1) -if __name__ == "__main__": + +if __name__ == '__main__': try: main() except KeyboardInterrupt: - print("\nEliteBot has been stopped.") + print('\nEliteBot has been stopped.') except Exception as e: - print(f"An unexpected error occurred: {e}") + print(f'An unexpected error occurred: {e}') diff --git a/plugins/commands.py b/plugins/commands.py index 318950e..47e145a 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -27,7 +27,7 @@ class Plugin(PluginBase): self.bot.ircsend(f'PART {message_parts[1]}') self.channel_manager.remove_channel(message_parts[1]) - elif message_parts[0] == "!quit": + elif message_parts[0] == '!quit': if len(message_parts) == 0: quit_message = 'EliteBot!' else: @@ -37,9 +37,9 @@ class Plugin(PluginBase): self.bot.connected = False sys.exit() - elif message_parts[0] == "!raw": + elif message_parts[0] == '!raw': if len(message_parts) > 1: - if message_parts[1].upper() == "PRIVMSG" and len(message_parts) > 3: + if message_parts[1].upper() == 'PRIVMSG' and len(message_parts) > 3: raw_command = ' '.join(message_parts[1:3]) + " :" + ' '.join(message_parts[3:]) else: raw_command = ' '.join(message_parts[1:]) -- 2.34.1 From 3ca7e9cf36f3a4c3399e2a9ce6ee3e743b68e187 Mon Sep 17 00:00:00 2001 From: Yuuki Chan Date: Mon, 19 Feb 2024 18:26:40 +0900 Subject: [PATCH 2/2] Add db support (W.I.P.), cookie.py and removed UseSASL requirement. --- config.json | 3 +++ config.yaml | 4 +++- plugins/cookie.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 5 ++++ src/bot.py | 4 +++- src/db.py | 39 +++++++++++++++++++++++++++++++ 6 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 plugins/cookie.py create mode 100644 src/db.py diff --git a/config.json b/config.json index 01bbaed..90a0e29 100644 --- a/config.json +++ b/config.json @@ -14,5 +14,8 @@ }, "Logging": { "Console": true + }, + "Database": { + "ConnectionString": "mysql://user:password@host:port/database" } } diff --git a/config.yaml b/config.yaml index f325370..041bd69 100644 --- a/config.yaml +++ b/config.yaml @@ -10,4 +10,6 @@ SASL: SASLNick: EliteBot SASLPassword: password Logging: - Console: true \ No newline at end of file + Console: true +Database: + ConnectionString: mysql://user:password@host:port/database \ No newline at end of file diff --git a/plugins/cookie.py b/plugins/cookie.py new file mode 100644 index 0000000..f8170af --- /dev/null +++ b/plugins/cookie.py @@ -0,0 +1,58 @@ +from sqlalchemy import Table, Column, Integer, String, MetaData, insert, select + +from src.channel_manager import ChannelManager +from src.db import Database +from src.plugin_base import PluginBase + +meta = MetaData() +cookie_table = Table( + 'Cookie', + meta, + Column('id', Integer, primary_key=True, autoincrement=True), + Column('name', String, unique=True, nullable=False), + Column('cookies', Integer, default=0), + Column('last', String, default='1999/01/01 00:00:00'), +) +c_db = Database(cookie_table, meta) + + +class Plugin(PluginBase): + def handle_message(self, source_nick, channel, message): + parts = message.split() + c_db.create_table('Cookie') + self.channel_manager = ChannelManager() + + if parts[0].lower() == '!cookie': + if len(parts) == 1: # !cookie + self.insert_user(source_nick) + self.bot.ircsend(f'PRIVMSG {channel} :Nooooo~~') + + c_db.set(source_nick, {'cookies': 1, 'last': '1999/01/01 00:00:01'}) + elif len(parts) == 2: # !cookie USER + cookies = c_db.get(parts[1], 2) + + if cookies == -1: + self.bot.ircsend(f'PRIVMSG {channel} :I\'ve looked everywhere for {parts[1]}, but I couldn\'t ' + f'find them.') + else: + c = 'cookie' + if cookies == 0: + c = 'no cookies.' + elif cookies == 1: + c = f'{cookies} cookie.' + else: + c = f'{cookies} cookies.' + + self.bot.ircsend(f'PRIVMSG {channel} :{parts[1]} currently has {c}') + + def insert_user(self, user: str): + with c_db.engine.connect() as conn: + stmt = select(cookie_table).where(cookie_table.c.name == user) + cnt = len(conn.execute(stmt).fetchall()) + + if cnt == 0: + conn.execute(( + insert(cookie_table). + values({'name': user}) + )) + conn.commit() diff --git a/requirements.txt b/requirements.txt index d0fd917..a901ff7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,7 @@ colorama==0.4.6 +greenlet==3.0.3 +mysql-connector==2.2.9 PyYAML==6.0.1 +SQLAlchemy==2.0.27 +SQLAlchemy-Utils==0.41.1 +typing_extensions==4.9.0 diff --git a/src/bot.py b/src/bot.py index e1ef083..d34cb19 100644 --- a/src/bot.py +++ b/src/bot.py @@ -21,6 +21,7 @@ class Bot: def __init__(self, config_file): self.config = self.load_config(config_file) self.validate_config(self.config) + self.connection_string = self.config['Database'].get('ConnectionString') self.channel_manager = ChannelManager() self.logger = Logger('logs/elitebot.log') self.connected = False @@ -36,7 +37,8 @@ class Bot: ["Connection", "Nick"], ["Connection", "Ident"], ["Connection", "Name"], - ["SASL", "UseSASL"] + # ["SASL", "UseSASL"], + ["Database", "ConnectionString"] ] for field in required_fields: diff --git a/src/db.py b/src/db.py new file mode 100644 index 0000000..2e252b0 --- /dev/null +++ b/src/db.py @@ -0,0 +1,39 @@ +from sqlalchemy import create_engine, Table, MetaData, inspect, update, select +from sqlalchemy_utils import database_exists, create_database + + +# TODO: Load ConnectionString from config +class Database: + def __init__(self, table: Table, meta: MetaData): + self.engine = create_engine(r'sqlite:///.\data\database.db') + self.table = table + self.meta = meta + + if not database_exists(self.engine.url): + create_database(self.engine.url) + + def create_table(self, table_name): + if not inspect(self.engine).has_table(table_name): + self.meta.create_all(self.engine) + + def set(self, user: str, values: dict): + with self.engine.connect() as conn: + stmt = select(self.table).where(self.table.c.name == user) + cnt = len(conn.execute(stmt).fetchall()) + + if cnt == 1: + conn.execute(( + update(self.table). + values(values) + )) + conn.commit() + + def get(self, user: str, index: int): + with self.engine.connect() as conn: + stmt = select(self.table).where(self.table.c.name == user) + cnt = len(conn.execute(stmt).fetchall()) + + if cnt == 1: + return conn.execute(select(self.table).where(self.table.c.name == user)).fetchone()[index] + else: + return -1 -- 2.34.1