2023-06-17, online dictionary support json format, ibon support dictionary anwser feature.

master
CHUN YU YAO 2023-06-17 00:04:55 +08:00
parent e090be7d29
commit 57535ea7a1
5 changed files with 285 additions and 290 deletions

View File

@ -53,7 +53,7 @@ import webbrowser
import argparse import argparse
import itertools import itertools
CONST_APP_VERSION = "MaxBot (2023.6.16)" CONST_APP_VERSION = "MaxBot (2023.6.17)"
CONST_MAXBOT_CONFIG_FILE = "settings.json" CONST_MAXBOT_CONFIG_FILE = "settings.json"
CONST_MAXBOT_LAST_URL_FILE = "MAXBOT_LAST_URL.txt" CONST_MAXBOT_LAST_URL_FILE = "MAXBOT_LAST_URL.txt"
@ -197,7 +197,6 @@ def get_config_dict(args):
return config_dict return config_dict
def write_question_to_file(question_text): def write_question_to_file(question_text):
print("write_question_to_file:", question_text)
with open(CONST_MAXBOT_QUESTION_FILE, "w") as text_file: with open(CONST_MAXBOT_QUESTION_FILE, "w") as text_file:
text_file.write("%s" % question_text) text_file.write("%s" % question_text)
@ -1379,7 +1378,7 @@ def get_answer_list_by_question(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captch
return return_list return return_list
def force_press_button(driver, select_by, select_query, force_by_js=True): def force_press_button(driver, select_by, select_query, force_submit=True):
ret = False ret = False
next_step_button = None next_step_button = None
try: try:
@ -1393,7 +1392,7 @@ def force_press_button(driver, select_by, select_query, force_by_js=True):
#print(exc) #print(exc)
pass pass
if force_by_js: if force_submit:
if not next_step_button is None: if not next_step_button is None:
is_visible = False is_visible = False
try: try:
@ -2269,13 +2268,7 @@ def tixcraft_ticket_number_auto_fill(driver, select_obj, ticket_number):
return is_ticket_number_assigned return is_ticket_number_assigned
def guess_tixcraft_question(driver): def get_tixcraft_question_text(driver):
show_debug_message = True # debug.
show_debug_message = False # online
inferred_answer_string = None
answer_list = []
form_select = None form_select = None
try: try:
form_select = driver.find_element(By.CSS_SELECTOR, '.zone-verify') form_select = driver.find_element(By.CSS_SELECTOR, '.zone-verify')
@ -2283,17 +2276,27 @@ def guess_tixcraft_question(driver):
print("find verify textbox fail") print("find verify textbox fail")
pass pass
question_text = None question_text = ""
if form_select is not None: if form_select is not None:
try: try:
question_text = form_select.text question_text = form_select.text
except Exception as exc: except Exception as exc:
print("get text fail") print("get text fail")
if question_text is None:
question_text = ""
return question_text
def guess_tixcraft_question(driver, question_text):
show_debug_message = True # debug.
show_debug_message = False # online
inferred_answer_string = None
answer_list = []
formated_html_text = "" formated_html_text = ""
if question_text is not None:
if len(question_text) > 0: if len(question_text) > 0:
write_question_to_file(question_text)
# format question text. # format question text.
formated_html_text = question_text formated_html_text = question_text
formated_html_text = formated_html_text.replace(u'',u'') formated_html_text = formated_html_text.replace(u'',u'')
@ -2316,8 +2319,6 @@ def guess_tixcraft_question(driver):
if show_debug_message: if show_debug_message:
print("formated_html_text:", formated_html_text) print("formated_html_text:", formated_html_text)
is_options_in_question = False
# 請輸入"YES",代表您已詳閱且瞭解並同意。 # 請輸入"YES",代表您已詳閱且瞭解並同意。
if inferred_answer_string is None: if inferred_answer_string is None:
if u'輸入"YES"' in formated_html_text: if u'輸入"YES"' in formated_html_text:
@ -2332,13 +2333,99 @@ def guess_tixcraft_question(driver):
if '輸入【同意】' in formated_html_text: if '輸入【同意】' in formated_html_text:
inferred_answer_string = '同意' inferred_answer_string = '同意'
if inferred_answer_string is None: if len(question_text) > 0:
if not question_text is None:
inferred_answer_string, answer_list = get_answer_list_from_question_string(None, question_text) inferred_answer_string, answer_list = get_answer_list_from_question_string(None, question_text)
return inferred_answer_string, answer_list return inferred_answer_string, answer_list
def tixcraft_verify(driver, config_dict, answer_index): def fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_list, input_text_css, next_step_button_css, submit_by_enter):
show_debug_message = True # debug.
show_debug_message = False # online
if config_dict["advanced"]["verbose"]:
show_debug_message = True
form_input_list = []
try:
form_input_list = driver.find_elements(By.CSS_SELECTOR, input_text_css)
except Exception as exc:
if show_debug_message:
print("find verify code input textbox fail")
pass
if form_input_list is None:
form_input_list = []
form_input_count = len(form_input_list)
if show_debug_message:
print("input textbox count:", form_input_count)
is_do_press_next_button = False
form_input = None
if form_input_count > 0:
form_input = form_input_list[0]
if form_input_count == 1:
is_do_press_next_button = True
inputed_value = None
if form_input is not None:
try:
inputed_value = form_input.get_attribute('value')
except Exception as exc:
if show_debug_message:
print("get_attribute of verify code fail")
pass
if inputed_value is None:
inputed_value = ""
is_answer_sent = False
if form_input is not None:
if len(inferred_answer_string) > 0:
try:
# PS: sometime may send key twice...
form_input.clear()
form_input.send_keys(inferred_answer_string)
is_button_clicked = False
if is_do_press_next_button:
if submit_by_enter:
form_input.send_keys(Keys.ENTER)
is_button_clicked = True
if len(next_step_button_css) > 0:
is_button_clicked = force_press_button(driver, By.CSS_SELECTOR, next_step_button_css)
if is_button_clicked:
is_answer_sent = True
fail_list.append(inferred_answer_string)
if show_debug_message:
print("sent password by bot:", inferred_answer_string, " at #", len(fail_list))
except Exception as exc:
if show_debug_message:
print(exc)
pass
if is_answer_sent:
for i in range(3):
time.sleep(0.1)
alert_ret = check_pop_alert(driver)
if alert_ret:
if show_debug_message:
print("press accept button at time #", i+1)
break
else:
# no answer to fill.
if len(inputed_value)==0:
try:
form_input.click()
time.sleep(0.1)
except Exception as exc:
pass
return is_answer_sent, fail_list
def tixcraft_verify(driver, config_dict, fail_list):
show_debug_message = True # debug. show_debug_message = True # debug.
show_debug_message = False # online show_debug_message = False # online
@ -2348,7 +2435,8 @@ def tixcraft_verify(driver, config_dict, answer_index):
inferred_answer_string = "" inferred_answer_string = ""
answer_list = [] answer_list = []
is_retry_user_single_answer = False question_text = get_tixcraft_question_text(driver)
write_question_to_file(question_text)
presale_code = config_dict["advanced"]["user_guess_string"] presale_code = config_dict["advanced"]["user_guess_string"]
@ -2366,110 +2454,27 @@ def tixcraft_verify(driver, config_dict, answer_index):
answer_list = json.loads("["+ presale_code +"]") answer_list = json.loads("["+ presale_code +"]")
except Exception as exc: except Exception as exc:
answer_list = [] answer_list = []
if len(answer_list) > 0:
if answer_index < len(answer_list)-1:
inferred_answer_string = answer_list[answer_index+1]
if inferred_answer_string is None: if len(inferred_answer_string)==0:
if config_dict["advanced"]["auto_guess_options"]: if config_dict["advanced"]["auto_guess_options"]:
inferred_answer_string, answer_list = guess_tixcraft_question(driver) inferred_answer_string, answer_list = guess_tixcraft_question(driver, question_text)
if inferred_answer_string is None:
if not answer_list is None: for answer_item in answer_list:
if len(answer_list) > 0: if not answer_item in fail_list:
if answer_index < len(answer_list)-1: inferred_answer_string = answer_item
inferred_answer_string = answer_list[answer_index+1] break
if show_debug_message: if show_debug_message:
print("answer_index:", answer_index) print("answer_index:", answer_index)
print("inferred_answer_string:", inferred_answer_string) print("inferred_answer_string:", inferred_answer_string)
print("answer_index:", answer_index) print("answer_list:", answer_list)
print("is_retry_user_single_answer:", is_retry_user_single_answer)
form_input = None input_text_css = "input[name='checkCode']"
try: next_step_button_css = ""
form_input = driver.find_element(By.CSS_SELECTOR, "input[name='checkCode']") submit_by_enter = True
except Exception as exc: is_answer_sent, fail_list = fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_list, input_text_css, next_step_button_css, submit_by_enter)
print("find verify code fail")
pass
inputed_value = None return fail_list
if form_input is not None:
try:
inputed_value = form_input.get_attribute('value')
except Exception as exc:
print("find verify code fail")
pass
if inputed_value is None:
inputed_value = ""
if not inferred_answer_string is None:
is_password_sent = False
if len(inputed_value)==0:
try:
# PS: sometime may send key twice...
form_input.clear()
form_input.send_keys(inferred_answer_string)
form_input.send_keys(Keys.ENTER)
is_password_sent = True
# guess answer mode.
answer_index += 1
if show_debug_message:
print("sent password by bot:", inferred_answer_string)
except Exception as exc:
pass
else:
if inputed_value == inferred_answer_string:
if show_debug_message:
print("sent password by previous time.")
is_password_sent = True
try:
form_input.send_keys(Keys.ENTER)
except Exception as exc:
pass
if is_retry_user_single_answer:
# increase counter for waiting for stop retry.
answer_index += 1
else:
# guess answer mode.
if answer_index > -1:
# here not is first option.
inferred_answer_previous = None
if answer_index < len(answer_list)-1:
inferred_answer_previous = answer_list[answer_index]
if inputed_value == inferred_answer_previous:
try:
form_input.clear()
form_input.send_keys(inferred_answer_string)
form_input.send_keys(Keys.ENTER)
is_password_sent = True
if show_debug_message:
print("sent password by bot:", inferred_answer_string, "at index:", answer_index+2)
answer_index += 1
except Exception as exc:
pass
if is_password_sent:
for i in range(3):
time.sleep(0.1)
alert_ret = check_pop_alert(driver)
if alert_ret:
if show_debug_message:
print("press accept button at time #", i+1)
break
else:
if len(inputed_value)==0:
try:
form_input.click()
except Exception as exc:
pass
return answer_index
def tixcraft_change_captcha(driver,url): def tixcraft_change_captcha(driver,url):
try: try:
@ -6714,9 +6719,9 @@ def tixcraft_main(driver, url, config_dict, tixcraft_dict, ocr, Captcha_Browser)
if '/ticket/verify/' in url: if '/ticket/verify/' in url:
tixcraft_dict["answer_index"] = tixcraft_verify(driver, config_dict, tixcraft_dict["answer_index"]) tixcraft_dict["fail_list"] = tixcraft_verify(driver, config_dict, tixcraft_dict["fail_list"])
else: else:
tixcraft_dict["answer_index"] = -1 tixcraft_dict["fail_list"] = []
# main app, to select ticket number. # main app, to select ticket number.
if '/ticket/ticket/' in url: if '/ticket/ticket/' in url:
@ -7289,13 +7294,7 @@ def cityline_main(driver, url, config_dict):
if len(url.split('/'))>=5: if len(url.split('/'))>=5:
cityline_shows_goto_cta(driver) cityline_shows_goto_cta(driver)
def guess_ibon_question(driver): def get_ibon_question_text(driver):
show_debug_message = True # debug.
show_debug_message = False # online
inferred_answer_string = None
answer_list = []
form_select = None form_select = None
try: try:
form_select = driver.find_element(By.CSS_SELECTOR, 'div.editor-box > div > div.form-group > label') form_select = driver.find_element(By.CSS_SELECTOR, 'div.editor-box > div > div.form-group > label')
@ -7303,148 +7302,80 @@ def guess_ibon_question(driver):
print("find verify textbox fail") print("find verify textbox fail")
pass pass
question_text = None question_text = ""
if form_select is not None: if form_select is not None:
try: try:
question_text = form_select.text question_text = form_select.text
except Exception as exc: except Exception as exc:
print("get text fail") print("get text fail")
is_options_in_question = False if question_text is None:
question_text = ""
if inferred_answer_string is None: return question_text
if not question_text is None:
def guess_ibon_question(driver, question_text):
show_debug_message = True # debug.
show_debug_message = False # online
inferred_answer_string = None
answer_list = []
if len(question_text) > 0:
inferred_answer_string, answer_list = get_answer_list_from_question_string(None, question_text) inferred_answer_string, answer_list = get_answer_list_from_question_string(None, question_text)
return inferred_answer_string, answer_list return inferred_answer_string, answer_list
def ibon_verification_question(driver, answer_index, config_dict): def ibon_verification_question(driver, fail_list, config_dict):
show_debug_message = True # debug. show_debug_message = True # debug.
show_debug_message = False # online show_debug_message = False # online
if config_dict["advanced"]["verbose"]: if config_dict["advanced"]["verbose"]:
show_debug_message = True show_debug_message = True
presale_code = config_dict["tixcraft"]["presale_code"] inferred_answer_string = ""
presale_code_delimiter = config_dict["tixcraft"]["presale_code_delimiter"]
inferred_answer_string = None
answer_list = [] answer_list = []
is_retry_user_single_answer = False question_text = get_ibon_question_text(driver)
write_question_to_file(question_text)
presale_code = config_dict["advanced"]["user_guess_string"]
# load from internet.
if len(presale_code) == 0:
if len(config_dict["advanced"]["online_dictionary_url"]) > 0:
if os.path.exists(CONST_MAXBOT_ANSWER_ONLINE_FILE):
with open(CONST_MAXBOT_ANSWER_ONLINE_FILE, "r") as text_file:
presale_code = text_file.readline()
if len(presale_code) > 0: if len(presale_code) > 0:
if len(presale_code_delimiter) > 0: presale_code = format_config_keyword_for_json(presale_code)
if presale_code_delimiter in presale_code: answer_list = []
answer_list = presale_code.split(presale_code_delimiter)
if len(answer_list) > 0:
if answer_index < len(answer_list)-1:
inferred_answer_string = answer_list[answer_index+1]
else:
is_retry_user_single_answer = True
if answer_index < 2:
inferred_answer_string = presale_code
if inferred_answer_string is None:
inferred_answer_string, answer_list = guess_ibon_question(driver)
if inferred_answer_string is None:
if not answer_list is None:
if len(answer_list) > 0:
if answer_index < len(answer_list)-1:
inferred_answer_string = answer_list[answer_index+1]
if show_debug_message:
print("answer_index:", answer_index)
print("inferred_answer_string:", inferred_answer_string)
print("answer_index:", answer_index)
print("is_retry_user_single_answer:", is_retry_user_single_answer)
form_input = None
try: try:
form_input = driver.find_element(By.CSS_SELECTOR, 'div.editor-box > div > div.form-group > input') answer_list = json.loads("["+ presale_code +"]")
except Exception as exc: except Exception as exc:
print("find verify code fail") answer_list = []
pass
inputed_value = None if len(inferred_answer_string)==0:
if form_input is not None: if config_dict["advanced"]["auto_guess_options"]:
try: inferred_answer_string, answer_list = guess_ibon_question(driver, question_text)
inputed_value = form_input.get_attribute('value')
except Exception as exc:
print("find verify code fail")
pass
if inputed_value is None: for answer_item in answer_list:
inputed_value = "" if not answer_item in fail_list:
inferred_answer_string = answer_item
if not inferred_answer_string is None:
is_password_sent = False
if len(inputed_value)==0:
try:
# PS: sometime may send key twice...
form_input.clear()
form_input.send_keys(inferred_answer_string)
is_button_clicked = force_press_button(driver, By.CSS_SELECTOR,'div.editor-box > div > div.form-group > a.btn')
if is_button_clicked:
is_password_sent = True
# guess answer mode.
answer_index += 1
if show_debug_message:
print("sent password by bot:", inferred_answer_string)
except Exception as exc:
pass
else:
if inputed_value == inferred_answer_string:
if show_debug_message:
print("sent password by previous time.")
is_password_sent = True
try:
form_input.send_keys(Keys.ENTER)
except Exception as exc:
pass
if is_retry_user_single_answer:
# increase counter for waiting for stop retry.
answer_index += 1
else:
# guess answer mode.
if answer_index > -1:
# here not is first option.
inferred_answer_previous = None
if answer_index < len(answer_list)-1:
inferred_answer_previous = answer_list[answer_index]
if inputed_value == inferred_answer_previous:
try:
form_input.clear()
form_input.send_keys(inferred_answer_string)
is_button_clicked = force_press_button(driver, By.CSS_SELECTOR,'div.editor-box > div > div.form-group > a.btn')
is_password_sent = True
if show_debug_message:
print("sent password by bot:", inferred_answer_string, "at index:", answer_index+2)
answer_index += 1
except Exception as exc:
pass
if is_password_sent:
for i in range(3):
time.sleep(0.1)
alert_ret = check_pop_alert(driver)
if alert_ret:
if show_debug_message:
print("press accept button at time #", i+1)
break break
else:
if len(inputed_value)==0:
try:
form_input.click()
except Exception as exc:
pass
return answer_index if show_debug_message:
print("inferred_answer_string:", inferred_answer_string)
print("answer_list:", answer_list)
print("fail_list:", fail_list)
input_text_css = 'div.editor-box > div > div.form-group > input'
next_step_button_css = 'div.editor-box > div > a.btn'
submit_by_enter = False
is_answer_sent, fail_list = fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_list, input_text_css, next_step_button_css, submit_by_enter)
return fail_list
def ibon_ticket_agree(driver): def ibon_ticket_agree(driver):
@ -7716,14 +7647,23 @@ def ibon_main(driver, url, config_dict, ibon_dict, ocr, Captcha_Browser):
is_match_target_feature = True is_match_target_feature = True
is_date_assign_by_bot = ibon_date_auto_select(driver, config_dict) is_date_assign_by_bot = ibon_date_auto_select(driver, config_dict)
if 'ibon.com.tw/error.html?' in url:
try:
driver.back()
except Exception as exc:
pass
is_enter_verify_mode = False
if not is_match_target_feature: if not is_match_target_feature:
# validation question url: # validation question url:
# https://orders.ibon.com.tw/application/UTK02/UTK0201_0.aspx?rn=1180872370&PERFORMANCE_ID=B04M7XZT&PRODUCT_ID=B04KS88E&SHOW_PLACE_MAP=True # https://orders.ibon.com.tw/application/UTK02/UTK0201_0.aspx?rn=1180872370&PERFORMANCE_ID=B04M7XZT&PRODUCT_ID=B04KS88E&SHOW_PLACE_MAP=True
if '/application/UTK02/' in url and '.aspx?rn=' in url: if '/application/UTK02/' in url and '.aspx?rn=' in url and '&PERFORMANCE_ID=' in url:
is_match_target_feature = True is_match_target_feature = True
ibon_dict["answer_index"] = ibon_verification_question(driver, ibon_dict["answer_index"], config_dict) is_enter_verify_mode = True
else: ibon_dict["fail_list"] = ibon_verification_question(driver, ibon_dict["fail_list"], config_dict)
ibon_dict["answer_index"] = -1
if not is_enter_verify_mode:
ibon_dict["fail_list"] = []
if not is_match_target_feature: if not is_match_target_feature:
# https://orders.ibon.com.tw/application/UTK02/UTK0201_000.aspx?PERFORMANCE_ID=0000 # https://orders.ibon.com.tw/application/UTK02/UTK0201_000.aspx?PERFORMANCE_ID=0000
@ -7783,8 +7723,12 @@ def ibon_main(driver, url, config_dict, ibon_dict, ocr, Captcha_Browser):
# plan-A # plan-A
#is_button_clicked = force_press_button(driver, By.CSS_SELECTOR, 'a.btn.btn-primary') #is_button_clicked = force_press_button(driver, By.CSS_SELECTOR, 'a.btn.btn-primary')
# plan-B, easy and better than plan-A # plan-B, easy and better than plan-A
try:
driver.back() driver.back()
driver.refresh() driver.refresh()
except Exception as exc:
pass
if not is_match_target_feature: if not is_match_target_feature:
#https://orders.ibon.com.tw/application/UTK02/UTK0206_.aspx #https://orders.ibon.com.tw/application/UTK02/UTK0206_.aspx
@ -10483,7 +10427,7 @@ def main(args):
# for tixcraft # for tixcraft
tixcraft_dict = {} tixcraft_dict = {}
tixcraft_dict["answer_index"]=-1 tixcraft_dict["fail_list"]=[]
tixcraft_dict["is_popup_checkout"] = False tixcraft_dict["is_popup_checkout"] = False
# for kktix # for kktix
@ -10493,7 +10437,7 @@ def main(args):
kktix_dict["is_popup_checkout"] = False kktix_dict["is_popup_checkout"] = False
ibon_dict = {} ibon_dict = {}
ibon_dict["answer_index"]=-1 ibon_dict["fail_list"]=[]
hkticketing_dict = {} hkticketing_dict = {}
hkticketing_dict["is_date_submiting"] = False hkticketing_dict["is_date_submiting"] = False

View File

@ -22,7 +22,7 @@ import base64
import threading import threading
import subprocess import subprocess
CONST_APP_VERSION = "MaxBot (2023.6.16)" CONST_APP_VERSION = "MaxBot (2023.6.17)"
CONST_MAXBOT_LAUNCHER_FILE = "config_launcher.json" CONST_MAXBOT_LAUNCHER_FILE = "config_launcher.json"
CONST_MAXBOT_CONFIG_FILE = "settings.json" CONST_MAXBOT_CONFIG_FILE = "settings.json"

View File

@ -1 +1 @@
{"homepage": "https://tixcraft.com", "browser": "chrome", "language": "English", "ticket_number": 2, "pass_1_seat_remaining": true, "auto_check_agree": true, "ocr_captcha": {"enable": true, "force_submit": true, "image_source": "canvas"}, "webdriver_type": "undetected_chromedriver", "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true}, "tixcraft": {"date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}, "pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true}, "area_auto_select": {"enable": true, "mode": "from top to bottom", "area_keyword": "", "area_keyword_exclude": "\"\u8f2a\u6905\",\"\u8eab\u969c\",\"\u8eab\u5fc3 \u969c\u7919\""}, "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, "disable_adjacent_seat": false, "headless": false, "verbose": false, "auto_guess_options": false, "user_guess_string": "", "online_dictionary_url": "", "auto_reload_page_interval": 1.5, "auto_reload_random_delay": false}} {"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": true, "image_source": "canvas"}, "webdriver_type": "undetected_chromedriver", "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true}, "tixcraft": {"date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}, "pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true}, "area_auto_select": {"enable": true, "mode": "from top to bottom", "area_keyword": "", "area_keyword_exclude": "\"\u8f2a\u6905\",\"\u8eab\u969c\",\"\u8eab\u5fc3 \u969c\u7919\""}, "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, "disable_adjacent_seat": false, "headless": false, "verbose": false, "auto_guess_options": false, "user_guess_string": "", "online_dictionary_url": "", "auto_reload_page_interval": 1.5, "auto_reload_random_delay": false}}

