From 7f0f608f01ee185a05babab7dd2c7dd91fa4324b Mon Sep 17 00:00:00 2001 From: Artemiy Rodionov Date: Fri, 25 Jan 2019 21:05:15 +0300 Subject: [PATCH 1/8] Create SuccessPage --- shopelectro/selenium/pages/__init__.py | 1 + shopelectro/selenium/pages/success.py | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 shopelectro/selenium/pages/success.py diff --git a/shopelectro/selenium/pages/__init__.py b/shopelectro/selenium/pages/__init__.py index dde4439c..de4af211 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 SuccesPage diff --git a/shopelectro/selenium/pages/success.py b/shopelectro/selenium/pages/success.py new file mode 100644 index 00000000..4a60555c --- /dev/null +++ b/shopelectro/selenium/pages/success.py @@ -0,0 +1,13 @@ +from shopelectro.selenium.pages import Page + +from pages.models import CustomPage + + +class SuccesPage(Page): + + @property + def path(self): + CustomPage.objects.get(slug='order-success').url + + def is_success(self): + 'Заказ принят' in self.driver.find_element_by_tag_name('h1').text From 2a6be11c13dd5356eea1fd15e7822952c5731f3c Mon Sep 17 00:00:00 2001 From: Artemiy Rodionov Date: Fri, 25 Jan 2019 21:05:57 +0300 Subject: [PATCH 2/8] Assert success_page.is_success() in check_purchase --- shopelectro/tasks.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shopelectro/tasks.py b/shopelectro/tasks.py index d5c3f799..d441e497 100644 --- a/shopelectro/tasks.py +++ b/shopelectro/tasks.py @@ -76,3 +76,7 @@ def check_purchase(): order_page.load() order_page.fill_contacts() order_page.make_order() + + success_page = selenium.SuccessPage(driver) + success_page.load() + assert success_page.is_success() From 99b178918a8158352e43b418a3f9072af63e82d6 Mon Sep 17 00:00:00 2001 From: Artemiy Rodionov Date: Fri, 25 Jan 2019 21:13:58 +0300 Subject: [PATCH 3/8] Setup auto-retry for the check_purchase --- shopelectro/tasks.py | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/shopelectro/tasks.py b/shopelectro/tasks.py index d441e497..1ab8c136 100644 --- a/shopelectro/tasks.py +++ b/shopelectro/tasks.py @@ -2,6 +2,7 @@ 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 @@ -65,18 +66,23 @@ def update_catalog(): # Report failed attempts. Schedule it 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() - - success_page = selenium.SuccessPage(driver) - success_page.load() - assert success_page.is_success() +@app.task(bind=True, autoretry_for=(Exception,), retry_kwargs={'max_retries': 3}) +def check_purchase(self): + try: + 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() + + success_page = selenium.SuccessPage(driver) + success_page.load() + assert success_page.is_success() + except (WebDriverException, AssertionError) as err: + if self.request.retries + 1 > self.max_retries: + # report fail + raise err From 7b0b7a0e5b6b4808fdd3e9067a3e8924352d32f0 Mon Sep 17 00:00:00 2001 From: Artemiy Rodionov Date: Sat, 26 Jan 2019 04:46:07 +0300 Subject: [PATCH 4/8] Create TGReport --- requirements.txt | 1 + shopelectro/report.py | 14 ++++++++++++++ shopelectro/settings/base.py | 5 +++++ shopelectro/tasks.py | 12 ++++++++---- 4 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 shopelectro/report.py 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..04e82676 --- /dev/null +++ b/shopelectro/report.py @@ -0,0 +1,14 @@ +import typing + +from django.conf import settings +from telegram import Bot + + +class TGReport: + + 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/settings/base.py b/shopelectro/settings/base.py index ff07abde..624c6640 100644 --- a/shopelectro/settings/base.py +++ b/shopelectro/settings/base.py @@ -501,3 +501,8 @@ 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_ADDRESSEE', '@artemiy312,@duker33' +).split(',') diff --git a/shopelectro/tasks.py b/shopelectro/tasks.py index 1ab8c136..4d1fb71f 100644 --- a/shopelectro/tasks.py +++ b/shopelectro/tasks.py @@ -6,6 +6,7 @@ from shopelectro import selenium from shopelectro.celery import app +from shopelectro.report import TGReport from shopelectro.models import CategoryPage from shopelectro.management.commands._update_catalog import utils @@ -62,11 +63,14 @@ 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(bind=True, autoretry_for=(Exception,), retry_kwargs={'max_retries': 3}) +@app.task( + bind=True, + autoretry_for=(WebDriverException, AssertionError), + retry_kwargs={'max_retries': 3}, +) def check_purchase(self): try: driver = selenium.SiteDriver(site_url=settings.BASE_URL) @@ -84,5 +88,5 @@ def check_purchase(self): assert success_page.is_success() except (WebDriverException, AssertionError) as err: if self.request.retries + 1 > self.max_retries: - # report fail + TGReport().send(f'Can\'t buy a product. Got the error: {err}') raise err From 761364a04c234bc1c266540317129f3467bae97f Mon Sep 17 00:00:00 2001 From: Artemiy Rodionov Date: Sun, 27 Jan 2019 08:08:27 +0300 Subject: [PATCH 5/8] Review fixes --- shopelectro/report.py | 2 +- shopelectro/settings/base.py | 3 ++- shopelectro/tasks.py | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/shopelectro/report.py b/shopelectro/report.py index 04e82676..a25e3e2d 100644 --- a/shopelectro/report.py +++ b/shopelectro/report.py @@ -4,7 +4,7 @@ from telegram import Bot -class TGReport: +class TelegramReport: def __init__(self): self.bot = Bot(settings.TG_BOT_TOKEN) diff --git a/shopelectro/settings/base.py b/shopelectro/settings/base.py index 624c6640..e204f113 100644 --- a/shopelectro/settings/base.py +++ b/shopelectro/settings/base.py @@ -504,5 +504,6 @@ def get_robots_content(): TG_BOT_TOKEN = os.environ.get('TG_BOT_TOKEN') TG_REPORT_ADDRESSEES = os.environ.get( - 'TG_REPORT_ADDRESSEE', '@artemiy312,@duker33' + '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 4d1fb71f..e358484d 100644 --- a/shopelectro/tasks.py +++ b/shopelectro/tasks.py @@ -6,7 +6,7 @@ from shopelectro import selenium from shopelectro.celery import app -from shopelectro.report import TGReport +from shopelectro.report import TelegramReport from shopelectro.models import CategoryPage from shopelectro.management.commands._update_catalog import utils @@ -69,7 +69,7 @@ def update_catalog(): @app.task( bind=True, autoretry_for=(WebDriverException, AssertionError), - retry_kwargs={'max_retries': 3}, + retry_kwargs={'max_retries': settings.CHECK_PURCHASE_RETRIES}, ) def check_purchase(self): try: @@ -88,5 +88,5 @@ def check_purchase(self): assert success_page.is_success() except (WebDriverException, AssertionError) as err: if self.request.retries + 1 > self.max_retries: - TGReport().send(f'Can\'t buy a product. Got the error: {err}') + TelegramReport().send(f'Can\'t buy a product. Got the error: {err}') raise err From ab94fa8502443b35c2c20b1b7ce4eb6558f2decd Mon Sep 17 00:00:00 2001 From: Artemiy Rodionov Date: Sun, 27 Jan 2019 08:10:15 +0300 Subject: [PATCH 6/8] Add the comment to check_purchase's report policy --- shopelectro/tasks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/shopelectro/tasks.py b/shopelectro/tasks.py index e358484d..71eb4186 100644 --- a/shopelectro/tasks.py +++ b/shopelectro/tasks.py @@ -88,5 +88,6 @@ def check_purchase(self): 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 From f4896c8c4599be52b41ece2ea8a9ecab8652b951 Mon Sep 17 00:00:00 2001 From: Artemiy Rodionov Date: Mon, 28 Jan 2019 15:35:37 +0300 Subject: [PATCH 7/8] Apply linter rules --- shopelectro/report.py | 2 -- shopelectro/selenium/pages/success.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/shopelectro/report.py b/shopelectro/report.py index a25e3e2d..cbe994e3 100644 --- a/shopelectro/report.py +++ b/shopelectro/report.py @@ -1,5 +1,3 @@ -import typing - from django.conf import settings from telegram import Bot diff --git a/shopelectro/selenium/pages/success.py b/shopelectro/selenium/pages/success.py index 4a60555c..ead0f209 100644 --- a/shopelectro/selenium/pages/success.py +++ b/shopelectro/selenium/pages/success.py @@ -10,4 +10,4 @@ def path(self): CustomPage.objects.get(slug='order-success').url def is_success(self): - 'Заказ принят' in self.driver.find_element_by_tag_name('h1').text + return 'Заказ принят' in self.driver.find_element_by_tag_name('h1').text From 01e4e9588c8b0f75692e5410ab2093c8b1800306 Mon Sep 17 00:00:00 2001 From: Artemiy Rodionov Date: Mon, 28 Jan 2019 16:04:40 +0300 Subject: [PATCH 8/8] Fix typos --- shopelectro/selenium/__init__.py | 2 +- shopelectro/selenium/pages/__init__.py | 2 +- shopelectro/selenium/pages/success.py | 2 +- shopelectro/tasks.py | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) 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 de4af211..c3812923 100644 --- a/shopelectro/selenium/pages/__init__.py +++ b/shopelectro/selenium/pages/__init__.py @@ -2,4 +2,4 @@ from .category import CategoryPage from .order import OrderPage -from .success import SuccesPage +from .success import SuccessPage diff --git a/shopelectro/selenium/pages/success.py b/shopelectro/selenium/pages/success.py index ead0f209..1e3c1781 100644 --- a/shopelectro/selenium/pages/success.py +++ b/shopelectro/selenium/pages/success.py @@ -3,7 +3,7 @@ from pages.models import CustomPage -class SuccesPage(Page): +class SuccessPage(Page): @property def path(self): diff --git a/shopelectro/tasks.py b/shopelectro/tasks.py index 71eb4186..dce6329c 100644 --- a/shopelectro/tasks.py +++ b/shopelectro/tasks.py @@ -74,7 +74,7 @@ def update_catalog(): def check_purchase(self): try: driver = selenium.SiteDriver(site_url=settings.BASE_URL) - category_page = selenium.CategoryPage(driver, CategoryPage.objects.first().url) + category_page = selenium.CategoryPage(driver, CategoryPage.objects.first().slug) category_page.load() category_page.add_to_cart() @@ -84,7 +84,6 @@ def check_purchase(self): order_page.make_order() success_page = selenium.SuccessPage(driver) - success_page.load() assert success_page.is_success() except (WebDriverException, AssertionError) as err: if self.request.retries + 1 > self.max_retries: