diff --git a/changelist.md b/changelist.md
index 9d00c8a..571bacc 100644
--- a/changelist.md
+++ b/changelist.md
@@ -524,5 +524,8 @@ FIX: исправил нажатие на submit на megafonb2b
FIX: pasha00000 прислал добавление по проверку на окончания срока действия абонемента avtodor-tr
FIX: pasha00000 прислал PR на исправление работы mangooffice
-## mbplugin v1.00.59 (01.08.23) fix beeline web
+## mbplugin v1.00.59 (03.08.23) fix beeline web, mts proxy, null_is_error option
FIX: еще раз (похоже не в последний) починил и ускорил работу WEB версии Beeline (напомню что по умолчанию по прежнему API)
+ADD: Опция null_is_error - считать нулевой баланс ошибкой, может быть использована как глобально, так и для конкретного телефона
+FIX: Исправлена работа через proxy на МТС и запуск хрома на linix и mac (issues 38 from yoman88111)
+ADD: Добавил утилиту csv_to_phones_ini.py из issue 36
diff --git a/mbplugin_ini.md b/mbplugin_ini.md
index d21b1db..122ba01 100644
--- a/mbplugin_ini.md
+++ b/mbplugin_ini.md
@@ -147,6 +147,10 @@
Описание: Что делать с полем balances
Значение по умолчанию: nochange
Варианты значения balances: nochange swap add
+## __null_is_error__
+Описание: Что делать с полем balances
+Значение по умолчанию: 0
+Варианты значения null_is_error: 0 - выключено или 1 - включено
## __subscription_keyword__
Описание: Признаки подписок, через запятую
Значение по умолчанию: 90 дней,TV Club,Услуга4,unwanted,нежелательная
diff --git a/plugin/csv_to_phones_ini.py b/plugin/csv_to_phones_ini.py
new file mode 100644
index 0000000..822c331
--- /dev/null
+++ b/plugin/csv_to_phones_ini.py
@@ -0,0 +1,27 @@
+'''
+https://github.com/artyl/mbplugin/issues/36
+Конвертер csv -> phones.ini
+Решил сделать более универсальный вариант.
+В файле phones.csv находятся все поля которые должны попасть в phones.ini разделенные табуляцией (если хотите другой символ его можно поменять в первой строчке файла скрипта csv_to_phones_ini.py)
+В архиве скрипт и пример CSV файла
+csv_to_phones_ini.zip
+Первая строчка phones.csv это заголовки (то что в ini будет перед равно) строчки начиная со второй - значения
+кладете в одну папку файл csv_to_phones_ini.py из архива и подготовленный csv файл.
+Запускаете (исправьте на путь к Вашему python)
+C:\mbstandalone\mbplugin\python\python.exe csv_to_phones_ini.py
+После запуска будет создан файл phones.gen.ini проверяете, если все ок - переименовываете и кладете вместо phones.ini
+Задача разовая, так что не уверен что стоит это добавлять в код mbplugin как опцию пока оставим в таком сыром виде.
+Возможно потом сделаю в более удобоваримом виде.
+'''
+
+delimeter = '\t'
+data = open('phones.csv', encoding='cp1251').read().strip().splitlines()
+res = []
+headers = data[0].split(delimeter)
+for num, lines in enumerate(data[1:], 1):
+ res.append(f'\n[Phone] #{num}')
+ for ne, el in enumerate(lines.split(delimeter)):
+ res.append(f'{headers[ne]} = {el}')
+print(('\n'.join(res)).strip())
+open('phones.gen.ini', 'w').write(('\n'.join(res)).strip())
+
diff --git a/plugin/httpserver_mobile.py b/plugin/httpserver_mobile.py
index 64f77bb..9a2f46d 100644
--- a/plugin/httpserver_mobile.py
+++ b/plugin/httpserver_mobile.py
@@ -216,14 +216,12 @@ def getbalance_plugin(method, param_source):
logging.info(f'Jitter {j_time:.2f} seconds')
time.sleep(j_time)
result = module.get_balance(param['login'], param['password'], storename, pkey=pkey)
- result = store.correct_result(result, pkey=pkey)
- if type(result) != dict or 'Balance' not in result:
- raise RuntimeError(f'В result отсутствует баланс')
+ result = store.correct_and_check_result(result, pkey=pkey)
text = store.result_to_html(result)
except Exception:
logging.info(f'{plugin} fail: {store.exception_text()}')
dbengine.flags('set', f"{lang}_{plugin}_{param['login']}", f'error call {time.asctime()}') # выставляем флаг о ошибке вызова
- return 'text/html', [f"Error call {param['fplugin']}"]
+ return 'text/html', [f"Error call {param['fplugin']}
{store.exception_text()}"] dbengine.flags('delete', f"{lang}_{plugin}_{param['login']}", 'start') # запрос завершился успешно - сбрасываем флаг try: # пишем в базу diff --git a/plugin/mbplugin.py b/plugin/mbplugin.py index c9d38c7..c914c63 100644 --- a/plugin/mbplugin.py +++ b/plugin/mbplugin.py @@ -51,9 +51,7 @@ def main(): storename = re.sub(r'\W', '_', f'{lang}_{plugin}_{login}') pkey = store.get_pkey(login, plugin) # Пара (номер, оператор) result = module.get_balance(login, password, storename, pkey=pkey) - result = store.correct_result(result, pkey=pkey) - if 'Balance' not in result: - raise RuntimeError(f'В result отсутствует баланс') + result = store.correct_and_check_result(result, pkey=pkey) except Exception: exception_text = f'Ошибка при вызове модуля \n{plugin}: {store.exception_text()}' logging.error(exception_text) diff --git a/plugin/mts.py b/plugin/mts.py index 933e472..15d7112 100644 --- a/plugin/mts.py +++ b/plugin/mts.py @@ -34,11 +34,12 @@ def exception_text(): class PureBrowserDebug(): - def __init__(self, user_data_dir, response_store_path=None, headless_chrome=False, show_chrome=True) -> None: + def __init__(self, user_data_dir, response_store_path=None, headless_chrome=False, show_chrome=True, chrome_args=None) -> None: self.user_data_dir = user_data_dir # chrome profile path self.response_store_path = response_store_path # path for file log, screenshot store fith same name but png extension self.headless = headless_chrome # for mts headles is broken headless_chrome always False self.show_chrome = show_chrome + self.chrome_args = chrome_args if type(chrome_args) == list else [] # additional cmd argements for chrome self.port = get_free_port() # port for CDP self._data: List[dict] = [] # store all winsocket reply self.chrome_hwnd: List[int] = [] # store chrome visible windows handle (windows only) @@ -107,10 +108,10 @@ def run_chromium(self): self.browser_path = os.path.join(pbp, f'chromium-{revision}', 'chrome-win', 'chrome.exe') elif sys.platform == 'linux': pbp = os.environ.get('PLAYWRIGHT_BROWSERS_PATH', os.path.join(pathlib.Path.home(), '.cache', 'ms-playwright')) - self.browser_path = os.path.join(pbp, f'chromium-{revision}', 'chrome-win', 'chrome') + self.browser_path = os.path.join(pbp, f'chromium-{revision}', 'chrome-linux', 'chrome') elif sys.platform == 'darwin': pbp = os.environ.get('PLAYWRIGHT_BROWSERS_PATH', os.path.join(pathlib.Path.home(), 'Library', 'Caches', 'ms-playwright')) - self.browser_path = os.path.join(pbp, f'chromium-{revision}', 'chrome-win', 'chrome') + self.browser_path = os.path.join(pbp, f'chromium-{revision}', 'chrome-mac', 'chrome') else: raise RuntimeError(f'Unknown platform {sys.platform} Chromium not found') if not os.path.exists(self.browser_path): @@ -119,6 +120,7 @@ def run_chromium(self): logging.error(exception_text()) raise RuntimeError('Chromium not found') self.cmd = [self.browser_path, f'--user-data-dir={self.user_data_dir}', f'--remote-debugging-port={self.port}', '--enable-features=NetworkService,NetworkServiceInProcess', '--disable-save-password-bubble', '--no-default-browser-check', ' --disable-component-update', '--disable-extensions', '--disable-sync', '--no-first-run', '--no-service-autorun', f'--remote-allow-origins=http://localhost:{self.port}'] + self.cmd.extend(self.chrome_args) # ??? ' --headless --no-sandbox about:blank' logging.info(f'Browser start: {" ".join(self.cmd)}') proc = subprocess.Popen(self.cmd) @@ -375,7 +377,10 @@ def wait_state(timeout=30): result = {} headless_chrome = False # FIX !!! МТС в headless не работает show_chrome = True # FIX !!! МТС без show_chrome не работает - pd = PureBrowserDebug(user_data_dir, response_store_path, headless_chrome=headless_chrome, show_chrome=show_chrome) + chrome_args = [] + if options('browser_proxy').strip() != '': + chrome_args.append(f'--proxy-server={options("browser_proxy").strip()}') + pd = PureBrowserDebug(user_data_dir, response_store_path, headless_chrome=headless_chrome, show_chrome=show_chrome, chrome_args=chrome_args) # 1 Is login ??? store.feedback.text(f"Run browser", append=True) pd.send('Page.navigate', {'url': login_url}) diff --git a/plugin/settings.py b/plugin/settings.py index 564c151..fa7a8ff 100644 --- a/plugin/settings.py +++ b/plugin/settings.py @@ -181,6 +181,9 @@ # Что делать с полями balance и balance2. ничего/(поменять местами с balance)/(прибавить к балансу) 'balances_': {'descr': 'Что делать с полем balances', 'type': 'select', 'variants': 'nochange swap add'}, 'balances': 'nochange', + # Считать нулевой баланс ошибкой (если включен balances=swap то ошибка будет если нулевой Balance2) + 'null_is_error_': {'descr': 'Что делать с полем balances', 'type': 'checkbox'}, + 'null_is_error': '0', # Слова, которые встречаются в названиях тарифов, про которые нужно выдать предупреждение и красить номер, нежелательные unwanted услуги 'subscription_keyword_': {'descr': 'Признаки подписок, через запятую', 'type': 'text'}, 'subscription_keyword': '90 дней,TV Club,Услуга4,unwanted,нежелательная', diff --git a/plugin/store.py b/plugin/store.py index 61bef20..c9db45c 100644 --- a/plugin/store.py +++ b/plugin/store.py @@ -105,8 +105,8 @@ def fix_num_params(result, int_params): result[k] = round(v, 2) # Чтобы не было паразитных микрокопеек return result -def correct_result(result, pkey): - 'Дополнительные коррекции после проверки' +def correct_and_check_result(result, pkey): + 'Дополнительные коррекции после проверки и проверка результата на валидность' if type(result) != dict: return result result = fix_num_params(result, int_params=['SMS', 'Min']) @@ -120,6 +120,10 @@ def correct_result(result, pkey): except Exception: logging.error(f"Addition error for {repr(result['Balance'])}+{repr(result['Balance2'])}: {exception_text()}") logging.info(f"Balance correct by option.balances={options('balances', pkey=pkey)} {[b, b2]} -> {[result['Balance'], result['Balance2']]}") + if type(result) != dict or 'Balance' not in result: + raise RuntimeError(f'В result отсутствует баланс') + if str(options('null_is_error', pkey=pkey)) == '1' and str(result['Balance']) == '0': + raise RuntimeError(f'Нулевой баланс считаем ошибкой. В result отсутствует баланс') return result class Feedback(): diff --git a/plugin/util.py b/plugin/util.py index 9500f50..63e4453 100644 --- a/plugin/util.py +++ b/plugin/util.py @@ -577,7 +577,7 @@ def check_plugin(ctx, bpoint, params, plugin, login, password): _ = login, password, storename # dummy linter - use in pdbpdb.run result = pdbpdb.run("module.get_balance(login, password, storename)", globals(), locals()) pkey = store.get_pkey(login, plugin) - result = store.correct_result(result, pkey) + result = store.correct_and_check_result(result, pkey) # res = exec("httpserver_mobile.getbalance_plugin('url', [plugin, login, password, '123'])", globals(), locals()) # breakpoint() else: