diff --git a/app/core/bot.py b/app/core/bot.py
index 9a0d0b9..0af69a5 100644
--- a/app/core/bot.py
+++ b/app/core/bot.py
@@ -4,7 +4,7 @@ from aiogram import Bot, types
from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram.dispatcher import Dispatcher
from aiogram.utils.callback_data import CallbackData
-from app.core.parse_web import get_driver, get_ttl_hash, parse_site
+from app.core.parse_web import get_driver, parse_site
from app.settings import TELEGRAM_API_TOKEN
bot = Bot(token=TELEGRAM_API_TOKEN)
@@ -36,7 +36,7 @@ def get_keyboard() -> types.InlineKeyboardMarkup:
async def home_office(
query: types.CallbackQuery, callback_data: dict[str, str]
) -> types.Message:
- driver = get_driver(ttl_hash=get_ttl_hash(seconds=10))
+ driver = get_driver()
text = parse_site(
driver=driver,
url='https://yandex.ru/maps/213/moscow/stops/stop__9640740/'
@@ -53,7 +53,7 @@ async def home_office(
async def office_home(
query: types.CallbackQuery, callback_data: dict[str, str]
) -> types.Message:
- driver = get_driver(ttl_hash=get_ttl_hash())
+ driver = get_driver()
text = parse_site(
driver=driver,
url='https://yandex.ru/maps/213/moscow/stops/stop__9640288/?'
@@ -79,7 +79,7 @@ async def echo(message: types.Message) -> types.Message:
async def morning_bus_mailing(chat_ids: list[int]) -> None:
- driver = get_driver(ttl_hash=get_ttl_hash())
+ driver = get_driver()
text = parse_site(
driver=driver,
url='https://yandex.ru/maps/213/moscow/stops/stop__9640740/'
diff --git a/app/core/logger.py b/app/core/logger.py
deleted file mode 100644
index 0e741d2..0000000
--- a/app/core/logger.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import sys
-
-from loguru import logger
-
-logger.remove()
-logger.add(
- sink=sys.stdout,
- colorize=True,
- level='DEBUG',
- format="{time:DD.MM.YYYY HH:mm:ss} | {level} | {message}",
-)
diff --git a/app/core/parse_web.py b/app/core/parse_web.py
index c65c337..4969582 100644
--- a/app/core/parse_web.py
+++ b/app/core/parse_web.py
@@ -1,12 +1,11 @@
import os
import tarfile
import time
-from functools import lru_cache
from pathlib import Path
import wget
-from app.core.logger import logger
-from app.settings import BASE_DIR, GECKO_DRIVER_VERSION
+from app.core.utils import logger, timed_cache
+from app.settings import BASE_DIR, DRIVER_SESSION_TTL, GECKO_DRIVER_VERSION
from selenium import webdriver
from selenium.common.exceptions import (
NoSuchElementException,
@@ -93,14 +92,8 @@ def parse_site(url: str, message: str, driver: RemoteWebDriver | None = None) ->
return answer
-def get_ttl_hash(seconds: int = 28) -> int:
- """Return the same value withing `seconds` time period"""
- return round(time.time() / seconds)
-
-
-@lru_cache
-def get_driver(ttl_hash: int | None = None) -> RemoteWebDriver:
- del ttl_hash
+@timed_cache(seconds=DRIVER_SESSION_TTL)
+def get_driver() -> RemoteWebDriver:
opt = options.Options()
opt.headless = True
driver = RemoteWebDriver(
diff --git a/app/core/utils.py b/app/core/utils.py
new file mode 100644
index 0000000..6f23475
--- /dev/null
+++ b/app/core/utils.py
@@ -0,0 +1,35 @@
+import sys
+from datetime import datetime, timedelta
+from functools import lru_cache, wraps
+from typing import Any
+
+from loguru import logger
+
+logger.remove()
+logger.add(
+ sink=sys.stdout,
+ colorize=True,
+ level='DEBUG',
+ format="{time:DD.MM.YYYY HH:mm:ss} | {level} | {message}",
+)
+
+
+def timed_cache(**timedelta_kwargs: Any) -> Any:
+ def _wrapper(func: Any) -> Any:
+ update_delta = timedelta(**timedelta_kwargs)
+ next_update = datetime.utcnow() + update_delta
+ # Apply @lru_cache to f with no cache size limit
+ cached_func = lru_cache(None)(func)
+
+ @wraps(func)
+ def _wrapped(*args: Any, **kwargs: Any) -> Any:
+ nonlocal next_update
+ now = datetime.utcnow()
+ if now >= next_update:
+ cached_func.cache_clear()
+ next_update = now + update_delta
+ return cached_func(*args, **kwargs)
+
+ return _wrapped
+
+ return _wrapper
diff --git a/app/main.py b/app/main.py
index 3d29cd0..5b3568f 100644
--- a/app/main.py
+++ b/app/main.py
@@ -11,8 +11,8 @@ from aiohttp import web
sys.path.append(str(Path(__file__).parent.parent))
from app.core.bot import bot, dispatcher
-from app.core.logger import logger
from app.core.scheduler import asyncio_schedule
+from app.core.utils import logger
from app.settings import (
START_WITH_WEBHOOK,
TELEGRAM_API_TOKEN,
@@ -88,7 +88,7 @@ async def get_updates_from_queue() -> None:
async def create_app() -> web.Application:
application = web.Application()
- application.router.add_get('/', health_check)
+ application.router.add_get(f'{WEBHOOK_PATH}/', health_check)
application.router.add_post(
f'{WEBHOOK_PATH}/{TELEGRAM_API_TOKEN}', put_updates_on_queue
)
diff --git a/app/settings.py b/app/settings.py
index a7d1314..ac17604 100644
--- a/app/settings.py
+++ b/app/settings.py
@@ -29,3 +29,5 @@ WEBAPP_HOST = config('WEBAPP_HOST', default='127.0.0.1') # or ip
WEBAPP_PORT = config('WEBAPP_PORT', cast=int, default=8084)
START_WITH_WEBHOOK = config('START_WITH_WEBHOOK', cast=bool, default=False)
+
+DRIVER_SESSION_TTL = 28 # driver cache ttl session in seconds
diff --git a/deploy/Caddyfile b/deploy/Caddyfile
index d275063..faaa223 100644
--- a/deploy/Caddyfile
+++ b/deploy/Caddyfile
@@ -4,7 +4,7 @@
# Removing some headers for improved security:
header -Server
- route /transport/{$TELEGRAM_API_TOKEN} {
+ route /transport/* {
reverse_proxy transport_bot:8084
}
}
diff --git a/docker-compose.yml b/docker-compose.yml
index 1d009ee..0422567 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -24,13 +24,16 @@ services:
args:
USER: web
restart: unless-stopped
+ environment:
+ - SESSION_TIMED_OUT=30s
networks:
transport_bot_network:
ipv4_address: 200.20.0.10
volumes:
- ./deploy/browsers.json:/etc/selenoid/browsers.json:ro
- /var/run/docker.sock:/var/run/docker.sock
- command: ["-conf", "/etc/selenoid/browsers.json", "-limit", "10", "-container-network", "transport_bot_network"]
+ command: ["-conf", "/etc/selenoid/browsers.json", "-limit", "10",
+ "-container-network", "transport_bot_network", "-timeout", "30s"]
expose:
- "4444"