Skip to content

Commit

Permalink
Tele2 sms, MTS captcha show, yota chrome, browser chromium support
Browse files Browse the repository at this point in the history
  • Loading branch information
artyl committed Oct 28, 2020
1 parent 1b99e3d commit 2c21b90
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 76 deletions.
15 changes: 13 additions & 2 deletions changelist.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ avtodor-tr - Автодор транспондер
Скорость работы плагинов на хроме увеличилась, у МТС примерно в 2-3 раза.
Как показала практика, для плагинов через хром включение логгирования DEBUG приводит к огромному количеству записей от самого движка puppeteer, и ряда библиотек, исправлено.
Добавил параметры для разборок плагинов через хром - log_responses=1 - запишет все просмотренные страницы, также не забывайте про show_chrome=1 они дадут достаточно понятную информацию
__Автономная версия__:
__Автономная версия__:
Теперь можно запрашивать балансы командой /receivebalance, без параметров - все телефоны, либо после через пробел какие балансы получить (как призапуске из батника mbstandalone.bat GETBALANCE). Естественно такая возможность, как и просмотр баланса доступна только если id вашего телеграма прописан в ini в строчке auth_id
В случае если низкий баланс, скорое время отключения либо баланс давно не менялся в боте напротив номера появляется соответстующий коментарий
Фильтр получаемых номеров в запросе в автономной версии добавлен Alias. Также можно не писать логин/алиас/оператор а можно его часть
Expand All @@ -127,5 +127,16 @@ __Автономная версия__:
Аналогично mbstandalone.bat init noweb - также не добавляет web сервер в автозапуск.

## mbplugin 0.99.23 (16.10.20) Mts obshchiy_paket, standalone version addition parameter
Плагин mts2 умеет забирать информацию из общего пакета для телефонов указанных в параетре mts_usedbyme, или по всем телефонам если mts_usedbyme=1
Плагин mts2 умеет забирать информацию из общего пакета для телефонов указанных в параметре mts_usedbyme, или по всем телефонам если mts_usedbyme=1
Можно показывать остаток по общему пакету МТС, а не по телефону если в поле номера телефона указать 9161234567/common, или общий расход пакета 9161234567/common_rest
В автономной версии теперь можно прописывать параметры BalanceNotChangedMoreThen, BalanceChangedLessThen, BalanceLessThen, TurnOffLessThen для каждого телефона (пример см standalone\phones.ini)

## mbplugin 0.99.24 (28.10.20) Tele2 sms, MTS captcha show, yota chrome, browser chromium support
Добавил в tele2 информацию по SMS (при участии 2350040)
Вынес параметр interUnit (еденицы измерения для инета) в ini. По умолчанию GB. Пока это включено для mts и tele2
Для плагинов через хром можно задать прокси сервер в формате http://user:[email protected]:6789
Для плагинов через хром добавлена возможность показа хрома в случае появления капчи (при участии comr)
Для плагинов через хром улучшена обработка ошибок при неожиданном закрытии хрома
Очередная попытка починить плагин mosenergosbyt для ряда случаев (при участии dimon_s2020)
Для плагинов через хром исправлена работа с другими браузерами на движке cromium (edge, yandex, brave и т.п., опера хоть и на хромиуме но нормально не заработала)
Плагин yota теперь тоже через хром
2 changes: 1 addition & 1 deletion plugin/httpserver_mobile.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def getreport(param=[]):
mark = ' class="mark" ' # Красим недавно поменялся а не должен был
if el is None:
el = ''
if he != 'Balance' and (el == 0.0 or el == 0):
if he != 'Balance' and (el == 0.0 or el == 0) and mark == '':
el = ''
html_line.append(f'<{"th" if he=="NN" else "td"} id="{he}"{mark}>{el}</td>')
html_table.append(f'<tr id="row" class="n">{"".join(html_line)}</tr>')
Expand Down
89 changes: 61 additions & 28 deletions plugin/pyppeteeradd.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ def enumWindowFunc(hwnd, windowList):
text = win32gui.GetWindowText(hwnd)
className = win32gui.GetClassName(hwnd)
_, pid = win32process.GetWindowThreadProcessId(hwnd)
if text.find("Chrome")>=0 and 'remote-debugging-port' in ''.join(psutil.Process(pid).cmdline()):
windowList.append((hwnd, text, className))
try: # ??? text.lower().find('chrome')>=0
if text != '' and 'remote-debugging-port' in ''.join(psutil.Process(pid).cmdline()):
windowList.append((hwnd, text, className))
except Exception:
pass
myWindows = []
# enumerate thru all top windows and get windows which are ours
win32gui.EnumWindows(enumWindowFunc, myWindows)
Expand All @@ -30,7 +33,7 @@ def enumWindowFunc(hwnd, windowList):
else:
win32gui.MoveWindow(hwnd, 0, 0, 1000, 1000, True) # Возвращаем нормальные координаты

