From 9893f26757c2f82c8e0bc36b0a2f5d7cd79def15 Mon Sep 17 00:00:00 2001 From: bzorn Date: Fri, 5 Jul 2024 18:09:09 +0300 Subject: [PATCH 01/33] flake8 and black configs in pyproject.toml --- .flake8 | 14 -------------- .github/workflows/python-app.yml | 4 ++-- pyproject.toml | 19 +++++++++++++++++++ requirements/test.txt | 1 + 4 files changed, 22 insertions(+), 16 deletions(-) delete mode 100644 .flake8 create mode 100644 pyproject.toml diff --git a/.flake8 b/.flake8 deleted file mode 100644 index b02f36d..0000000 --- a/.flake8 +++ /dev/null @@ -1,14 +0,0 @@ -[flake8] -inline-quotes=double -import-order-style=google -max-line-length = 89 -extend-ignore = R503,R502,F401,N802 -exclude = - .git, - __pycache__, - docs/source/conf.py, - old, - build, - dist, - venv, - __init__.py, \ No newline at end of file diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 07b1448..9b37780 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -18,7 +18,7 @@ jobs: - name: Install dependencies run: pip install black - name: Check code formatting with black - run: black ./ --check --verbose --diff --line-length 89 + run: black ./ --check --verbose --diff flake8-test: runs-on: ubuntu-latest @@ -28,4 +28,4 @@ jobs: - name: Install dependencies run: pip install -r requirements/test.txt - name: Check code formatting with flake8 - run: flake8 ./ --config=.flake8 \ No newline at end of file + run: flake8 ./ \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..276515c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,19 @@ +[tool.flake8] +max-line-length = 89 +inline-quotes="double" +import-order-style="google" +extend-ignore = [ + "R503", + "R502", + "F401", + "N802", +] +exclude = [ + ".git", + "__pycache__", + "docs/source/conf.py", + "venv", +] + +[tool.black] +line-length = 89 \ No newline at end of file diff --git a/requirements/test.txt b/requirements/test.txt index 35031c4..25ee9fe 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -2,6 +2,7 @@ flake8>=6.1.0 flake8-commas>=2.1.0 flake8-comments>=0.1.2 flake8-print>=5.0.0 +Flake8-pyproject>=1.2.3 flake8-quotes>=3.3.2 flake8-return>=1.2.0 flake8-use-pathlib>=0.3.0 From 2c404c6613ecd431213bbb42416cd6fec3f19fbc Mon Sep 17 00:00:00 2001 From: bzorn Date: Fri, 2 Aug 2024 11:21:16 +0300 Subject: [PATCH 02/33] moved dirs and added .env --- .gitignore | 8 ++++---- requirements/prod.txt | 1 + blast.py => tfinance/blast.py | 0 database.py => tfinance/database.py | 0 exceptions.py => tfinance/exceptions.py | 0 functions.py => tfinance/functions.py | 0 game.py => tfinance/game.py | 0 main.py => tfinance/main.py | 6 +++--- models.py => tfinance/models.py | 0 stock.py => tfinance/stock.py | 0 10 files changed, 8 insertions(+), 7 deletions(-) rename blast.py => tfinance/blast.py (100%) rename database.py => tfinance/database.py (100%) rename exceptions.py => tfinance/exceptions.py (100%) rename functions.py => tfinance/functions.py (100%) rename game.py => tfinance/game.py (100%) rename main.py => tfinance/main.py (98%) rename models.py => tfinance/models.py (100%) rename stock.py => tfinance/stock.py (100%) diff --git a/.gitignore b/.gitignore index 4d257f8..3e0e1cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /.idea -/logs -/data.db -/safety_key.py -stocks.json \ No newline at end of file +logs +data.db +stocks.json +.env \ No newline at end of file diff --git a/requirements/prod.txt b/requirements/prod.txt index 1525017..e6683f1 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -1,4 +1,5 @@ matplotlib>=3.5.3 +python-dotenv>=1.0.1 python-telegram-bot>=21.1.1 python-telegram-bot[job-queue] pytz>=2024.1 diff --git a/blast.py b/tfinance/blast.py similarity index 100% rename from blast.py rename to tfinance/blast.py diff --git a/database.py b/tfinance/database.py similarity index 100% rename from database.py rename to tfinance/database.py diff --git a/exceptions.py b/tfinance/exceptions.py similarity index 100% rename from exceptions.py rename to tfinance/exceptions.py diff --git a/functions.py b/tfinance/functions.py similarity index 100% rename from functions.py rename to tfinance/functions.py diff --git a/game.py b/tfinance/game.py similarity index 100% rename from game.py rename to tfinance/game.py diff --git a/main.py b/tfinance/main.py similarity index 98% rename from main.py rename to tfinance/main.py index d2c7f03..56aae9c 100644 --- a/main.py +++ b/tfinance/main.py @@ -8,6 +8,7 @@ import warnings import pytz +from dotenv import load_dotenv from telegram import Update # Работа с telegram-bot-api. @@ -28,7 +29,6 @@ from functions import create_user from game import game_menu, game_results, higher_game, lower_game from graphics.visualize import do_stock_image -from safety_key import TOKEN from stock import check_stock, get_all_stocks, load_stocks @@ -193,13 +193,13 @@ async def stats(update: Update, _): # Основной цикл, активирующийся при запуске. def main(): + load_dotenv() # Получение и сохранение списка всех акций в stocks.json. try: get_all_stocks() except Exception as e: logging.error(e) - - application = Application.builder().token(TOKEN).build() + application = Application.builder().token(os.getenv("TOKEN")).build() job_queue = application.job_queue # Ежедневные задачи. diff --git a/models.py b/tfinance/models.py similarity index 100% rename from models.py rename to tfinance/models.py diff --git a/stock.py b/tfinance/stock.py similarity index 100% rename from stock.py rename to tfinance/stock.py From 1eacbd5129c696dc49cfa157fbad36e7ebf6e8bb Mon Sep 17 00:00:00 2001 From: bzorn Date: Fri, 2 Aug 2024 11:48:12 +0300 Subject: [PATCH 03/33] added deploy --- .github/workflows/python-app.yml | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 9b37780..160c73b 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -18,7 +18,7 @@ jobs: - name: Install dependencies run: pip install black - name: Check code formatting with black - run: black ./ --check --verbose --diff + run: black ./tfinance --check --verbose --diff flake8-test: runs-on: ubuntu-latest @@ -28,4 +28,27 @@ jobs: - name: Install dependencies run: pip install -r requirements/test.txt - name: Check code formatting with flake8 - run: flake8 ./ \ No newline at end of file + run: flake8 ./tfinance + + prod-deploy: + if: github.ref == 'refs/heads/main' + needs: [ black-test, flake8-test ] + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Deploy to server + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USERNAME }} + key: ${{ secrets.SERVER_SSH_KEY }} + script: | + cd ~/tfinance + git reset --hard origin/main + git pull origin main + source venv/bin/activate + pip install -r requirements/prod.txt + cd ~/tfinance/tfinance + python main.py \ No newline at end of file From 9d432bb4d36f942562e2bd4ba88f51cb0c552431 Mon Sep 17 00:00:00 2001 From: bzorn Date: Fri, 2 Aug 2024 11:54:35 +0300 Subject: [PATCH 04/33] removed commnets --- tfinance/main.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tfinance/main.py b/tfinance/main.py index 56aae9c..902ff65 100644 --- a/tfinance/main.py +++ b/tfinance/main.py @@ -199,10 +199,10 @@ def main(): get_all_stocks() except Exception as e: logging.error(e) + application = Application.builder().token(os.getenv("TOKEN")).build() job_queue = application.job_queue - # Ежедневные задачи. job_queue.run_daily( notify_assignees, datetime.time( @@ -218,7 +218,6 @@ def main(): ), ) - # Обработчик для игры. game_handler = ConversationHandler( entry_points=[CommandHandler("game", game_menu)], states={ @@ -231,7 +230,6 @@ def main(): ) application.add_handler(game_handler) - # Регистрируем обработчик команд. application.add_handler(CommandHandler("daily", daily)) application.add_handler(CommandHandler("start", start)) application.add_handler(CommandHandler("help", help_msg)) @@ -242,7 +240,6 @@ def main(): application.add_handler(CommandHandler("stocks", get_list_stocks)) application.add_handler(CommandHandler("stats", stats)) - # Обработка сообщений. application.run_polling(allowed_updates=Update.ALL_TYPES) From 7847a6c79485b1098ece4c00a519db2bcfdb1d59 Mon Sep 17 00:00:00 2001 From: bzorn Date: Fri, 2 Aug 2024 13:14:13 +0300 Subject: [PATCH 05/33] fixed files --- requirements.txt | 1 + {graphics => tfinance/graphics}/visualize.py | 0 2 files changed, 1 insertion(+) rename {graphics => tfinance/graphics}/visualize.py (100%) diff --git a/requirements.txt b/requirements.txt index 1525017..e6683f1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ matplotlib>=3.5.3 +python-dotenv>=1.0.1 python-telegram-bot>=21.1.1 python-telegram-bot[job-queue] pytz>=2024.1 diff --git a/graphics/visualize.py b/tfinance/graphics/visualize.py similarity index 100% rename from graphics/visualize.py rename to tfinance/graphics/visualize.py From dcb245276afebcf0f543e37f485175fea9471f55 Mon Sep 17 00:00:00 2001 From: bzorn Date: Sat, 3 Aug 2024 11:20:14 +0300 Subject: [PATCH 06/33] . --- tfinance/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tfinance/main.py b/tfinance/main.py index 902ff65..64ac859 100644 --- a/tfinance/main.py +++ b/tfinance/main.py @@ -191,7 +191,6 @@ async def stats(update: Update, _): ) -# Основной цикл, активирующийся при запуске. def main(): load_dotenv() # Получение и сохранение списка всех акций в stocks.json. From 76550fc6029440cded698f9a887845c9b4d90fc6 Mon Sep 17 00:00:00 2001 From: bzorn Date: Sat, 3 Aug 2024 11:37:45 +0300 Subject: [PATCH 07/33] updated deploy --- .github/workflows/python-app.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 160c73b..4caa357 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -46,9 +46,9 @@ jobs: key: ${{ secrets.SERVER_SSH_KEY }} script: | cd ~/tfinance - git reset --hard origin/main + git reset --hard origin/main git pull origin main source venv/bin/activate - pip install -r requirements/prod.txt + pip3 install -r requirements/prod.txt cd ~/tfinance/tfinance - python main.py \ No newline at end of file + python3 main.py \ No newline at end of file From 4ea920f88cbf01eaca71db629b34f55504972416 Mon Sep 17 00:00:00 2001 From: bzorn Date: Sat, 3 Aug 2024 11:43:09 +0300 Subject: [PATCH 08/33] using pathlib --- tfinance/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tfinance/stock.py b/tfinance/stock.py index 8124627..a14d45e 100644 --- a/tfinance/stock.py +++ b/tfinance/stock.py @@ -34,7 +34,7 @@ def check_stock(stock_name: str) -> bool: # Сохранение списка акций в json. def save_stocks(file_name: str, stocks: list): - with Path(f"{Path.cwd()}/{file_name}").open("w") as f: + with (Path.cwd() / file_name).open("w") as f: json.dump(stocks, f) From c57efc82627dc775520570fb7e65d4d031b63f83 Mon Sep 17 00:00:00 2001 From: bzorn Date: Sat, 3 Aug 2024 11:45:41 +0300 Subject: [PATCH 09/33] fixed paths --- .github/workflows/python-app.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 4caa357..4148779 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -45,10 +45,10 @@ jobs: username: ${{ secrets.SERVER_USERNAME }} key: ${{ secrets.SERVER_SSH_KEY }} script: | - cd ~/tfinance + cd ~/TFinance git reset --hard origin/main git pull origin main source venv/bin/activate pip3 install -r requirements/prod.txt - cd ~/tfinance/tfinance + cd ~/TFinance/tfinance python3 main.py \ No newline at end of file From 0700f736e1f77f5ba941c9163a8694c355bdadd4 Mon Sep 17 00:00:00 2001 From: bzorn Date: Sat, 3 Aug 2024 11:51:19 +0300 Subject: [PATCH 10/33] . --- .github/workflows/python-app.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 4148779..bce17aa 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -51,4 +51,6 @@ jobs: source venv/bin/activate pip3 install -r requirements/prod.txt cd ~/TFinance/tfinance - python3 main.py \ No newline at end of file + python3 main.py + deactivate + cd ~ \ No newline at end of file From 75ed944c59085d4267f03f4500e6055528d9e9b5 Mon Sep 17 00:00:00 2001 From: bzorn Date: Sun, 4 Aug 2024 10:28:22 +0300 Subject: [PATCH 11/33] docker support --- .dockerignore | 2 ++ .github/workflows/python-app.yml | 10 +++------- Dockerfile | 12 ++++++++++++ docker-compose.yml | 12 ++++++++++++ tfinance/database.py | 3 ++- 5 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8a12fac --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +**/*.db +**/logs \ No newline at end of file diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index bce17aa..05ea390 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -46,11 +46,7 @@ jobs: key: ${{ secrets.SERVER_SSH_KEY }} script: | cd ~/TFinance - git reset --hard origin/main + git reset --hard origin/main git pull origin main - source venv/bin/activate - pip3 install -r requirements/prod.txt - cd ~/TFinance/tfinance - python3 main.py - deactivate - cd ~ \ No newline at end of file + docker compose down -v + docker compose up --build -d diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0c789ac --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.12.4-slim + +RUN apt update + +COPY ./requirements /requirements +RUN pip install -r requirements/prod.txt +RUN rm -rf requirements + +COPY ./tfinance /tfinance/ +WORKDIR /tfinance + +CMD ["python", "main.py"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c49ff7f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +name: "tfinance" + +services: + main_tfinance: + build: . + container_name: tfinance + env_file: + - ./.env + restart: always + volumes: + - ./for_docker/logs:/tfinance/logs + - ./for_docker/:/tfinance/data.db diff --git a/tfinance/database.py b/tfinance/database.py index e3c9998..7a6cf90 100644 --- a/tfinance/database.py +++ b/tfinance/database.py @@ -1,3 +1,4 @@ +import os import sqlite3 from models import User @@ -22,7 +23,7 @@ class Database: def __init__(self): # Подключение к БД с отключенной проверкой потока. - self.con = sqlite3.connect("data.db", check_same_thread=False) + self.con = sqlite3.connect(os.getcwd() + "data.db", check_same_thread=False) self.cur = self.con.cursor() self.setup() From 6d53478a62303d9012751b171d9c391c18667dcd Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 12 Aug 2024 11:40:57 +0300 Subject: [PATCH 12/33] updated docker files --- docker-compose.yml | 12 ------------ tfinance/database.py | 2 +- tfinance/main.py | 2 +- tfinance/stock.py | 4 ++-- 4 files changed, 4 insertions(+), 16 deletions(-) delete mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index c49ff7f..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: "tfinance" - -services: - main_tfinance: - build: . - container_name: tfinance - env_file: - - ./.env - restart: always - volumes: - - ./for_docker/logs:/tfinance/logs - - ./for_docker/:/tfinance/data.db diff --git a/tfinance/database.py b/tfinance/database.py index 7a6cf90..bc156cd 100644 --- a/tfinance/database.py +++ b/tfinance/database.py @@ -23,7 +23,7 @@ class Database: def __init__(self): # Подключение к БД с отключенной проверкой потока. - self.con = sqlite3.connect(os.getcwd() + "data.db", check_same_thread=False) + self.con = sqlite3.connect("data.db", check_same_thread=False) self.cur = self.con.cursor() self.setup() diff --git a/tfinance/main.py b/tfinance/main.py index 64ac859..535b0ae 100644 --- a/tfinance/main.py +++ b/tfinance/main.py @@ -33,7 +33,7 @@ # Запускаем логирование -logs_path = Path(f"{os.getcwd()}/logs") +logs_path = Path("logs") if not logs_path.exists(): logs_path.mkdir(exist_ok=True) logging.basicConfig( diff --git a/tfinance/stock.py b/tfinance/stock.py index a14d45e..c3849b9 100644 --- a/tfinance/stock.py +++ b/tfinance/stock.py @@ -14,7 +14,7 @@ # Загрузка списка всех акций. def load_stocks(file_name: str) -> list[dict[str, str]]: - path = Path(f"{Path.cwd()}/{file_name}") + path = Path(f"{file_name}") if path.exists(): with path.open() as f: return json.load(f) @@ -34,7 +34,7 @@ def check_stock(stock_name: str) -> bool: # Сохранение списка акций в json. def save_stocks(file_name: str, stocks: list): - with (Path.cwd() / file_name).open("w") as f: + with Path(file_name).open("w") as f: json.dump(stocks, f) From 0b52a5d6c38277c409300ed7cc21230eb855e500 Mon Sep 17 00:00:00 2001 From: bzorn Date: Tue, 4 Mar 2025 19:09:26 +0300 Subject: [PATCH 13/33] Update Docker config --- Dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0c789ac..d2af024 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,4 @@ -FROM python:3.12.4-slim - -RUN apt update +FROM python:3.13.2-slim COPY ./requirements /requirements RUN pip install -r requirements/prod.txt From 9c2a3495ce08d9e0bf798beb79b1c87d281bc612 Mon Sep 17 00:00:00 2001 From: bzorn Date: Fri, 7 Mar 2025 18:32:17 +0300 Subject: [PATCH 14/33] Update python image --- Dockerfile | 2 +- pyproject.toml | 3 --- requirements.txt | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index d2af024..a9b32d8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.13.2-slim +FROM python:3.13-alpine COPY ./requirements /requirements RUN pip install -r requirements/prod.txt diff --git a/pyproject.toml b/pyproject.toml index 276515c..99412c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,9 +4,6 @@ inline-quotes="double" import-order-style="google" extend-ignore = [ "R503", - "R502", - "F401", - "N802", ] exclude = [ ".git", diff --git a/requirements.txt b/requirements.txt index e6683f1..8cbc1e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,5 +3,4 @@ python-dotenv>=1.0.1 python-telegram-bot>=21.1.1 python-telegram-bot[job-queue] pytz>=2024.1 -requests>=2.31.0 yfinance>=0.2.38 \ No newline at end of file From 83b0e8d38664603c6ab48e707542a5e403c48567 Mon Sep 17 00:00:00 2001 From: bzorn Date: Fri, 7 Mar 2025 18:32:51 +0300 Subject: [PATCH 15/33] Moved some consts to config --- tfinance/config.py | 10 ++++++++++ tfinance/database.py | 1 - tfinance/main.py | 12 ++++-------- 3 files changed, 14 insertions(+), 9 deletions(-) create mode 100644 tfinance/config.py diff --git a/tfinance/config.py b/tfinance/config.py new file mode 100644 index 0000000..1e25b9d --- /dev/null +++ b/tfinance/config.py @@ -0,0 +1,10 @@ +import os + +import pytz +from dotenv import load_dotenv + +load_dotenv() + + +BOT_TOKEN = os.getenv("BOT_TOKEN") +TIMEZONE = pytz.timezone("Europe/Moscow") diff --git a/tfinance/database.py b/tfinance/database.py index bc156cd..e3c9998 100644 --- a/tfinance/database.py +++ b/tfinance/database.py @@ -1,4 +1,3 @@ -import os import sqlite3 from models import User diff --git a/tfinance/main.py b/tfinance/main.py index 535b0ae..510393b 100644 --- a/tfinance/main.py +++ b/tfinance/main.py @@ -3,12 +3,9 @@ # Встроенные библиотеки. import datetime import logging -import os from pathlib import Path import warnings -import pytz -from dotenv import load_dotenv from telegram import Update # Работа с telegram-bot-api. @@ -30,7 +27,7 @@ from game import game_menu, game_results, higher_game, lower_game from graphics.visualize import do_stock_image from stock import check_stock, get_all_stocks, load_stocks - +from tfinance.config import BOT_TOKEN, TIMEZONE # Запускаем логирование logs_path = Path("logs") @@ -192,28 +189,27 @@ async def stats(update: Update, _): def main(): - load_dotenv() # Получение и сохранение списка всех акций в stocks.json. try: get_all_stocks() except Exception as e: logging.error(e) - application = Application.builder().token(os.getenv("TOKEN")).build() + application = Application.builder().token(BOT_TOKEN).build() job_queue = application.job_queue job_queue.run_daily( notify_assignees, datetime.time( hour=8, - tzinfo=pytz.timezone("Europe/Moscow"), + tzinfo=TIMEZONE, ), ) job_queue.run_daily( game_results, datetime.time( hour=3, - tzinfo=pytz.timezone("Europe/Moscow"), + tzinfo=TIMEZONE, ), ) From e5b9e13e7b8fa881908506c95602258d530c3c3e Mon Sep 17 00:00:00 2001 From: bzorn Date: Fri, 7 Mar 2025 18:34:10 +0300 Subject: [PATCH 16/33] Add database name param --- tfinance/config.py | 2 ++ tfinance/database.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tfinance/config.py b/tfinance/config.py index 1e25b9d..a1a71f7 100644 --- a/tfinance/config.py +++ b/tfinance/config.py @@ -7,4 +7,6 @@ BOT_TOKEN = os.getenv("BOT_TOKEN") +DATABASE_NAME = os.getenv("DATABASE_NAME") + TIMEZONE = pytz.timezone("Europe/Moscow") diff --git a/tfinance/database.py b/tfinance/database.py index e3c9998..429589e 100644 --- a/tfinance/database.py +++ b/tfinance/database.py @@ -1,6 +1,7 @@ import sqlite3 from models import User +from tfinance.config import DATABASE_NAME def singleton(cls): @@ -22,7 +23,7 @@ class Database: def __init__(self): # Подключение к БД с отключенной проверкой потока. - self.con = sqlite3.connect("data.db", check_same_thread=False) + self.con = sqlite3.connect(f"{DATABASE_NAME}.db", check_same_thread=False) self.cur = self.con.cursor() self.setup() From 36762d5fcb789f86853383cd796cee8c63cfa7d4 Mon Sep 17 00:00:00 2001 From: bzorn Date: Fri, 7 Mar 2025 18:36:08 +0300 Subject: [PATCH 17/33] Add docker compose --- docker-compose.yml | 10 ++++++++++ tfinance/database.py | 2 ++ 2 files changed, 12 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..3ce0109 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +services: + tfinance_bot: + build: . + container_name: tfinance_bot + env_file: + - ./.env + restart: unless-stopped + volumes: + - ./etc_tfinance/logs:/tfinance/logs + - ./etc_tfinance/sqlite:/tfinance/sqlite diff --git a/tfinance/database.py b/tfinance/database.py index 429589e..e5c0c1f 100644 --- a/tfinance/database.py +++ b/tfinance/database.py @@ -1,4 +1,5 @@ import sqlite3 +from pathlib import Path from models import User from tfinance.config import DATABASE_NAME @@ -23,6 +24,7 @@ class Database: def __init__(self): # Подключение к БД с отключенной проверкой потока. + Path("sqlite").mkdir(exist_ok=True) self.con = sqlite3.connect(f"{DATABASE_NAME}.db", check_same_thread=False) self.cur = self.con.cursor() self.setup() From 6a5dd1899fb031edb8502c2efbe99992aff51c2b Mon Sep 17 00:00:00 2001 From: bzorn Date: Fri, 7 Mar 2025 18:37:57 +0300 Subject: [PATCH 18/33] Change jobs python image --- .github/workflows/python-app.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 05ea390..c5bdc65 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -12,7 +12,7 @@ permissions: jobs: black-test: runs-on: ubuntu-latest - container: python:3.11 + container: python:3.13-alpine steps: - uses: actions/checkout@v3 - name: Install dependencies @@ -22,7 +22,7 @@ jobs: flake8-test: runs-on: ubuntu-latest - container: python:3.11 + container: python:3.13-alpine steps: - uses: actions/checkout@v3 - name: Install dependencies From f0662a468f399bb83580f39882caca7e54a47e47 Mon Sep 17 00:00:00 2001 From: bzorn Date: Fri, 7 Mar 2025 18:43:34 +0300 Subject: [PATCH 19/33] Fix bugs --- .gitignore | 3 ++- tfinance/database.py | 4 ++-- tfinance/main.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 3e0e1cd..732e2c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /.idea logs -data.db +sqlite +*.db stocks.json .env \ No newline at end of file diff --git a/tfinance/database.py b/tfinance/database.py index e5c0c1f..2748d0a 100644 --- a/tfinance/database.py +++ b/tfinance/database.py @@ -2,7 +2,7 @@ from pathlib import Path from models import User -from tfinance.config import DATABASE_NAME +from config import DATABASE_NAME def singleton(cls): @@ -25,7 +25,7 @@ class Database: def __init__(self): # Подключение к БД с отключенной проверкой потока. Path("sqlite").mkdir(exist_ok=True) - self.con = sqlite3.connect(f"{DATABASE_NAME}.db", check_same_thread=False) + self.con = sqlite3.connect(f"sqlite/{DATABASE_NAME}.db", check_same_thread=False) self.cur = self.con.cursor() self.setup() diff --git a/tfinance/main.py b/tfinance/main.py index 510393b..6c9d669 100644 --- a/tfinance/main.py +++ b/tfinance/main.py @@ -27,7 +27,7 @@ from game import game_menu, game_results, higher_game, lower_game from graphics.visualize import do_stock_image from stock import check_stock, get_all_stocks, load_stocks -from tfinance.config import BOT_TOKEN, TIMEZONE +from config import BOT_TOKEN, TIMEZONE # Запускаем логирование logs_path = Path("logs") From e0015f4ea98b0bcb2f18dbee7fdb03d98ce4a889 Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 14 Apr 2025 11:36:07 +0300 Subject: [PATCH 20/33] add .env.example --- .env.example | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..7dd18cb --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +BOT_TOKEN=your_telegram_bot_token +DATABASE_NAME=database \ No newline at end of file From f115e5a1e5cfe2e34f331ff2146b168943358cc7 Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 13:16:39 +0300 Subject: [PATCH 21/33] refactor: replace pytz with zoneinfo for timezone handling --- requirements.txt | 1 - tfinance/config.py | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8cbc1e9..e4ba589 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,5 +2,4 @@ matplotlib>=3.5.3 python-dotenv>=1.0.1 python-telegram-bot>=21.1.1 python-telegram-bot[job-queue] -pytz>=2024.1 yfinance>=0.2.38 \ No newline at end of file diff --git a/tfinance/config.py b/tfinance/config.py index a1a71f7..da9b843 100644 --- a/tfinance/config.py +++ b/tfinance/config.py @@ -1,6 +1,6 @@ import os +from zoneinfo import ZoneInfo -import pytz from dotenv import load_dotenv load_dotenv() @@ -9,4 +9,4 @@ BOT_TOKEN = os.getenv("BOT_TOKEN") DATABASE_NAME = os.getenv("DATABASE_NAME") -TIMEZONE = pytz.timezone("Europe/Moscow") +TIMEZONE = ZoneInfo("Europe/Moscow") From b6ac85dc6be77041b1b73e6c8d6b13da2284c351 Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 13:34:14 +0300 Subject: [PATCH 22/33] chore: replace CMD with ENTRYPOINT in Dockerfile & add --no-cache-dir to pip --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index a9b32d8..6c25353 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ FROM python:3.13-alpine COPY ./requirements /requirements -RUN pip install -r requirements/prod.txt +RUN pip install --no-cache-dir -r requirements/prod.txt RUN rm -rf requirements COPY ./tfinance /tfinance/ WORKDIR /tfinance -CMD ["python", "main.py"] \ No newline at end of file +ENTRYPOINT ["python", "main.py"] \ No newline at end of file From f5bcf7eb6bbab6249c83edf325cad3ee13c5d081 Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 13:34:56 +0300 Subject: [PATCH 23/33] feat: save logs to file with timestamp in logs folder --- tfinance/main.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tfinance/main.py b/tfinance/main.py index 6c9d669..57c9f9d 100644 --- a/tfinance/main.py +++ b/tfinance/main.py @@ -4,7 +4,6 @@ import datetime import logging from pathlib import Path -import warnings from telegram import Update @@ -30,19 +29,21 @@ from config import BOT_TOKEN, TIMEZONE # Запускаем логирование -logs_path = Path("logs") -if not logs_path.exists(): - logs_path.mkdir(exist_ok=True) +Path("logs").mkdir(exist_ok=True) logging.basicConfig( format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.WARNING, - filename=f"{logs_path}/tfinance_main.log", + handlers=[ + logging.FileHandler( + datetime.datetime.now(tz=TIMEZONE).strftime("logs/%Y-%m-%d_%H-%M-%S.log"), + encoding="utf-8", + ), + logging.StreamHandler(), + ], ) +logging.getLogger("httpx").setLevel(logging.WARNING) logger = logging.getLogger(__name__) -# Отключаем предупреждения пользователей библиотек -warnings.simplefilter("ignore") - # Получение списка необходимых акций по команде /stocks [args]. # Обработчик команды /stocks. From 051710a20f7369c6b2626e9b8018c2074989324f Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 13:37:12 +0300 Subject: [PATCH 24/33] style: fix PEP8 violations in code formatting --- tfinance/database.py | 3 ++- tfinance/stock.py | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tfinance/database.py b/tfinance/database.py index 2748d0a..6ee0725 100644 --- a/tfinance/database.py +++ b/tfinance/database.py @@ -168,7 +168,7 @@ def select_stock(self, user: User, stock_name: str): ) self.con.commit() - def get_selected_stock_byid(self, user: User, message_id) -> str: + def get_selected_stock_byid(self, user: User, message_id) -> str | None: """ Получить название акции по id сообщения с игрой. :param user: Экземпляр класса User с данными об этом пользователе. @@ -182,6 +182,7 @@ def get_selected_stock_byid(self, user: User, message_id) -> str: for i in data.split(): if str(message_id) == i.split(":")[-1]: return i.split(":")[0] + return None def get_selected_stocks(self, user: User) -> list: """ diff --git a/tfinance/stock.py b/tfinance/stock.py index c3849b9..de8cd2d 100644 --- a/tfinance/stock.py +++ b/tfinance/stock.py @@ -25,8 +25,7 @@ def load_stocks(file_name: str) -> list[dict[str, str]]: def check_stock(stock_name: str) -> bool: try: stock = yf.download(stock_name, period="1mo") - if stock["Close"][-2]: - return True + return bool(stock["Close"][-2]) except Exception as e: logging.exception(e) return False From ec82f37a40f93b5458255161c3baf5acc52522d1 Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 13:38:12 +0300 Subject: [PATCH 25/33] feat: add flake8-encodings & flake8-eradicate for testing --- requirements/test.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements/test.txt b/requirements/test.txt index 25ee9fe..7bcb324 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -1,6 +1,8 @@ flake8>=6.1.0 flake8-commas>=2.1.0 flake8-comments>=0.1.2 +flake8-encodings>=0.5.1 +flake8-eradicate>=1.5.0 flake8-print>=5.0.0 Flake8-pyproject>=1.2.3 flake8-quotes>=3.3.2 From 0f2b1e465903cf194a4ac6a256f234b9b337092c Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 13:39:03 +0300 Subject: [PATCH 26/33] build: remove unnecessary dependencies from requirements.txt --- requirements.txt | 1 + requirements/prod.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e4ba589..04a9c77 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ matplotlib>=3.5.3 python-dotenv>=1.0.1 python-telegram-bot>=21.1.1 python-telegram-bot[job-queue] +requests>=2.31.0 yfinance>=0.2.38 \ No newline at end of file diff --git a/requirements/prod.txt b/requirements/prod.txt index e6683f1..04a9c77 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -2,6 +2,5 @@ matplotlib>=3.5.3 python-dotenv>=1.0.1 python-telegram-bot>=21.1.1 python-telegram-bot[job-queue] -pytz>=2024.1 requests>=2.31.0 yfinance>=0.2.38 \ No newline at end of file From 123b3b171e881725528a7ffeebe75c632ba7744d Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 13:50:48 +0300 Subject: [PATCH 27/33] fix: change logging level to INFO --- tfinance/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tfinance/main.py b/tfinance/main.py index 57c9f9d..48dcc5f 100644 --- a/tfinance/main.py +++ b/tfinance/main.py @@ -32,7 +32,7 @@ Path("logs").mkdir(exist_ok=True) logging.basicConfig( format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", - level=logging.WARNING, + level=logging.INFO, handlers=[ logging.FileHandler( datetime.datetime.now(tz=TIMEZONE).strftime("logs/%Y-%m-%d_%H-%M-%S.log"), From 5436e455c214e83c6e8cf0b00948cbb6221d3876 Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 19:17:04 +0300 Subject: [PATCH 28/33] style: wrap lines to 79 characters to comply with PEP8 --- pyproject.toml | 8 ++------ tfinance/blast.py | 3 ++- tfinance/database.py | 24 +++++++++++++++++------- tfinance/game.py | 15 +++++++++++---- tfinance/graphics/visualize.py | 9 ++++++--- tfinance/main.py | 10 +++++++--- tfinance/stock.py | 7 ++++++- 7 files changed, 51 insertions(+), 25 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 99412c2..7bdbcf3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,16 +1,12 @@ [tool.flake8] -max-line-length = 89 +max-line-length = 79 inline-quotes="double" import-order-style="google" -extend-ignore = [ - "R503", -] exclude = [ ".git", "__pycache__", - "docs/source/conf.py", "venv", ] [tool.black] -line-length = 89 \ No newline at end of file +line-length = 79 \ No newline at end of file diff --git a/tfinance/blast.py b/tfinance/blast.py index 14db945..c1dfc58 100644 --- a/tfinance/blast.py +++ b/tfinance/blast.py @@ -11,7 +11,8 @@ async def notify_assignees(context: CallbackContext): db = Database() - # Перебираем всех пользователей и рассылаем каждому курсы их избранных акций. + # Перебираем всех пользователей и + # рассылаем каждому курсы их избранных акций. for user in db.get_users(): if db.check_user_daily_notify(user): if user.favourite_stocks: diff --git a/tfinance/database.py b/tfinance/database.py index 6ee0725..2f55a7d 100644 --- a/tfinance/database.py +++ b/tfinance/database.py @@ -25,7 +25,10 @@ class Database: def __init__(self): # Подключение к БД с отключенной проверкой потока. Path("sqlite").mkdir(exist_ok=True) - self.con = sqlite3.connect(f"sqlite/{DATABASE_NAME}.db", check_same_thread=False) + self.con = sqlite3.connect( + f"sqlite/{DATABASE_NAME}.db", + check_same_thread=False, + ) self.cur = self.con.cursor() self.setup() @@ -114,7 +117,8 @@ def add_prediction(self, user: User, stock_name: str, updown: str): if predictions[0]: prediction = f"{predictions[0]} {prediction}" self.cur.execute( - f"UPDATE users SET prediction = ' {prediction}' WHERE id = {user.id}", + f"UPDATE users SET prediction = ' {prediction}' " + f"WHERE id = {user.id}", ) self.con.commit() @@ -148,7 +152,9 @@ def delete_predictions(self, user: User): :param user: Экземпляр класса User с данными об этом пользователе. :return: None """ - self.cur.execute(f"UPDATE users SET prediction = '' WHERE id = {user.id}") + self.cur.execute( + f"UPDATE users SET prediction = '' WHERE id = {user.id}", + ) self.con.commit() def select_stock(self, user: User, stock_name: str): @@ -164,7 +170,8 @@ def select_stock(self, user: User, stock_name: str): if selected_stocks: stock_name = f"{selected_stocks} {stock_name}" self.cur.execute( - f"UPDATE users SET selected_stock = '{stock_name}' WHERE id = {user.id}", + f"UPDATE users SET selected_stock = '{stock_name}' " + f"WHERE id = {user.id}", ) self.con.commit() @@ -257,7 +264,8 @@ def add_favourites_stocks(self, user: User, stock_name: str): if stocks and stocks[0]: stock_name = f"{stocks[0]} {stock_name}" self.cur.execute( - f"UPDATE users SET favourites_stocks = '{stock_name}' WHERE id = {user.id}", + f"UPDATE users SET favourites_stocks = '{stock_name}' " + f"WHERE id = {user.id}", ) self.con.commit() @@ -303,7 +311,8 @@ def remove_favourites_stock(self, user: User, stock_name: str): else: a = f"'{' '.join(a)}'" self.cur.execute( - f"UPDATE users SET favourites_stocks = {a} WHERE id = {user.id}", + f"UPDATE users SET favourites_stocks = {a} " + f"WHERE id = {user.id}", ) self.con.commit() @@ -314,7 +323,8 @@ def user_daily_notify(self, user: User): :return: None """ self.cur.execute( - f"UPDATE users SET daily_notify = NOT daily_notify WHERE id = {user.id}", + f"UPDATE users SET daily_notify = NOT daily_notify " + f"WHERE id = {user.id}", ) self.con.commit() diff --git a/tfinance/game.py b/tfinance/game.py index 926e9d5..c5a96fc 100644 --- a/tfinance/game.py +++ b/tfinance/game.py @@ -2,7 +2,11 @@ from telegram.ext import ContextTypes, CallbackContext from database import Database -from exceptions import EmptyDataFrameError, PredictionAlreadySet, StockSelectedAlready +from exceptions import ( + EmptyDataFrameError, + PredictionAlreadySet, + StockSelectedAlready, +) from functions import create_user from graphics.visualize import check_stock_prices, do_stock_image from models import User @@ -17,12 +21,14 @@ async def game_menu(update: Update, context: ContextTypes.DEFAULT_TYPE): # Сохраняем id сообщения для возможности одновременной message_id = str(int(update.message.message_id) + 2) # Игры на многих акциях. - # Прибавляем 2 т.к. отправляем 2 сообщения: фото и приписку к нему с клавиатурой. + # Прибавляем 2 т.к. отправляем 2 сообщения: + # фото и приписку к нему с клавиатурой. try: # Проверка на наличие аргументов. if not context.args: await update.message.reply_text( - "Неправильно введена команда! Попробуйте: /game [индекс акции]", + "Неправильно введена команда! " + "Попробуйте: /game [индекс акции]", ) # Проверка: была ли выбрана акция до этого? Избегаем читерства. if db.check_selected_stocks(user): @@ -80,7 +86,8 @@ async def game_menu(update: Update, context: ContextTypes.DEFAULT_TYPE): ) db.remove_selected_stock(user, message_id) - # Возвращаем 1, чтобы показать ConversationHandler'у состояние, в котором находимся. + # Возвращаем 1, чтобы показать ConversationHandler'у состояние, + # в котором находимся. return 1 diff --git a/tfinance/graphics/visualize.py b/tfinance/graphics/visualize.py index d76e988..b4a5808 100644 --- a/tfinance/graphics/visualize.py +++ b/tfinance/graphics/visualize.py @@ -5,7 +5,7 @@ from exceptions import EmptyDataFrameError, WrongPeriodError -time_periods = { +TIME_PERIODS = { "1d": "за 1 день", "5d": "за 5 дней", "1mo": "за 1 месяц", @@ -27,7 +27,7 @@ def do_stock_image(stock_name, period="1mo"): :param period: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max :return: Картинка в байтовом формате. """ - if period not in time_periods: + if period not in TIME_PERIODS: raise WrongPeriodError # Забираем данные из Yahoo Finance. stock = yf.download(stock_name, period=period) @@ -38,7 +38,10 @@ def do_stock_image(stock_name, period="1mo"): # Создаем полотно с графиком. stock["Close"].plot(grid=True) - plt.title(f"Курс акции {stock_name} {time_periods.get(period)}", fontsize=14) + plt.title( + f"Курс акции {stock_name} {TIME_PERIODS.get(period)}", + fontsize=14, + ) plt.gca().set(ylabel="Price USD") # Записываем полученный график в байты и возвращаем полученное изображение. diff --git a/tfinance/main.py b/tfinance/main.py index 48dcc5f..cbef748 100644 --- a/tfinance/main.py +++ b/tfinance/main.py @@ -35,7 +35,9 @@ level=logging.INFO, handlers=[ logging.FileHandler( - datetime.datetime.now(tz=TIMEZONE).strftime("logs/%Y-%m-%d_%H-%M-%S.log"), + datetime.datetime.now( + tz=TIMEZONE, + ).strftime("logs/%Y-%m-%d_%H-%M-%S.log"), encoding="utf-8", ), logging.StreamHandler(), @@ -84,7 +86,8 @@ async def get_stock_image(update: Update, context: ContextTypes.DEFAULT_TYPE): ) except WrongPeriodError: await update.message.reply_text( - "Неверный период. Доступные периоды: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max", + "Неверный период. " + "Доступные периоды: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max", ) except EmptyDataFrameError: await update.message.reply_text( @@ -150,7 +153,8 @@ async def follow(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text("Акция не найдена") else: await update.message.reply_text( - "Неверный способ ввода. /follow [индекс акции]. Например: /follow AAPL", + "Неверный способ ввода. " + "/follow [индекс акции]. Например: /follow AAPL", ) diff --git a/tfinance/stock.py b/tfinance/stock.py index de8cd2d..e40bb8f 100644 --- a/tfinance/stock.py +++ b/tfinance/stock.py @@ -53,5 +53,10 @@ def get_all_stocks(): .get("table") .get("rows") ) - stocks = [{"symbol": i.get("symbol"), "name": i.get("name")} for i in stocks] + stocks = [ + { + "symbol": i.get("symbol"), + "name": i.get("name"), + } for i in stocks + ] save_stocks("stocks.json", stocks) From eb5433236a911182bbcde59dc39a4409eead1790 Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 19:21:10 +0300 Subject: [PATCH 29/33] refactor: move game_handler to game.py --- tfinance/game.py | 26 ++++++++++++++++++++++++-- tfinance/main.py | 18 +++--------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/tfinance/game.py b/tfinance/game.py index c5a96fc..42c122c 100644 --- a/tfinance/game.py +++ b/tfinance/game.py @@ -1,5 +1,15 @@ -from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update -from telegram.ext import ContextTypes, CallbackContext +from telegram import ( + InlineKeyboardButton, + InlineKeyboardMarkup, + Update, +) +from telegram.ext import ( + ContextTypes, + CallbackContext, + ConversationHandler, + CommandHandler, + CallbackQueryHandler, +) from database import Database from exceptions import ( @@ -201,3 +211,15 @@ async def game_results(context: CallbackContext): # Удаляем пройденные прогнозы db.delete_predictions(user) user.prediction = db.get_predictions(user) + + +game_handler = ConversationHandler( + entry_points=[CommandHandler("game", game_menu)], + states={ + 1: [ + CallbackQueryHandler(higher_game, pattern="^1$"), + CallbackQueryHandler(lower_game, pattern="^2$"), + ], + }, + fallbacks=[CommandHandler("game", game_menu)], +) diff --git a/tfinance/main.py b/tfinance/main.py index cbef748..ae03e77 100644 --- a/tfinance/main.py +++ b/tfinance/main.py @@ -1,5 +1,5 @@ -# -------------------------- Основной файл приложения -------------------------- # -# --------------- Импорт необходимых библиотек, функций, классов --------------- # +# ------------------------ Основной файл приложения ------------------------ # +# ------------- Импорт необходимых библиотек, функций, классов ------------- # # Встроенные библиотеки. import datetime import logging @@ -9,9 +9,7 @@ # Работа с telegram-bot-api. from telegram.ext import ( - CallbackQueryHandler, CommandHandler, - ConversationHandler, Application, ContextTypes, ) @@ -23,7 +21,7 @@ from database import Database from exceptions import EmptyDataFrameError, WrongPeriodError from functions import create_user -from game import game_menu, game_results, higher_game, lower_game +from game import game_handler, game_results from graphics.visualize import do_stock_image from stock import check_stock, get_all_stocks, load_stocks from config import BOT_TOKEN, TIMEZONE @@ -218,16 +216,6 @@ def main(): ), ) - game_handler = ConversationHandler( - entry_points=[CommandHandler("game", game_menu)], - states={ - 1: [ - CallbackQueryHandler(higher_game, pattern="^1$"), - CallbackQueryHandler(lower_game, pattern="^2$"), - ], - }, - fallbacks=[CommandHandler("game", game_menu)], - ) application.add_handler(game_handler) application.add_handler(CommandHandler("daily", daily)) From 390412470dfadb9d6cd6b77853cb9fa66568fd40 Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 19:22:52 +0300 Subject: [PATCH 30/33] chore: add __all__ for explicit module exports --- tfinance/blast.py | 6 ++++++ tfinance/database.py | 5 +++++ tfinance/exceptions.py | 8 ++++++++ tfinance/functions.py | 5 +++++ tfinance/game.py | 6 ++++++ tfinance/graphics/visualize.py | 6 ++++++ tfinance/main.py | 2 ++ tfinance/models.py | 5 +++++ tfinance/stock.py | 7 +++++++ 9 files changed, 50 insertions(+) diff --git a/tfinance/blast.py b/tfinance/blast.py index c1dfc58..42a1cbd 100644 --- a/tfinance/blast.py +++ b/tfinance/blast.py @@ -36,3 +36,9 @@ async def daily(update: Update, _): else: await update.message.reply_text("Ежедневная рассылка включена") db.user_daily_notify(user) + + +__all__ = [ + "daily", + "notify_assignees", +] diff --git a/tfinance/database.py b/tfinance/database.py index 2f55a7d..ac22a7a 100644 --- a/tfinance/database.py +++ b/tfinance/database.py @@ -353,3 +353,8 @@ def add_point(self, user: User): ) user.points += 1 self.con.commit() + + +__all__ = [ + "Database", +] diff --git a/tfinance/exceptions.py b/tfinance/exceptions.py index 186abcc..74ae891 100644 --- a/tfinance/exceptions.py +++ b/tfinance/exceptions.py @@ -14,3 +14,11 @@ class EmptyDataFrameError(Exception): # Пустой дата фрейм class WrongPeriodError(Exception): # Неверный период pass + + +__all__ = [ + "StockSelectedAlready", + "PredictionAlreadySet", + "EmptyDataFrameError", + "WrongPeriodError", +] diff --git a/tfinance/functions.py b/tfinance/functions.py index cc77e8a..b5b751c 100644 --- a/tfinance/functions.py +++ b/tfinance/functions.py @@ -13,3 +13,8 @@ def create_user(update: Update) -> User: user_data["language_code"], user_data["is_bot"], ) + + +__all__ = [ + "create_user", +] diff --git a/tfinance/game.py b/tfinance/game.py index 42c122c..c683c93 100644 --- a/tfinance/game.py +++ b/tfinance/game.py @@ -223,3 +223,9 @@ async def game_results(context: CallbackContext): }, fallbacks=[CommandHandler("game", game_menu)], ) + + +__all__ = [ + "game_handler", + "game_results", +] diff --git a/tfinance/graphics/visualize.py b/tfinance/graphics/visualize.py index b4a5808..dc87888 100644 --- a/tfinance/graphics/visualize.py +++ b/tfinance/graphics/visualize.py @@ -63,3 +63,9 @@ def check_stock_prices(stock_name) -> bool: curr_price = stock["Close"][-1] return curr_price > prev_price + + +__all__ = [ + "check_stock_prices", + "do_stock_image", +] diff --git a/tfinance/main.py b/tfinance/main.py index ae03e77..71219f8 100644 --- a/tfinance/main.py +++ b/tfinance/main.py @@ -26,6 +26,8 @@ from stock import check_stock, get_all_stocks, load_stocks from config import BOT_TOKEN, TIMEZONE +__all__ = [] + # Запускаем логирование Path("logs").mkdir(exist_ok=True) logging.basicConfig( diff --git a/tfinance/models.py b/tfinance/models.py index a60b081..1fb3ef0 100644 --- a/tfinance/models.py +++ b/tfinance/models.py @@ -21,3 +21,8 @@ def __init__( self.prediction = prediction self.selected_stock = selected_stock self.points: int = 0 + + +__all__ = [ + "User", +] diff --git a/tfinance/stock.py b/tfinance/stock.py index e40bb8f..63d3596 100644 --- a/tfinance/stock.py +++ b/tfinance/stock.py @@ -60,3 +60,10 @@ def get_all_stocks(): } for i in stocks ] save_stocks("stocks.json", stocks) + + +__all__ = [ + "check_stock", + "get_all_stocks", + "load_stocks", +] From f2bc14aaa20a74f920166b59b1553ca8cc318322 Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 19:25:30 +0300 Subject: [PATCH 31/33] style: move 'for' to a new line in comprehension for PEP8 compliance --- tfinance/stock.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tfinance/stock.py b/tfinance/stock.py index 63d3596..b6ddc9f 100644 --- a/tfinance/stock.py +++ b/tfinance/stock.py @@ -57,7 +57,8 @@ def get_all_stocks(): { "symbol": i.get("symbol"), "name": i.get("name"), - } for i in stocks + } + for i in stocks ] save_stocks("stocks.json", stocks) From 0f57c22f3fcfa3160b823c2936c83844df1335c0 Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 19:27:09 +0300 Subject: [PATCH 32/33] build: add flake8-all-not-strings and flake8-dunder-all plugins --- requirements/test.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements/test.txt b/requirements/test.txt index 7bcb324..85a115b 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -1,6 +1,8 @@ flake8>=6.1.0 +flake8-all-not-strings>=0.0.2 flake8-commas>=2.1.0 flake8-comments>=0.1.2 +flake8-dunder-all>=0.4.1 flake8-encodings>=0.5.1 flake8-eradicate>=1.5.0 flake8-print>=5.0.0 From 9792e7fd1bc0706e6d26233d063b2593663d9c4f Mon Sep 17 00:00:00 2001 From: bzorn Date: Mon, 5 May 2025 19:27:54 +0300 Subject: [PATCH 33/33] docs: fix typos in README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6eb4225..1b3d400 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ Проект: Telegram bot TFinace TFinance - телеграм бот, позволяющий получить доступ к курсу -акций. На понравившиеся вам акции вы можете подписаться и включить ежедненую -рассылку их курса. Также вы можете попытать удачу и сыграть в игру, предугодав +акций. На понравившиеся вам акции вы можете подписаться и включить ежедневную +рассылку их курса. Также вы можете попытать удачу и сыграть в игру, предугадав будущий курс, в случае удачи вы заработаете 1 очко в криптоигре.

Задачи, которые мы выполнили:

@@ -23,7 +23,7 @@ TFinance - телеграм бот, позволяющий получить до
  • Использовали команду /unfollow для отписки от акции.
  • Использовали команду /stock для вывода курса акции.
  • Использовали команду /stocks для вывода акций с биржи.
  • -
  • Использовали команду /daily для подписки на ежедненую расслылку курсов +
  • Использовали команду /daily для подписки на ежедневную рассылку курсов избранных акций.
  • Получение списка акций с биржи с помощью http-запросов.