From ecfd40b318e5c1749b65562ef0e415e12c524aad Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Fri, 31 Mar 2023 00:08:18 +0300 Subject: [PATCH 01/23] Update requirements.txt & .gitignore; add sqlitedb.py with sqlalchemy --- .gitignore | 6 +++++- requirements.txt | 3 ++- sqlitedb.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 sqlitedb.py diff --git a/.gitignore b/.gitignore index 31ce078..c1b5a26 100644 --- a/.gitignore +++ b/.gitignore @@ -131,6 +131,10 @@ dmypy.json # List of user ids & answers *_list.txt *_response.txt +*.txt # Session journals -*.session* \ No newline at end of file +*.session* + +# SQLite +*.db \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 1b7af3c..edc282e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ black isort -telethon~=1.25.4 \ No newline at end of file +telethon~=1.25.4 +SQLAlchemy~=2.0.7 \ No newline at end of file diff --git a/sqlitedb.py b/sqlitedb.py new file mode 100644 index 0000000..1c3e993 --- /dev/null +++ b/sqlitedb.py @@ -0,0 +1,53 @@ +import logging +# import sqlite3 +# from sqlite3 import Error +import sqlalchemy +from sqlalchemy import exc + +# Logging +logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO +) +logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(message)s", level=logging.ERROR +) + +META = sqlalchemy.MetaData() +PEOPLE = sqlalchemy.Table( + 'people', META, + sqlalchemy.Column('name', sqlalchemy.String), + sqlalchemy.Column('date', sqlalchemy.String), + sqlalchemy.Column('tg_id', sqlalchemy.String), + sqlalchemy.Column('congrats_file_path', sqlalchemy.String), +) + + +def engine(database_name="herold_database.db"): + return sqlalchemy.create_engine(f'sqlite:///{database_name}', echo=False) + + +def connection(): + return engine().connect() + + +def create_db(): + try: + META.create_all(engine()) + except exc.SQLAlchemyError as sql_err: + logging.error(f"Err while creating db - {sql_err}") + + +def get_all_people(): + """ + Query all rows in the people db table + :return: + """ + try: + return connection().execute(PEOPLE.select()).fetchall() + except exc.SQLAlchemyError as sql_err: + logging.error(f"Err while fetching from {PEOPLE} db - {sql_err}") + + +if __name__ == "__main__": + # print(get_all_people()) + pass From ce145a038f7605429424d7e97fc4d6e6b2a113b7 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Tue, 11 Apr 2023 17:29:02 +0300 Subject: [PATCH 02/23] Add sqlitedb.py & update bot.py --- bot.py | 105 ++++++++++++++-------------------------------------- sqlitedb.py | 19 ++++++++-- 2 files changed, 43 insertions(+), 81 deletions(-) diff --git a/bot.py b/bot.py index 224fdcc..d623295 100644 --- a/bot.py +++ b/bot.py @@ -15,18 +15,6 @@ CLIENT = TelegramClient(SESSION, API_ID, API_HASH) -# Users files -FRIENDS_IDS_FILE = Path("friends_ids_list.txt") -FAMILIAR_IDS_FILE = Path("familiar_ids_list.txt") - -# Response files -FRIENDS_RESPONSE_FILE = Path("friend_response.txt") -FAMILIAR_RESPONSE_FILE = Path("familiar_response.txt") -HR_RESPONSE_FILE = Path("hr_response.txt") - -# Key words file -HR_KEY_WORDS_FILE = Path("hr_key_words_list.txt") - # Logging logging.basicConfig( format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO @@ -36,28 +24,6 @@ ) -def load_ids_from_files(file: Path) -> List[int]: - """ - Load user ids from the files - Try to load from file, if exception caught, send message about err - Also convert to int to compare with ids from Telegram - :return: - """ - try: - with open(file, "r") as users_ids_file: - result = [int(u_ids) for u_ids in users_ids_file.read().split()] - logging.info( - f"Uploaded ids from the {users_ids_file.name} done successfully." - ) - return result - except FileNotFoundError as file_not_found_err: - logging.error(file_not_found_err) - - -FRIENDS_IDS = load_ids_from_files(FRIENDS_IDS_FILE) -FAMILIAR_IDS = load_ids_from_files(FAMILIAR_IDS_FILE) - - def load_responses_from_files(file: Path) -> str: """ Load responses from the files @@ -72,26 +38,12 @@ def load_responses_from_files(file: Path) -> str: ) return result except FileNotFoundError as file_not_found_err: - logging.error(file_not_found_err) - - -FRIEND_RESPONSE = load_responses_from_files(FRIENDS_RESPONSE_FILE) -FAMILIAR_RESPONSE = load_responses_from_files(FAMILIAR_RESPONSE_FILE) -HR_RESPONSE = load_responses_from_files(HR_RESPONSE_FILE) - -HR_KEY_WORDS = load_responses_from_files(HR_KEY_WORDS_FILE) - - -async def show_selected_users(): - async for dialog in CLIENT.iter_dialogs(): - if dialog.id in FRIENDS_IDS: - logging.info(f"Selected friends username: {dialog.name}; ID: {dialog.id}") - elif dialog.id in FAMILIAR_IDS: - logging.info(f"Selected familiar username: {dialog.name}; ID: {dialog.id}") + logging.error(f"Err while load file - {file_not_found_err}") + return "" async def send_message_template( - user_data, event, start_range, end_range, response_type + user_data, event, start_range, end_range ): logging.info( f"Contact: {user_data.contact} -" @@ -109,35 +61,34 @@ async def send_message_template( **This message was sent automatically.** \n """, ) - await CLIENT.send_message(user_data.id, response_type) + await CLIENT.send_message(user_data.id, ) logging.info(f"Response was sent to {user_data.first_name}.") -@CLIENT.on(events.NewMessage) -async def response_to_group(event): - await show_selected_users() - - user_data = await event.client.get_entity(event.from_id) - - logging.info(f"Raw sender data: {user_data}") - - try: - if user_data.id in FRIENDS_IDS: - await send_message_template(user_data, event, 5, 10, FRIEND_RESPONSE) - elif user_data.id in FAMILIAR_IDS: - await send_message_template(user_data, event, 15, 20, FAMILIAR_RESPONSE) - elif not user_data.contact: - for key_words in HR_KEY_WORDS: - if key_words in event.message.message: - logging.info("Looks like HR is on the line.") - await send_message_template(user_data, event, 1, 5, HR_RESPONSE) - except ValueError as val_err: - logging.error(f"Sender is {user_data.first_name}") - logging.error(val_err) - except TypeError as type_err: - logging.error("That maybe sticker was sent, not text.") - logging.error(f"Sender is {user_data.first_name}") - logging.error(type_err) +# @CLIENT.on(events.NewMessage) +# async def response_to_group(event): +# +# user_data = await event.client.get_entity(event.from_id) +# +# logging.info(f"Raw sender data: {user_data}") +# +# try: +# if user_data.id in 123: +# await send_message_template(user_data, event, 5, 10, ) +# elif user_data.id in 123: +# await send_message_template(user_data, event, 15, 20, ) +# elif not user_data.contact: +# for key_words in 123: +# if key_words in event.message.message: +# logging.info("Looks like HR is on the line.") +# await send_message_template(user_data, event, 1, 5, ) +# except ValueError as val_err: +# logging.error(f"Sender is {user_data.first_name}") +# logging.error(val_err) +# except TypeError as type_err: +# logging.error("That maybe sticker was sent, not text.") +# logging.error(f"Sender is {user_data.first_name}") +# logging.error(type_err) if __name__ == "__main__": diff --git a/sqlitedb.py b/sqlitedb.py index 1c3e993..c04490c 100644 --- a/sqlitedb.py +++ b/sqlitedb.py @@ -16,11 +16,14 @@ PEOPLE = sqlalchemy.Table( 'people', META, sqlalchemy.Column('name', sqlalchemy.String), - sqlalchemy.Column('date', sqlalchemy.String), + sqlalchemy.Column('day_month', sqlalchemy.String), + sqlalchemy.Column('year', sqlalchemy.String), sqlalchemy.Column('tg_id', sqlalchemy.String), sqlalchemy.Column('congrats_file_path', sqlalchemy.String), ) +# TODO Class & inheritance it + def engine(database_name="herold_database.db"): return sqlalchemy.create_engine(f'sqlite:///{database_name}', echo=False) @@ -37,9 +40,9 @@ def create_db(): logging.error(f"Err while creating db - {sql_err}") -def get_all_people(): +def get_all(): """ - Query all rows in the people db table + Query all rows from the db :return: """ try: @@ -48,6 +51,14 @@ def get_all_people(): logging.error(f"Err while fetching from {PEOPLE} db - {sql_err}") +# For one type of subclass +def get_tg_id(current_date) -> str: + for d in get_all(): + if d[1] == current_date: + return d[3] + return "" + + if __name__ == "__main__": - # print(get_all_people()) + print(get_tg_id("05.11")) pass From 551f2c7b5f787a6fec92236a820c2a68fddf98ed Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Thu, 13 Apr 2023 18:18:29 +0300 Subject: [PATCH 03/23] Fixed; add models.py --- bot.py | 36 +++++------------------------- db.py | 52 +++++++++++++++++++++++++++++++++++++++++++ models.py | 12 ++++++++++ sqlitedb.py | 64 ----------------------------------------------------- 4 files changed, 69 insertions(+), 95 deletions(-) create mode 100644 db.py create mode 100644 models.py delete mode 100644 sqlitedb.py diff --git a/bot.py b/bot.py index d623295..c0f390f 100644 --- a/bot.py +++ b/bot.py @@ -39,12 +39,10 @@ def load_responses_from_files(file: Path) -> str: return result except FileNotFoundError as file_not_found_err: logging.error(f"Err while load file - {file_not_found_err}") - return "" + return None -async def send_message_template( - user_data, event, start_range, end_range -): +async def send_message_template(user_data, event, start_range, end_range): logging.info( f"Contact: {user_data.contact} -" f"username: {user_data.first_name} - " @@ -61,36 +59,12 @@ async def send_message_template( **This message was sent automatically.** \n """, ) - await CLIENT.send_message(user_data.id, ) + await CLIENT.send_message( + user_data.id, + ) logging.info(f"Response was sent to {user_data.first_name}.") -# @CLIENT.on(events.NewMessage) -# async def response_to_group(event): -# -# user_data = await event.client.get_entity(event.from_id) -# -# logging.info(f"Raw sender data: {user_data}") -# -# try: -# if user_data.id in 123: -# await send_message_template(user_data, event, 5, 10, ) -# elif user_data.id in 123: -# await send_message_template(user_data, event, 15, 20, ) -# elif not user_data.contact: -# for key_words in 123: -# if key_words in event.message.message: -# logging.info("Looks like HR is on the line.") -# await send_message_template(user_data, event, 1, 5, ) -# except ValueError as val_err: -# logging.error(f"Sender is {user_data.first_name}") -# logging.error(val_err) -# except TypeError as type_err: -# logging.error("That maybe sticker was sent, not text.") -# logging.error(f"Sender is {user_data.first_name}") -# logging.error(type_err) - - if __name__ == "__main__": CLIENT.start() CLIENT.run_until_disconnected() diff --git a/db.py b/db.py new file mode 100644 index 0000000..6208d7f --- /dev/null +++ b/db.py @@ -0,0 +1,52 @@ +import logging + +import sqlalchemy +from sqlalchemy import exc + +import models + +# Logging +logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO +) +logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(message)s", level=logging.ERROR +) + + +def engine(db_name="herold_database.db"): + return sqlalchemy.create_engine(f"sqlite:///{db_name}", echo=False) + + +def connect(): + return engine().connect() + + +def create_db(): + try: + models.META.create_all(engine()) + except exc.SQLAlchemyError as sql_err: + logging.error(f"Err while creating db - {sql_err}") + + +def get_all_rows(): + """ + Query all rows from the db + :return: + """ + try: + return connect().execute(models.PEOPLE.select()).fetchall() + except exc.SQLAlchemyError as sql_err: + logging.error(f"Err while fetching from {models.PEOPLE} db - {sql_err}") + + +def get_tg_id(current_date) -> str: + for d in get_all_rows(): + if d[1] == current_date: + return d[3] + return None + + +if __name__ == "__main__": + print(get_tg_id("05.11")) + pass diff --git a/models.py b/models.py new file mode 100644 index 0000000..cdf470f --- /dev/null +++ b/models.py @@ -0,0 +1,12 @@ +import sqlalchemy + +META = sqlalchemy.MetaData() +PEOPLE = sqlalchemy.Table( + "people", + META, + sqlalchemy.Column("name", sqlalchemy.String), + sqlalchemy.Column("day_month", sqlalchemy.String), + sqlalchemy.Column("year", sqlalchemy.String), + sqlalchemy.Column("tg_id", sqlalchemy.String), + sqlalchemy.Column("congrats_file_path", sqlalchemy.String), +) diff --git a/sqlitedb.py b/sqlitedb.py deleted file mode 100644 index c04490c..0000000 --- a/sqlitedb.py +++ /dev/null @@ -1,64 +0,0 @@ -import logging -# import sqlite3 -# from sqlite3 import Error -import sqlalchemy -from sqlalchemy import exc - -# Logging -logging.basicConfig( - format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO -) -logging.basicConfig( - format="%(asctime)s - %(levelname)s - %(message)s", level=logging.ERROR -) - -META = sqlalchemy.MetaData() -PEOPLE = sqlalchemy.Table( - 'people', META, - sqlalchemy.Column('name', sqlalchemy.String), - sqlalchemy.Column('day_month', sqlalchemy.String), - sqlalchemy.Column('year', sqlalchemy.String), - sqlalchemy.Column('tg_id', sqlalchemy.String), - sqlalchemy.Column('congrats_file_path', sqlalchemy.String), -) - -# TODO Class & inheritance it - - -def engine(database_name="herold_database.db"): - return sqlalchemy.create_engine(f'sqlite:///{database_name}', echo=False) - - -def connection(): - return engine().connect() - - -def create_db(): - try: - META.create_all(engine()) - except exc.SQLAlchemyError as sql_err: - logging.error(f"Err while creating db - {sql_err}") - - -def get_all(): - """ - Query all rows from the db - :return: - """ - try: - return connection().execute(PEOPLE.select()).fetchall() - except exc.SQLAlchemyError as sql_err: - logging.error(f"Err while fetching from {PEOPLE} db - {sql_err}") - - -# For one type of subclass -def get_tg_id(current_date) -> str: - for d in get_all(): - if d[1] == current_date: - return d[3] - return "" - - -if __name__ == "__main__": - print(get_tg_id("05.11")) - pass From 0c8c8b0ec90c6a8a3af486e3d274c251268491a4 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Thu, 13 Apr 2023 18:37:12 +0300 Subject: [PATCH 04/23] Small fixes --- db.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/db.py b/db.py index 6208d7f..d9df119 100644 --- a/db.py +++ b/db.py @@ -14,17 +14,17 @@ ) -def engine(db_name="herold_database.db"): +def engine_creation(db_name="herold_database.db"): return sqlalchemy.create_engine(f"sqlite:///{db_name}", echo=False) def connect(): - return engine().connect() + return engine_creation().connect() def create_db(): try: - models.META.create_all(engine()) + models.META.create_all(engine_creation()) except exc.SQLAlchemyError as sql_err: logging.error(f"Err while creating db - {sql_err}") From 2fbaa28bc8190fca3512243c0c104eb33f9d710d Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Thu, 13 Apr 2023 18:38:49 +0300 Subject: [PATCH 05/23] Small fixes --- db.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/db.py b/db.py index d9df119..4a948a2 100644 --- a/db.py +++ b/db.py @@ -14,17 +14,13 @@ ) -def engine_creation(db_name="herold_database.db"): - return sqlalchemy.create_engine(f"sqlite:///{db_name}", echo=False) - - -def connect(): - return engine_creation().connect() +def connect(db_name="herold_database.db"): + return sqlalchemy.create_engine(f"sqlite:///{db_name}", echo=False).connect() def create_db(): try: - models.META.create_all(engine_creation()) + models.META.create_all(connect()) except exc.SQLAlchemyError as sql_err: logging.error(f"Err while creating db - {sql_err}") From 95fb94bb4bd34053ed00249f91cdc95504da4047 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Sun, 16 Apr 2023 00:07:43 +0300 Subject: [PATCH 06/23] Update congrats func --- bot.py | 65 +++++++++++++++++++++++++-------------------- db.py | 4 ++- docker-compose.yaml | 5 ++-- 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/bot.py b/bot.py index c0f390f..fdccfea 100644 --- a/bot.py +++ b/bot.py @@ -1,12 +1,15 @@ -import asyncio import codecs import logging import os import random +import time +from datetime import datetime from pathlib import Path from typing import List -from telethon import TelegramClient, events +from telethon import TelegramClient + +import db # Environment variables API_ID = os.environ["API_ID"] @@ -24,47 +27,51 @@ ) -def load_responses_from_files(file: Path) -> str: +def load_congrats_from_files(file: Path) -> List: """ - Load responses from the files + Load congrats from the file Try to load from file, if exception caught, send message about err :return: """ try: - with codecs.open(file, "r", "utf-8") as response_file: - result = response_file.read() - logging.info( - f"Uploaded response from the {response_file.name} done successfully." - ) + with codecs.open(Path(file), "r", "utf-8") as file: + result = file.readlines() + logging.info(f"Uploaded response from the {file.name} done successfully.") return result except FileNotFoundError as file_not_found_err: logging.error(f"Err while load file - {file_not_found_err}") return None -async def send_message_template(user_data, event, start_range, end_range): - logging.info( - f"Contact: {user_data.contact} -" - f"username: {user_data.first_name} - " - f"ID: {user_data.id} - " - f"sent message: {event.message.message}" - ) - logging.info("Waiting for response...") - async with CLIENT.action(user_data.id, "typing"): - await asyncio.sleep(random.randrange(start_range, end_range)) - await CLIENT.send_message( - user_data.id, - f""" -Hello, {user_data.first_name}. \n -**This message was sent automatically.** \n -""", +CONGRATULATIONS_FILE = load_congrats_from_files(Path("congrats_file.txt")) + + +async def send_congratulations(): + """ + Send congratulations if date is correct + Wait for one day to check date + :return: + """ + current_date = datetime.today().strftime("%m.%d") + if db.get_tg_id(current_date) is None: + logging.info(f"Today - {current_date} - are no one to congratulate") + time.sleep(86400) + else: + user_data = await CLIENT.get_entity(db.get_tg_id(current_date)) + logging.info( + f"Today - {current_date} - going to congratulate {user_data.first_name} - {user_data.username}" ) await CLIENT.send_message( - user_data.id, + db.get_tg_id(current_date), random.choice(CONGRATULATIONS_FILE) ) - logging.info(f"Response was sent to {user_data.first_name}.") + time.sleep(86400) + + +async def main(): + while True: + await send_congratulations() if __name__ == "__main__": - CLIENT.start() - CLIENT.run_until_disconnected() + with CLIENT: + CLIENT.loop.run_until_complete(main()) diff --git a/db.py b/db.py index 4a948a2..5a78767 100644 --- a/db.py +++ b/db.py @@ -39,10 +39,12 @@ def get_all_rows(): def get_tg_id(current_date) -> str: for d in get_all_rows(): if d[1] == current_date: + logging.info(f"{d[1]} = {current_date}") return d[3] return None +# TODO Add update db from file + if __name__ == "__main__": - print(get_tg_id("05.11")) pass diff --git a/docker-compose.yaml b/docker-compose.yaml index d6d6bc5..7701acf 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -11,9 +11,8 @@ services: - API_HASH=YOURAPIHASH - SESSION=YOURSESSION volumes: - - "/root/herold_bot/circulation_ids_list.txt:/opt/circulation_ids_list.txt" - - "/root/herold_bot/circulation_response.txt:/opt/circulation_response.txt" - - "/root/herold_bot/new_year_patterns.txt:/opt/new_year_patterns.txt" + - "/root/herold_bot/herold_database.db:/opt/herold_database.db" + - "/root/herold_bot/congrats_file.txt:/opt/congrats_file.txt" - "/root/herold_bot/JustTalk.session:/opt/JustTalk.session" volumes: herold_bot: \ No newline at end of file From 402b759028e0c67c9c4a3f45e8035f28b2f49a72 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Sun, 16 Apr 2023 00:11:21 +0300 Subject: [PATCH 07/23] Fix Containerfile --- Containerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Containerfile b/Containerfile index 766208a..ecb4f71 100644 --- a/Containerfile +++ b/Containerfile @@ -3,6 +3,7 @@ FROM python:3.9-alpine as builder WORKDIR /opt COPY ["bot.py", "/opt/"] +COPY ["db.py", "/opt/"] COPY requirements.txt requirements.txt RUN pip3 install --no-cache-dir -r requirements.txt From 66f264397e962c269bd02b4d9fde3a59c8822d43 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Sun, 16 Apr 2023 00:14:42 +0300 Subject: [PATCH 08/23] Update docker-compose.yaml --- docker-compose.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 7701acf..8eb44f3 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -5,7 +5,7 @@ services: container_name: herold_bot image: h0d0user/herold_bot:latest restart: always - network_mode: host + network_mode: herold_net environment: - API_ID=YOURAPIID - API_HASH=YOURAPIHASH @@ -14,5 +14,9 @@ services: - "/root/herold_bot/herold_database.db:/opt/herold_database.db" - "/root/herold_bot/congrats_file.txt:/opt/congrats_file.txt" - "/root/herold_bot/JustTalk.session:/opt/JustTalk.session" + volumes: - herold_bot: \ No newline at end of file + herold_bot: + +networks: + herold_net: \ No newline at end of file From c1b6870b8dfba6fe303336fc32f890761e3478c8 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Sun, 16 Apr 2023 00:17:56 +0300 Subject: [PATCH 09/23] Update docker-compose.yaml & Containerfile --- Containerfile | 1 + docker-compose.yaml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Containerfile b/Containerfile index ecb4f71..27cb4cb 100644 --- a/Containerfile +++ b/Containerfile @@ -4,6 +4,7 @@ WORKDIR /opt COPY ["bot.py", "/opt/"] COPY ["db.py", "/opt/"] +COPY ["models.py", "/opt/"] COPY requirements.txt requirements.txt RUN pip3 install --no-cache-dir -r requirements.txt diff --git a/docker-compose.yaml b/docker-compose.yaml index 8eb44f3..372d36f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -5,7 +5,8 @@ services: container_name: herold_bot image: h0d0user/herold_bot:latest restart: always - network_mode: herold_net + networks: + - herold_net environment: - API_ID=YOURAPIID - API_HASH=YOURAPIHASH From 3d0a04c6502bf7547037e831df3b20e865848fa1 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Sun, 16 Apr 2023 23:30:54 +0300 Subject: [PATCH 10/23] Update docker-compose.yaml & Containerfile & requirements.txt --- Containerfile | 2 ++ docker-compose.yaml | 1 + requirements.txt | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Containerfile b/Containerfile index 27cb4cb..24f2a4c 100644 --- a/Containerfile +++ b/Containerfile @@ -5,6 +5,8 @@ WORKDIR /opt COPY ["bot.py", "/opt/"] COPY ["db.py", "/opt/"] COPY ["models.py", "/opt/"] +COPY ["bucket.py", "/opt/"] +COPY ["dynaconf.py", "/opt/"] COPY requirements.txt requirements.txt RUN pip3 install --no-cache-dir -r requirements.txt diff --git a/docker-compose.yaml b/docker-compose.yaml index 372d36f..ac8e79f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -15,6 +15,7 @@ services: - "/root/herold_bot/herold_database.db:/opt/herold_database.db" - "/root/herold_bot/congrats_file.txt:/opt/congrats_file.txt" - "/root/herold_bot/JustTalk.session:/opt/JustTalk.session" + - "/root/herold_bot/settings.toml:/opt/settings.toml" volumes: herold_bot: diff --git a/requirements.txt b/requirements.txt index edc282e..d23de2f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,6 @@ black isort telethon~=1.25.4 -SQLAlchemy~=2.0.7 \ No newline at end of file +SQLAlchemy~=2.0.7 +boto3~=1.26.114 +botocore~=1.29.114 \ No newline at end of file From 9d8b267d7d152d2e3191520f8e431215f9b3fcc8 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Sun, 16 Apr 2023 23:31:36 +0300 Subject: [PATCH 11/23] Update .gitignore --- .gitignore | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 90fd9e8..6431125 100644 --- a/.gitignore +++ b/.gitignore @@ -138,4 +138,12 @@ dmypy.json *.session* # SQLite -*.db \ No newline at end of file +*.db + +# Bucket objects +birthdays/ +*.jpg +*.png + +# Dynaconf +*.toml \ No newline at end of file From 54706e36d52aac1548401f0dec5a75403d5188de Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Sun, 16 Apr 2023 23:34:49 +0300 Subject: [PATCH 12/23] Add bucket.py & dynaconfig.py; update bot.py --- bot.py | 3 ++- bucket.py | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ dynaconfig.py | 16 ++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 bucket.py create mode 100644 dynaconfig.py diff --git a/bot.py b/bot.py index fdccfea..3dd56c6 100644 --- a/bot.py +++ b/bot.py @@ -64,7 +64,8 @@ async def send_congratulations(): await CLIENT.send_message( db.get_tg_id(current_date), random.choice(CONGRATULATIONS_FILE) ) - time.sleep(86400) + # await CLIENT.send_file(db.get_tg_id(current_date), path_to_file) + time.sleep(86400) async def main(): diff --git a/bucket.py b/bucket.py new file mode 100644 index 0000000..95c4403 --- /dev/null +++ b/bucket.py @@ -0,0 +1,67 @@ +import os +import boto3 +import botocore +import random +from typing import List + +import dynaconfig + +session = boto3.session.Session() + +BUCKET_NAME = dynaconfig.settings["BUCKET_NAME"] +ENDPOINT_URL = dynaconfig.settings["ENDPOINT_URL"] +REGION_NAME = dynaconfig.settings["REGION_NAME"] +AWS_ACCESS_KEY_ID = dynaconfig.settings["AWS_ACCESS_KEY_ID"] +AWS_SECRET_ACCESS_KEY = dynaconfig.settings["AWS_SECRET_ACCESS_KEY"] + +CLIENT = session.client('s3', + endpoint_url=ENDPOINT_URL, + config=botocore.config.Config(s3={'addressing_style': 'virtual'}), + region_name=REGION_NAME, + aws_access_key_id=AWS_ACCESS_KEY_ID, + aws_secret_access_key=AWS_SECRET_ACCESS_KEY + ) + + +def filter_conf(dir_to_filter): + """ + Configure what to filter from the list files of directory + :param dir_to_filter: + :return: + """ + def check_dir(directory: str): + """ + Check the needed directory + :param directory: + :return: + """ + return True if directory.startswith(dir_to_filter) else False + return check_dir + + +def get_random_object(search_dir: str) -> str: + """ + Get random object from searched directory in bucket + :param search_dir: + :return: + """ + response = CLIENT.list_objects(Bucket=BUCKET_NAME) + result = [] + for obj in response['Contents']: + result.append(obj['Key']) + + f_c = filter_conf(search_dir) + result = filter(f_c, result) + + return random.choices(list(result)[1:])[0] + + +# CLIENT.download_file(BUCKET_NAME, +# 'birthdays/birthdays-1.jpg', +# './') + + +if __name__ == '__main__': + # print(os.listdir("birthdays")) + + print(get_random_object("birthdays")) diff --git a/dynaconfig.py b/dynaconfig.py new file mode 100644 index 0000000..5e61926 --- /dev/null +++ b/dynaconfig.py @@ -0,0 +1,16 @@ +import logging + +from dynaconf import Dynaconf + +# Logging +logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO +) + +settings = Dynaconf( + settings_files=["settings.toml"], +) + +if __name__ == "__main__": + for data in settings: + logging.info(f"Loaded variable {data}") \ No newline at end of file From 268c8c5a1a4f4018bc2891835885a245c8c97011 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Mon, 17 Apr 2023 00:00:18 +0300 Subject: [PATCH 13/23] Update docker-compose.yaml --- docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index ac8e79f..612f214 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -18,7 +18,7 @@ services: - "/root/herold_bot/settings.toml:/opt/settings.toml" volumes: - herold_bot: + herold_volume: networks: herold_net: \ No newline at end of file From 88fc886ec30aa3b64b48e19e236d173ee4b66a34 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Mon, 17 Apr 2023 00:59:29 +0300 Subject: [PATCH 14/23] Send picture from bucket --- bot.py | 11 ++++++++-- bucket.py | 56 ++++++++++++++++++++++++++++++++++----------------- dynaconfig.py | 2 +- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/bot.py b/bot.py index 3dd56c6..5cc945e 100644 --- a/bot.py +++ b/bot.py @@ -1,3 +1,4 @@ +import asyncio import codecs import logging import os @@ -9,6 +10,7 @@ from telethon import TelegramClient +import bucket import db # Environment variables @@ -64,11 +66,16 @@ async def send_congratulations(): await CLIENT.send_message( db.get_tg_id(current_date), random.choice(CONGRATULATIONS_FILE) ) - # await CLIENT.send_file(db.get_tg_id(current_date), path_to_file) + async with CLIENT.action(user_data.id, "typing"): + await asyncio.sleep(random.randrange(2, 5)) + await CLIENT.send_file( + db.get_tg_id(current_date), + bucket.download_file_from_bucket(Path("/opt/")), + ) time.sleep(86400) -async def main(): +def main(): while True: await send_congratulations() diff --git a/bucket.py b/bucket.py index 95c4403..b6eed75 100644 --- a/bucket.py +++ b/bucket.py @@ -1,8 +1,10 @@ +import logging import os +import random +from pathlib import Path + import boto3 import botocore -import random -from typing import List import dynaconfig @@ -14,13 +16,22 @@ AWS_ACCESS_KEY_ID = dynaconfig.settings["AWS_ACCESS_KEY_ID"] AWS_SECRET_ACCESS_KEY = dynaconfig.settings["AWS_SECRET_ACCESS_KEY"] -CLIENT = session.client('s3', - endpoint_url=ENDPOINT_URL, - config=botocore.config.Config(s3={'addressing_style': 'virtual'}), - region_name=REGION_NAME, - aws_access_key_id=AWS_ACCESS_KEY_ID, - aws_secret_access_key=AWS_SECRET_ACCESS_KEY - ) +CLIENT = session.client( + "s3", + endpoint_url=ENDPOINT_URL, + config=botocore.config.Config(s3={"addressing_style": "virtual"}), + region_name=REGION_NAME, + aws_access_key_id=AWS_ACCESS_KEY_ID, + aws_secret_access_key=AWS_SECRET_ACCESS_KEY, +) + +# Logging +logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO +) +logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(message)s", level=logging.ERROR +) def filter_conf(dir_to_filter): @@ -29,6 +40,7 @@ def filter_conf(dir_to_filter): :param dir_to_filter: :return: """ + def check_dir(directory: str): """ Check the needed directory @@ -36,6 +48,7 @@ def check_dir(directory: str): :return: """ return True if directory.startswith(dir_to_filter) else False + return check_dir @@ -47,21 +60,26 @@ def get_random_object(search_dir: str) -> str: """ response = CLIENT.list_objects(Bucket=BUCKET_NAME) result = [] - for obj in response['Contents']: - result.append(obj['Key']) + for obj in response["Contents"]: + result.append(obj["Key"]) f_c = filter_conf(search_dir) result = filter(f_c, result) - return random.choices(list(result)[1:])[0] - + return random.choices(list(result)[1:])[0].split("/")[1] -# CLIENT.download_file(BUCKET_NAME, -# 'birthdays/birthdays-1.jpg', -# './') +def download_file_from_bucket(target_dir: Path): + # random_file = "" + try: + random_file = get_random_object("birthdays") + CLIENT.download_file(BUCKET_NAME, random_file, target_dir) + logging.info(f"File {random_file} downloaded to f{target_dir}") + logging.info(f"Directory {target_dir} - {os.listdir(target_dir)}") + return random_file + except Exception as err: + logging.error(f"File not downloaded ! - {err}") -if __name__ == '__main__': - # print(os.listdir("birthdays")) - print(get_random_object("birthdays")) +if __name__ == "__main__": + pass diff --git a/dynaconfig.py b/dynaconfig.py index 5e61926..524ab92 100644 --- a/dynaconfig.py +++ b/dynaconfig.py @@ -13,4 +13,4 @@ if __name__ == "__main__": for data in settings: - logging.info(f"Loaded variable {data}") \ No newline at end of file + logging.info(f"Loaded variable {data}") From bdf4b12416e654a73ad308e87224182fe9fad1d1 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Mon, 17 Apr 2023 01:01:15 +0300 Subject: [PATCH 15/23] Fix Containerfile --- Containerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Containerfile b/Containerfile index 24f2a4c..aac71db 100644 --- a/Containerfile +++ b/Containerfile @@ -6,7 +6,7 @@ COPY ["bot.py", "/opt/"] COPY ["db.py", "/opt/"] COPY ["models.py", "/opt/"] COPY ["bucket.py", "/opt/"] -COPY ["dynaconf.py", "/opt/"] +COPY ["dynaconfig.py", "/opt/"] COPY requirements.txt requirements.txt RUN pip3 install --no-cache-dir -r requirements.txt From b98a34007b6fc7e34688e0197118ee9406c94daa Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Mon, 17 Apr 2023 01:04:04 +0300 Subject: [PATCH 16/23] Fix bot.py --- bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 5cc945e..82c446d 100644 --- a/bot.py +++ b/bot.py @@ -75,7 +75,7 @@ async def send_congratulations(): time.sleep(86400) -def main(): +async def main(): while True: await send_congratulations() From f2e942cb8a0f8d4daa3607dc278208008c8f5849 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Mon, 17 Apr 2023 01:06:28 +0300 Subject: [PATCH 17/23] Fix requirements.txt --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d23de2f..e56ff39 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ black isort +boto3~=1.26.114 +dynaconf~=3.1.12 telethon~=1.25.4 SQLAlchemy~=2.0.7 -boto3~=1.26.114 botocore~=1.29.114 \ No newline at end of file From f95ee09fa2d624cfbe3e87216fbcdfc9557d78ac Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Mon, 17 Apr 2023 01:29:21 +0300 Subject: [PATCH 18/23] Add prune func to clear container --- bot.py | 6 ++++-- bucket.py | 24 +++++++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/bot.py b/bot.py index 82c446d..58cc78b 100644 --- a/bot.py +++ b/bot.py @@ -70,9 +70,11 @@ async def send_congratulations(): await asyncio.sleep(random.randrange(2, 5)) await CLIENT.send_file( db.get_tg_id(current_date), - bucket.download_file_from_bucket(Path("/opt/")), + bucket.download_file_from_bucket(Path("/home/")), ) - time.sleep(86400) + time.sleep(400) + bucket.prune_directory(Path("/home/")) + time.sleep(86000) async def main(): diff --git a/bucket.py b/bucket.py index b6eed75..9b7e932 100644 --- a/bucket.py +++ b/bucket.py @@ -70,7 +70,11 @@ def get_random_object(search_dir: str) -> str: def download_file_from_bucket(target_dir: Path): - # random_file = "" + """ + Download random file from bucket + :param target_dir: + :return: + """ try: random_file = get_random_object("birthdays") CLIENT.download_file(BUCKET_NAME, random_file, target_dir) @@ -81,5 +85,23 @@ def download_file_from_bucket(target_dir: Path): logging.error(f"File not downloaded ! - {err}") +def prune_directory(directory_to_prune: Path): + """ + Need to prune directory after downloading to evade container enlargement + :param directory_to_prune: + :return: + """ + try: + for file in os.listdir(directory_to_prune): + os.remove(os.path.join(directory_to_prune, file)) + logging.info(f"Directory {directory_to_prune} was pruned !") + except FileNotFoundError as dir_not_found: + logging.error( + f"Directory {directory_to_prune} was not pruned - {dir_not_found}" + ) + except Exception as err: + logging.error(f"Directory {directory_to_prune} was not pruned - {err}") + + if __name__ == "__main__": pass From 22be4e01757327c2a1e04d54e89c777961ce7dee Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Tue, 18 Apr 2023 22:17:29 +0300 Subject: [PATCH 19/23] Update .gitignore & docker-compose.yaml --- .gitignore | 4 ++-- docker-compose.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 6431125..ac49a48 100644 --- a/.gitignore +++ b/.gitignore @@ -132,7 +132,7 @@ dmypy.json *_list.txt *_response.txt -*.txt +*_patterns.txt # Session journals *.session* @@ -146,4 +146,4 @@ birthdays/ *.png # Dynaconf -*.toml \ No newline at end of file +settings.toml \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 612f214..a407492 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -21,4 +21,4 @@ volumes: herold_volume: networks: - herold_net: \ No newline at end of file + herold_net: From 4f5db8d239a5c460e28ec95b6a66f13a633421bf Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Tue, 18 Apr 2023 22:18:15 +0300 Subject: [PATCH 20/23] Update .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ac49a48..9a3ef9b 100644 --- a/.gitignore +++ b/.gitignore @@ -131,7 +131,7 @@ dmypy.json # List of user ids & answers *_list.txt *_response.txt - +*_file.txt *_patterns.txt # Session journals From 0d6c21bc1e9427df8aec7455369506389043b9ca Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Tue, 18 Apr 2023 22:22:50 +0300 Subject: [PATCH 21/23] Update docker-compose.yaml --- docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index a407492..e359ebe 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -13,7 +13,7 @@ services: - SESSION=YOURSESSION volumes: - "/root/herold_bot/herold_database.db:/opt/herold_database.db" - - "/root/herold_bot/congrats_file.txt:/opt/congrats_file.txt" + - "/root/herold_bot/congrats_list.txt:/opt/congrats_list.txt" - "/root/herold_bot/JustTalk.session:/opt/JustTalk.session" - "/root/herold_bot/settings.toml:/opt/settings.toml" From 319c529a32414e1822537c97859d6d2b85512069 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Tue, 18 Apr 2023 22:23:41 +0300 Subject: [PATCH 22/23] Move to src; update & fixes --- Containerfile | 7 ++----- bot.py => src/bot.py | 25 ++++++++++++------------- bucket.py => src/bucket.py | 8 ++++++-- db.py => src/db.py | 19 ++++++++++++------- dynaconfig.py => src/dynaconfig.py | 0 models.py => src/models.py | 7 ++++--- 6 files changed, 36 insertions(+), 30 deletions(-) rename bot.py => src/bot.py (76%) rename bucket.py => src/bucket.py (92%) rename db.py => src/db.py (61%) rename dynaconfig.py => src/dynaconfig.py (100%) rename models.py => src/models.py (81%) diff --git a/Containerfile b/Containerfile index aac71db..2da05e9 100644 --- a/Containerfile +++ b/Containerfile @@ -2,11 +2,8 @@ FROM python:3.9-alpine as builder WORKDIR /opt -COPY ["bot.py", "/opt/"] -COPY ["db.py", "/opt/"] -COPY ["models.py", "/opt/"] -COPY ["bucket.py", "/opt/"] -COPY ["dynaconfig.py", "/opt/"] +ADD ["/src/", "/opt/"] + COPY requirements.txt requirements.txt RUN pip3 install --no-cache-dir -r requirements.txt diff --git a/bot.py b/src/bot.py similarity index 76% rename from bot.py rename to src/bot.py index 58cc78b..8d25383 100644 --- a/bot.py +++ b/src/bot.py @@ -1,5 +1,4 @@ import asyncio -import codecs import logging import os import random @@ -18,7 +17,7 @@ API_HASH = os.environ["API_HASH"] SESSION = os.environ["SESSION"] -CLIENT = TelegramClient(SESSION, API_ID, API_HASH) +client = TelegramClient(SESSION, API_ID, API_HASH) # Logging logging.basicConfig( @@ -29,14 +28,14 @@ ) -def load_congrats_from_files(file: Path) -> List: +def load_congrats_from_file(file: Path) -> List[str]: """ Load congrats from the file Try to load from file, if exception caught, send message about err :return: """ try: - with codecs.open(Path(file), "r", "utf-8") as file: + with open(Path(file), "r", encoding="utf-8") as file: result = file.readlines() logging.info(f"Uploaded response from the {file.name} done successfully.") return result @@ -45,12 +44,12 @@ def load_congrats_from_files(file: Path) -> List: return None -CONGRATULATIONS_FILE = load_congrats_from_files(Path("congrats_file.txt")) +CONGRATULATIONS = load_congrats_from_file(Path("congrats_list.txt")) async def send_congratulations(): """ - Send congratulations if date is correct + Check if someone has a birthday on this date then send congratulation Wait for one day to check date :return: """ @@ -59,16 +58,16 @@ async def send_congratulations(): logging.info(f"Today - {current_date} - are no one to congratulate") time.sleep(86400) else: - user_data = await CLIENT.get_entity(db.get_tg_id(current_date)) + user_data = await client.get_entity(db.get_tg_id(current_date)) logging.info( f"Today - {current_date} - going to congratulate {user_data.first_name} - {user_data.username}" ) - await CLIENT.send_message( - db.get_tg_id(current_date), random.choice(CONGRATULATIONS_FILE) + await client.send_message( + db.get_tg_id(current_date), random.choice(CONGRATULATIONS) ) - async with CLIENT.action(user_data.id, "typing"): + async with client.action(user_data.id, "typing"): await asyncio.sleep(random.randrange(2, 5)) - await CLIENT.send_file( + await client.send_file( db.get_tg_id(current_date), bucket.download_file_from_bucket(Path("/home/")), ) @@ -83,5 +82,5 @@ async def main(): if __name__ == "__main__": - with CLIENT: - CLIENT.loop.run_until_complete(main()) + with client: + client.loop.run_until_complete(main()) diff --git a/bucket.py b/src/bucket.py similarity index 92% rename from bucket.py rename to src/bucket.py index 9b7e932..8cab4b7 100644 --- a/bucket.py +++ b/src/bucket.py @@ -25,6 +25,9 @@ aws_secret_access_key=AWS_SECRET_ACCESS_KEY, ) +# transfer = S3Transfer(CLIENT) +# transfer.upload_file("filetoupload", BUCKET_NAME, "filedest") + # Logging logging.basicConfig( format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO @@ -41,7 +44,7 @@ def filter_conf(dir_to_filter): :return: """ - def check_dir(directory: str): + def check_dir(directory: str) -> bool: """ Check the needed directory :param directory: @@ -69,7 +72,8 @@ def get_random_object(search_dir: str) -> str: return random.choices(list(result)[1:])[0].split("/")[1] -def download_file_from_bucket(target_dir: Path): +# TODO input param for dir - birthdays for now +def download_file_from_bucket(target_dir: Path) -> str: """ Download random file from bucket :param target_dir: diff --git a/db.py b/src/db.py similarity index 61% rename from db.py rename to src/db.py index 5a78767..1d11c80 100644 --- a/db.py +++ b/src/db.py @@ -14,31 +14,36 @@ ) -def connect(db_name="herold_database.db"): +def connect_to_db(db_name="herold_database.db") -> sqlalchemy.engine.base.Connection: return sqlalchemy.create_engine(f"sqlite:///{db_name}", echo=False).connect() def create_db(): try: - models.META.create_all(connect()) + models.meta.create_all(connect_to_db()) except exc.SQLAlchemyError as sql_err: logging.error(f"Err while creating db - {sql_err}") -def get_all_rows(): +def get_all_people_from_db(model): """ Query all rows from the db :return: """ try: - return connect().execute(models.PEOPLE.select()).fetchall() + return connect_to_db().execute(model.birthdays.select()).fetchall() except exc.SQLAlchemyError as sql_err: - logging.error(f"Err while fetching from {models.PEOPLE} db - {sql_err}") + logging.error(f"Err while fetching from {models.birthdays} db - {sql_err}") def get_tg_id(current_date) -> str: - for d in get_all_rows(): - if d[1] == current_date: + """ + Get telegram ID if today is anyone to congrats + :param current_date: + :return: + """ + for d in get_all_people_from_db(model=models): + if current_date == d[1]: logging.info(f"{d[1]} = {current_date}") return d[3] return None diff --git a/dynaconfig.py b/src/dynaconfig.py similarity index 100% rename from dynaconfig.py rename to src/dynaconfig.py diff --git a/models.py b/src/models.py similarity index 81% rename from models.py rename to src/models.py index cdf470f..18844b8 100644 --- a/models.py +++ b/src/models.py @@ -1,9 +1,10 @@ import sqlalchemy -META = sqlalchemy.MetaData() -PEOPLE = sqlalchemy.Table( +meta = sqlalchemy.MetaData() + +birthdays = sqlalchemy.Table( "people", - META, + meta, sqlalchemy.Column("name", sqlalchemy.String), sqlalchemy.Column("day_month", sqlalchemy.String), sqlalchemy.Column("year", sqlalchemy.String), From 3bb6199ef18776c6abbd54fd71736928e7462da7 Mon Sep 17 00:00:00 2001 From: CoolCoderCarl <123qwekir2wl@gmail.com> Date: Tue, 18 Apr 2023 23:00:32 +0300 Subject: [PATCH 23/23] Small fixes --- src/bot.py | 2 +- src/bucket.py | 21 ++++++++++----------- src/db.py | 2 -- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/bot.py b/src/bot.py index 8d25383..ac8cb12 100644 --- a/src/bot.py +++ b/src/bot.py @@ -69,7 +69,7 @@ async def send_congratulations(): await asyncio.sleep(random.randrange(2, 5)) await client.send_file( db.get_tg_id(current_date), - bucket.download_file_from_bucket(Path("/home/")), + bucket.download_file_from_bucket("birthdays", Path("/home/")), ) time.sleep(400) bucket.prune_directory(Path("/home/")) diff --git a/src/bucket.py b/src/bucket.py index 8cab4b7..422e29c 100644 --- a/src/bucket.py +++ b/src/bucket.py @@ -16,7 +16,7 @@ AWS_ACCESS_KEY_ID = dynaconfig.settings["AWS_ACCESS_KEY_ID"] AWS_SECRET_ACCESS_KEY = dynaconfig.settings["AWS_SECRET_ACCESS_KEY"] -CLIENT = session.client( +client = session.client( "s3", endpoint_url=ENDPOINT_URL, config=botocore.config.Config(s3={"addressing_style": "virtual"}), @@ -25,8 +25,6 @@ aws_secret_access_key=AWS_SECRET_ACCESS_KEY, ) -# transfer = S3Transfer(CLIENT) -# transfer.upload_file("filetoupload", BUCKET_NAME, "filedest") # Logging logging.basicConfig( @@ -61,7 +59,7 @@ def get_random_object(search_dir: str) -> str: :param search_dir: :return: """ - response = CLIENT.list_objects(Bucket=BUCKET_NAME) + response = client.list_objects(Bucket=BUCKET_NAME) result = [] for obj in response["Contents"]: result.append(obj["Key"]) @@ -72,21 +70,22 @@ def get_random_object(search_dir: str) -> str: return random.choices(list(result)[1:])[0].split("/")[1] -# TODO input param for dir - birthdays for now -def download_file_from_bucket(target_dir: Path) -> str: +def download_file_from_bucket(remote_directory: str, local_directory: Path) -> str: """ Download random file from bucket - :param target_dir: + :param remote_directory: + :param local_directory: :return: """ try: - random_file = get_random_object("birthdays") - CLIENT.download_file(BUCKET_NAME, random_file, target_dir) - logging.info(f"File {random_file} downloaded to f{target_dir}") - logging.info(f"Directory {target_dir} - {os.listdir(target_dir)}") + random_file = get_random_object(remote_directory) + client.download_file(BUCKET_NAME, random_file, local_directory) + logging.info(f"File {random_file} downloaded to f{local_directory}") + logging.info(f"Directory {local_directory} - {os.listdir(local_directory)}") return random_file except Exception as err: logging.error(f"File not downloaded ! - {err}") + return None def prune_directory(directory_to_prune: Path): diff --git a/src/db.py b/src/db.py index 1d11c80..e68841d 100644 --- a/src/db.py +++ b/src/db.py @@ -49,7 +49,5 @@ def get_tg_id(current_date) -> str: return None -# TODO Add update db from file - if __name__ == "__main__": pass