View File

@ -32,7 +32,7 @@ warnings.simplefilter('ignore',InsecureRequestWarning)
import ssl import ssl
ssl._create_default_https_context = ssl._create_unverified_context ssl._create_default_https_context = ssl._create_unverified_context
CONST_APP_VERSION = "MaxBot (2023.6.16)" CONST_APP_VERSION = "MaxBot (2023.6.17)"
CONST_MAXBOT_CONFIG_FILE = "settings.json" CONST_MAXBOT_CONFIG_FILE = "settings.json"
CONST_MAXBOT_LAST_URL_FILE = "MAXBOT_LAST_URL.txt" CONST_MAXBOT_LAST_URL_FILE = "MAXBOT_LAST_URL.txt"
@ -468,9 +468,17 @@ def format_config_keyword_for_json(user_input):
if len(user_input) > 0: if len(user_input) > 0:
if not ('\"' in user_input): if not ('\"' in user_input):
user_input = '"' + user_input + '"' user_input = '"' + user_input + '"'
if user_input[:1]=="{" and user_input[-1:]=="}": if user_input[:1]=="{" and user_input[-1:]=="}":
user_input=user_input[1:] tmp_json = {}
user_input=user_input[:-1] try:
tmp_json = json.loads(user_input)
key=list(tmp_json.keys())[0]
first_item=tmp_json[key]
user_input=json.dumps(first_item)
except Exception as exc:
pass
if user_input[:1]=="[" and user_input[-1:]=="]": if user_input[:1]=="[" and user_input[-1:]=="]":
user_input=user_input[1:] user_input=user_input[1:]
user_input=user_input[:-1] user_input=user_input[:-1]
@ -889,9 +897,18 @@ def show_preview_text():
answer_text = "" answer_text = ""
with open(CONST_MAXBOT_ANSWER_ONLINE_FILE, "r") as text_file: with open(CONST_MAXBOT_ANSWER_ONLINE_FILE, "r") as text_file:
answer_text = text_file.readline() answer_text = text_file.readline()
answer_text = format_config_keyword_for_json(answer_text)
date_array = []
try: try:
date_array = json.loads("["+ answer_text +"]")
except Exception as exc:
date_array = []
global lbl_online_dictionary_preview global lbl_online_dictionary_preview
lbl_online_dictionary_preview.config(text=answer_text) try:
lbl_online_dictionary_preview.config(text=','.join(date_array))
except Exception as exc: except Exception as exc:
pass pass
@ -902,7 +919,7 @@ def save_url_to_file(new_online_dictionary_url, force_write = False):
headers = {"Accept-Language": "zh-TW,zh;q=0.5", 'User-Agent': user_agent} headers = {"Accept-Language": "zh-TW,zh;q=0.5", 'User-Agent': user_agent}
html_result = None html_result = None
try: try:
html_result = requests.get(new_online_dictionary_url , headers=headers, timeout=0.7, allow_redirects=False) html_result = requests.get(new_online_dictionary_url , headers=headers, timeout=0.5, allow_redirects=False)
except Exception as exc: except Exception as exc:
html_result = None html_result = None
#print(exc) #print(exc)
@ -911,6 +928,7 @@ def save_url_to_file(new_online_dictionary_url, force_write = False):
#print("status_code:", status_code) #print("status_code:", status_code)
if status_code == 200: if status_code == 200:
html_text = html_result.text html_text = html_result.text
#print("html_text:", html_text)
is_write_to_file = False is_write_to_file = False
if force_write: if force_write:
@ -919,13 +937,18 @@ def save_url_to_file(new_online_dictionary_url, force_write = False):
is_write_to_file = True is_write_to_file = True
if is_write_to_file: if is_write_to_file:
html_text = format_config_keyword_for_json(html_text)
with open(CONST_MAXBOT_ANSWER_ONLINE_FILE, "w") as text_file: with open(CONST_MAXBOT_ANSWER_ONLINE_FILE, "w") as text_file:
text_file.write("%s" % html_text) text_file.write("%s" % html_text)
return is_write_to_file return is_write_to_file
def btn_preview_text_clicked(): def btn_preview_text_clicked():
global txt_online_dictionary_url global txt_online_dictionary_url
online_dictionary_url = ""
try:
online_dictionary_url = txt_online_dictionary_url.get("1.0",END).strip() online_dictionary_url = txt_online_dictionary_url.get("1.0",END).strip()
except Exception as exc:
pass
online_dictionary_url = format_config_keyword_for_json(online_dictionary_url) online_dictionary_url = format_config_keyword_for_json(online_dictionary_url)
if len(online_dictionary_url) > 0: if len(online_dictionary_url) > 0:
url_array = [] url_array = []
@ -2146,11 +2169,15 @@ def AutofillTab(root, config_dict, language_code, UI_PADDING_X):
frame_group_header.grid(column=0, row=row_count, padx=UI_PADDING_X) frame_group_header.grid(column=0, row=row_count, padx=UI_PADDING_X)
def resetful_api_timer():
while True:
btn_preview_text_clicked()
time.sleep(0.2)
def settings_timer(): def settings_timer():
while True: while True:
update_maxbot_runtime_status() update_maxbot_runtime_status()
btn_preview_text_clicked() time.sleep(0.6)
time.sleep(0.2)
def update_maxbot_runtime_status(): def update_maxbot_runtime_status():
is_paused = False is_paused = False
@ -2472,5 +2499,6 @@ def clean_tmp_file():
force_remove_file(filepath) force_remove_file(filepath)
if __name__ == "__main__": if __name__ == "__main__":
threading.Thread(target=resetful_api_timer, daemon=True).start()
clean_tmp_file() clean_tmp_file()
main() main()

