2021-03-21 add new feature: pass 1 seat remaining

master
CHUN YU YAO 2021-03-21 14:14:20 +08:00
parent 7fa4fbf680
commit 6c17d55ffe
3 changed files with 133 additions and 65 deletions

View File

@ -44,7 +44,7 @@ warnings.simplefilter('ignore',InsecureRequestWarning)
#附註1沒有寫的很好很多地方應該可以模組化。 #附註1沒有寫的很好很多地方應該可以模組化。
#附註2 #附註2
CONST_APP_VERSION = u"MaxBot (2020.12.08)" CONST_APP_VERSION = u"MaxBot (2021.03.21)"
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"
@ -53,6 +53,8 @@ CONST_SELECT_ORDER_DEFAULT = CONST_FROM_TOP_TO_BOTTOM
CONST_SELECT_OPTIONS_DEFAULT = (CONST_FROM_TOP_TO_BOTTOM, CONST_FROM_BOTTOM_TO_TOP, CONST_RANDOM) CONST_SELECT_OPTIONS_DEFAULT = (CONST_FROM_TOP_TO_BOTTOM, CONST_FROM_BOTTOM_TO_TOP, CONST_RANDOM)
CONST_SELECT_OPTIONS_ARRAY = [CONST_FROM_TOP_TO_BOTTOM, CONST_FROM_BOTTOM_TO_TOP, CONST_RANDOM] CONST_SELECT_OPTIONS_ARRAY = [CONST_FROM_TOP_TO_BOTTOM, CONST_FROM_BOTTOM_TO_TOP, CONST_RANDOM]
CONT_STRING_1_SEATS_REMAINING = [u'1 seat(s) remaining',u'剩餘 1',u'1 席残り']
# initial webdriver # initial webdriver
# 說明:初始化 webdriver # 說明:初始化 webdriver
driver = None driver = None
@ -80,17 +82,19 @@ auto_press_next_step_button = False
auto_fill_ticket_number = False auto_fill_ticket_number = False
auto_fill_ticket_price = None auto_fill_ticket_price = None
date_auto_select_enable = None date_auto_select_enable = False
date_auto_select_mode = None date_auto_select_mode = None
date_keyword = None date_keyword = None
area_auto_select_enable = None area_auto_select_enable = False
area_auto_select_mode = None area_auto_select_mode = None
area_keyword = None area_keyword = None
area_keyword_1 = None area_keyword_1 = None
area_keyword_2 = None area_keyword_2 = None
pass_1_seat_remaining_enable = False # default not checked.
kktix_area_auto_select_mode = None kktix_area_auto_select_mode = None
kktix_area_keyword = None kktix_area_keyword = None
@ -149,8 +153,12 @@ if not config_dict is None:
# for ["tixcraft"] # for ["tixcraft"]
if 'tixcraft' in config_dict: if 'tixcraft' in config_dict:
date_auto_select_enable = config_dict["tixcraft"]["date_auto_select"]["enable"] date_auto_select_enable = False
date_auto_select_mode = config_dict["tixcraft"]["date_auto_select"]["mode"] date_auto_select_mode = None
if 'date_auto_select' in config_dict["tixcraft"]:
date_auto_select_enable = config_dict["tixcraft"]["date_auto_select"]["enable"]
date_auto_select_mode = config_dict["tixcraft"]["date_auto_select"]["mode"]
if not date_auto_select_mode in CONST_SELECT_OPTIONS_ARRAY: if not date_auto_select_mode in CONST_SELECT_OPTIONS_ARRAY:
date_auto_select_mode = CONST_SELECT_ORDER_DEFAULT date_auto_select_mode = CONST_SELECT_ORDER_DEFAULT
@ -159,8 +167,12 @@ if not config_dict is None:
date_keyword = config_dict["tixcraft"]["date_auto_select"]["date_keyword"] date_keyword = config_dict["tixcraft"]["date_auto_select"]["date_keyword"]
date_keyword = date_keyword.strip() date_keyword = date_keyword.strip()
area_auto_select_enable = config_dict["tixcraft"]["area_auto_select"]["enable"] area_auto_select_enable = False
area_auto_select_mode = config_dict["tixcraft"]["area_auto_select"]["mode"] area_auto_select_mode = None
if 'area_auto_select' in config_dict["tixcraft"]:
area_auto_select_enable = config_dict["tixcraft"]["area_auto_select"]["enable"]
area_auto_select_mode = config_dict["tixcraft"]["area_auto_select"]["mode"]
if not area_auto_select_mode in CONST_SELECT_OPTIONS_ARRAY: if not area_auto_select_mode in CONST_SELECT_OPTIONS_ARRAY:
area_auto_select_mode = CONST_SELECT_ORDER_DEFAULT area_auto_select_mode = CONST_SELECT_ORDER_DEFAULT
@ -173,6 +185,10 @@ if not config_dict is None:
area_keyword_2 = config_dict["tixcraft"]["area_auto_select"]["area_keyword_2"] area_keyword_2 = config_dict["tixcraft"]["area_auto_select"]["area_keyword_2"]
area_keyword_2 = area_keyword_2.strip() area_keyword_2 = area_keyword_2.strip()
pass_1_seat_remaining_enable = False
if 'pass_1_seat_remaining' in config_dict["tixcraft"]:
pass_1_seat_remaining_enable = config_dict["tixcraft"]["pass_1_seat_remaining"]
# output config: # output config:
print("version", CONST_APP_VERSION) print("version", CONST_APP_VERSION)
print("homepage", homepage) print("homepage", homepage)
@ -199,6 +215,8 @@ if not config_dict is None:
print("area_keyword_1", area_keyword_1) print("area_keyword_1", area_keyword_1)
print("area_keyword_2", area_keyword_2) print("area_keyword_2", area_keyword_2)
print("pass_1_seat_remaining", pass_1_seat_remaining_enable)
# entry point # entry point
# 說明:自動開啟第一個的網頁 # 說明:自動開啟第一個的網頁
if homepage is None: if homepage is None:
@ -792,64 +810,79 @@ def get_tixcraft_target_area(el, area_keyword):
is_need_refresh = False is_need_refresh = False
if el is not None: if el is not None:
if len(area_keyword) == 0: area_list = None
try: try:
areas = el.find_elements(By.TAG_NAME, "a") area_list = el.find_elements(By.TAG_NAME, 'a')
except Exception as exc: except Exception as exc:
pass #print("find area list a tag fail")
pass
if areas is not None: if area_list is not None:
if len(areas) == 0: if len(area_list) == 0:
print("list is empty, do refresh!") print("(with keyword) list is empty, do refresh!")
is_need_refresh = True
else:
print("list is None, do refresh!")
is_need_refresh = True is_need_refresh = True
else: else:
# match keyword. print("(with keyword) list is None, do refresh!")
area_list = None is_need_refresh = True
try:
area_list = el.find_elements(By.TAG_NAME, 'a')
except Exception as exc:
#print("find area list a tag fail")
pass
if area_list is not None: if area_list is not None:
if len(area_list) == 0: areas = []
print("(with keyword) list is empty, do refresh!") for row in area_list:
is_need_refresh = True row_is_enabled=False
else: try:
print("(with keyword) list is None, do refresh!") row_is_enabled = row.is_enabled()
is_need_refresh = True except Exception as exc:
pass
if area_list is not None: row_text = ""
areas = [] if row_is_enabled:
for row in area_list:
row_is_enabled=False
try: try:
row_is_enabled = row.is_enabled() row_text = row.text
except Exception as exc: except Exception as exc:
pass print("get text fail")
break
row_text = "" if len(row_text) > 0:
if row_is_enabled: is_append_this_row = False
try:
row_text = row.text
except Exception as exc:
print("get text fail")
break
if len(row_text) > 0: if len(area_keyword) > 0:
# must match keyword.
if area_keyword in row_text: if area_keyword in row_text:
areas.append(row) is_append_this_row = True
else:
# without keyword.
is_append_this_row = True
if area_auto_select_mode == CONST_FROM_TOP_TO_BOTTOM: if is_append_this_row:
print("only need first item, break area list loop.") if pass_1_seat_remaining_enable:
break area_item_font_el = None
#print("row_text:" + row_text) try:
#print("match:" + area_keyword) #print('try to find font tag at row:', row_text)
if len(areas) == 0: area_item_font_el = row.find_element(By.TAG_NAME, 'font')
areas = None if not area_item_font_el is None:
font_el_text = area_item_font_el.text
#print('font tag text:', font_el_text)
if font_el_text in CONT_STRING_1_SEATS_REMAINING:
#print("match pass 1 seats remaining 1 full text:", row_text)
#print("match pass 1 seats remaining 2 font text:", font_el_text)
is_append_this_row = False
else:
#print("row withou font tag.")
pass
except Exception as exc:
#print("find font text in a tag fail:", exc)
pass
if is_append_this_row:
areas.append(row)
if area_auto_select_mode == CONST_FROM_TOP_TO_BOTTOM:
print("only need first item, break area list loop.")
break
#print("row_text:" + row_text)
#print("match:" + area_keyword)
if len(areas) == 0:
areas = None
return is_need_refresh, areas return is_need_refresh, areas

