09.02.2023: Магический четверг

А я точно проснулся? А когда? Очень странно. Ну вот-же в сценарии написано: проснулся, посидел в телефоне, позавтракал, отправился на рабочее место. И я действительно на рабочем месте, снова пытаюсь поднять тестовый сервер. Значит точно просыпался и завтракал. Вон отмечено, что даже новости посмотрел (канал «Испания наизнанку»).

Написанному верить! А потому, что не верить вроде-бы нет причин. Просто не чувствую…

Впрочем, не важно. Солнце на окнами светит? Светит. Чайник вскипел? Как не вскипел? Воды нет? А куда делась? Мистика какая-то…

Налил, поставил, вскипятил, заварил. Кажется локальный миропорядок восстановлен.

Теперь по чудесам, которые предстоит сегодня сделать.

  • Во-первых, закинуть Тенетте тестовый проект.
  • Во-вторых, поднять Селениум.
  • В-третьих, заставить всё это дело работать в связке.

Это только кажется просто. По факту — бьюсь о задумку как о стену не первый день.

Зачем? Чтобы открыть виджет донейшин алертса в браузере, сделать скриншот и выложить в доступном месте в пиде готовой картинки (которую поставлю на сайте).

Магия, хи-хи!

И, как это водится, решение оказывается довольно простым.

  1. Делаю pip install pytest-seleniumbase
  2. Делаю dnf install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
  3. Запускаю тест из примера
cd examples/
pytest my_first_test.py

Всё работает.

Ну хорошо. А дальше что?

А дальше, пишу уже собственный «тест».

"""get screenshot m."""
from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)


class GetScreen(BaseCase):
url = "ссылка_на_виджет"
img_folder = "/путь_к_папке_на_сайте/img/"
css_element = "div.widget-goal"

def test_swag_labs(self):
self.open(self.url)

self.save_element_as_image_file("div.widget-goal", "money_sbor", folder=self.img_folder)

# Меняю бэкграунд тела страницы
self.execute_script('document.body.style.backgroundColor = "#003300";')
# Убираю скругление углов
self.execute_script(f'document.querySelector("{self.css_element}").style.borderRadius = "0";')
# Задаю элементу абсолютное позиционирование
self.execute_script(f'document.querySelector("{self.css_element}").style.position = "absolute";')
# Добавляю элемету высоту
height = self.execute_script(f'return document.querySelector("{self.css_element}").getBoundingClientRect().height;')
self.execute_script(f'document.querySelector("{self.css_element}").style.height = "{height - 5}px";')
# Задаю скрывать не попавшее в блок
self.execute_script(f'document.querySelector("{self.css_element}").style.overflow = "hidden";')

self.save_element_as_image_file(f"{self.css_element}", "money_sbor_bg", folder=self.img_folder)

Он сохраняет два файла:

  • money_sbor.png — скриншот виджета на белом фоне.
  • money_sbor_bg.png — скриншот виджета (с изменёнными стилями).

Для изменения стилей пришлось добавить немножечко js. Там и фон пришлось менять, и скругления убрать, и светлая полоска по нижнеё части картинки всё время появлялась.

И вот вроде всё. Остаётся лишь прописать команду запуска py-скрипта в cron и стартовать раз в 3 минуты, а картинку подгружать из папки.

pytest /путь_к_скрипту_от_корня/название_скрипта.py --chrome

Примерно так выглядит команда запуска.

Но потом я спросил у Эс, как она получает сигнал, если приходит донат и оказалось, что вне стрима никакого сигнала нет. А это значит, нужно сделать чтобы «таки-есть».

Задумка такая:

  • Добываю текущую сумму из виджета.
  • Сравниваю с той, что на этот момент уже хранится в логе.
  • Если сумма отличается — пишу сообщение в ТГ и сохраняю в лог новую сумму.

Вроде ничего сложного.

Вечером продолжил. Добился получения текущей суммы.