View File

@ -27,7 +27,7 @@ import asyncio
import tornado import tornado
from tornado.web import Application from tornado.web import Application
CONST_APP_VERSION = "MaxBot (2023.6.16)" CONST_APP_VERSION = "MaxBot (2023.6.17)"
CONST_MAXBOT_QUESTION_FILE = "MAXBOT_QUESTION.txt" CONST_MAXBOT_QUESTION_FILE = "MAXBOT_QUESTION.txt"
@ -51,6 +51,9 @@ def btn_copy_question_clicked():
question_text = txt_question.get("1.0",END).strip() question_text = txt_question.get("1.0",END).strip()
pyperclip.copy(question_text) pyperclip.copy(question_text)
def btn_paste_answer_by_user():
print("btn_paste_answer_by_user")
def TextInput(root, UI_PADDING_X): def TextInput(root, UI_PADDING_X):
row_count = 0 row_count = 0
@ -97,11 +100,12 @@ def TextInput(root, UI_PADDING_X):
lbl_answer = Label(frame_group_header, text="Answer") lbl_answer = Label(frame_group_header, text="Answer")
lbl_answer.grid(column=0, row=group_row_count, sticky = E) lbl_answer.grid(column=0, row=group_row_count, sticky = E)
global txt_keyword global txt_answer
txt_keyword_value = StringVar(frame_group_header, value="") global txt_answer_value
txt_keyword = Entry(frame_group_header, width=30, textvariable = txt_keyword_value) txt_answer_value = StringVar(frame_group_header, value="")
txt_keyword.grid(column=1, row=group_row_count, sticky = W) txt_answer = Entry(frame_group_header, width=30, textvariable = txt_answer_value)
txt_answer.grid(column=1, row=group_row_count, sticky = W)
txt_answer.bind('<Control-v>', lambda e: btn_paste_answer_by_user())
frame_group_header.grid(column=0, row=row_count, padx=UI_PADDING_X, pady=15) frame_group_header.grid(column=0, row=row_count, padx=UI_PADDING_X, pady=15)
@ -155,10 +159,28 @@ def main_ui():
root.mainloop() root.mainloop()
class MainHandler(tornado.web.RequestHandler): class MainHandler(tornado.web.RequestHandler):
def format_config_keyword_for_json(self, user_input):
if len(user_input) > 0:
if not ('\"' in user_input):
user_input = '"' + user_input + '"'
return user_input
def compose_as_json(self, user_input):
user_input = self.format_config_keyword_for_json(user_input)
return "{\"data\":[%s]}" % user_input
def get(self): def get(self):
global txt_keyword global txt_answer_value
self.write(txt_keyword.get().strip()) answer_text = ""
try:
answer_text = txt_answer_value.get().strip()
except Exception as exc:
pass
answer_text_output = self.compose_as_json(answer_text)
#print("answer_text_output:", answer_text_output)
self.write(answer_text_output)
class QuestionHandler(tornado.web.RequestHandler): class QuestionHandler(tornado.web.RequestHandler):
def get(self): def get(self):
@ -183,12 +205,13 @@ def preview_question_text_file():
with open(CONST_MAXBOT_QUESTION_FILE, "r") as text_file: with open(CONST_MAXBOT_QUESTION_FILE, "r") as text_file:
question_text = text_file.readline() question_text = text_file.readline()
try:
global txt_question global txt_question
inputed_question_text = txt_question.get("1.0",END).strip() try:
if inputed_question_text != question_text: displayed_question_text = txt_question.get("1.0",END).strip()
if displayed_question_text != question_text:
# start to refresh # start to refresh
txt_question.delete("1.0","end") txt_question.delete("1.0","end")
if len(question_text) > 0:
txt_question.insert("1.0", question_text) txt_question.insert("1.0", question_text)
except Exception as exc: except Exception as exc:
pass pass