diff --git a/changelist.md b/changelist.md index 5394c14..76f3067 100644 --- a/changelist.md +++ b/changelist.md @@ -396,6 +396,9 @@ ADD: mbp browser - открытие движка браузера FIX: починил сортировку по колонке время запроса ## mbplugin v1.00.30 (12.07.22) Button cancel, fix onlime, fix mts new lk -ADD: Кнопка Cancel для прерывания очереди запросов в тенлеграме и веб интерфейсе (не останавливает текущий запрос, остановит после того как отработает тот что выполняется сейчас). +ADD: Кнопка Cancel для прерывания очереди запросов в телеграмме и веб интерфейсе (не останавливает текущий запрос, остановит после того как отработает тот что выполняется сейчас). FIX: Dimas прислал исправленный плагин onlime. У меня onlime нет, так что у себя проверить не могу, только внешне посмотрел, оставлю на суд пользователей onlime -FIX: МТС снова показывает свое истинное отношение, снова исправления \ No newline at end of file +FIX: МТС снова показывает свое истинное отношение, снова исправления + +## mbplugin v1.00.31 (15.07.22) Fix mts new lk, attempt 2 +FIX: МТС еще одна попытка починить личный кабинет, пока не ясно где информация по общему пакету diff --git a/plugin/browsercontroller.py b/plugin/browsercontroller.py index 33b3a3d..9da3f65 100644 --- a/plugin/browsercontroller.py +++ b/plugin/browsercontroller.py @@ -30,8 +30,8 @@ 'lk_page_url': '', # Если задан то появление в списке self.responces этого url или его части будет означать что мы залогинились 'chk_login_page_js': "document.querySelector('form input[type=password]') !== null", # true если мы в окне логина 'before_login_js': '', # Команда которую надо выполнить перед вводом логина - 'login_clear_js': "document.querySelector('form input[type=text]').value=''", # команда для очистки поля логина - 'login_selector': 'form input[type=text]', # селектор поля ввода логина + 'login_clear_js': "document.querySelector('form input[type^=te]').value=''", # команда для очистки поля логина + 'login_selector': 'form input[type^=te]', # селектор поля ввода логина 'chk_submit_after_login_js': "", # проверка нужен ли submit после логина 'submit_after_login_js': "document.querySelector('form [type=submit]').click()", # Если после ввода логина нужно нажать submit через js 'submit_after_login_selector': "", # или через селектор @@ -590,7 +590,7 @@ def do_logon(self, url=None, user_selectors=None): logging.error(f'Не все ключи из user_selectors есть в selectors. Возможна опечатка, проверьте {set(user_selectors)-set(selectors)}') selectors.update(user_selectors) # Если проверка на нахождение в личном кабинете на отсутствие элемента - дополнительно ожидаем чтобы страница гарантированно загрузилась - is_bad_chk_lk_page_js = ' == null' in selectors['chk_lk_page_js'] or '=== null' in selectors['chk_lk_page_js'] + is_bad_chk_lk_page_js = '= null' in selectors['chk_lk_page_js'] if url is not None: # Иногда мы должны сложным путем попасть на страницу - тогда указываем url=None self.page_goto(url) # Появилось слишком много сайтов на которых медленно открывается страница логона и мы успеваем подумать что пароля на странице нет diff --git a/plugin/mts.py b/plugin/mts.py index 3504eaf..6b3ae19 100644 --- a/plugin/mts.py +++ b/plugin/mts.py @@ -6,14 +6,14 @@ icon = '789C75524D4F5341143D84B6A8C0EB2BAD856A4B0BE5E301A508A9F8158DC18498A889896E8C3B638C31F147B83171E34E4388AE5C68E246A3C68D0B5DA82180B5B40A5A94B6F651DA423F012D2DE09D79CF4A207DC949A733F79C39F7CC1D3A37A801FF060912415451058772A09E6FFD04CD18F4DA09C267C214210051FB857EFFC1AFEEB3F3495E2F68DEA35EF396F086F6BCBC46D47E257C2304A1D7045157350DA13A80FA6A1F6AAB7CB4F6AB5A5E08DA71D2F840FC772AEF3B44DD0F1874215A87D1DA34871B57658CDE4F1212B87E2504BBD94F5A01D5938F7B16341F8937CB79C65DBF60DA2DC3E594F1FAE532D64B1BD8DCDCE428D1FAC5B30CDAAD33E483799C2E6B187411E245D124CC63BF18C3DD3BB9326F3B6EDF4A506FB3C49FE5BE99C6DE3D32F6E9636836C671A0631153DEB58AFCC9F155EA4DE951D40579CE8C6B37C5693F895347D388C9EB15F9D148119E1E190D3551F23DC7F366F73A2D4974DA52183E9E831CADCC0F878A38E88AC15C3B4F1A119E5D8B39814EEB125CAD199CF0E4C97FA9227F7CAC809E96382CE4D9489989BA9F7092EF2E7B8A7ACF62D0B58C278F8A15F90F4656D0D29880D5B0C07363EFD6665944B72385012947FC15DCBC56403EB7939BCD6CE0F2852CF193B0352C500F8C1F267EB2CC3FEC5EA10CFFE0D5F39D193C7D5C80BB2DCDEFDBCADFEEFF58FF2A2E9D2FC0F7E9BFC6C45809A74FE62035A778BDE23FCAFD3B28BF0EEB22E597E61E0EF52EE348DF2A2E9EFD8D87236B18BD57C099A13CE596E639B37AF6E66C5E597ECC0B7B7BA97909BDCE0CFA3BB3F074E73906A43CFADA73FC6DBAD4BB597D63DD3C0C35CA0C59049A3D933203926D89DFE3261D779B0217FD67DA2C273667AC9ECDBB323F33F80B823D9864' -login_url = 'https://login.mts.ru/amserver/UI/Login' # - другая форма логина - там оба поля на одной странице, и можно запомнить сессию -# login_url = 'https://lk.mts.ru/' # а на этой запомнить сессию нельзя +# login_url = 'https://login.mts.ru/amserver/UI/Login' # - другая форма логина - там оба поля на одной странице, и можно запомнить сессию +login_url = 'https://lk.mts.ru/' # а на этой запомнить сессию нельзя, но другой больше нет user_selectors = { # Возможно 2 разных формы логина, кроме того при заходе через мобильный МТС форма будет отличаться поэтому в выражении предусмотрены все варианты - 'chk_lk_page_js': "['form input[id=phoneInput]','form input[id=password]','form button[value=Ignore]','enter-with-phone-form'].filter(el => document.querySelector(el)!=null).length==0", - 'lk_page_url': 'login/userInfo', # не считаем что зашли в ЛК пока не прогрузим этот url + 'chk_lk_page_js': "['form input[name=login]','form input[id=phoneInput]','form input[id=password]','form button[value=Ignore]','enter-with-phone-form'].filter(el => document.querySelector(el)!== null).length==0", + # obsolete 'lk_page_url': 'login/userInfo', # не считаем что зашли в ЛК пока не прогрузим этот url # У нас форма из двух последовательных окон (хотя иногда бывает и одно, у МТС две разных формы логона) - 'chk_login_page_js': "['form input[id=phoneInput]','form input[id=password]','form button[value=Ignore]','enter-with-phone-form'].filter(el => document.querySelector(el)!=null).length>0", + 'chk_login_page_js': "['form input[name=login]','form input[id=phoneInput]','form input[id=password]','form button[value=Ignore]','enter-with-phone-form'].filter(el => document.querySelector(el)!== null).length>0", # Если мы зашли с интернета МТС то предлагается вариант зайти под номером владельца (есть два варианта этой формы), надо нажать кнопку проигнорить этот вариант 'before_login_js': """b1=document.querySelector('button[value=Ignore]'); if(b1!==null){b1.click()}; @@ -21,10 +21,10 @@ i2=document.getElementById('IDButton'); if(b2!==null && i2!==null){i2.value='Ignore';b2.submit.click();} """, - 'login_clear_js': "document.querySelector('form input[id=phoneInput]').value=''", - 'login_selector': 'form input[id=phoneInput]', + 'login_clear_js': "document.querySelector('form input[type=tel]').value=''", + 'login_selector': 'form input[type=tel]', # проверка нужен ли submit после логина (если поле пароля уже есть то не нужен, иначе нужен) - 'chk_submit_after_login_js': "document.querySelector('form input[id=phoneInput]')!=null || document.querySelector('form input[id=password]')==null", + 'chk_submit_after_login_js': "document.querySelector('form input[type=tel]')!=null || document.querySelector('form input[id=password]')==null", 'submit_after_login_js': "document.querySelectorAll('form [type=submit]').forEach(el => el.click())", # js для нажатия на далее после логона 'submit_js': "document.querySelectorAll('form [type=submit]').forEach(el => el.click())", # js для нажатия на финальный submit 'remember_checker': "document.querySelector('form input[name=rememberme]')!=null && document.querySelector('form input[name=rememberme]').checked==false", # Проверка что флаг remember me не выставлен @@ -40,45 +40,56 @@ def data_collector(self): 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())") + # 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(): # это финт для захода через другой номер # если заход через другой номер то переключаемся на нужный номер # TODO возможно с прошлого раза может сохраниться переключенный но вроде работает и так - self.page_wait_for(selector="[id=ng-header__account-phone_desktop]") + # New LK '.mts-multi-account' old LK [id=ng-header__account-phone_desktop] + self.page_wait_for(expression="document.querySelector('.mts-multi-account')!=null || document.querySelector('[id=ng-header__account-phone_desktop]')!=null") + self.responses = {} # Сбрасываем все загруженные данные - там данные по материнскому телефону - # Так больше не работает - # url_redirect = f'https://login.mts.ru/amserver/UI/Login?service=idp2idp&IDButton=switch&IDToken1=id={self.acc_num},ou=user,o=users,ou=services,dc=amroot&org=/users&ForceAuth=true&goto=https://lk.mts.ru' - # Так тоже больше не работает - # url_redirect = self.page_evaluate(f"Array.from(document.querySelectorAll('a.user-block__content')).filter(el => el.querySelector('.user-block__phone').innerText.replace(/\D/g,'').endsWith('{self.acc_num}'))[0].href") - # self.page_goto(url_redirect) # Теперь сразу кликаем на нужный блок, если и это сломают - будем кликать playwright - self.page_evaluate(f"Array.from(document.querySelectorAll('a.user-block__content')).filter(el => el.querySelector('.user-block__phone').innerText.replace(/\D/g,'').endsWith('{self.acc_num}'))[0].click()") + # Старый ЛК + if self.page_evaluate("document.querySelector('[id=ng-header__account-phone_desktop]')!=null", False): + self.page_evaluate(f"Array.from(document.querySelectorAll('a.user-block__content')).filter(el => el.querySelector('.user-block__phone').innerText.replace(/\D/g,'').endsWith('{self.acc_num}'))[0].click()") + # Новый ЛК + if self.page_evaluate("document.querySelector('.mts-multi-account')!=null", False): + self.page_evaluate(f"Array.from(document.querySelectorAll('.mts-multi-account .account-badge')).filter(el => el.querySelector('.account-badge__phone').innerText.replace(/\D/g,'').endsWith('{self.acc_num}'))[0].click()") # !!! Раньше я на каждой странице при таком заходе проверял что номер тот, сейчас проверяю только на старте for _ in range(10): self.sleep(1) - numb = self.page_evaluate("document.getElementById('ng-header__account-phone_desktop').innerText") + numb = '' + if self.page_evaluate("document.querySelector('[id=ng-header__account-phone_desktop]')!=null", False): + numb = self.page_evaluate("document.getElementById('ng-header__account-phone_desktop').innerText", None) + if self.page_evaluate("document.querySelector('.mts-multi-account')!=null", False): + numb = self.page_evaluate("document.querySelectorAll('.mts-multi-account .account-badge.active .account-badge__phone')[0].innerText", None) if numb is not None and numb !='': break else: return # номера на странице так и нет - уходим + numb = re.sub(r'(?:\+7|\D)', '', numb) logging.info(f'PHONE {numb}') - if re.sub(r'(?:\+7|\D)', '', numb) != self.acc_num: + if numb != self.acc_num: return # Если номер не наш - уходим + # 'api/login/userInfo' старый ЛК, 'api/login/user-info' новый ЛК остальное крое amount одинаковое + api_login_userinfo = 'api/login/user-info' + if self.page_evaluate("document.querySelector('[id=ng-header__account-phone_desktop]')!=null", False): + api_login_userinfo = 'api/login/userInfo' # Для начала только баланс быстрым способом (может запаздывать) self.wait_params(params=[ - {'name': 'Balance', 'url_tag': ['api/login/userInfo'], 'jsformula': "parseFloat(data.userProfile.balance).toFixed(2)"}, + {'name': 'Balance', 'url_tag': [api_login_userinfo], 'jsformula': "parseFloat(data.userProfile.balance).toFixed(2)"}, # Закрываем банеры (для эстетики) - {'name': '#banner1', 'url_tag': ['api/login/userInfo'], 'jsformula': "document.querySelectorAll('mts-dialog div[class=popup__close]').forEach(s=>s.click())", 'wait':False}, + {'name': '#banner1', 'url_tag': [api_login_userinfo], 'jsformula': "document.querySelectorAll('mts-dialog div[class=popup__close]').forEach(s=>s.click())", 'wait':False}, ]) # Потом все остальное res1 = self.wait_params(params=[ - {'name': 'TarifPlan', 'url_tag': ['api/login/userInfo'], 'jsformula': "data.userProfile.tariff.replace('(МАСС) (SCP)','')"}, - {'name': 'UserName', 'url_tag': ['api/login/userInfo'], 'jsformula': "data.userProfile.displayName"}, - {'name': 'Balance', 'url_tag': ['for=api/accountInfo/mscpBalance'], 'jsformula': "parseFloat(data.data.amount).toFixed(2)"}, + {'name': 'TarifPlan', 'url_tag': [api_login_userinfo], 'jsformula': "data.userProfile.tariff.replace('(МАСС) (SCP)','')"}, + {'name': 'UserName', 'url_tag': [api_login_userinfo], 'jsformula': "data.userProfile.displayName"}, + {'name': 'Balance', 'url_tag': ['for=api/accountInfo/mscpBalance'], 'jsformula': "parseFloat(data.data==null ? data.amount : data.data.amount).toFixed(2)"}, {'name': 'Balance2', 'url_tag': ['for=api/cashback/account'], 'jsformula': "parseFloat(data.data.balance).toFixed(2)"}, {'name': '#counters', 'url_tag': ['for=api/sharing/counters'], 'jsformula': "data.data.counters"}, ])