Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
artyl committed Jul 12, 2022
2 parents 1cca320 + c89b63b commit 7c14ad2
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 21 deletions.
5 changes: 5 additions & 0 deletions changelist.md
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,8 @@ ADD: Сортировка по полям balance.html (за идею спаси
FIX: починка баланса МТС
ADD: mbp browser - открытие движка браузера
FIX: починил сортировку по колонке время запроса

## mbplugin v1.00.30 (12.07.22) Button cancel, fix onlime, fix mts new lk
ADD: Кнопка Cancel для прерывания очереди запросов в тенлеграме и веб интерфейсе (не останавливает текущий запрос, остановит после того как отработает тот что выполняется сейчас).
FIX: Dimas прислал исправленный плагин onlime. У меня onlime нет, так что у себя проверить не могу, только внешне посмотрел, оставлю на суд пользователей onlime
FIX: МТС снова показывает свое истинное отношение, снова исправления
2 changes: 1 addition & 1 deletion docker/requirements_arm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ cryptography==3.4.8
idna==2.10
Pillow==9.0.1
#playwright==1.14.1 installed separately
#playwright-stealth==1.0.5
playwright-stealth==1.0.5
psutil==5.8.0
pycparser==2.20
pyee==8.2.2
Expand Down
1 change: 1 addition & 0 deletions plugin/browsercontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@ def do_logon(self, url=None, user_selectors=None):
self.page_screenshot()
for countdown in range(self.wait_loop):
if self.page_evaluate(selectors['fatal'], False):
self.page_screenshot(suffix='fatal')
logging.error(f'Fatal detected')
raise RuntimeError(f'Fatal detected')
if self.page_evaluate(selectors['captcha_checker'], False):
Expand Down
51 changes: 41 additions & 10 deletions plugin/httpserver_mobile.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@

Job = collections.namedtuple('Job' , 'job_str job_sched cmd filter err_msg')

cmdqueue: queue.Queue = queue.Queue() # Диспетчер комманд - нужен для передачи сигналов между трэдами, в т.к. для завершения в докере - kill для pid=1 не работает
Q_CMD_EXIT = 'exit'
Q_CMD_CANCEL = 'cancel'
cmdqueue: queue.Queue = queue.Queue() # Диспетчер команд - нужен для передачи сигналов между трэдами, в т.к. для завершения в докере - kill для pid=1 не работает

HTML_NO_REPORT = '''Для того чтобы были доступны отчеты необходимо в mbplugin.ini включить запись результатов в sqlite базу<br>
sqlitestore = 1<br>Также можно настроить импорт из базы BalanceHistory.mdb включив <br>
Expand All @@ -50,6 +52,7 @@
{'text': "Reload schedule", 'cmd': lambda: Scheduler().reload(), 'show': True},
{'text': "Recompile jsmblh plugin", 'cmd': lambda: compile_all_jsmblh.recompile(), 'show': True},
#{'text': "Version update", 'cmd': lambda: run_update(), 'show': True}, # TODO продумать как это показывать
{'text': "Cancel the balance request", 'cmd': lambda: cancel_query(reason='tray icon command'), 'show': True},
{'text': "Restart server", 'cmd': lambda: restart_program(reason='tray icon command'), 'show': True},
{'text': "Exit program", 'cmd': lambda: restart_program(reason='Tray icon exit', exit_only=True), 'show': True}
)
Expand Down Expand Up @@ -83,11 +86,19 @@ def getbalance_standalone_one_pass(filter:list=[], only_failed:bool=False) -> No
for val in queue_balance:
# TODO пока дергаем метод от вебсервера там уже все есть, потом может вынесем отдельно
try:
# проверяем на сигнал Q_CMD_CANCEL, все остальное - кладем обратно
if Q_CMD_CANCEL in cmdqueue.queue:
qu = [cmdqueue.get(block=False) for el in range(cmdqueue.qsize())]
[cmdqueue.put(el) for el in qu if el != Q_CMD_CANCEL] # type: ignore
logging.info(f'Receive cancel signal to query')
store.feedback.text(f"Receive cancel signal")
return
store.feedback.text(f"Receive {val['Alias']}:{val['Region']}_{val['Number']}")
getbalance_plugin('get', {'plugin': [val['Region']], 'login': [val['Number']], 'password': [val['Password2']], 'date': ['date']})
except Exception:
logging.error(f"Unsuccessful check {val['Region']} {val['Number']} {store.exception_text()}")


def getbalance_standalone(filter:list=[], only_failed:bool=False, retry:int=-1, params=None) -> None:
''' Получаем балансы делая несколько проходов по неудачным
retry=N количество повторов по неудачным попыткам, после запроса по всем (повторы только при only_failed=False)
Expand Down Expand Up @@ -516,9 +527,15 @@ def restart_program(reason='', exit_only=False, delay=0):
if not exit_only:
subprocess.Popen(cmd) # Crossplatform run process
psutil.Process().kill()
cmdqueue.put('exit') # Если kill не сработал (для pid=1 не сработает) - шлем сигнал


if Q_CMD_EXIT not in cmdqueue.queue: # Если есть то второй раз не кладем
cmdqueue.put(Q_CMD_EXIT) # Если kill не сработал (для pid=1 не сработает) - шлем сигнал

def cancel_query(reason=''):
'Cancel query in getbalance_standalone_one_pass by Q_CMD_CANCEL'
if Q_CMD_CANCEL not in cmdqueue.queue: # Если есть то второй раз не кладем
cmdqueue.put(Q_CMD_CANCEL)
logging.info(f'Send cancel signal to query')

def send_http_signal(cmd, force=True):
'Посылаем сигнал локальному веб-серверу'
logging.info(f'Send {cmd} signal to web server')
Expand Down Expand Up @@ -793,6 +810,7 @@ def __init__(self):
TgCommand('/receivebalance', 'запросить балансы, аналог команды mbp get-balance (фильтр после пробела)', self.receivebalance),
TgCommand('/receivebalancefailed', 'запросить балансы номеров с ошибками', self.receivebalance),
TgCommand('/restart', 'перезапустить сервер', self.restartservice),
TgCommand('/cancel', 'остановить очередь запросов', self.cancel),
TgCommand('/getone', 'получить баланс одного номера', self.get_one),
TgCommand('/checkone', 'запросить баланс одного номера', self.get_one, ),
TgCommand('/schedule', 'текущие задачи в планировщике', self.get_schedule),
Expand Down Expand Up @@ -934,6 +952,12 @@ def restartservice(self, update, context):
self.put_text(update.effective_message.reply_text, 'Service will be restarted')
restart_program(reason=f'TG:{update.effective_message.chat_id} /restart {context.args}')

@auth_decorator()
def cancel(self, update, context):
"""Send cancel signal to receive balance query"""
self.put_text(update.effective_message.reply_text, 'Query will be canceled')
cancel_query(reason=f'TG:{update.effective_message.chat_id} /cancel {context.args}')

@auth_decorator()
def receivebalance(self, update, context):
""" Запросить балансы по всем номерам, only auth user.
Expand All @@ -948,7 +972,7 @@ def feedback_func(txt):
# Если запросили все - запрашиваем все, потом два раза только плохие
only_failed = (update.effective_message.text == "/receivebalancefailed")
params = {'include': None if context.args == [] else ','.join(context.args)}
Scheduler().run_once(cmd='check', feedback_func=feedback_func, kwargs={'filter':context.args, 'params':params, 'only_failed':only_failed})
Scheduler().run_once(cmd=CMD_CHECK, feedback_func=feedback_func, kwargs={'filter':context.args, 'params':params, 'only_failed':only_failed})

@auth_decorator()
def get_schedule(self, update, context):
Expand Down Expand Up @@ -980,7 +1004,7 @@ def get_one(self, update, context: callbackcontext.CallbackContext):
self.put_text(message.edit_text, f'Not found {args}') # type: ignore
return
feedback_func = lambda txt:self.put_text(message.edit_text, txt) # type: ignore
Scheduler().run_once(cmd='get_one', feedback_func=feedback_func, kwargs={'keypair': keypair, 'check': cmd == 'checkone'})
Scheduler().run_once(cmd=CMD_GET_ONE, feedback_func=feedback_func, kwargs={'keypair': keypair, 'check': cmd == 'checkone'})
return
query: typing.Optional[telegram.callbackquery.CallbackQuery] = update.callback_query
if query is None: # Создаем клавиатуру
Expand All @@ -1001,7 +1025,7 @@ def get_one(self, update, context: callbackcontext.CallbackContext):
return
cmd, keypair = query.data.split('_', 1) # До _ команда, далее Region_Number
feedback_func = lambda txt:self.put_text(query.edit_message_text, txt) # type: ignore
Scheduler().run_once(cmd='get_one', feedback_func=feedback_func, kwargs={'keypair': keypair, 'check': cmd == 'checkone'})
Scheduler().run_once(cmd=CMD_GET_ONE, feedback_func=feedback_func, kwargs={'keypair': keypair, 'check': cmd == 'checkone'})

@auth_decorator()
def get_log(self, update: telegram.update.Update, context: callbackcontext.CallbackContext):
Expand Down Expand Up @@ -1158,8 +1182,12 @@ def __init__(self):
self.telegram_bot = TelegramBot()
if 'schedule' in sys.modules: # Scheduler (он сам все запустит в threading)
self.scheduler = Scheduler()
# Запустили все остальное демонами и ждем, когда они пришлют сигнал
cmdqueue.get()
# Запустили все остальное демонами и ждем, когда они пришлют сигнал exit
while True:
cmd = cmdqueue.get()
if cmd != Q_CMD_EXIT: # если это не наша команда - кладем обратно.
cmdqueue.put(cmd)
time.sleep(1)

def shutdown(self):
self.telegram_bot.stop()
Expand Down Expand Up @@ -1350,7 +1378,7 @@ def web_app(self, environ, start_response):
ct, text, status, add_headers = self.editor(environ)
elif cmd == 'getbalance_standalone': # start balance request
# TODO подумать над передачей параметров в fetch - filter=filter,only_failed=only_failed
Scheduler().run_once(cmd='check')
Scheduler().run_once(cmd=CMD_CHECK)
ct, text = 'text/html; charset=cp1251', ['OK']
elif cmd == 'flushlog': # Start new log
store.logging_restart()
Expand All @@ -1362,6 +1390,9 @@ def web_app(self, environ, start_response):
ct, text = 'text/html; charset=cp1251', ['OK']
# TODO нужен редирект иначе она зацикливается на рестарте
threading.Thread(target=lambda: restart_program(reason=f'WEB: /restart', delay=0.1), name='Restart', daemon=True).start()
elif cmd == 'cancel': # cancel query
ct, text = 'text/html; charset=cp1251', ['OK']
cancel_query(reason=f'WEB: /cancel')
elif cmd == 'exit': # exit cmd
ct, text = 'text/html; charset=cp1251', ['OK']
threading.Thread(target=lambda: restart_program(reason=f'WEB: /exit', exit_only=True, delay=0.1), name='Exit', daemon=True).start()
Expand Down
5 changes: 4 additions & 1 deletion plugin/mts.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,17 @@
'remember_js': "document.querySelector('form input[name=rememberme]').click()", # js для выставления remember me
'captcha_checker': "document.querySelector('img[id=captchaImage]')!=null||document.querySelector('div[id=captcha-wrapper]')!=null||document.body.innerText.startsWith('This question is for testing whether you are a human visitor and to prevent automated spam submission.')",
'captcha_focus': "[document.getElementById('ans'),document.getElementById('password'),document.getElementById('captchaInput')].filter(s => s!=null).map(s=>s.focus())",
'fatal': "/Доступ к сайту login.mts.ru запрещен./.test(document.querySelector('.descr').innerText)"
'fatal': "d=document.querySelector('.descr');d===null?false:/Доступ к сайту login.mts.ru запрещен./.test(d.innerText)"
}

class browserengine(browsercontroller.BrowserController):
def data_collector(self):
mts_usedbyme = self.options('mts_usedbyme')
self.do_logon(url=login_url, user_selectors=user_selectors)

# ни дня без приключений - теперь у нас снова новый личный кабинет, пока переходим в старый, будет время переделаем
self.page_evaluate(f"Array.from(document.querySelectorAll('button')).filter(el=>el.innerText=='Вернуться в старый'||el.innerText=='В старый Личный кабинет').forEach(el=>el.click())")

# TODO close banner # document.querySelectorAll('div[class=popup__close]').forEach(s=>s.click())
if self.login_ori != self.login and self.acc_num.isdigit(): # это финт для захода через другой номер
# если заход через другой номер то переключаемся на нужный номер
Expand Down
22 changes: 13 additions & 9 deletions plugin/onlime.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
# -*- coding: utf8 -*-
''' Автор ArtyLa '''
''' Автор ArtyLa, исправил Dimas '''
import browsercontroller

icon = '789C73F235636100033320D600620128666450804840E5A905989999F1CAB359A833B0DBEB90AC9F595A88817F423283D895490C5C31F644EB67E46065E0CEF264103DD3CB20B2AF9924FDEC2EFA0CC23B1B1844CFF531F0E4FB3230097013AD9F7F6A1A582DFF943406663911885BD85888D62F7AAC8381B72E9C81919111A2174833B2B1E2D40F5387AC9FA7D08F4150408841008841348FA0205C3F0F0F2F032F2F1F0307072703171737033FBF2056FD1CEC1C0C6C6CEC0C3CDCBC0C2C9C1C70FDDCDC3C0CEC40391066656503D3C8FA450EB63288EC6D6260773744B811C9FF30F7E2F23FB38C3003FFC414B07A8179B90C2CAA5224851F0CB0596930086DAA6610BB38011C9EA4EA0703166606AE782706D1135DE4E9870226113E06BE966806CE683BB2F4C300232BEE4C4B8C7EBC6603E305008A3A3F17'

login_url = 'https://my.rt.ru/'
user_selectors = {'chk_lk_page_js': "document.querySelector('div.lk-login input[type=password]') == null",
'chk_login_page_js': "document.querySelector('div.lk-login input[type=password]') !== null",
'login_clear_js': "document.querySelector('div.lk-login input[name=auth_login]').value=''",
'password_clear_js': "document.querySelector('div.lk-login input[type=password]').value=''",
'login_selector': 'div.lk-login input[name=auth_login]',
'password_selector': 'div.lk-login input[type=password]',
'submit_js': 'document.querySelector("div.lk-login input[type=submit]").click()',
login_url = None
user_selectors = {'chk_lk_page_js': "document.querySelector('#account_info_block') != null",
'chk_login_page_js': "['#standard_auth_btn', '#username'].filter(el=> document.querySelector(el)!=null).length > 0",
'before_login_js': """b1=document.querySelector('#standard_auth_btn');
if(b1!==null){b1.click()};
""",
'login_clear_js': "document.querySelector('#username').value=''",
'password_clear_js': "document.querySelector('#password').value=''",
'login_selector': '#username',
'password_selector': '#password',
'submit_js': 'document.querySelector("#kc-login").click()'
}

class browserengine(browsercontroller.BrowserController):
def data_collector(self):
self.page_goto('https://my.rt.ru')
self.do_logon(url=login_url, user_selectors=user_selectors)
# Здесь мы берем данные с загружаемой страницы
self.wait_params(params=[
Expand Down
1 change: 1 addition & 0 deletions plugin/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ def find_file_up(folder, filename):
<button onclick="fetch('/reload_schedule').then(function(response) {return response})">Reload schedule</button><br>
<button onclick="fetch('/recompile').then(function(response) {return response})">Recompile jsmblh plugin</button><br>
<button onclick="fetch('/restart').then(function(response) {return response})">Restart web server</button><br>
<button onclick="fetch('/cancel').then(function(response) {return response})">Cancel the balance request</button><br>
<button onclick="fetch('/exit').then(function(response) {return response})">Exit web server</button><br>
<br>
<a href=https://github.com/artyl/mbplugin/blob/master/readme.md>Документация на github</a><br>
Expand Down

0 comments on commit 7c14ad2

Please sign in to comment.