From b4cc7d46e473695c616219209ee7ddc862c135d7 Mon Sep 17 00:00:00 2001 From: CHUN YU YAO Date: Sun, 26 Feb 2023 16:39:37 +0800 Subject: [PATCH] MaxBot 2023-02-25, add new field ibonqware, fix ibon bugfixs. --- chrome_tixcraft.py | 269 ++++++++++++++++++++++++++++++--------------- settings.json | 2 +- settings.py | 91 ++++++++++++++- 3 files changed, 270 insertions(+), 92 deletions(-) diff --git a/chrome_tixcraft.py b/chrome_tixcraft.py index 09076d8..5eb95ca 100644 --- a/chrome_tixcraft.py +++ b/chrome_tixcraft.py @@ -53,7 +53,7 @@ import argparse import ssl ssl._create_default_https_context = ssl._create_unverified_context -CONST_APP_VERSION = u"MaxBot (2023.02.24)" +CONST_APP_VERSION = u"MaxBot (2023.02.25)" CONST_HOMEPAGE_DEFAULT = "https://tixcraft.com" URL_GOOGLE_OAUTH = 'https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground&prompt=consent&response_type=code&client_id=407408718192.apps.googleusercontent.com&scope=email&access_type=offline&flowName=GeneralOAuthFlow' @@ -154,6 +154,10 @@ def get_config_dict(args): if not args.kktix_password is None: if len(args.kktix_password) > 0: config_dict["advanced"]["kktix_password"] = args.kktix_password + if not args.ibonqware is None: + if len(args.ibonqware) > 0: + config_dict["advanced"]["ibonqware"] = encryptMe(args.ibonqware) + # special case for headless. is_headless_enable = False @@ -635,6 +639,14 @@ def get_driver_by_config(config_dict): tixcraft_sid = decryptMe(config_dict["advanced"]["tixcraft_sid"]) driver.delete_cookie("SID") driver.add_cookie({"name":"SID", "value": tixcraft_sid, "path" : "/", "secure":True}) + + + if 'ibon.com' in homepage: + if len(config_dict["advanced"]["ibonqware"]) > 1: + ibonqware = decryptMe(config_dict["advanced"]["ibonqware"]) + driver.delete_cookie("ibonqware") + driver.add_cookie({"name":"ibonqware", "value": ibonqware, "domain" : "ibon.com.tw", "secure":True}) + except WebDriverException as exce2: print('oh no not again, WebDriverException') print('WebDriverException:', exce2) @@ -1090,7 +1102,6 @@ def guess_answer_list_from_hint(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captch return return_list def format_question_string(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captcha_text_div_text): - tmp_text = captcha_text_div_text tmp_text = tmp_text.replace(u' ',u' ') tmp_text = tmp_text.replace(u':',u':') @@ -1159,6 +1170,37 @@ def get_answer_list_by_question(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captch return return_list +def force_press_button(driver, select_by, select_query, force_by_js=True): + ret = False + next_step_button = None + try: + next_step_button = driver.find_element(select_by ,select_query) + if not next_step_button is None: + if next_step_button.is_enabled(): + next_step_button.click() + ret = True + except Exception as exc: + print("find %s clickable Exception:" % (select_query)) + #print(exc) + pass + + if force_by_js: + if not next_step_button is None: + is_visible = False + try: + if next_step_button.is_enabled(): + is_visible = True + except Exception as exc: + pass + + if is_visible: + try: + driver.execute_script("arguments[0].click();", next_step_button) + ret = True + except Exception as exc: + pass + return ret + # close some div on home url. def tixcraft_home_close_window(driver): show_debug_message = True # debug. @@ -2283,43 +2325,14 @@ def kktix_confirm_order_button(driver): return ret + # PS: There are two "Next" button in kktix. # : 1: /events/xxx # : 2: /events/xxx/registrations/new # : This is ONLY for case-1, because case-2 lenght >5 def kktix_events_press_next_button(driver): - ret = False - - wait = WebDriverWait(driver, 1) - next_step_button = None - try: - # method #3 wait - next_step_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.tickets a.btn-point'))) - if not next_step_button is None: - if next_step_button.is_enabled(): - next_step_button.click() - ret = True - except Exception as exc: - print("wait form-actions div wait to be clickable Exception:") - #print(exc) - pass - - if not next_step_button is None: - is_visible = False - try: - if next_step_button.is_enabled(): - is_visible = True - except Exception as exc: - pass - - if is_visible: - try: - driver.execute_script("arguments[0].click();", next_step_button) - ret = True - except Exception as exc: - pass - - return ret + is_button_clicked = force_press_button(driver, By.CSS_SELECTOR,'div.tickets a.btn-point') + return is_button_clicked # : This is for case-2 next button. def kktix_press_next_button(driver): @@ -5071,19 +5084,22 @@ def ibon_area_auto_select(driver, area_auto_select_mode, area_keyword_1, area_ke for row in area_list: row_index += 1 row_is_enabled=True - try: - button_class_string = str(row.get_attribute('class')) - if len(button_class_string) > 1: - if 'disabled' in button_class_string: + + if row_is_enabled: + try: + if '已售完' in row.text: row_is_enabled=False - if 'sold-out' in button_class_string: - row_is_enabled=False - if 'selected' in button_class_string: - # someone is selected. skip this process. - is_price_assign_by_bot = True - break - except Exception as exc: - pass + except Exception as exc: + pass + + if row_is_enabled: + try: + button_class_string = str(row.get_attribute('class')) + if len(button_class_string) > 1: + if 'disabled' in button_class_string: + row_is_enabled=False + except Exception as exc: + pass if row_is_enabled: formated_area_list.append(row) @@ -5181,6 +5197,10 @@ def ibon_area_auto_select(driver, area_auto_select_mode, area_keyword_1, area_ke target_row_index = random.randint(0,len(matched_blocks)-1) target_area = matched_blocks[target_row_index] + else: + is_need_refresh = True + if show_debug_message: + print("matched_blocks is empty.") if target_area is not None: try: @@ -5218,6 +5238,12 @@ def ibon_performance(driver, config_dict): area_keyword_4 = config_dict["tixcraft"]["area_auto_select"]["area_keyword_4"].strip() area_keyword_1_and = "" area_keyword_2_and = "" + area_keyword_3_and = "" + area_keyword_4_and = "" + + area_keyword_2_enable = config_dict["tixcraft"]["area_auto_select"]["area_keyword_2_enable"] + area_keyword_3_enable = config_dict["tixcraft"]["area_auto_select"]["area_keyword_3_enable"] + area_keyword_4_enable = config_dict["tixcraft"]["area_auto_select"]["area_keyword_4_enable"] if show_debug_message: print("area_keyword_1:", area_keyword_1) @@ -5229,20 +5255,23 @@ def ibon_performance(driver, config_dict): if not is_price_assign_by_bot: is_need_refresh, is_price_assign_by_bot = ibon_area_auto_select(driver, area_auto_select_mode, area_keyword_1, area_keyword_1_and) - if not is_need_refresh: - if not is_price_assign_by_bot: - # try keyword_2 - if len(area_keyword_2) > 0: + if is_need_refresh: + if area_keyword_2_enable: is_need_refresh, is_price_assign_by_bot = ibon_area_auto_select(driver, area_auto_select_mode, area_keyword_2, area_keyword_2_and) + if show_debug_message: + print("is_need_refresh for keyword2:", is_need_refresh) - if not is_need_refresh: - if not is_price_assign_by_bot: - if len(area_keyword_3) > 0: - is_need_refresh, is_price_assign_by_bot = ibon_area_auto_select(driver, area_auto_select_mode, area_keyword_3, "") - if not is_need_refresh: - if not is_price_assign_by_bot: - if len(area_keyword_4) > 0: - is_need_refresh, is_price_assign_by_bot = ibon_area_auto_select(driver, area_auto_select_mode, area_keyword_4, "") + if is_need_refresh: + if area_keyword_3_enable: + is_need_refresh, is_price_assign_by_bot = ibon_area_auto_select(driver, area_auto_select_mode, area_keyword_3, area_keyword_3_and) + if show_debug_message: + print("is_need_refresh for keyword3:", is_need_refresh) + + if is_need_refresh: + if area_keyword_4_enable: + is_need_refresh, is_price_assign_by_bot = ibon_area_auto_select(driver, area_auto_select_mode, area_keyword_4, area_keyword_4_and) + if show_debug_message: + print("is_need_refresh for keyword4:", is_need_refresh) if is_need_refresh: try: @@ -5253,33 +5282,8 @@ def ibon_performance(driver, config_dict): return is_price_assign_by_bot def ibon_purchase_button_press(driver): - ret = False - - el_btn = None - try: - el_btn = driver.find_element(By.CSS_SELECTOR, '#ticket-wrap > a.btn') - except Exception as exc: - print("find next button fail...") - print(exc) - - if el_btn is not None: - print("bingo, found next button, start to press") - try: - if el_btn.is_enabled(): - el_btn.click() - ret = True - except Exception as exc: - print("click next button fail...") - print(exc) - # use plan B - try: - print("force to click by js.") - driver.execute_script("arguments[0].click();", el_btn) - ret = True - except Exception as exc: - pass - - return ret + is_button_clicked = force_press_button(driver, By.CSS_SELECTOR, '#ticket-wrap > a.btn') + return is_button_clicked def facebook_login(driver, account, password): ret = False @@ -6125,11 +6129,75 @@ def ibon_verification_question(driver, answer_index, config_dict): return answer_index +def ibon_ticket_agree(driver): + # check agree + form_checkbox = None + try: + form_checkbox = driver.find_element(By.ID, 'agreen') + except Exception as exc: + print("find #agreen fail") + + is_finish_checkbox_click = False + if form_checkbox is not None: + try: + # TODO: check the status: checked. + if form_checkbox.is_enabled(): + if not form_checkbox.is_selected(): + form_checkbox.click() + is_finish_checkbox_click = True + except Exception as exc: + print("click #agreen fail") + #pass + try: + print("use plan_b to check #agreen.") + driver.execute_script("$(\"input[type='checkbox']\").prop('checked', true);") + is_finish_checkbox_click = True + except Exception as exc: + print("javascript check #agreen fail") + print(exc) + pass + + return is_finish_checkbox_click + +def ibon_check_sold_out(driver): + is_sold_out = False + + # check agree + div_ticket_info = None + try: + div_ticket_info = driver.find_element(By.CSS_SELECTOR, '#ticket-info') + except Exception as exc: + print("find #ticket-info fail") + + if div_ticket_info is not None: + try: + div_ticket_info_text = div_ticket_info.text + if not div_ticket_info_text is None: + if '已售完' in div_ticket_info_text: + is_sold_out = True + except Exception as exc: + pass + + return is_sold_out + +def ibon_auto_signup(driver): + is_button_clicked = force_press_button(driver, By.CSS_SELECTOR, '.btn.btn-signup') + return is_button_clicked + def ibon_main(driver, url, config_dict, ibon_dict): + # https://tour.ibon.com.tw/event/e23010000300mxu + if 'tour' in url and '/event/' in url: + is_event_page = False + if len(url.split('/'))==5: + is_event_page = True + + if is_event_page: + ibon_auto_signup(driver) + #https://ticket.ibon.com.tw/ActivityInfo/Details/0000?pattern=entertainment if '/ActivityInfo/Details/' in url: is_event_page = False - if len(url.split('/'))<=6: + if len(url.split('/'))==6: is_event_page = True if is_event_page: @@ -6152,7 +6220,7 @@ def ibon_main(driver, url, config_dict, ibon_dict): # https://orders.ibon.com.tw/application/UTK02/UTK0201_000.aspx?PERFORMANCE_ID=0000 if '/application/UTK02/' in url and '.aspx?PERFORMANCE_ID=' in url: is_event_page = False - if len(url.split('/'))<=6: + if len(url.split('/'))==6: is_event_page = True if is_event_page: @@ -6164,10 +6232,33 @@ def ibon_main(driver, url, config_dict, ibon_dict): is_ticket_number_assigned = ibon_ticket_number_auto_select(driver, ticket_number) if is_ticket_number_assigned: click_ret = ibon_purchase_button_press(driver) + else: + is_sold_out = ibon_check_sold_out(driver) + if is_sold_out: + #is_button_clicked = force_press_button(driver, By.CSS_SELECTOR, 'a.btn.btn-primary') + driver.back() + driver.refresh() else: # step 1: select area. ibon_performance(driver, config_dict) + #https://orders.ibon.com.tw/application/UTK02/UTK0206_.aspx + if 'orders.ibon.com.tw/application/UTK02/UTK020' in url and '.aspx' in url: + is_event_page = False + if len(url.split('/'))==6: + is_event_page = True + + if is_event_page: + auto_check_agree = config_dict["auto_check_agree"] + if auto_check_agree: + is_finish_checkbox_click = False + for i in range(3): + is_finish_checkbox_click = ibon_ticket_agree(driver) + if is_finish_checkbox_click: + break + if is_finish_checkbox_click: + is_button_clicked = force_press_button(driver, By.CSS_SELECTOR, 'a.btn.btn-pink.continue') + return ibon_dict def hkticketing_home(driver): @@ -8135,6 +8226,10 @@ def cli(): help="overwrite kktix_password field", type=str) + parser.add_argument("--ibonqware", + help="overwrite ibonqware field", + type=str) + parser.add_argument("--headless", help="headless mode", default='False', diff --git a/settings.json b/settings.json index c296ce5..f694369 100644 --- a/settings.json +++ b/settings.json @@ -1 +1 @@ -{"homepage": "https://tixcraft.com", "browser": "chrome", "language": "\u7e41\u9ad4\u4e2d\u6587", "ticket_number": 2, "pass_1_seat_remaining": true, "auto_check_agree": true, "ocr_captcha": {"enable": true, "force_submit": false, "image_source": "canvas"}, "webdriver_type": "undetected_chromedriver", "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true, "area_mode": "from top to bottom", "area_keyword_1": "", "area_keyword_1_and": "", "area_keyword_2": "", "area_keyword_2_and": "", "area_keyword_2_enable": true, "auto_guess_options": true, "user_guess_string": ""}, "tixcraft": {"date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}, "area_auto_select": {"enable": true, "area_keyword_1": "", "area_keyword_2": "", "area_keyword_3": "", "area_keyword_4": "", "area_keyword_2_enable": true, "area_keyword_3_enable": true, "area_keyword_4_enable": true, "mode": "from top to bottom"}, "pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true, "presale_code": "", "presale_code_delimiter": ""}, "advanced": {"play_captcha_sound": {"enable": true, "filename": "ding-dong.wav"}, "tixcraft_sid": "", "facebook_account": "", "kktix_account": "", "cityline_account": "", "urbtix_account": "", "hkticketing_account": "", "kham_account": "", "facebook_password": "", "kktix_password": "", "cityline_password": "", "urbtix_password": "", "hkticketing_password": "", "kham_password": "", "adblock_plus_enable": false, "open_google_oauth_url": false, "headless": false}, "debug": false} \ No newline at end of file +{"homepage": "https://tixcraft.com", "browser": "chrome", "language": "\u7e41\u9ad4\u4e2d\u6587", "ticket_number": 2, "pass_1_seat_remaining": true, "auto_check_agree": true, "ocr_captcha": {"enable": true, "force_submit": false, "image_source": "canvas"}, "webdriver_type": "undetected_chromedriver", "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true, "area_mode": "from top to bottom", "area_keyword_1": "", "area_keyword_1_and": "", "area_keyword_2": "", "area_keyword_2_and": "", "area_keyword_2_enable": true, "auto_guess_options": true, "user_guess_string": ""}, "tixcraft": {"date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}, "area_auto_select": {"enable": true, "area_keyword_1": "", "area_keyword_2": "", "area_keyword_3": "", "area_keyword_4": "", "area_keyword_2_enable": true, "area_keyword_3_enable": true, "area_keyword_4_enable": true, "mode": "from top to bottom"}, "pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true, "presale_code": "", "presale_code_delimiter": ""}, "advanced": {"play_captcha_sound": {"enable": true, "filename": "ding-dong.wav"}, "tixcraft_sid": "", "ibonqware": "", "facebook_account": "", "kktix_account": "", "cityline_account": "", "urbtix_account": "", "hkticketing_account": "", "kham_account": "", "facebook_password": "", "kktix_password": "", "cityline_password": "", "urbtix_password": "", "hkticketing_password": "", "kham_password": "", "adblock_plus_enable": false, "open_google_oauth_url": false, "headless": false}, "debug": false} \ No newline at end of file diff --git a/settings.py b/settings.py index 48926fc..912297e 100644 --- a/settings.py +++ b/settings.py @@ -20,7 +20,9 @@ import webbrowser import pyperclip import base64 -CONST_APP_VERSION = u"MaxBot (2023.02.24)" +CONST_APP_VERSION = u"MaxBot (2023.02.25)" + +CONST_SETTINGS_CONFIG_FILENAME = "settings.json" CONST_FROM_TOP_TO_BOTTOM = u"from top to bottom" CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top" @@ -104,9 +106,11 @@ def load_translate(): en_us["exit"] = 'Close' en_us["copy"] = 'Copy' en_us["restore_defaults"] = 'Restore Defaults' + en_us["config_launcher"] = 'Launcher' en_us["done"] = 'Done' en_us["tixcraft_sid"] = 'Tixcraft cookie SID' + en_us["ibon_ibonqware"] = 'ibon cookie ibonqware' en_us["facebook_account"] = 'Facebook account' en_us["kktix_account"] = 'KKTIX account' en_us["cityline_account"] = 'cityline account' @@ -181,9 +185,11 @@ def load_translate(): zh_tw["exit"] = '關閉' zh_tw["copy"] = '複製' zh_tw["restore_defaults"] = '恢復預設值' + zh_tw["config_launcher"] = '設定檔管理' zh_tw["done"] = '完成' zh_tw["tixcraft_sid"] = 'Tixcraft cookie SID' + zh_tw["ibon_ibonqware"] = 'ibon cookie ibonqware' zh_tw["facebook_account"] = 'Facebook 帳號' zh_tw["kktix_account"] = 'KKTIX 帳號' zh_tw["cityline_account"] = 'cityline 帳號' @@ -259,9 +265,11 @@ def load_translate(): zh_cn["exit"] = '关闭' zh_cn["copy"] = '复制' zh_cn["restore_defaults"] = '恢复默认值' + zh_cn["config_launcher"] = '设定档管理' zh_cn["done"] = '完成' zh_cn["tixcraft_sid"] = 'Tixcraft cookie SID' + zh_cn["ibon_ibonqware"] = 'ibon cookie ibonqware' zh_cn["facebook_account"] = 'Facebook 帐号' zh_cn["kktix_account"] = 'KKTIX 帐号' zh_cn["cityline_account"] = 'cityline 帐号' @@ -336,9 +344,11 @@ def load_translate(): ja_jp["exit"] = '閉じる' ja_jp["copy"] = 'コピー' ja_jp["restore_defaults"] = 'デフォルトに戻す' + ja_jp["config_launcher"] = 'ランチャー' ja_jp["done"] = '終わり' ja_jp["tixcraft_sid"] = 'Tixcraft cookie SID' + ja_jp["ibon_ibonqware"] = 'ibon cookie ibonqware' ja_jp["facebook_account"] = 'Facebookのアカウント' ja_jp["kktix_account"] = 'KKTIXのアカウント' ja_jp["cityline_account"] = 'citylineのアカウント' @@ -455,6 +465,7 @@ def get_default_config(): config_dict["advanced"]["play_captcha_sound"]["filename"] = CONST_CAPTCHA_SOUND_FILENAME_DEFAULT config_dict["advanced"]["tixcraft_sid"] = "" + config_dict["advanced"]["ibonqware"] = "" config_dict["advanced"]["facebook_account"] = "" config_dict["advanced"]["kktix_account"] = "" config_dict["advanced"]["cityline_account"] = "" @@ -481,7 +492,7 @@ def load_json(): app_root = get_app_root() # overwrite config path. - config_filepath = os.path.join(app_root, 'settings.json') + config_filepath = os.path.join(app_root, CONST_SETTINGS_CONFIG_FILENAME) config_dict = None if os.path.isfile(config_filepath): @@ -493,7 +504,7 @@ def load_json(): def btn_restore_defaults_clicked(language_code): app_root = get_app_root() - config_filepath = os.path.join(app_root, 'settings.json') + config_filepath = os.path.join(app_root, CONST_SETTINGS_CONFIG_FILENAME) config_dict = get_default_config() import json @@ -504,12 +515,61 @@ def btn_restore_defaults_clicked(language_code): global root load_GUI(root, config_dict) +def btn_launcher_clicked(language_code): + import subprocess + + print('run button pressed.') + Root_Dir = "" + save_ret = btn_save_act(language_code, slience_mode=True) + print("save config result:", save_ret) + if save_ret: + working_dir = os.path.dirname(os.path.realpath(__file__)) + if hasattr(sys, 'frozen'): + print("execute in frozen mode") + + # check platform here. + if platform.system() == 'Darwin': + print("execute MacOS python script") + subprocess.Popen("./config_launcher", shell=True, cwd=working_dir) + if platform.system() == 'Linux': + print("execute linux binary") + subprocess.Popen("./config_launcher", shell=True, cwd=working_dir) + if platform.system() == 'Windows': + print("execute .exe binary.") + subprocess.Popen("config_launcher.exe", shell=True, cwd=working_dir) + else: + interpreter_binary = 'python' + interpreter_binary_alt = 'python3' + if platform.system() == 'Darwin': + # try python3 before python. + interpreter_binary = 'python3' + interpreter_binary_alt = 'python' + print("execute in shell mode.") + #print("script path:", working_dir) + #messagebox.showinfo(title="Debug0", message=working_dir) + + # some python3 binary, running in 'python' command. + try: + print('try', interpreter_binary) + s=subprocess.Popen([interpreter_binary, 'config_launcher.py'], cwd=working_dir) + #s=subprocess.Popen(['./chrome_tixcraft'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=working_dir) + #s=subprocess.run(['python3', 'chrome_tixcraft.py'], cwd=working_dir) + #messagebox.showinfo(title="Debug1", message=str(s)) + except Exception as exc: + print('try', interpreter_binary_alt) + try: + s=subprocess.Popen([interpreter_binary_alt, 'config_launcher.py'], cwd=working_dir) + except Exception as exc: + msg=str(exc) + print("exeption:", msg) + #messagebox.showinfo(title="Debug2", message=msg) + pass def btn_save_clicked(language_code): btn_save_act(language_code) def btn_save_act(language_code, slience_mode=False): app_root = get_app_root() - config_filepath = os.path.join(app_root, 'settings.json') + config_filepath = os.path.join(app_root, CONST_SETTINGS_CONFIG_FILENAME) config_dict = get_default_config() @@ -550,6 +610,7 @@ def btn_save_act(language_code, slience_mode=False): global txt_presale_code_delimiter global txt_tixcraft_sid + global txt_ibon_ibonqware global txt_facebook_account global txt_kktix_account global txt_cityline_account @@ -651,6 +712,7 @@ def btn_save_act(language_code, slience_mode=False): config_dict["advanced"]["play_captcha_sound"]["filename"] = txt_captcha_sound_filename.get().strip() config_dict["advanced"]["tixcraft_sid"] = txt_tixcraft_sid.get().strip() + config_dict["advanced"]["ibonqware"] = txt_ibon_ibonqware.get().strip() config_dict["advanced"]["facebook_account"] = txt_facebook_account.get().strip() config_dict["advanced"]["kktix_account"] = txt_kktix_account.get().strip() config_dict["advanced"]["cityline_account"] = txt_cityline_account.get().strip() @@ -666,6 +728,7 @@ def btn_save_act(language_code, slience_mode=False): config_dict["advanced"]["kham_password"] = txt_kham_password.get().strip() config_dict["advanced"]["tixcraft_sid"] = encryptMe(config_dict["advanced"]["tixcraft_sid"]) + config_dict["advanced"]["ibonqware"] = encryptMe(config_dict["advanced"]["ibonqware"]) config_dict["advanced"]["facebook_password"] = encryptMe(config_dict["advanced"]["facebook_password"]) config_dict["advanced"]["kktix_password"] = encryptMe(config_dict["advanced"]["kktix_password"]) config_dict["advanced"]["cityline_password"] = encryptMe(config_dict["advanced"]["cityline_password"]) @@ -947,6 +1010,7 @@ def applyNewLanguage(): tabControl.tab(3, text=translate[language_code]["about"]) global lbl_tixcraft_sid + global lbl_ibon_ibonqware global lbl_facebook_account global lbl_kktix_account global lbl_cityline_account @@ -967,6 +1031,7 @@ def applyNewLanguage(): global lbl_captcha_sound_filename lbl_tixcraft_sid.config(text=translate[language_code]["tixcraft_sid"]) + lbl_ibon_ibonqware.config(text=translate[language_code]["ibon_ibonqware"]) lbl_facebook_account.config(text=translate[language_code]["facebook_account"]) lbl_kktix_account.config(text=translate[language_code]["kktix_account"]) lbl_cityline_account.config(text=translate[language_code]["cityline_account"]) @@ -999,12 +1064,14 @@ def applyNewLanguage(): global btn_save global btn_exit global btn_restore_defaults + global btn_launcher btn_run.config(text=translate[language_code]["run"]) btn_save.config(text=translate[language_code]["save"]) if btn_exit: btn_exit.config(text=translate[language_code]["exit"]) btn_restore_defaults.config(text=translate[language_code]["restore_defaults"]) + btn_launcher.config(text=translate[language_code]["config_launcher"]) def callbackHomepageOnChange(event): showHideBlocks() @@ -1970,6 +2037,17 @@ def AutofillTab(root, config_dict, language_code, UI_PADDING_X): group_row_count +=1 + global lbl_ibon_ibonqware + lbl_ibon_ibonqware = Label(frame_group_header, text=translate[language_code]['ibon_ibonqware']) + lbl_ibon_ibonqware.grid(column=0, row=group_row_count, sticky = E) + + global txt_ibon_ibonqware + txt_ibon_ibonqware_value = StringVar(frame_group_header, value=decryptMe(config_dict["advanced"]["ibonqware"].strip())) + txt_ibon_ibonqware = Entry(frame_group_header, width=20, textvariable = txt_ibon_ibonqware_value, show="*") + txt_ibon_ibonqware.grid(column=1, row=group_row_count, sticky = W) + + group_row_count +=1 + global lbl_facebook_account lbl_facebook_account = Label(frame_group_header, text=translate[language_code]['facebook_account']) lbl_facebook_account.grid(column=0, row=group_row_count, sticky = E) @@ -2205,6 +2283,7 @@ def get_action_bar(root, language_code): global btn_save global btn_exit global btn_restore_defaults + global btn_launcher btn_run = ttk.Button(frame_action, text=translate[language_code]['run'], command= lambda: btn_run_clicked(language_code)) btn_run.grid(column=0, row=0) @@ -2218,6 +2297,10 @@ def get_action_bar(root, language_code): btn_restore_defaults = ttk.Button(frame_action, text=translate[language_code]['restore_defaults'], command= lambda: btn_restore_defaults_clicked(language_code)) btn_restore_defaults.grid(column=2, row=0) + btn_launcher = ttk.Button(frame_action, text=translate[language_code]['config_launcher'], command= lambda: btn_launcher_clicked(language_code)) + btn_launcher.grid(column=3, row=0) + + return frame_action def clearFrame(frame):