MaxBot 2023-02-25, add new field ibonqware, fix ibon bugfixs.
parent
9ed628ee56
commit
b4cc7d46e4
|
@ -53,7 +53,7 @@ import argparse
|
||||||
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 = u"MaxBot (2023.02.24)"
|
CONST_APP_VERSION = u"MaxBot (2023.02.25)"
|
||||||
|
|
||||||
CONST_HOMEPAGE_DEFAULT = "https://tixcraft.com"
|
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'
|
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 not args.kktix_password is None:
|
||||||
if len(args.kktix_password) > 0:
|
if len(args.kktix_password) > 0:
|
||||||
config_dict["advanced"]["kktix_password"] = args.kktix_password
|
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.
|
# special case for headless.
|
||||||
is_headless_enable = False
|
is_headless_enable = False
|
||||||
|
@ -635,6 +639,14 @@ def get_driver_by_config(config_dict):
|
||||||
tixcraft_sid = decryptMe(config_dict["advanced"]["tixcraft_sid"])
|
tixcraft_sid = decryptMe(config_dict["advanced"]["tixcraft_sid"])
|
||||||
driver.delete_cookie("SID")
|
driver.delete_cookie("SID")
|
||||||
driver.add_cookie({"name":"SID", "value": tixcraft_sid, "path" : "/", "secure":True})
|
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:
|
except WebDriverException as exce2:
|
||||||
print('oh no not again, WebDriverException')
|
print('oh no not again, WebDriverException')
|
||||||
print('WebDriverException:', exce2)
|
print('WebDriverException:', exce2)
|
||||||
|
@ -1090,7 +1102,6 @@ def guess_answer_list_from_hint(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captch
|
||||||
return return_list
|
return return_list
|
||||||
|
|
||||||
def format_question_string(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captcha_text_div_text):
|
def format_question_string(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captcha_text_div_text):
|
||||||
|
|
||||||
tmp_text = captcha_text_div_text
|
tmp_text = captcha_text_div_text
|
||||||
tmp_text = tmp_text.replace(u' ',u' ')
|
tmp_text = tmp_text.replace(u' ',u' ')
|
||||||
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
|
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.
|
# close some div on home url.
|
||||||
def tixcraft_home_close_window(driver):
|
def tixcraft_home_close_window(driver):
|
||||||
show_debug_message = True # debug.
|
show_debug_message = True # debug.
|
||||||
|
@ -2283,43 +2325,14 @@ def kktix_confirm_order_button(driver):
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
# PS: There are two "Next" button in kktix.
|
# PS: There are two "Next" button in kktix.
|
||||||
# : 1: /events/xxx
|
# : 1: /events/xxx
|
||||||
# : 2: /events/xxx/registrations/new
|
# : 2: /events/xxx/registrations/new
|
||||||
# : This is ONLY for case-1, because case-2 lenght >5
|
# : This is ONLY for case-1, because case-2 lenght >5
|
||||||
def kktix_events_press_next_button(driver):
|
def kktix_events_press_next_button(driver):
|
||||||
ret = False
|
is_button_clicked = force_press_button(driver, By.CSS_SELECTOR,'div.tickets a.btn-point')
|
||||||
|
return is_button_clicked
|
||||||
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
|
|
||||||
|
|
||||||
# : This is for case-2 next button.
|
# : This is for case-2 next button.
|
||||||
def kktix_press_next_button(driver):
|
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:
|
for row in area_list:
|
||||||
row_index += 1
|
row_index += 1
|
||||||
row_is_enabled=True
|
row_is_enabled=True
|
||||||
try:
|
|
||||||
button_class_string = str(row.get_attribute('class'))
|
if row_is_enabled:
|
||||||
if len(button_class_string) > 1:
|
try:
|
||||||
if 'disabled' in button_class_string:
|
if '已售完' in row.text:
|
||||||
row_is_enabled=False
|
row_is_enabled=False
|
||||||
if 'sold-out' in button_class_string:
|
except Exception as exc:
|
||||||
row_is_enabled=False
|
pass
|
||||||
if 'selected' in button_class_string:
|
|
||||||
# someone is selected. skip this process.
|
if row_is_enabled:
|
||||||
is_price_assign_by_bot = True
|
try:
|
||||||
break
|
button_class_string = str(row.get_attribute('class'))
|
||||||
except Exception as exc:
|
if len(button_class_string) > 1:
|
||||||
pass
|
if 'disabled' in button_class_string:
|
||||||
|
row_is_enabled=False
|
||||||
|
except Exception as exc:
|
||||||
|
pass
|
||||||
|
|
||||||
if row_is_enabled:
|
if row_is_enabled:
|
||||||
formated_area_list.append(row)
|
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_row_index = random.randint(0,len(matched_blocks)-1)
|
||||||
|
|
||||||
target_area = matched_blocks[target_row_index]
|
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:
|
if target_area is not None:
|
||||||
try:
|
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_4 = config_dict["tixcraft"]["area_auto_select"]["area_keyword_4"].strip()
|
||||||
area_keyword_1_and = ""
|
area_keyword_1_and = ""
|
||||||
area_keyword_2_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:
|
if show_debug_message:
|
||||||
print("area_keyword_1:", area_keyword_1)
|
print("area_keyword_1:", area_keyword_1)
|
||||||
|
@ -5229,20 +5255,23 @@ def ibon_performance(driver, config_dict):
|
||||||
if not is_price_assign_by_bot:
|
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)
|
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 is_need_refresh:
|
||||||
if not is_price_assign_by_bot:
|
if area_keyword_2_enable:
|
||||||
# try keyword_2
|
|
||||||
if len(area_keyword_2) > 0:
|
|
||||||
is_need_refresh, is_price_assign_by_bot = ibon_area_auto_select(driver, area_auto_select_mode, area_keyword_2, area_keyword_2_and)
|
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 is_need_refresh:
|
||||||
if not is_price_assign_by_bot:
|
if area_keyword_3_enable:
|
||||||
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, area_keyword_3_and)
|
||||||
is_need_refresh, is_price_assign_by_bot = ibon_area_auto_select(driver, area_auto_select_mode, area_keyword_3, "")
|
if show_debug_message:
|
||||||
if not is_need_refresh:
|
print("is_need_refresh for keyword3:", is_need_refresh)
|
||||||
if not is_price_assign_by_bot:
|
|
||||||
if len(area_keyword_4) > 0:
|
if is_need_refresh:
|
||||||
is_need_refresh, is_price_assign_by_bot = ibon_area_auto_select(driver, area_auto_select_mode, area_keyword_4, "")
|
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:
|
if is_need_refresh:
|
||||||
try:
|
try:
|
||||||
|
@ -5253,33 +5282,8 @@ def ibon_performance(driver, config_dict):
|
||||||
return is_price_assign_by_bot
|
return is_price_assign_by_bot
|
||||||
|
|
||||||
def ibon_purchase_button_press(driver):
|
def ibon_purchase_button_press(driver):
|
||||||
ret = False
|
is_button_clicked = force_press_button(driver, By.CSS_SELECTOR, '#ticket-wrap > a.btn')
|
||||||
|
return is_button_clicked
|
||||||
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
|
|
||||||
|
|
||||||
def facebook_login(driver, account, password):
|
def facebook_login(driver, account, password):
|
||||||
ret = False
|
ret = False
|
||||||
|
@ -6125,11 +6129,75 @@ def ibon_verification_question(driver, answer_index, config_dict):
|
||||||
|
|
||||||
return answer_index
|
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):
|
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
|
#https://ticket.ibon.com.tw/ActivityInfo/Details/0000?pattern=entertainment
|
||||||
if '/ActivityInfo/Details/' in url:
|
if '/ActivityInfo/Details/' in url:
|
||||||
is_event_page = False
|
is_event_page = False
|
||||||
if len(url.split('/'))<=6:
|
if len(url.split('/'))==6:
|
||||||
is_event_page = True
|
is_event_page = True
|
||||||
|
|
||||||
if is_event_page:
|
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
|
# https://orders.ibon.com.tw/application/UTK02/UTK0201_000.aspx?PERFORMANCE_ID=0000
|
||||||
if '/application/UTK02/' in url and '.aspx?PERFORMANCE_ID=' in url:
|
if '/application/UTK02/' in url and '.aspx?PERFORMANCE_ID=' in url:
|
||||||
is_event_page = False
|
is_event_page = False
|
||||||
if len(url.split('/'))<=6:
|
if len(url.split('/'))==6:
|
||||||
is_event_page = True
|
is_event_page = True
|
||||||
|
|
||||||
if is_event_page:
|
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)
|
is_ticket_number_assigned = ibon_ticket_number_auto_select(driver, ticket_number)
|
||||||
if is_ticket_number_assigned:
|
if is_ticket_number_assigned:
|
||||||
click_ret = ibon_purchase_button_press(driver)
|
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:
|
else:
|
||||||
# step 1: select area.
|
# step 1: select area.
|
||||||
ibon_performance(driver, config_dict)
|
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
|
return ibon_dict
|
||||||
|
|
||||||
def hkticketing_home(driver):
|
def hkticketing_home(driver):
|
||||||
|
@ -8135,6 +8226,10 @@ def cli():
|
||||||
help="overwrite kktix_password field",
|
help="overwrite kktix_password field",
|
||||||
type=str)
|
type=str)
|
||||||
|
|
||||||
|
parser.add_argument("--ibonqware",
|
||||||
|
help="overwrite ibonqware field",
|
||||||
|
type=str)
|
||||||
|
|
||||||
parser.add_argument("--headless",
|
parser.add_argument("--headless",
|
||||||
help="headless mode",
|
help="headless mode",
|
||||||
default='False',
|
default='False',
|
||||||
|
|
|
@ -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}
|
{"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}
|
91
settings.py
91
settings.py
|
@ -20,7 +20,9 @@ import webbrowser
|
||||||
import pyperclip
|
import pyperclip
|
||||||
import base64
|
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_TOP_TO_BOTTOM = u"from top to bottom"
|
||||||
CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top"
|
CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top"
|
||||||
|
@ -104,9 +106,11 @@ def load_translate():
|
||||||
en_us["exit"] = 'Close'
|
en_us["exit"] = 'Close'
|
||||||
en_us["copy"] = 'Copy'
|
en_us["copy"] = 'Copy'
|
||||||
en_us["restore_defaults"] = 'Restore Defaults'
|
en_us["restore_defaults"] = 'Restore Defaults'
|
||||||
|
en_us["config_launcher"] = 'Launcher'
|
||||||
en_us["done"] = 'Done'
|
en_us["done"] = 'Done'
|
||||||
|
|
||||||
en_us["tixcraft_sid"] = 'Tixcraft cookie SID'
|
en_us["tixcraft_sid"] = 'Tixcraft cookie SID'
|
||||||
|
en_us["ibon_ibonqware"] = 'ibon cookie ibonqware'
|
||||||
en_us["facebook_account"] = 'Facebook account'
|
en_us["facebook_account"] = 'Facebook account'
|
||||||
en_us["kktix_account"] = 'KKTIX account'
|
en_us["kktix_account"] = 'KKTIX account'
|
||||||
en_us["cityline_account"] = 'cityline account'
|
en_us["cityline_account"] = 'cityline account'
|
||||||
|
@ -181,9 +185,11 @@ def load_translate():
|
||||||
zh_tw["exit"] = '關閉'
|
zh_tw["exit"] = '關閉'
|
||||||
zh_tw["copy"] = '複製'
|
zh_tw["copy"] = '複製'
|
||||||
zh_tw["restore_defaults"] = '恢復預設值'
|
zh_tw["restore_defaults"] = '恢復預設值'
|
||||||
|
zh_tw["config_launcher"] = '設定檔管理'
|
||||||
zh_tw["done"] = '完成'
|
zh_tw["done"] = '完成'
|
||||||
|
|
||||||
zh_tw["tixcraft_sid"] = 'Tixcraft cookie SID'
|
zh_tw["tixcraft_sid"] = 'Tixcraft cookie SID'
|
||||||
|
zh_tw["ibon_ibonqware"] = 'ibon cookie ibonqware'
|
||||||
zh_tw["facebook_account"] = 'Facebook 帳號'
|
zh_tw["facebook_account"] = 'Facebook 帳號'
|
||||||
zh_tw["kktix_account"] = 'KKTIX 帳號'
|
zh_tw["kktix_account"] = 'KKTIX 帳號'
|
||||||
zh_tw["cityline_account"] = 'cityline 帳號'
|
zh_tw["cityline_account"] = 'cityline 帳號'
|
||||||
|
@ -259,9 +265,11 @@ def load_translate():
|
||||||
zh_cn["exit"] = '关闭'
|
zh_cn["exit"] = '关闭'
|
||||||
zh_cn["copy"] = '复制'
|
zh_cn["copy"] = '复制'
|
||||||
zh_cn["restore_defaults"] = '恢复默认值'
|
zh_cn["restore_defaults"] = '恢复默认值'
|
||||||
|
zh_cn["config_launcher"] = '设定档管理'
|
||||||
zh_cn["done"] = '完成'
|
zh_cn["done"] = '完成'
|
||||||
|
|
||||||
zh_cn["tixcraft_sid"] = 'Tixcraft cookie SID'
|
zh_cn["tixcraft_sid"] = 'Tixcraft cookie SID'
|
||||||
|
zh_cn["ibon_ibonqware"] = 'ibon cookie ibonqware'
|
||||||
zh_cn["facebook_account"] = 'Facebook 帐号'
|
zh_cn["facebook_account"] = 'Facebook 帐号'
|
||||||
zh_cn["kktix_account"] = 'KKTIX 帐号'
|
zh_cn["kktix_account"] = 'KKTIX 帐号'
|
||||||
zh_cn["cityline_account"] = 'cityline 帐号'
|
zh_cn["cityline_account"] = 'cityline 帐号'
|
||||||
|
@ -336,9 +344,11 @@ def load_translate():
|
||||||
ja_jp["exit"] = '閉じる'
|
ja_jp["exit"] = '閉じる'
|
||||||
ja_jp["copy"] = 'コピー'
|
ja_jp["copy"] = 'コピー'
|
||||||
ja_jp["restore_defaults"] = 'デフォルトに戻す'
|
ja_jp["restore_defaults"] = 'デフォルトに戻す'
|
||||||
|
ja_jp["config_launcher"] = 'ランチャー'
|
||||||
ja_jp["done"] = '終わり'
|
ja_jp["done"] = '終わり'
|
||||||
|
|
||||||
ja_jp["tixcraft_sid"] = 'Tixcraft cookie SID'
|
ja_jp["tixcraft_sid"] = 'Tixcraft cookie SID'
|
||||||
|
ja_jp["ibon_ibonqware"] = 'ibon cookie ibonqware'
|
||||||
ja_jp["facebook_account"] = 'Facebookのアカウント'
|
ja_jp["facebook_account"] = 'Facebookのアカウント'
|
||||||
ja_jp["kktix_account"] = 'KKTIXのアカウント'
|
ja_jp["kktix_account"] = 'KKTIXのアカウント'
|
||||||
ja_jp["cityline_account"] = 'citylineのアカウント'
|
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"]["play_captcha_sound"]["filename"] = CONST_CAPTCHA_SOUND_FILENAME_DEFAULT
|
||||||
|
|
||||||
config_dict["advanced"]["tixcraft_sid"] = ""
|
config_dict["advanced"]["tixcraft_sid"] = ""
|
||||||
|
config_dict["advanced"]["ibonqware"] = ""
|
||||||
config_dict["advanced"]["facebook_account"] = ""
|
config_dict["advanced"]["facebook_account"] = ""
|
||||||
config_dict["advanced"]["kktix_account"] = ""
|
config_dict["advanced"]["kktix_account"] = ""
|
||||||
config_dict["advanced"]["cityline_account"] = ""
|
config_dict["advanced"]["cityline_account"] = ""
|
||||||
|
@ -481,7 +492,7 @@ def load_json():
|
||||||
app_root = get_app_root()
|
app_root = get_app_root()
|
||||||
|
|
||||||
# overwrite config path.
|
# 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
|
config_dict = None
|
||||||
if os.path.isfile(config_filepath):
|
if os.path.isfile(config_filepath):
|
||||||
|
@ -493,7 +504,7 @@ def load_json():
|
||||||
|
|
||||||
def btn_restore_defaults_clicked(language_code):
|
def btn_restore_defaults_clicked(language_code):
|
||||||
app_root = get_app_root()
|
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()
|
config_dict = get_default_config()
|
||||||
import json
|
import json
|
||||||
|
@ -504,12 +515,61 @@ def btn_restore_defaults_clicked(language_code):
|
||||||
global root
|
global root
|
||||||
load_GUI(root, config_dict)
|
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):
|
def btn_save_clicked(language_code):
|
||||||
btn_save_act(language_code)
|
btn_save_act(language_code)
|
||||||
|
|
||||||
def btn_save_act(language_code, slience_mode=False):
|
def btn_save_act(language_code, slience_mode=False):
|
||||||
app_root = get_app_root()
|
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()
|
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_presale_code_delimiter
|
||||||
|
|
||||||
global txt_tixcraft_sid
|
global txt_tixcraft_sid
|
||||||
|
global txt_ibon_ibonqware
|
||||||
global txt_facebook_account
|
global txt_facebook_account
|
||||||
global txt_kktix_account
|
global txt_kktix_account
|
||||||
global txt_cityline_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"]["play_captcha_sound"]["filename"] = txt_captcha_sound_filename.get().strip()
|
||||||
|
|
||||||
config_dict["advanced"]["tixcraft_sid"] = txt_tixcraft_sid.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"]["facebook_account"] = txt_facebook_account.get().strip()
|
||||||
config_dict["advanced"]["kktix_account"] = txt_kktix_account.get().strip()
|
config_dict["advanced"]["kktix_account"] = txt_kktix_account.get().strip()
|
||||||
config_dict["advanced"]["cityline_account"] = txt_cityline_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"]["kham_password"] = txt_kham_password.get().strip()
|
||||||
|
|
||||||
config_dict["advanced"]["tixcraft_sid"] = encryptMe(config_dict["advanced"]["tixcraft_sid"])
|
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"]["facebook_password"] = encryptMe(config_dict["advanced"]["facebook_password"])
|
||||||
config_dict["advanced"]["kktix_password"] = encryptMe(config_dict["advanced"]["kktix_password"])
|
config_dict["advanced"]["kktix_password"] = encryptMe(config_dict["advanced"]["kktix_password"])
|
||||||
config_dict["advanced"]["cityline_password"] = encryptMe(config_dict["advanced"]["cityline_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"])
|
tabControl.tab(3, text=translate[language_code]["about"])
|
||||||
|
|
||||||
global lbl_tixcraft_sid
|
global lbl_tixcraft_sid
|
||||||
|
global lbl_ibon_ibonqware
|
||||||
global lbl_facebook_account
|
global lbl_facebook_account
|
||||||
global lbl_kktix_account
|
global lbl_kktix_account
|
||||||
global lbl_cityline_account
|
global lbl_cityline_account
|
||||||
|
@ -967,6 +1031,7 @@ def applyNewLanguage():
|
||||||
global lbl_captcha_sound_filename
|
global lbl_captcha_sound_filename
|
||||||
|
|
||||||
lbl_tixcraft_sid.config(text=translate[language_code]["tixcraft_sid"])
|
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_facebook_account.config(text=translate[language_code]["facebook_account"])
|
||||||
lbl_kktix_account.config(text=translate[language_code]["kktix_account"])
|
lbl_kktix_account.config(text=translate[language_code]["kktix_account"])
|
||||||
lbl_cityline_account.config(text=translate[language_code]["cityline_account"])
|
lbl_cityline_account.config(text=translate[language_code]["cityline_account"])
|
||||||
|
@ -999,12 +1064,14 @@ def applyNewLanguage():
|
||||||
global btn_save
|
global btn_save
|
||||||
global btn_exit
|
global btn_exit
|
||||||
global btn_restore_defaults
|
global btn_restore_defaults
|
||||||
|
global btn_launcher
|
||||||
|
|
||||||
btn_run.config(text=translate[language_code]["run"])
|
btn_run.config(text=translate[language_code]["run"])
|
||||||
btn_save.config(text=translate[language_code]["save"])
|
btn_save.config(text=translate[language_code]["save"])
|
||||||
if btn_exit:
|
if btn_exit:
|
||||||
btn_exit.config(text=translate[language_code]["exit"])
|
btn_exit.config(text=translate[language_code]["exit"])
|
||||||
btn_restore_defaults.config(text=translate[language_code]["restore_defaults"])
|
btn_restore_defaults.config(text=translate[language_code]["restore_defaults"])
|
||||||
|
btn_launcher.config(text=translate[language_code]["config_launcher"])
|
||||||
|
|
||||||
def callbackHomepageOnChange(event):
|
def callbackHomepageOnChange(event):
|
||||||
showHideBlocks()
|
showHideBlocks()
|
||||||
|
@ -1970,6 +2037,17 @@ def AutofillTab(root, config_dict, language_code, UI_PADDING_X):
|
||||||
|
|
||||||
group_row_count +=1
|
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
|
global lbl_facebook_account
|
||||||
lbl_facebook_account = Label(frame_group_header, text=translate[language_code]['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)
|
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_save
|
||||||
global btn_exit
|
global btn_exit
|
||||||
global btn_restore_defaults
|
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 = ttk.Button(frame_action, text=translate[language_code]['run'], command= lambda: btn_run_clicked(language_code))
|
||||||
btn_run.grid(column=0, row=0)
|
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 = 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_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
|
return frame_action
|
||||||
|
|
||||||
def clearFrame(frame):
|
def clearFrame(frame):
|
||||||
|
|
Loading…
Reference in New Issue