Посмотрел, подумал, и решил до кучи сделать выгрузку TOP10 донатеров. Вот тут и случился затык. Элементы, с именами я получаю, но они приходят в виде объекта. Пробовал извлечь из него текст штатными методами, но ничего не получилось.

А потому, что IDE в этом проекте плохо настроена. Ей приходится работать со скриптами, которые лежат и работают на сервере.

Подумал ещё. Попробовал и так, и эдак. Получилось! Вот так теперь выглядит выгребалка топа.

"""get screenshot m."""
from seleniumbase import BaseCase

BaseCase.main(__name__, __file__)


class GetTop10(BaseCase):
    # URL виджета с www.donationalerts.com
    url = "ссылка_на_виджет_топ_данатеров"
    # Путь к папке для сохранения картинок
    img_folder = "/путь_к_папке_сайта_на_этом_сервере/img/"
    # Тело виджета (By CSS)
    css_element = "div.iss-list div.iss-element"
    file_name = 'top10.log'
    flag_name = 'top10.flag'

    def test_top10(self):
        flag_name = f'{self.img_folder}{self.flag_name}'
        flag_value = "0"
        if os.path.exists(flag_name):
            with open(flag_name, 'r', encoding="utf8") as flag:
                flag_value = flag.read()
        else:
            with open(flag_name, 'w+', encoding="utf8") as flag:
                flag.write("0")

        if int(flag_value) == 1:
            # Если флаг активирован, то запускаю парсинг ТОП10
            self.open(self.url)
            elements = self.find_elements(self.css_element)
            top10 = ""
            for element in elements:
                print(element.text)
                if top10 == "":
                    top10 = f"{element.text}"
                else:
                    top10 = f"{top10}\n{element.text}"
            file_name = f'{self.img_folder}{self.file_name}'
            with open(file_name, 'w+', encoding="utf8") as f:
                old_top10 = f.read()
                if top10 != old_top10:
                    f.write(top10)

            with open(flag_name, 'w+', encoding="utf8") as flag:
                flag.write("0")

Осталось сделать пару вещей.

  • Написать простенького телеграмм-бота для отправки сообщения о донате.
  • Добавить запуск скрипта в Cron.
  • Прикрутить топ и баннер к какому-нибудь моему блогу. Или к нескольким.
  • Протестировать работу.

Погнали.

С телеграмм-ботом сложностей не возникло. Во всяком случае, написал его без особого труда. Работать будет через библиотеку requests и API-телеграмм.

Посмотрим что получится на тесте.

Теперь Cron. Пока его настраивал, обнаружил ошибку в логике. У меня тест запускался из теста, а это невозможно, поскольку потребуется запустить браузер в браузере.

Не совсем так, но примерно. Оно просто падало.

Создал флаг. Теперь пересобиралка ТОП10 не будет ничего делать, если флаг равен 0. Однако, пересобиралку топа тоже пришлось добавить в Cron.

Попробовал. Не работает. Поправил логику снова. Вроде пошло. Cron перестал вываливаться с ошибкой.

Отлично. Дальше!

Прикрутил баннер и ТОП10 к вот этому блогу.

Упарился писать виджет.

И вроде даже выводится всё в правой колонке как и планировалось. Осталось протестировать. Ну-с, доначу себе денежку.

Ещё раз немного переписал логику и добавил ещё один виджет. Ещё раз закинул денежку.

Ура. Работает!

Подкорректировал стили, глянул на часы, а там скоро полночь. Вот это я засел кодить. Сам не ожидал. Но, всё получилось. Чудо!

Ещё пара финальных правок и можно пока оставить так.

Перед сном включил видосик по созданию клиентского железа для Wi-Fi-радио.

Давно хотел сделать одну штуковину на базе чего-нибудь подобного. Часть деталей лежит на складе ещё с прошлого года.

Но если и буду делать, то уже не сегодня. Полночь на улице. I’m OFF.

Напишите комментарий

Введите имя

Введите адрес электронной почты

Введите адрес вашего сайта

Нажмите эту кнопку, чтобы отправить комментарий.

Введите текст комментария