diff --git a/requirements.txt b/requirements.txt index 2cc9e028..b3702f3d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,5 +22,6 @@ Unidecode==1.0.22 ua-parser==0.8.0 user-agents==1.1.0 sorl-thumbnail==12.5.0 +python-telegram-bot==11.1.0 https://github.com/selwin/django-user_agents/archive/master.zip https://github.com/fidals/refarm-site/archive/0.4.27.zip diff --git a/shopelectro/report.py b/shopelectro/report.py new file mode 100644 index 00000000..cbe994e3 --- /dev/null +++ b/shopelectro/report.py @@ -0,0 +1,12 @@ +from django.conf import settings +from telegram import Bot + + +class TelegramReport: + + def __init__(self): + self.bot = Bot(settings.TG_BOT_TOKEN) + + def send(self, text: str): + for id in settings.TG_REPORT_ADDRESSEES: + self.bot.send_message(id, text) diff --git a/shopelectro/selenium/__init__.py b/shopelectro/selenium/__init__.py index db437b54..9bfee511 100644 --- a/shopelectro/selenium/__init__.py +++ b/shopelectro/selenium/__init__.py @@ -13,4 +13,4 @@ """ from .driver import SiteDriver -from .pages import CategoryPage, OrderPage +from .pages import CategoryPage, OrderPage, SuccessPage diff --git a/shopelectro/selenium/pages/__init__.py b/shopelectro/selenium/pages/__init__.py index dde4439c..c3812923 100644 --- a/shopelectro/selenium/pages/__init__.py +++ b/shopelectro/selenium/pages/__init__.py @@ -2,3 +2,4 @@ from .category import CategoryPage from .order import OrderPage +from .success import SuccessPage diff --git a/shopelectro/selenium/pages/success.py b/shopelectro/selenium/pages/success.py new file mode 100644 index 00000000..1e3c1781 --- /dev/null +++ b/shopelectro/selenium/pages/success.py @@ -0,0 +1,13 @@ +from shopelectro.selenium.pages import Page + +from pages.models import CustomPage + + +class SuccessPage(Page): + + @property + def path(self): + CustomPage.objects.get(slug='order-success').url + + def is_success(self): + return 'Заказ принят' in self.driver.find_element_by_tag_name('h1').text diff --git a/shopelectro/settings/base.py b/shopelectro/settings/base.py index ff07abde..e204f113 100644 --- a/shopelectro/settings/base.py +++ b/shopelectro/settings/base.py @@ -501,3 +501,9 @@ def get_robots_content(): PRODUCTS_ON_PAGE_PC = 48 PRODUCTS_ON_PAGE_MOB = 12 + +TG_BOT_TOKEN = os.environ.get('TG_BOT_TOKEN') +TG_REPORT_ADDRESSEES = os.environ.get( + 'TG_REPORT_ADDRESSEES', '@shopelectro_reports' +).split(',') +CHECK_PURCHASE_RETRIES = int(os.environ.get('CHECK_PURCHASE_RETRIES', '3')) diff --git a/shopelectro/tasks.py b/shopelectro/tasks.py index d5c3f799..dce6329c 100644 --- a/shopelectro/tasks.py +++ b/shopelectro/tasks.py @@ -2,9 +2,11 @@ from django.conf import settings from django.core.management import call_command +from selenium.common.exceptions import WebDriverException from shopelectro import selenium from shopelectro.celery import app +from shopelectro.report import TelegramReport from shopelectro.models import CategoryPage from shopelectro.management.commands._update_catalog import utils @@ -61,18 +63,30 @@ def update_catalog(): collect_static() ] -# @todo #690:60m Handle errors in check_purchase. -# Report failed attempts. Schedule it in the celery beat. +# @todo #690:30m Schedule check_purchase in the celery beat. -@app.task -def check_purchase(): - driver = selenium.SiteDriver(site_url=settings.BASE_URL) - category_page = selenium.CategoryPage(driver, CategoryPage.objects.first().url) - category_page.load() - category_page.add_to_cart() - - order_page = selenium.OrderPage(driver) - order_page.load() - order_page.fill_contacts() - order_page.make_order() +@app.task( + bind=True, + autoretry_for=(WebDriverException, AssertionError), + retry_kwargs={'max_retries': settings.CHECK_PURCHASE_RETRIES}, +) +def check_purchase(self): + try: + driver = selenium.SiteDriver(site_url=settings.BASE_URL) + category_page = selenium.CategoryPage(driver, CategoryPage.objects.first().slug) + category_page.load() + category_page.add_to_cart() + + order_page = selenium.OrderPage(driver) + order_page.load() + order_page.fill_contacts() + order_page.make_order() + + success_page = selenium.SuccessPage(driver) + assert success_page.is_success() + except (WebDriverException, AssertionError) as err: + if self.request.retries + 1 > self.max_retries: + # report on the last attempt + TelegramReport().send(f'Can\'t buy a product. Got the error: {err}') + raise err