async def launch_browser(storename, response_worker=None):
async def launch_browser(storename, response_worker=None, disconnected_worker=None):
hide_chrome_flag = str(store.options('show_chrome')) == '0' and store.options('logginglevel') != 'DEBUG'
storefolder = store.options('storefolder')
user_data_dir = os.path.join(storefolder,'puppeteer')
Expand Down Expand Up @@ -77,14 +80,18 @@ async def launch_browser(storename, response_worker=None):
await page.close() # Закрываем остальные страницы, если вдруг открыты
page = pages[0] # await browser.newPage()
if response_worker is not None:
page.on("response", response_worker) # вешаем обработчик на страницы
page.on("response", response_worker) # вешаем обработчик на страницы
if disconnected_worker is not None:
browser.on("disconnected", disconnected_worker) # вешаем обработчик закрытие браузера
return browser, page

def kill_chrome():
'Киляем дебажный хром если вдруг какой-то висит'
'''Киляем дебажный хром если вдруг какой-то висит, т.к. народ умудряется запускать не только хром, то имя exe возьмем из пути '''
chrome_executable_path = store.options('chrome_executable_path')
pname = os.path.split(chrome_executable_path)[-1].lower()
for p in psutil.process_iter():
try:
if p.name()=='chrome.exe' and 'remote-debugging-port' in ''.join(p.cmdline()):
if p.name().lower()==pname and 'remote-debugging-port' in ''.join(p.cmdline()):
p.kill()
except Exception:
pass
Expand Down Expand Up @@ -162,7 +169,19 @@ async def do_waitfor(page, waitfor, tokens, wait_and_reload=10, wait_loop=30):

class balance_over_puppeteer():
'''Основная часть общих действий вынесена сюда см mosenergosbyt для примера использования '''

def check_browser_opened_decorator(func): # pylint: disable=no-self-argument
async def wrapper(self, *args, **kwargs):
if self.browser_open:
res = await func(self, *args, **kwargs) # pylint: disable=not-callable
return res
else:
logging.error(f'Browser was not open')
raise RuntimeError(f'Browser was not open')
return wrapper