View File

@ -1 +1 @@
{"tixcraft": {"area_auto_select": {"enable": true, "area_keyword": "", "mode": "from top to bottom", "area_keyword_2": "", "area_keyword_1": ""}, "date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}}, "homepage1": "https://kktix.com", "homepage2": "https://tixcraft.com", "facebook_account": "", "browser1": "chrome", "browser2": "firefox", "kktix": {"auto_guess_options": true, "answer_dictionary": "", "area_keyword": "", "auto_press_next_step_button": true, "area_mode": "random", "auto_fill_ticket_number": true, "auto_fill_ticket_price": "$1,500"}, "ticket_number": 2, "homepage": "https://kktix.com", "browser": "chrome"} {"tixcraft": {"pass_1_seat_remaining": true, "area_auto_select": {"area_keyword_1": "", "enable": true, "mode": "from top to bottom", "area_keyword_2": "", "area_keyword": ""}, "date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}}, "homepage1": "https://kktix.com", "homepage2": "https://tixcraft.com", "facebook_account": "", "browser1": "chrome", "browser2": "firefox", "kktix": {"auto_fill_ticket_price": "$1,500", "auto_guess_options": true, "answer_dictionary": "", "area_keyword": "", "auto_press_next_step_button": true, "auto_fill_ticket_number": true, "area_mode": "random"}, "ticket_number": 2, "homepage": "https://tixcraft.com", "browser": "chrome"}

View File

@ -16,7 +16,7 @@ import os
import sys import sys
import json import json
CONST_APP_VERSION = u"MaxBot (2020.12.08)" CONST_APP_VERSION = u"MaxBot (2021.03.21)"
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"
@ -86,6 +86,8 @@ def btn_save_act(slience_mode=False):
global combo_date_auto_select_mode global combo_date_auto_select_mode
global combo_area_auto_select_mode global combo_area_auto_select_mode
global chk_state_pass_1_seat_remaining
if is_all_data_correct: if is_all_data_correct:
if combo_homepage.get().strip()=="": if combo_homepage.get().strip()=="":
is_all_data_correct = False is_all_data_correct = False
@ -130,6 +132,8 @@ def btn_save_act(slience_mode=False):
config_dict["tixcraft"]["date_auto_select"]["mode"] = combo_date_auto_select_mode.get().strip() config_dict["tixcraft"]["date_auto_select"]["mode"] = combo_date_auto_select_mode.get().strip()
config_dict["tixcraft"]["area_auto_select"]["mode"] = combo_area_auto_select_mode.get().strip() config_dict["tixcraft"]["area_auto_select"]["mode"] = combo_area_auto_select_mode.get().strip()
config_dict["tixcraft"]["pass_1_seat_remaining"] = bool(chk_state_pass_1_seat_remaining.get())
# save config. # save config.
if is_all_data_correct: if is_all_data_correct:
import json import json
@ -245,7 +249,7 @@ def showHideBlocks(all_layout_visible=False):
showHideTixcraftBlocks() showHideTixcraftBlocks()
# purpose: show detail blocks if master field is enable.
def showHideTixcraftBlocks(): def showHideTixcraftBlocks():
# for tixcraft show/hide enable. # for tixcraft show/hide enable.
# field 1 # field 1
@ -349,6 +353,8 @@ def MainMenu(root):
area_keyword_1 = "" area_keyword_1 = ""
area_keyword_2 = "" area_keyword_2 = ""
pass_1_seat_remaining_enable = False # default not checked.
global config_dict global config_dict
if not config_dict is None: if not config_dict is None:
# read config. # read config.
@ -397,8 +403,12 @@ def MainMenu(root):
# for ["tixcraft"] # for ["tixcraft"]
if 'tixcraft' in config_dict: if 'tixcraft' in config_dict:
date_auto_select_enable = config_dict["tixcraft"]["date_auto_select"]["enable"] date_auto_select_enable = False
date_auto_select_mode = config_dict["tixcraft"]["date_auto_select"]["mode"] date_auto_select_mode = None
if 'date_auto_select' in config_dict["tixcraft"]:
date_auto_select_enable = config_dict["tixcraft"]["date_auto_select"]["enable"]
date_auto_select_mode = config_dict["tixcraft"]["date_auto_select"]["mode"]
if not date_auto_select_mode in CONST_SELECT_OPTIONS_ARRAY: if not date_auto_select_mode in CONST_SELECT_OPTIONS_ARRAY:
date_auto_select_mode = CONST_SELECT_ORDER_DEFAULT date_auto_select_mode = CONST_SELECT_ORDER_DEFAULT
@ -407,8 +417,12 @@ def MainMenu(root):
date_keyword = config_dict["tixcraft"]["date_auto_select"]["date_keyword"] date_keyword = config_dict["tixcraft"]["date_auto_select"]["date_keyword"]
date_keyword = date_keyword.strip() date_keyword = date_keyword.strip()
area_auto_select_enable = config_dict["tixcraft"]["area_auto_select"]["enable"] area_auto_select_enable = False
area_auto_select_mode = config_dict["tixcraft"]["area_auto_select"]["mode"] area_auto_select_mode = None
if 'area_auto_select' in config_dict["tixcraft"]:
area_auto_select_enable = config_dict["tixcraft"]["area_auto_select"]["enable"]
area_auto_select_mode = config_dict["tixcraft"]["area_auto_select"]["mode"]
if not area_auto_select_mode in CONST_SELECT_OPTIONS_ARRAY: if not area_auto_select_mode in CONST_SELECT_OPTIONS_ARRAY:
area_auto_select_mode = CONST_SELECT_ORDER_DEFAULT area_auto_select_mode = CONST_SELECT_ORDER_DEFAULT
@ -421,6 +435,10 @@ def MainMenu(root):
area_keyword_2 = config_dict["tixcraft"]["area_auto_select"]["area_keyword_2"] area_keyword_2 = config_dict["tixcraft"]["area_auto_select"]["area_keyword_2"]
area_keyword_2 = area_keyword_2.strip() area_keyword_2 = area_keyword_2.strip()
pass_1_seat_remaining_enable = False
if 'pass_1_seat_remaining' in config_dict["tixcraft"]:
pass_1_seat_remaining_enable = config_dict["tixcraft"]["pass_1_seat_remaining"]
# output config: # output config:
print("homepage", homepage) print("homepage", homepage)
print("browser", browser) print("browser", browser)
@ -447,6 +465,8 @@ def MainMenu(root):
print("area_auto_select_mode", area_auto_select_mode) print("area_auto_select_mode", area_auto_select_mode)
print("area_keyword_1", area_keyword_1) print("area_keyword_1", area_keyword_1)
print("area_keyword_2", area_keyword_2) print("area_keyword_2", area_keyword_2)
print("pass_1_seat_remaining", pass_1_seat_remaining_enable)
else: else:
print('config is none') print('config is none')
@ -543,9 +563,8 @@ def MainMenu(root):
chk_state_auto_fill_ticket_number = BooleanVar() chk_state_auto_fill_ticket_number = BooleanVar()
chk_state_auto_fill_ticket_number.set(auto_fill_ticket_number) chk_state_auto_fill_ticket_number.set(auto_fill_ticket_number)
chk_auto_auto_fill_ticket_number = Checkbutton(frame_group_kktix, text='Enable', variable=chk_state_auto_fill_ticket_number) chk_auto_fill_ticket_number = Checkbutton(frame_group_kktix, text='Enable', variable=chk_state_auto_fill_ticket_number)
chk_auto_auto_fill_ticket_number.grid(column=1, row=group_row_count, sticky = W) chk_auto_fill_ticket_number.grid(column=1, row=group_row_count, sticky = W)
group_row_count+=1 group_row_count+=1
@ -718,6 +737,22 @@ def MainMenu(root):
txt_area_keyword_2 = Entry(frame_group_tixcraft, width=20, textvariable = txt_area_keyword_2_value) txt_area_keyword_2 = Entry(frame_group_tixcraft, width=20, textvariable = txt_area_keyword_2_value)
txt_area_keyword_2.grid(column=1, row=area_keyword_2_index, sticky = W) txt_area_keyword_2.grid(column=1, row=area_keyword_2_index, sticky = W)
group_row_count+=1
lbl_pass_1_seat_remaining = Label(frame_group_tixcraft, text="Pass 1 seat remaining")
lbl_pass_1_seat_remaining.grid(column=0, row=group_row_count, sticky = E)
global chk_state_pass_1_seat_remaining
chk_state_pass_1_seat_remaining = BooleanVar()
chk_state_pass_1_seat_remaining.set(pass_1_seat_remaining_enable)
global chk_pass_1_seat_remaining
chk_pass_1_seat_remaining = Checkbutton(frame_group_tixcraft, text='Enable', variable=chk_state_pass_1_seat_remaining)
chk_pass_1_seat_remaining.grid(column=1, row=group_row_count, sticky = W)
group_row_count+=1
global frame_group_tixcraft_index global frame_group_tixcraft_index
frame_group_tixcraft_index = row_count frame_group_tixcraft_index = row_count
frame_group_tixcraft.grid(column=0, row=row_count, sticky = W, padx=UI_PADDING_X) frame_group_tixcraft.grid(column=0, row=row_count, sticky = W, padx=UI_PADDING_X)
@ -765,7 +800,7 @@ def main():
GUI = MainMenu(root) GUI = MainMenu(root)
GUI_SIZE_WIDTH = 420 GUI_SIZE_WIDTH = 420
GUI_SIZE_HEIGHT = 370 GUI_SIZE_HEIGHT = 395
GUI_SIZE_MACOS = str(GUI_SIZE_WIDTH) + 'x' + str(GUI_SIZE_HEIGHT) GUI_SIZE_MACOS = str(GUI_SIZE_WIDTH) + 'x' + str(GUI_SIZE_HEIGHT)
GUI_SIZE_WINDOWS=str(GUI_SIZE_WIDTH-60) + 'x' + str(GUI_SIZE_HEIGHT-20) GUI_SIZE_WINDOWS=str(GUI_SIZE_WIDTH-60) + 'x' + str(GUI_SIZE_HEIGHT-20)