def __init__(self, login, password, storename=None, wait_loop=30, wait_and_reload=10, login_attempt=1):
self.browser_open = True # флаг что браузер рабобтает
self.wait_loop = wait_loop # TODO подобрать параметр
self.login_attempt = login_attempt
self.wait_and_reload = wait_and_reload
Expand All @@ -178,19 +197,49 @@ def __init__(self, login, password, storename=None, wait_loop=30, wait_and_relo
self.result = {}
self.responses = {}

async def response_worker(self, response):
'Response Worker вызывается на каждый url который открывается при загрузке страницы (т.е. список тот же что на вкладке сеть в хроме)'
'Проходящие запросы, которые json сохраняем в responses'
if response.status == 200:
try:
data = await response.json() # Берем только json
except Exception:
return
try:
post = ''
if response.request.method == 'POST' and response.request.postData is not None:
post = response.request.postData
self.responses[f'{response.request.method}:{post} URL:{response.request.url}$'] = data
# TODO Сделать какой-нибудь механизм для поиска по загруженным страницам
# txt = await response.text()
# if '2336' in txt:
# logging.info(f'2336 in {response.request.url}')
except:
exception_text = f'Ошибка: {"".join(traceback.format_exception(*sys.exc_info()))}'
logging.debug(exception_text)

async def disconnected_worker(self):
'disconnected_worker вызывается когда закрыли браузер'
logging.info(f'Browser was closed')
self.browser_open = False # выставляем флаг

# потом наверно перенесем их совсем сюда, а отдельные прибьем
@check_browser_opened_decorator
async def page_evaluate(self, eval_string, default=None):
''' переносим вызов в класс для того чтобы каждый раз не указывать page'''
return (await page_evaluate(self.page, eval_string, default=None))

@check_browser_opened_decorator
async def page_goto(self, url):
''' переносим вызов в класс для того чтобы каждый раз не указывать page'''
return (await page_goto(self.page, url))

@check_browser_opened_decorator
async def page_reload(self, reason=''):
''' переносим вызов в класс для того чтобы каждый раз не указывать page'''
return (await page_reload(self.page, reason=''))

@check_browser_opened_decorator
async def page_type(self, selector, text, *args, **kwargs):
'Безопасный type - не падает при ошибке а возвращает None'
try:
Expand All @@ -200,6 +249,7 @@ async def page_type(self, selector, text, *args, **kwargs):
except Exception:
logging.info(f'page.type fail: {repr(selector)}')

@check_browser_opened_decorator
async def page_click(self, selector, *args, **kwargs):
'Безопасный click - не падает при ошибке а возвращает None'
try:
Expand All @@ -209,6 +259,7 @@ async def page_click(self, selector, *args, **kwargs):
except Exception:
logging.info(f'page.click fail: {repr(selector)}')

@check_browser_opened_decorator
async def page_waitForNavigation(self, *args, **kwargs):
'Безопасный waitForNavigation - не падает при ошибке а возвращает None'
try:
Expand All @@ -220,6 +271,7 @@ async def page_waitForNavigation(self, *args, **kwargs):
logging.info(f'page.waitForNavigation timeout')

# !!! TODO есть page.waitForSelector - покопать в эту сторону
@check_browser_opened_decorator
async def page_waitForSelector(self, selector, *args, **kwargs):
'Безопасный waitForSelector - не падает при ошибке а возвращает None'
try:
Expand All @@ -230,27 +282,7 @@ async def page_waitForSelector(self, selector, *args, **kwargs):
logging.info(f'page.waitForSelector fail: {repr(selector)}')
return None

async def worker(self, response):
'Worker вызывается на каждый url который открывается при загрузке страницы (т.е. список тот же что на вкладке сеть в хроме)'
'Проходящие запросы, которые json сохраняем в responses'
if response.status == 200:
try:
data = await response.json() # Берем только json
except Exception:
return
try:
post = ''
if response.request.method == 'POST' and response.request.postData is not None:
post = response.request.postData
self.responses[f'{response.request.method}:{post} URL:{response.request.url}$'] = data
# TODO Сделать какой-нибудь механизм для поиска по загруженным страницам
# txt = await response.text()
# if '2336' in txt:
# logging.info(f'2336 in {response.request.url}')
except:
exception_text = f'Ошибка: {"".join(traceback.format_exception(*sys.exc_info()))}'
logging.debug(exception_text)

@check_browser_opened_decorator
async def do_logon(self, url,user_selectors={}):
'Делаем заход в личный кабинет/ проверяем не залогинены ли уже'
'На вход передаем словарь селекторов и скриптов который перекроет действия по умолчанию'
Expand Down Expand Up @@ -337,6 +369,7 @@ async def do_logon(self, url,user_selectors={}):
logging.error(f'Unknown state')
raise RuntimeError(f'Unknown state')

@check_browser_opened_decorator
async def wait_params(self, params, url='', save_to_result=True):
''' Переходим по url и ждем параметры
---
Expand Down Expand Up @@ -409,7 +442,7 @@ async def wait_params(self, params, url='', save_to_result=True):
return result

async def _async_main(self):
self.browser, self.page = await launch_browser(self.storename, self.worker)
self.browser, self.page = await launch_browser(self.storename, response_worker=self.response_worker, disconnected_worker=self.disconnected_worker)
await self.async_main() # !!! CALL async_main
logging.debug(f'Data ready {self.result.keys()}')
if str(store.options('log_responses')) == '1' or store.options('logginglevel') == 'DEBUG':
Expand Down
9 changes: 8 additions & 1 deletion plugin/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Значения по умолчанию, здесь ничего не меняем, если хотим поменять меняем в mbplugin.ini
подробное описание см в readme.md
'''
import os
UNIT = {'TB': 1073741824, 'ТБ': 1073741824, 'TByte': 1073741824,
'GB': 1048576, 'ГБ': 1048576, 'GByte': 1048576,
'MB': 1024, 'МБ': 1024, 'MByte': 1024,
Expand All @@ -15,7 +16,13 @@
# сюда пропишем сразу возможные варианты для путя хрома
chrome_executable_path_alternate = [
'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',]
'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
'C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe',
'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
f'{os.environ.get("LOCALAPPDATA","")}\\Yandex\\YandexBrowser\\Application\\browser.exe',
'C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe',
'C:\\Program Files (x86)\\BraveSoftware\\Brave-Browser\\Application\\brave.exe',
]
########################################################################################
ini = {
'Options': { # Раздел mbplugin.ini [Options]
Expand Down
Loading

0 comments on commit 2c21b90

Please sign in to comment.