Compare commits
10 Commits
cd70d97d44
...
8142d85ddc
Author | SHA1 | Date |
---|---|---|
Your Name | 8142d85ddc | |
Your Name | 7d6ff4330f | |
Your Name | cf444bc2e2 | |
Your Name | 312a26b84e | |
Your Name | 75843b5f00 | |
Your Name | 9b0d32918f | |
Max | 3d335b7410 | |
Max | 1a159aeb6c | |
Your Name | 7f5ca0ad4c | |
Your Name | d499fa8af2 |
98
README.md
98
README.md
|
@ -44,24 +44,24 @@ A:從之前 MaxBot 執行秒數來看,較好的電腦花費秒數大約 8
|
||||||
|
|
||||||
如果說你想增加在伺服器上存取記錄的變化程度,可以使用秒數的關鍵字功能,讓 MaxBot 在特定秒數時啟動與暫停。參考影片:https://youtu.be/u3YQCZZu6kE
|
如果說你想增加在伺服器上存取記錄的變化程度,可以使用秒數的關鍵字功能,讓 MaxBot 在特定秒數時啟動與暫停。參考影片:https://youtu.be/u3YQCZZu6kE
|
||||||
|
|
||||||
MaxBot 的出發點是幫助大家在購票時,可以有效率地自動化在花時間、重覆又無聊的刷新網頁。如果有任何違法,必定立即修正。
|
MaxBot 的出發點是幫助大家在購票時,可以有效率地自動化在花時間、重覆又無聊的刷新網頁。
|
||||||
|
|
||||||
|
如果有任何違法,必定立即修正。
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Download 蛋黃酥上車程式下載
|
## Download 蛋黃酥上車程式下載
|
||||||
|
|
||||||
<details>
|
蛋黃酥上車程式下載:
|
||||||
<summary><code><b>蛋黃酥上車程式下載</b>(點我展開)</code></summary>
|
|
||||||
|
|
||||||
https://github.com/max32002/tixcraft_bot/releases
|
https://github.com/max32002/tixcraft_bot/releases
|
||||||
|
|
||||||
下載說明:
|
下載說明:
|
||||||
|
|
||||||
- 目前有打包的「執行檔」,只有 Windows 平台,其他作業系統需要使用原始碼來執行。當然 Windows 平台也可以用原始碼執行 MaxBot.
|
- 目前有打包的「執行檔」,只有 Windows 平台,其他作業系統需要使用原始碼來執行。當然 Windows 平台也可以用原始碼執行 MaxBot.
|
||||||
- 如果你是要用「原始碼」執行 MaxBot, 在透過 git clone 或在 github 按下載原始碼的 zip 檔,你的 python 版本可以使用 3.7 / 3.8 / 3.9 / 3.10 這 4 個版號。
|
- 如果你是要用「原始碼」執行 MaxBot, 在透過 git clone 或在 github 按下載原始碼的 zip 檔, python 版本使用 3.7 / 3.8 / 3.9 / 3.10 這 4 個版號測試功能正常。
|
||||||
- 如果有辦法的話,建議使用原始碼來執行 MaxBot,執行上的「效率」與「相容性」的問題會較少。
|
- 如果有辦法的話,建議使用原始碼來執行 MaxBot,執行上的「效率」與「相容性」的問題會較少。
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## Demo 示範影片
|
## Demo 示範影片
|
||||||
|
|
||||||
|
@ -69,17 +69,13 @@ https://github.com/max32002/tixcraft_bot/releases
|
||||||
|
|
||||||
## How to Use 如何使用
|
## How to Use 如何使用
|
||||||
|
|
||||||
<details>
|
如何使用網頁說明:
|
||||||
<summary><code><b>如何使用</b>(點我展開)</code></summary>
|
|
||||||
|
|
||||||
- tixcraft / indievox / ticketmaster: https://max-everyday.com/2018/03/tixcraft-bot/
|
- tixcraft / indievox / ticketmaster: https://max-everyday.com/2018/03/tixcraft-bot/
|
||||||
- kktix: https://max-everyday.com/2018/12/kktix-bot/
|
- kktix: https://max-everyday.com/2018/12/kktix-bot/
|
||||||
- cityline: https://max-everyday.com/2019/03/cityline-bot/
|
- cityline: https://max-everyday.com/2019/03/cityline-bot/
|
||||||
- urbtix: https://max-everyday.com/2019/02/urbtix-bot/
|
- urbtix: https://max-everyday.com/2019/02/urbtix-bot/
|
||||||
- hkticketing / galaxymacau: https://max-everyday.com/2023/01/hkticketing-bot/
|
- hkticketing / galaxymacau: https://max-everyday.com/2023/01/hkticketing-bot/
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## How to Execute Source Code 透過原始碼的執行方法
|
## How to Execute Source Code 透過原始碼的執行方法
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
@ -176,99 +172,29 @@ https://zh-tw.emeditor.com/increase-virtual-memory/
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## File Description 檔案說明
|
## File Description 檔案說明
|
||||||
|
主要的檔案說明:
|
||||||
<details>
|
|
||||||
<summary><code><b>檔案說明</b>(點我展開)</code></summary>
|
|
||||||
|
|
||||||
- chrome_tixcraft.py : 搶票機器人主程式,用來自動化網頁的操作,使用元件是 selenium。
|
- chrome_tixcraft.py : 搶票機器人主程式,用來自動化網頁的操作,使用元件是 selenium。
|
||||||
- nodriver_tixcraft.py : 也是搶票機器人主程式,用來自動化網頁的操作,使用的元件是 nodriver。
|
- nodriver_tixcraft.py : 也是搶票機器人主程式,用來自動化網頁的操作,使用的元件是 nodriver。
|
||||||
- settings.py : 編輯 settings.json 的 GUI 介面。提供圖片 OCR 功能給 chrome 擴充功能。支援定時啟用/停用 MaxBot。
|
- settings.py : 編輯 settings.json 的 GUI 介面。提供圖片 OCR 功能給 chrome 擴充功能。支援定時啟用/停用 MaxBot。
|
||||||
- settings_old.py : 舊版本的編輯 settings.json 的 GUI 介面,與 settings.py 的差別在介面一個是網頁形式,old 的用的是視窗形式。
|
- settings_old.py : 舊版本的編輯 settings.json 的 GUI 介面,與 settings.py 的差別在介面一個是網頁形式,old 的用的是視窗形式。
|
||||||
- config_launcher.py : 設定檔管理, 方便對多個設定檔案搶票。
|
- config_launcher.py : 設定檔管理, 方便對多個設定檔案搶票。
|
||||||
</details>
|
|
||||||
|
|
||||||
## Introduce the Implement 實作方法
|
## Introduce the Implement 實作方法
|
||||||
|
|
||||||
[實作方法 點我查看](https://stackoverflow.max-everyday.com/2018/03/selenium-chrome-webdriver/)
|
https://stackoverflow.max-everyday.com/2018/03/selenium-chrome-webdriver/
|
||||||
|
|
||||||
## Execute Suggestion 蛋黃酥上車相關建議
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><code><b>蛋黃酥上車相關建議</b>(點我展開)</code></summary>
|
|
||||||
|
|
||||||
please run this source code with high performance hardware computer and high speed + stable network.
|
|
||||||
|
|
||||||
門票的「限量」是很殘酷的,建議不要用破舊的電腦或連線不穩的手機網路來搶票,因為只要比別人慢個 0.1 秒,票可能就沒了。為了要搶到限量的票真心建議去一下網咖或找一個網路連線穩定且快的地方並使用硬體不差的電腦來搶票。
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## TODO about Cpatcha 關於驗證碼
|
## TODO about Cpatcha 關於驗證碼
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><code><b>關於驗證碼</b>(點我展開)</code></summary>
|
|
||||||
|
|
||||||
目前自動輸入驗證碼用的元件是:
|
目前自動輸入驗證碼用的元件是:
|
||||||
|
|
||||||
https://github.com/sml2h3/ddddocr
|
https://github.com/sml2h3/ddddocr
|
||||||
|
|
||||||
附註:
|
|
||||||
|
|
||||||
- 由於 ddddocr 元件的因素,python 版本要降到 3.10.11 版, 傳送門:
|
|
||||||
https://www.python.org/downloads/release/python-31011/
|
|
||||||
- 猜測驗證碼時比較容易出錯的是字英 f 和 t,還有 q 和 g, v 和 u 還有 w.
|
|
||||||
|
|
||||||
想自動輸入驗證碼,除了可以使用 ddddocr 提供的 trainer, 也可以參考看看:實作基於 CNN 的台鐵訂票驗證碼辨識以及透過模仿及資料增強的訓練集產生器 (Simple captcha solver based on CNN and a training set generator by imitating the style of captcha and data augmentation)
|
|
||||||
|
|
||||||
https://github.com/JasonLiTW/simple-railway-captcha-solver
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## Common Problems 常見問題整理
|
## Common Problems 常見問題整理
|
||||||
|
|
||||||
<details>
|
整理大家在搶票時常遇到的問題:
|
||||||
<summary><code><b>常見問題整理</b>(點我展開)</code></summary>
|
https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket
|
||||||
|
|
||||||
### 整理大家在搶票時常遇到的問題:
|
|
||||||
|
|
||||||
- [使用搶票程式有違法嗎?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#law)
|
|
||||||
- [沒講清楚成功後的報酬](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#reward)
|
|
||||||
- [買到太多票](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#too_many_ticket)
|
|
||||||
- [如何處理多的票?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#many_tickets)
|
|
||||||
- [讓票要注意的詐騙](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#ticket-fraud)
|
|
||||||
- [使用搶票程式會讓自己的帳號被鎖住嗎?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#account_locked)
|
|
||||||
- [如何恢復拓元的「購票權限」?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#unlock)
|
|
||||||
- [網頁刷新速度有推薦幾秒刷新一次嗎?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#refresh)
|
|
||||||
- [搶票的電腦需要多少的網路頻寬才夠?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#bandwidth)
|
|
||||||
- [使用VPN/代理伺服器(Proxy)來搶票會有用嗎?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#proxy)
|
|
||||||
- [同一個IP短時間重試被系統視為惡意程式而封鎖怎麼辦?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#ip_blocked)
|
|
||||||
- [Firefox和chrome搶票上有差距嗎?我看大家基本上都用chrome 很少用Firefox.](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#firefox_vs_chrome)
|
|
||||||
- [為什麼要設計搶票的機制?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#race_game)
|
|
||||||
- [為什麼網頁會有驗證碼?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#captcha)
|
|
||||||
- [你的硬體設備該不該升級?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#hardware)
|
|
||||||
- [想組一台新的電腦,是不是可以給我一些建議呢?](https://max-everyday.com/2023/02/common-problem-when-you-buy-ticket/#new_compute_suggestion)
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## Extension Privacy 擴充功能隱私權政策
|
## Extension Privacy 擴充功能隱私權政策
|
||||||
|
|
||||||
<details>
|
https://github.com/max32002/tixcraft_bot/blob/master/README_EXTENSION.md
|
||||||
<summary><code><b>MaxBot Plus擴充功能隱私權政策</b>(點我展開)</code></summary>
|
|
||||||
|
|
||||||
### 產品如何收集、使用及分享使用者資料
|
|
||||||
|
|
||||||
- 擴充取得會取得特定網頁內容, 並且自動輸入張數。
|
|
||||||
- 擴充功能會移除特定網頁內容裡已售完的網頁區塊。
|
|
||||||
- 擴充功能會取得特定網址資訊, 並置換為下一個新的網址。
|
|
||||||
- 擴充取得會取得特定網頁內容, 判斷為需要重新整理時, 自動刷新頁面。
|
|
||||||
|
|
||||||
### 使用者資料的所有分享對象。
|
|
||||||
|
|
||||||
- 擴充功能沒有分享使用者資料。
|
|
||||||
|
|
||||||
### 擴充功能主要功能:
|
|
||||||
|
|
||||||
- 特定的訂票網頁內容, 並且自動輸入張數。
|
|
||||||
- 移除特定的訂票網頁內容裡已售完的網頁區塊。
|
|
||||||
- 特定的訂票網址, 自動置換為下一步的新網址。
|
|
||||||
- 當訂票網頁內容已經無票或沒有符合的關鍵字時, 自動刷新網頁。
|
|
||||||
- 特定網頁支援驗證碼功能, 需要同時開啟 MaxBot 主程式。
|
|
||||||
</details>
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
## Extension Privacy 擴充功能隱私權政策
|
||||||
|
|
||||||
|
### 產品如何收集、使用及分享使用者資料
|
||||||
|
|
||||||
|
- 擴充取得會取得特定網頁內容, 並且自動輸入張數。
|
||||||
|
- 擴充功能會移除特定網頁內容裡已售完的網頁區塊。
|
||||||
|
- 擴充功能會取得特定網址資訊, 並置換為下一個新的網址。
|
||||||
|
- 擴充取得會取得特定網頁內容, 判斷為需要重新整理時, 自動刷新頁面。
|
||||||
|
|
||||||
|
### 使用者資料的所有分享對象。
|
||||||
|
|
||||||
|
- 擴充功能沒有分享使用者資料。
|
||||||
|
|
||||||
|
### 擴充功能主要功能:
|
||||||
|
|
||||||
|
- 特定的訂票網頁內容, 並且自動輸入張數。
|
||||||
|
- 移除特定的訂票網頁內容裡已售完的網頁區塊。
|
||||||
|
- 特定的訂票網址, 自動置換為下一步的新網址。
|
||||||
|
- 當訂票網頁內容已經無票或沒有符合的關鍵字時, 自動刷新網頁。
|
||||||
|
- 特定網頁支援驗證碼功能, 需要同時開啟 MaxBot 主程式。
|
|
@ -44,7 +44,7 @@ except Exception as exc:
|
||||||
print(exc)
|
print(exc)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
CONST_APP_VERSION = "MaxBot (2024.04.21)"
|
CONST_APP_VERSION = "MaxBot (2024.04.24)"
|
||||||
|
|
||||||
CONST_MAXBOT_ANSWER_ONLINE_FILE = "MAXBOT_ONLINE_ANSWER.txt"
|
CONST_MAXBOT_ANSWER_ONLINE_FILE = "MAXBOT_ONLINE_ANSWER.txt"
|
||||||
CONST_MAXBOT_CONFIG_FILE = "settings.json"
|
CONST_MAXBOT_CONFIG_FILE = "settings.json"
|
||||||
|
@ -1923,12 +1923,13 @@ def tixcraft_change_captcha(driver,url):
|
||||||
def tixcraft_toast(driver, message):
|
def tixcraft_toast(driver, message):
|
||||||
toast_element = None
|
toast_element = None
|
||||||
try:
|
try:
|
||||||
my_css_selector = ".remark-word"
|
my_css_selector = "p.remark-word"
|
||||||
toast_element = driver.find_element(By.CSS_SELECTOR, my_css_selector)
|
toast_element = driver.find_element(By.CSS_SELECTOR, my_css_selector)
|
||||||
if not toast_element is None:
|
if not toast_element is None:
|
||||||
driver.execute_script("arguments[0].innerHTML='%s';" % message, toast_element)
|
driver.execute_script("arguments[0].innerHTML='%s';" % message, toast_element)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print("find toast element fail")
|
#print("find toast element fail")
|
||||||
|
pass
|
||||||
|
|
||||||
def tixcraft_keyin_captcha_code(driver, answer = "", auto_submit = False):
|
def tixcraft_keyin_captcha_code(driver, answer = "", auto_submit = False):
|
||||||
is_verifyCode_editing = False
|
is_verifyCode_editing = False
|
||||||
|
@ -1962,22 +1963,28 @@ def tixcraft_keyin_captcha_code(driver, answer = "", auto_submit = False):
|
||||||
is_visible = False
|
is_visible = False
|
||||||
|
|
||||||
if is_visible:
|
if is_visible:
|
||||||
try:
|
is_text_clicked = False
|
||||||
form_verifyCode.click()
|
|
||||||
is_verifyCode_editing = True
|
if inputed_value == "":
|
||||||
except Exception as exc:
|
|
||||||
print("click form_verifyCode fail, trying to use javascript.")
|
|
||||||
# plan B
|
|
||||||
try:
|
try:
|
||||||
driver.execute_script("document.getElementById(\"TicketForm_verifyCode\").focus();")
|
form_verifyCode.click()
|
||||||
|
is_text_clicked = True
|
||||||
is_verifyCode_editing = True
|
is_verifyCode_editing = True
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
#print("click form_verifyCode fail.")
|
print("click form_verifyCode fail, trying to use javascript.")
|
||||||
pass
|
# plan B
|
||||||
|
try:
|
||||||
|
driver.execute_script("document.getElementById(\"TicketForm_verifyCode\").focus();")
|
||||||
|
is_verifyCode_editing = True
|
||||||
|
except Exception as exc:
|
||||||
|
#print("click form_verifyCode fail.")
|
||||||
|
pass
|
||||||
|
|
||||||
if len(answer) > 0:
|
if len(answer) > 0:
|
||||||
#print("start to fill answer.")
|
#print("start to fill answer.")
|
||||||
try:
|
try:
|
||||||
|
if not is_text_clicked:
|
||||||
|
form_verifyCode.click()
|
||||||
form_verifyCode.clear()
|
form_verifyCode.clear()
|
||||||
form_verifyCode.send_keys(answer)
|
form_verifyCode.send_keys(answer)
|
||||||
|
|
||||||
|
@ -1987,6 +1994,7 @@ def tixcraft_keyin_captcha_code(driver, answer = "", auto_submit = False):
|
||||||
is_form_sumbited = True
|
is_form_sumbited = True
|
||||||
else:
|
else:
|
||||||
driver.execute_script("document.getElementById(\"TicketForm_verifyCode\").select();")
|
driver.execute_script("document.getElementById(\"TicketForm_verifyCode\").select();")
|
||||||
|
# TODO: show text message on ticketmaster web page.
|
||||||
tixcraft_toast(driver, "※ 按 Enter 如果答案是: " + answer)
|
tixcraft_toast(driver, "※ 按 Enter 如果答案是: " + answer)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print("send_keys ocr answer fail.")
|
print("send_keys ocr answer fail.")
|
||||||
|
@ -2118,7 +2126,6 @@ def tixcraft_auto_ocr(driver, ocr, away_from_keyboard_enable, previous_answer, C
|
||||||
else:
|
else:
|
||||||
if not away_from_keyboard_enable:
|
if not away_from_keyboard_enable:
|
||||||
tixcraft_keyin_captcha_code(driver)
|
tixcraft_keyin_captcha_code(driver)
|
||||||
tixcraft_toast(driver, "※ OCR辨識失敗Q_Q,驗證碼請手動輸入...")
|
|
||||||
else:
|
else:
|
||||||
is_need_redo_ocr = True
|
is_need_redo_ocr = True
|
||||||
if previous_answer != ocr_answer:
|
if previous_answer != ocr_answer:
|
||||||
|
@ -10844,9 +10851,85 @@ def resize_window(driver, config_dict):
|
||||||
driver.set_window_size(int(size_array[0]), int(size_array[1]))
|
driver.set_window_size(int(size_array[0]), int(size_array[1]))
|
||||||
driver.set_window_position(position_left, 30)
|
driver.set_window_position(position_left, 30)
|
||||||
|
|
||||||
|
def check_refresh_datetime_occur(driver, target_time):
|
||||||
|
is_refresh_datetime_sent = False
|
||||||
|
|
||||||
|
system_clock_data = datetime.now()
|
||||||
|
current_time = system_clock_data.strftime('%H:%M:%S')
|
||||||
|
if target_time == current_time:
|
||||||
|
try:
|
||||||
|
driver.refresh()
|
||||||
|
is_refresh_datetime_sent = True
|
||||||
|
print("send refresh at time:", current_time)
|
||||||
|
except Exception as exc:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return is_refresh_datetime_sent
|
||||||
|
|
||||||
|
def sendkey_to_browser(driver, config_dict):
|
||||||
|
tmp_filepath = ""
|
||||||
|
if "token" in config_dict:
|
||||||
|
app_root = util.get_app_root()
|
||||||
|
tmp_file = config_dict["token"] + ".tmp"
|
||||||
|
tmp_filepath = os.path.join(app_root, tmp_file)
|
||||||
|
|
||||||
|
if os.path.exists(tmp_filepath):
|
||||||
|
sendkey_to_browser_exist(driver, tmp_filepath)
|
||||||
|
|
||||||
|
def sendkey_to_browser_exist(driver, tmp_filepath):
|
||||||
|
sendkey_dict = None
|
||||||
|
try:
|
||||||
|
with open(tmp_filepath) as json_data:
|
||||||
|
sendkey_dict = json.load(json_data)
|
||||||
|
print(sendkey_dict)
|
||||||
|
except Exception as e:
|
||||||
|
print("error on open file")
|
||||||
|
print(e)
|
||||||
|
pass
|
||||||
|
|
||||||
|
if sendkey_dict:
|
||||||
|
all_command_done = True
|
||||||
|
if "command" in sendkey_dict:
|
||||||
|
for cmd_dict in sendkey_dict["command"]:
|
||||||
|
#print("cmd_dict", cmd_dict)
|
||||||
|
if cmd_dict["type"] == "sendkey":
|
||||||
|
print("sendkey")
|
||||||
|
target_text = cmd_dict["text"]
|
||||||
|
try:
|
||||||
|
form_input_1 = driver.find_element(By.CSS_SELECTOR, cmd_dict["selector"])
|
||||||
|
inputed_value_1 = form_input_1.get_attribute('value')
|
||||||
|
if not inputed_value_1 == target_text:
|
||||||
|
form_input_1.clear()
|
||||||
|
form_input_1.click()
|
||||||
|
form_input_1.send_keys(cmd_dict["text"])
|
||||||
|
except Exception as exc:
|
||||||
|
all_command_done = False
|
||||||
|
print("error on sendkey")
|
||||||
|
print(exc)
|
||||||
|
pass
|
||||||
|
|
||||||
|
if cmd_dict["type"] == "click":
|
||||||
|
print("click")
|
||||||
|
try:
|
||||||
|
form_input_1 = driver.find_element(By.CSS_SELECTOR, cmd_dict["selector"])
|
||||||
|
form_input_1.click()
|
||||||
|
except Exception as exc:
|
||||||
|
all_command_done = False
|
||||||
|
print("error on click")
|
||||||
|
print(exc)
|
||||||
|
pass
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
# must all command success to delete tmp file.
|
||||||
|
if all_command_done:
|
||||||
|
try:
|
||||||
|
os.unlink(tmp_filepath)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
config_dict = get_config_dict(args)
|
config_dict = get_config_dict(args)
|
||||||
|
config_dict["token"] = util.get_token()
|
||||||
|
|
||||||
driver = None
|
driver = None
|
||||||
if not config_dict is None:
|
if not config_dict is None:
|
||||||
|
@ -10860,7 +10943,6 @@ def main(args):
|
||||||
else:
|
else:
|
||||||
print("Load config error!")
|
print("Load config error!")
|
||||||
|
|
||||||
# internal variable. 說明:這是一個內部變數,請略過。
|
|
||||||
url = ""
|
url = ""
|
||||||
last_url = ""
|
last_url = ""
|
||||||
|
|
||||||
|
@ -10878,6 +10960,8 @@ def main(args):
|
||||||
|
|
||||||
maxbot_last_reset_time = time.time()
|
maxbot_last_reset_time = time.time()
|
||||||
is_quit_bot = False
|
is_quit_bot = False
|
||||||
|
is_refresh_datetime_sent = False
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
@ -10904,6 +10988,9 @@ def main(args):
|
||||||
if len(url) == 0:
|
if len(url) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if not is_refresh_datetime_sent:
|
||||||
|
is_refresh_datetime_sent = check_refresh_datetime_occur(driver, config_dict["refresh_datetime"])
|
||||||
|
|
||||||
is_maxbot_paused = False
|
is_maxbot_paused = False
|
||||||
if os.path.exists(CONST_MAXBOT_INT28_FILE):
|
if os.path.exists(CONST_MAXBOT_INT28_FILE):
|
||||||
is_maxbot_paused = True
|
is_maxbot_paused = True
|
||||||
|
@ -10923,6 +11010,9 @@ def main(args):
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
sendkey_to_browser(driver, config_dict)
|
||||||
|
|
||||||
|
# default is 0, not reset.
|
||||||
if config_dict["advanced"]["reset_browser_interval"] > 0:
|
if config_dict["advanced"]["reset_browser_interval"] > 0:
|
||||||
maxbot_running_time = time.time() - maxbot_last_reset_time
|
maxbot_running_time = time.time() - maxbot_last_reset_time
|
||||||
if maxbot_running_time > config_dict["advanced"]["reset_browser_interval"]:
|
if maxbot_running_time > config_dict["advanced"]["reset_browser_interval"]:
|
||||||
|
|
|
@ -24,7 +24,7 @@ import webbrowser
|
||||||
|
|
||||||
import util
|
import util
|
||||||
|
|
||||||
CONST_APP_VERSION = "MaxBot (2024.04.21)"
|
CONST_APP_VERSION = "MaxBot (2024.04.24)"
|
||||||
|
|
||||||
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"
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
# Demo (示範影片)
|
# Demo (示範影片)
|
||||||
|
|
||||||
### 2024-04-14
|
|
||||||
|
|
||||||
網頁設定介面
|
|
||||||
|
|
||||||
https://youtu.be/VDQFbweMLxU
|
|
||||||
|
|
||||||
### 2024-04-11
|
### 2024-04-11
|
||||||
|
|
||||||
信用卡活動登錄自動填身份證號碼
|
信用卡活動登錄自動填身份證號碼
|
||||||
|
|
|
@ -32,7 +32,7 @@ except Exception as exc:
|
||||||
print(exc)
|
print(exc)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
CONST_APP_VERSION = "MaxBot (2024.04.21)"
|
CONST_APP_VERSION = "MaxBot (2024.04.24)"
|
||||||
|
|
||||||
CONST_MAXBOT_ANSWER_ONLINE_FILE = "MAXBOT_ONLINE_ANSWER.txt"
|
CONST_MAXBOT_ANSWER_ONLINE_FILE = "MAXBOT_ONLINE_ANSWER.txt"
|
||||||
CONST_MAXBOT_CONFIG_FILE = "settings.json"
|
CONST_MAXBOT_CONFIG_FILE = "settings.json"
|
||||||
|
@ -2152,6 +2152,21 @@ def nodriver_overwrite_prefs(conf):
|
||||||
with open(state_filepath, 'w') as outfile:
|
with open(state_filepath, 'w') as outfile:
|
||||||
outfile.write(json_str)
|
outfile.write(json_str)
|
||||||
|
|
||||||
|
async def check_refresh_datetime_occur(tab, target_time):
|
||||||
|
is_refresh_datetime_sent = False
|
||||||
|
|
||||||
|
system_clock_data = datetime.now()
|
||||||
|
current_time = system_clock_data.strftime('%H:%M:%S')
|
||||||
|
if target_time == current_time:
|
||||||
|
try:
|
||||||
|
await tab.reload()
|
||||||
|
is_refresh_datetime_sent = True
|
||||||
|
print("send refresh at time:", current_time)
|
||||||
|
except Exception as exc:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return is_refresh_datetime_sent
|
||||||
|
|
||||||
async def main(args):
|
async def main(args):
|
||||||
config_dict = get_config_dict(args)
|
config_dict = get_config_dict(args)
|
||||||
|
|
||||||
|
@ -2178,7 +2193,6 @@ async def main(args):
|
||||||
else:
|
else:
|
||||||
print("Load config error!")
|
print("Load config error!")
|
||||||
|
|
||||||
# internal variable. 說明:這是一個內部變數,請略過。
|
|
||||||
url = ""
|
url = ""
|
||||||
last_url = ""
|
last_url = ""
|
||||||
|
|
||||||
|
@ -2205,6 +2219,8 @@ async def main(args):
|
||||||
|
|
||||||
maxbot_last_reset_time = time.time()
|
maxbot_last_reset_time = time.time()
|
||||||
is_quit_bot = False
|
is_quit_bot = False
|
||||||
|
is_refresh_datetime_sent = False
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
@ -2231,6 +2247,9 @@ async def main(args):
|
||||||
if len(url) == 0:
|
if len(url) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if not is_refresh_datetime_sent:
|
||||||
|
is_refresh_datetime_sent = await check_refresh_datetime_occur(tab, config_dict["refresh_datetime"])
|
||||||
|
|
||||||
is_maxbot_paused = False
|
is_maxbot_paused = False
|
||||||
if os.path.exists(CONST_MAXBOT_INT28_FILE):
|
if os.path.exists(CONST_MAXBOT_INT28_FILE):
|
||||||
is_maxbot_paused = True
|
is_maxbot_paused = True
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
"browser": "chrome",
|
"browser": "chrome",
|
||||||
"language": "English",
|
"language": "English",
|
||||||
"ticket_number": 2,
|
"ticket_number": 2,
|
||||||
|
"refresh_datetime": "",
|
||||||
"ocr_captcha": {
|
"ocr_captcha": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"beta": true,
|
"beta": true,
|
||||||
|
@ -24,7 +25,7 @@
|
||||||
"kktix": {
|
"kktix": {
|
||||||
"auto_press_next_step_button": true,
|
"auto_press_next_step_button": true,
|
||||||
"auto_fill_ticket_number": true,
|
"auto_fill_ticket_number": true,
|
||||||
"max_dwell_time": 60
|
"max_dwell_time": 90
|
||||||
},
|
},
|
||||||
"cityline": {
|
"cityline": {
|
||||||
"cityline_queue_retry": true
|
"cityline_queue_retry": true
|
||||||
|
@ -77,7 +78,7 @@
|
||||||
"block_facebook_network": false,
|
"block_facebook_network": false,
|
||||||
"headless": false,
|
"headless": false,
|
||||||
"verbose": false,
|
"verbose": false,
|
||||||
"auto_guess_options": true,
|
"auto_guess_options": false,
|
||||||
"user_guess_string": "",
|
"user_guess_string": "",
|
||||||
"remote_url": "\"http://127.0.0.1:16888/\"",
|
"remote_url": "\"http://127.0.0.1:16888/\"",
|
||||||
"auto_reload_page_interval": 0.1,
|
"auto_reload_page_interval": 0.1,
|
||||||
|
|
45
settings.py
45
settings.py
|
@ -39,7 +39,7 @@ try:
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
CONST_APP_VERSION = "MaxBot (2024.04.21)"
|
CONST_APP_VERSION = "MaxBot (2024.04.24)"
|
||||||
|
|
||||||
CONST_MAXBOT_ANSWER_ONLINE_FILE = "MAXBOT_ONLINE_ANSWER.txt"
|
CONST_MAXBOT_ANSWER_ONLINE_FILE = "MAXBOT_ONLINE_ANSWER.txt"
|
||||||
CONST_MAXBOT_CONFIG_FILE = "settings.json"
|
CONST_MAXBOT_CONFIG_FILE = "settings.json"
|
||||||
|
@ -104,6 +104,8 @@ def get_default_config():
|
||||||
config_dict["browser"] = "chrome"
|
config_dict["browser"] = "chrome"
|
||||||
config_dict["language"] = "English"
|
config_dict["language"] = "English"
|
||||||
config_dict["ticket_number"] = 2
|
config_dict["ticket_number"] = 2
|
||||||
|
config_dict["refresh_datetime"] = ""
|
||||||
|
|
||||||
config_dict["ocr_captcha"] = {}
|
config_dict["ocr_captcha"] = {}
|
||||||
config_dict["ocr_captcha"]["enable"] = True
|
config_dict["ocr_captcha"]["enable"] = True
|
||||||
config_dict["ocr_captcha"]["beta"] = True
|
config_dict["ocr_captcha"]["beta"] = True
|
||||||
|
@ -125,7 +127,7 @@ def get_default_config():
|
||||||
config_dict['kktix']={}
|
config_dict['kktix']={}
|
||||||
config_dict["kktix"]["auto_press_next_step_button"] = True
|
config_dict["kktix"]["auto_press_next_step_button"] = True
|
||||||
config_dict["kktix"]["auto_fill_ticket_number"] = True
|
config_dict["kktix"]["auto_fill_ticket_number"] = True
|
||||||
config_dict["kktix"]["max_dwell_time"] = 60
|
config_dict["kktix"]["max_dwell_time"] = 90
|
||||||
|
|
||||||
config_dict['cityline']={}
|
config_dict['cityline']={}
|
||||||
config_dict["cityline"]["cityline_queue_retry"] = True
|
config_dict["cityline"]["cityline_queue_retry"] = True
|
||||||
|
@ -183,7 +185,7 @@ def get_default_config():
|
||||||
|
|
||||||
config_dict["advanced"]["headless"] = False
|
config_dict["advanced"]["headless"] = False
|
||||||
config_dict["advanced"]["verbose"] = False
|
config_dict["advanced"]["verbose"] = False
|
||||||
config_dict["advanced"]["auto_guess_options"] = True
|
config_dict["advanced"]["auto_guess_options"] = False
|
||||||
config_dict["advanced"]["user_guess_string"] = ""
|
config_dict["advanced"]["user_guess_string"] = ""
|
||||||
|
|
||||||
# remote_url not under ocr, due to not only support ocr features.
|
# remote_url not under ocr, due to not only support ocr features.
|
||||||
|
@ -382,6 +384,12 @@ def clean_tmp_file():
|
||||||
for filepath in remove_file_list:
|
for filepath in remove_file_list:
|
||||||
util.force_remove_file(filepath)
|
util.force_remove_file(filepath)
|
||||||
|
|
||||||
|
Root_Dir = util.get_app_root()
|
||||||
|
target_folder = os.listdir(Root_Dir)
|
||||||
|
for item in target_folder:
|
||||||
|
if item.endswith(".tmp"):
|
||||||
|
os.remove(os.path.join(Root_Dir, item))
|
||||||
|
|
||||||
class QuestionHandler(tornado.web.RequestHandler):
|
class QuestionHandler(tornado.web.RequestHandler):
|
||||||
def get(self):
|
def get(self):
|
||||||
global txt_question
|
global txt_question
|
||||||
|
@ -477,6 +485,36 @@ class SaveJsonHandler(tornado.web.RequestHandler):
|
||||||
|
|
||||||
self.finish()
|
self.finish()
|
||||||
|
|
||||||
|
class SendkeyHandler(tornado.web.RequestHandler):
|
||||||
|
def post(self):
|
||||||
|
self.set_header("Access-Control-Allow-Origin", "*")
|
||||||
|
self.set_header("Access-Control-Allow-Headers", "x-requested-with")
|
||||||
|
self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
|
||||||
|
|
||||||
|
_body = None
|
||||||
|
is_pass_check = True
|
||||||
|
errorMessage = ""
|
||||||
|
errorCode = 0
|
||||||
|
|
||||||
|
if is_pass_check:
|
||||||
|
is_pass_check = False
|
||||||
|
try :
|
||||||
|
_body = json.loads(self.request.body)
|
||||||
|
is_pass_check = True
|
||||||
|
except Exception:
|
||||||
|
errorMessage = "wrong json format"
|
||||||
|
errorCode = 1001
|
||||||
|
pass
|
||||||
|
|
||||||
|
if is_pass_check:
|
||||||
|
app_root = util.get_app_root()
|
||||||
|
if "token" in _body:
|
||||||
|
tmp_file = _body["token"] + ".tmp"
|
||||||
|
config_filepath = os.path.join(app_root, tmp_file)
|
||||||
|
util.save_json(_body, config_filepath)
|
||||||
|
|
||||||
|
self.write({"return": True})
|
||||||
|
|
||||||
class OcrHandler(tornado.web.RequestHandler):
|
class OcrHandler(tornado.web.RequestHandler):
|
||||||
def get(self):
|
def get(self):
|
||||||
self.write({"answer": "1234"})
|
self.write({"answer": "1234"})
|
||||||
|
@ -558,6 +596,7 @@ async def main_server():
|
||||||
app = Application([
|
app = Application([
|
||||||
("/version", VersionHandler),
|
("/version", VersionHandler),
|
||||||
("/shutdown", ShutdownHandler),
|
("/shutdown", ShutdownHandler),
|
||||||
|
("/sendkey", SendkeyHandler),
|
||||||
|
|
||||||
# status api
|
# status api
|
||||||
("/status", StatusHandler),
|
("/status", StatusHandler),
|
||||||
|
|
|
@ -34,7 +34,7 @@ try:
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
CONST_APP_VERSION = "MaxBot (2024.04.21)"
|
CONST_APP_VERSION = "MaxBot (2024.04.24)"
|
||||||
|
|
||||||
CONST_MAXBOT_ANSWER_ONLINE_FILE = "MAXBOT_ONLINE_ANSWER.txt"
|
CONST_MAXBOT_ANSWER_ONLINE_FILE = "MAXBOT_ONLINE_ANSWER.txt"
|
||||||
CONST_MAXBOT_CONFIG_FILE = "settings.json"
|
CONST_MAXBOT_CONFIG_FILE = "settings.json"
|
||||||
|
@ -106,6 +106,7 @@ def load_translate():
|
||||||
en_us["browser"] = 'Browser'
|
en_us["browser"] = 'Browser'
|
||||||
en_us["language"] = 'Language'
|
en_us["language"] = 'Language'
|
||||||
en_us["ticket_number"] = 'Ticker Number'
|
en_us["ticket_number"] = 'Ticker Number'
|
||||||
|
en_us["refresh_datetime"] = 'Refresh at specified time'
|
||||||
|
|
||||||
en_us["enable"] = 'Enable'
|
en_us["enable"] = 'Enable'
|
||||||
en_us["recommand_enable"] = "Recommended to enable"
|
en_us["recommand_enable"] = "Recommended to enable"
|
||||||
|
@ -226,6 +227,7 @@ def load_translate():
|
||||||
zh_tw["browser"] = '瀏覽器'
|
zh_tw["browser"] = '瀏覽器'
|
||||||
zh_tw["language"] = '語言'
|
zh_tw["language"] = '語言'
|
||||||
zh_tw["ticket_number"] = '門票張數'
|
zh_tw["ticket_number"] = '門票張數'
|
||||||
|
zh_tw["refresh_datetime"] = '刷新在指定時間'
|
||||||
|
|
||||||
zh_tw["enable"] = '啟用'
|
zh_tw["enable"] = '啟用'
|
||||||
zh_tw["recommand_enable"] = "建議啟用"
|
zh_tw["recommand_enable"] = "建議啟用"
|
||||||
|
@ -344,6 +346,7 @@ def load_translate():
|
||||||
zh_cn["browser"] = '浏览器'
|
zh_cn["browser"] = '浏览器'
|
||||||
zh_cn["language"] = '语言'
|
zh_cn["language"] = '语言'
|
||||||
zh_cn["ticket_number"] = '门票张数'
|
zh_cn["ticket_number"] = '门票张数'
|
||||||
|
zh_cn["refresh_datetime"] = '刷新在指定时间'
|
||||||
|
|
||||||
zh_cn["enable"] = '启用'
|
zh_cn["enable"] = '启用'
|
||||||
zh_cn["recommand_enable"] = "建议启用"
|
zh_cn["recommand_enable"] = "建议启用"
|
||||||
|
@ -464,6 +467,7 @@ def load_translate():
|
||||||
ja_jp["browser"] = 'ブラウザ'
|
ja_jp["browser"] = 'ブラウザ'
|
||||||
ja_jp["language"] = '言語'
|
ja_jp["language"] = '言語'
|
||||||
ja_jp["ticket_number"] = '枚数'
|
ja_jp["ticket_number"] = '枚数'
|
||||||
|
ja_jp["refresh_datetime"] = '目標時間にリフレッシュ'
|
||||||
|
|
||||||
ja_jp["enable"] = '有効'
|
ja_jp["enable"] = '有効'
|
||||||
ja_jp["recommand_enable"] = "有効化を推奨"
|
ja_jp["recommand_enable"] = "有効化を推奨"
|
||||||
|
@ -591,6 +595,8 @@ def get_default_config():
|
||||||
config_dict["browser"] = "chrome"
|
config_dict["browser"] = "chrome"
|
||||||
config_dict["language"] = "English"
|
config_dict["language"] = "English"
|
||||||
config_dict["ticket_number"] = 2
|
config_dict["ticket_number"] = 2
|
||||||
|
config_dict["refresh_datetime"] = ""
|
||||||
|
|
||||||
config_dict["ocr_captcha"] = {}
|
config_dict["ocr_captcha"] = {}
|
||||||
config_dict["ocr_captcha"]["enable"] = True
|
config_dict["ocr_captcha"]["enable"] = True
|
||||||
config_dict["ocr_captcha"]["beta"] = True
|
config_dict["ocr_captcha"]["beta"] = True
|
||||||
|
@ -612,7 +618,7 @@ def get_default_config():
|
||||||
config_dict['kktix']={}
|
config_dict['kktix']={}
|
||||||
config_dict["kktix"]["auto_press_next_step_button"] = True
|
config_dict["kktix"]["auto_press_next_step_button"] = True
|
||||||
config_dict["kktix"]["auto_fill_ticket_number"] = True
|
config_dict["kktix"]["auto_fill_ticket_number"] = True
|
||||||
config_dict["kktix"]["max_dwell_time"] = 60
|
config_dict["kktix"]["max_dwell_time"] = 90
|
||||||
|
|
||||||
config_dict['cityline']={}
|
config_dict['cityline']={}
|
||||||
config_dict["cityline"]["cityline_queue_retry"] = True
|
config_dict["cityline"]["cityline_queue_retry"] = True
|
||||||
|
@ -670,7 +676,7 @@ def get_default_config():
|
||||||
|
|
||||||
config_dict["advanced"]["headless"] = False
|
config_dict["advanced"]["headless"] = False
|
||||||
config_dict["advanced"]["verbose"] = False
|
config_dict["advanced"]["verbose"] = False
|
||||||
config_dict["advanced"]["auto_guess_options"] = True
|
config_dict["advanced"]["auto_guess_options"] = False
|
||||||
config_dict["advanced"]["user_guess_string"] = ""
|
config_dict["advanced"]["user_guess_string"] = ""
|
||||||
config_dict["advanced"]["remote_url"] = "http://127.0.0.1:%d/" % (CONST_SERVER_PORT)
|
config_dict["advanced"]["remote_url"] = "http://127.0.0.1:%d/" % (CONST_SERVER_PORT)
|
||||||
|
|
||||||
|
@ -1023,6 +1029,7 @@ def btn_save_act(slience_mode=False):
|
||||||
txt_resume_keyword_second.insert("1.0", config_dict["advanced"]["resume_keyword_second"].strip())
|
txt_resume_keyword_second.insert("1.0", config_dict["advanced"]["resume_keyword_second"].strip())
|
||||||
|
|
||||||
if is_all_data_correct:
|
if is_all_data_correct:
|
||||||
|
config_dict["refresh_datetime"] = txt_refresh_datetime.get().strip()
|
||||||
config_dict["area_auto_select"]["enable"] = bool(chk_state_area_auto_select.get())
|
config_dict["area_auto_select"]["enable"] = bool(chk_state_area_auto_select.get())
|
||||||
config_dict["area_auto_select"]["mode"] = combo_area_auto_select_mode.get().strip()
|
config_dict["area_auto_select"]["mode"] = combo_area_auto_select_mode.get().strip()
|
||||||
|
|
||||||
|
@ -1258,6 +1265,7 @@ def applyNewLanguage():
|
||||||
global lbl_browser
|
global lbl_browser
|
||||||
global lbl_language
|
global lbl_language
|
||||||
global lbl_ticket_number
|
global lbl_ticket_number
|
||||||
|
global lbl_refresh_datetime
|
||||||
|
|
||||||
# for kktix
|
# for kktix
|
||||||
global lbl_auto_press_next_step_button
|
global lbl_auto_press_next_step_button
|
||||||
|
@ -1347,6 +1355,7 @@ def applyNewLanguage():
|
||||||
lbl_browser.config(text=translate[language_code]["browser"])
|
lbl_browser.config(text=translate[language_code]["browser"])
|
||||||
lbl_language.config(text=translate[language_code]["language"])
|
lbl_language.config(text=translate[language_code]["language"])
|
||||||
lbl_ticket_number.config(text=translate[language_code]["ticket_number"])
|
lbl_ticket_number.config(text=translate[language_code]["ticket_number"])
|
||||||
|
lbl_refresh_datetime.config(text=translate[language_code]["refresh_datetime"])
|
||||||
|
|
||||||
lbl_auto_press_next_step_button.config(text=translate[language_code]["auto_press_next_step_button"])
|
lbl_auto_press_next_step_button.config(text=translate[language_code]["auto_press_next_step_button"])
|
||||||
lbl_auto_fill_ticket_number.config(text=translate[language_code]["auto_fill_ticket_number"])
|
lbl_auto_fill_ticket_number.config(text=translate[language_code]["auto_fill_ticket_number"])
|
||||||
|
@ -1674,9 +1683,6 @@ def PreferenctTab(root, config_dict, language_code, UI_PADDING_X):
|
||||||
print("python version:", platform.python_version())
|
print("python version:", platform.python_version())
|
||||||
print("platform:", platform.platform())
|
print("platform:", platform.platform())
|
||||||
|
|
||||||
global lbl_homepage
|
|
||||||
global lbl_ticket_number
|
|
||||||
|
|
||||||
global lbl_kktix
|
global lbl_kktix
|
||||||
global lbl_tixcraft
|
global lbl_tixcraft
|
||||||
|
|
||||||
|
@ -1686,6 +1692,7 @@ def PreferenctTab(root, config_dict, language_code, UI_PADDING_X):
|
||||||
group_row_count = 0
|
group_row_count = 0
|
||||||
|
|
||||||
# first row need padding Y
|
# first row need padding Y
|
||||||
|
global lbl_homepage
|
||||||
lbl_homepage = Label(frame_group_header, text=translate[language_code]['homepage'])
|
lbl_homepage = Label(frame_group_header, text=translate[language_code]['homepage'])
|
||||||
lbl_homepage.grid(column=0, row=group_row_count, sticky = E)
|
lbl_homepage.grid(column=0, row=group_row_count, sticky = E)
|
||||||
|
|
||||||
|
@ -1699,6 +1706,7 @@ def PreferenctTab(root, config_dict, language_code, UI_PADDING_X):
|
||||||
|
|
||||||
group_row_count+=1
|
group_row_count+=1
|
||||||
|
|
||||||
|
global lbl_ticket_number
|
||||||
lbl_ticket_number = Label(frame_group_header, text=translate[language_code]['ticket_number'])
|
lbl_ticket_number = Label(frame_group_header, text=translate[language_code]['ticket_number'])
|
||||||
lbl_ticket_number.grid(column=0, row=group_row_count, sticky = E)
|
lbl_ticket_number.grid(column=0, row=group_row_count, sticky = E)
|
||||||
|
|
||||||
|
@ -1719,6 +1727,17 @@ def PreferenctTab(root, config_dict, language_code, UI_PADDING_X):
|
||||||
|
|
||||||
frame_group_header.grid(column=0, row=row_count, sticky = W, padx=UI_PADDING_X)
|
frame_group_header.grid(column=0, row=row_count, sticky = W, padx=UI_PADDING_X)
|
||||||
|
|
||||||
|
group_row_count+=1
|
||||||
|
|
||||||
|
global lbl_refresh_datetime
|
||||||
|
lbl_refresh_datetime = Label(frame_group_header, text=translate[language_code]['refresh_datetime'])
|
||||||
|
lbl_refresh_datetime.grid(column=0, row=group_row_count, sticky = E)
|
||||||
|
|
||||||
|
global txt_refresh_datetime
|
||||||
|
txt_refresh_datetime_value = StringVar(frame_group_header, value=str(config_dict["refresh_datetime"]))
|
||||||
|
txt_refresh_datetime = Entry(frame_group_header, width=30, textvariable = txt_refresh_datetime_value)
|
||||||
|
txt_refresh_datetime.grid(column=1, row=group_row_count, sticky = W)
|
||||||
|
|
||||||
row_count+=1
|
row_count+=1
|
||||||
|
|
||||||
# for sub group KKTix.
|
# for sub group KKTix.
|
||||||
|
@ -3130,7 +3149,7 @@ def main_gui():
|
||||||
|
|
||||||
load_GUI(root, config_dict)
|
load_GUI(root, config_dict)
|
||||||
|
|
||||||
GUI_SIZE_WIDTH = 590
|
GUI_SIZE_WIDTH = 610
|
||||||
GUI_SIZE_HEIGHT = 645
|
GUI_SIZE_HEIGHT = 645
|
||||||
|
|
||||||
GUI_SIZE_MACOS = str(GUI_SIZE_WIDTH) + 'x' + str(GUI_SIZE_HEIGHT)
|
GUI_SIZE_MACOS = str(GUI_SIZE_WIDTH) + 'x' + str(GUI_SIZE_HEIGHT)
|
||||||
|
@ -3179,6 +3198,12 @@ def clean_tmp_file():
|
||||||
for filepath in remove_file_list:
|
for filepath in remove_file_list:
|
||||||
util.force_remove_file(filepath)
|
util.force_remove_file(filepath)
|
||||||
|
|
||||||
|
Root_Dir = util.get_app_root()
|
||||||
|
target_folder = os.listdir(Root_Dir)
|
||||||
|
for item in target_folder:
|
||||||
|
if item.endswith(".tmp"):
|
||||||
|
os.remove(os.path.join(Root_Dir, item))
|
||||||
|
|
||||||
def btn_copy_ip_clicked():
|
def btn_copy_ip_clicked():
|
||||||
local_ip = util.get_ip_address()
|
local_ip = util.get_ip_address()
|
||||||
ip_address = "http://%s:%d/" % (local_ip,CONST_SERVER_PORT)
|
ip_address = "http://%s:%d/" % (local_ip,CONST_SERVER_PORT)
|
||||||
|
@ -3227,6 +3252,36 @@ class VersionHandler(tornado.web.RequestHandler):
|
||||||
def get(self):
|
def get(self):
|
||||||
self.write({"version":self.application.version})
|
self.write({"version":self.application.version})
|
||||||
|
|
||||||
|
class SendkeyHandler(tornado.web.RequestHandler):
|
||||||
|
def post(self):
|
||||||
|
self.set_header("Access-Control-Allow-Origin", "*")
|
||||||
|
self.set_header("Access-Control-Allow-Headers", "x-requested-with")
|
||||||
|
self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
|
||||||
|
|
||||||
|
_body = None
|
||||||
|
is_pass_check = True
|
||||||
|
errorMessage = ""
|
||||||
|
errorCode = 0
|
||||||
|
|
||||||
|
if is_pass_check:
|
||||||
|
is_pass_check = False
|
||||||
|
try :
|
||||||
|
_body = json.loads(self.request.body)
|
||||||
|
is_pass_check = True
|
||||||
|
except Exception:
|
||||||
|
errorMessage = "wrong json format"
|
||||||
|
errorCode = 1001
|
||||||
|
pass
|
||||||
|
|
||||||
|
if is_pass_check:
|
||||||
|
app_root = util.get_app_root()
|
||||||
|
if "token" in _body:
|
||||||
|
tmp_file = _body["token"] + ".tmp"
|
||||||
|
config_filepath = os.path.join(app_root, tmp_file)
|
||||||
|
util.save_json(_body, config_filepath)
|
||||||
|
|
||||||
|
self.write({"return": True})
|
||||||
|
|
||||||
class OcrHandler(tornado.web.RequestHandler):
|
class OcrHandler(tornado.web.RequestHandler):
|
||||||
def get(self):
|
def get(self):
|
||||||
self.write({"answer": "1234"})
|
self.write({"answer": "1234"})
|
||||||
|
@ -3286,6 +3341,8 @@ async def main_server():
|
||||||
app = Application([
|
app = Application([
|
||||||
("/", MainHandler),
|
("/", MainHandler),
|
||||||
("/version", VersionHandler),
|
("/version", VersionHandler),
|
||||||
|
("/sendkey", SendkeyHandler),
|
||||||
|
|
||||||
("/ocr", OcrHandler),
|
("/ocr", OcrHandler),
|
||||||
("/query", MainHandler),
|
("/query", MainHandler),
|
||||||
("/question", QuestionHandler),
|
("/question", QuestionHandler),
|
||||||
|
|
4
util.py
4
util.py
|
@ -12,6 +12,7 @@ import threading
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
import uuid
|
||||||
|
|
||||||
CONST_FROM_TOP_TO_BOTTOM = "from top to bottom"
|
CONST_FROM_TOP_TO_BOTTOM = "from top to bottom"
|
||||||
CONST_FROM_BOTTOM_TO_TOP = "from bottom to top"
|
CONST_FROM_BOTTOM_TO_TOP = "from bottom to top"
|
||||||
|
@ -2041,3 +2042,6 @@ def launch_maxbot(script_name="chrome_tixcraft", filename="", homepage="", kktix
|
||||||
msg=str(exc)
|
msg=str(exc)
|
||||||
print("exeption:", msg)
|
print("exeption:", msg)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_token():
|
||||||
|
return str(uuid.uuid4().hex)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"homepage": "about:blank", "browser": "chrome", "language": "English", "ticket_number": 2, "ocr_captcha": {"enable": true, "beta": true, "force_submit": true, "image_source": "canvas"}, "webdriver_type": "undetected_chromedriver", "date_auto_select": {"enable": true, "date_keyword": "", "mode": "random"}, "area_auto_select": {"enable": true, "mode": "random", "area_keyword": ""}, "keyword_exclude": "\"\u8f2a\u6905\",\"\u8eab\u969c\",\"\u8eab\u5fc3 \u969c\u7919\",\"Restricted View\",\"\u71c8\u67f1\u906e\u853d\",\"\u8996\u7dda\u4e0d\u5b8c\u6574\"", "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true, "max_dwell_time": 60}, "cityline": {"cityline_queue_retry": true}, "tixcraft": {"pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true}, "advanced": {"play_sound": {"ticket": true, "order": true, "filename": "ding-dong.wav"}, "tixcraft_sid": "", "ibonqware": "", "facebook_account": "", "kktix_account": "", "fami_account": "", "cityline_account": "", "urbtix_account": "", "hkticketing_account": "", "kham_account": "", "ticket_account": "", "udn_account": "", "ticketplus_account": "", "facebook_password": "", "kktix_password": "", "fami_password": "", "urbtix_password": "", "cityline_password": "", "hkticketing_password": "", "kham_password": "", "ticket_password": "", "udn_password": "", "ticketplus_password": "", "facebook_password_plaintext": "", "kktix_password_plaintext": "", "fami_password_plaintext": "", "urbtix_password_plaintext": "", "cityline_password_plaintext": "", "hkticketing_password_plaintext": "", "kham_password_plaintext": "", "ticket_password_plaintext": "", "udn_password_plaintext": "", "ticketplus_password_plaintext": "", "chrome_extension": true, "disable_adjacent_seat": false, "hide_some_image": false, "block_facebook_network": false, "headless": false, "verbose": false, "auto_guess_options": true, "user_guess_string": "", "remote_url": "\"http://127.0.0.1:16888/\"", "auto_reload_page_interval": 0.1, "auto_reload_overheat_count": 4, "auto_reload_overheat_cd": 1, "reset_browser_interval": 0, "proxy_server_port": "", "window_size": "480,1024,0", "idle_keyword": "", "resume_keyword": "", "idle_keyword_second": "", "resume_keyword_second": ""}, "domain_filter": ["*.doubleclick.net/*", "*.googlesyndication.com/*", "*.ssp.hinet.net/*", "*a.amnet.tw/*", "*adx.c.appier.net/*", "*cdn.cookielaw.org/*", "*cdnjs.cloudflare.com/ajax/libs/clipboard.js/*", "*clarity.ms/*", "*cloudfront.com/*", "*cms.analytics.yahoo.com/*", "*e2elog.fetnet.net/*", "*fundingchoicesmessages.google.com/*", "*ghtinc.com/*", "*google-analytics.com/*", "*googletagmanager.com/*", "*googletagservices.com/*", "*img.uniicreative.com/*", "*lndata.com/*", "*match.adsrvr.org/*", "*onead.onevision.com.tw/*", "*play.google.com/log?*", "*popin.cc/*", "*rollbar.com/*", "*sb.scorecardresearch.com/*", "*tagtoo.co/*", "*ticketmaster.sg/js/adblock*", "*ticketmaster.sg/js/adblock.js*", "*tixcraft.com/js/analytics.js*", "*tixcraft.com/js/common.js*", "*tixcraft.com/js/custom.js*", "*treasuredata.com/*", "*www.youtube.com/youtubei/v1/player/heartbeat*"]}
|
{"homepage": "about:blank", "browser": "chrome", "language": "English", "ticket_number": 2, "refresh_datetime": "", "ocr_captcha": {"enable": true, "beta": true, "force_submit": true, "image_source": "canvas"}, "webdriver_type": "undetected_chromedriver", "date_auto_select": {"enable": true, "date_keyword": "", "mode": "random"}, "area_auto_select": {"enable": true, "mode": "random", "area_keyword": ""}, "keyword_exclude": "\"\u8f2a\u6905\",\"\u8eab\u969c\",\"\u8eab\u5fc3 \u969c\u7919\",\"Restricted View\",\"\u71c8\u67f1\u906e\u853d\",\"\u8996\u7dda\u4e0d\u5b8c\u6574\"", "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true, "max_dwell_time": 90}, "cityline": {"cityline_queue_retry": true}, "tixcraft": {"pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true}, "advanced": {"play_sound": {"ticket": true, "order": true, "filename": "ding-dong.wav"}, "tixcraft_sid": "", "ibonqware": "", "facebook_account": "", "kktix_account": "", "fami_account": "", "cityline_account": "", "urbtix_account": "", "hkticketing_account": "", "kham_account": "", "ticket_account": "", "udn_account": "", "ticketplus_account": "", "facebook_password": "", "kktix_password": "", "fami_password": "", "urbtix_password": "", "cityline_password": "", "hkticketing_password": "", "kham_password": "", "ticket_password": "", "udn_password": "", "ticketplus_password": "", "facebook_password_plaintext": "", "kktix_password_plaintext": "", "fami_password_plaintext": "", "urbtix_password_plaintext": "", "cityline_password_plaintext": "", "hkticketing_password_plaintext": "", "kham_password_plaintext": "", "ticket_password_plaintext": "", "udn_password_plaintext": "", "ticketplus_password_plaintext": "", "chrome_extension": true, "disable_adjacent_seat": false, "hide_some_image": false, "block_facebook_network": false, "headless": false, "verbose": false, "auto_guess_options": false, "user_guess_string": "", "remote_url": "\"http://127.0.0.1:16888/\"", "auto_reload_page_interval": 0.1, "auto_reload_overheat_count": 4, "auto_reload_overheat_cd": 1, "reset_browser_interval": 0, "proxy_server_port": "", "window_size": "480,1024,1", "idle_keyword": "", "resume_keyword": "", "idle_keyword_second": "", "resume_keyword_second": ""}, "token": "3fbc8123327e468b8ac6e9280cf0653a", "domain_filter": ["*.doubleclick.net/*", "*.googlesyndication.com/*", "*.ssp.hinet.net/*", "*a.amnet.tw/*", "*adx.c.appier.net/*", "*cdn.cookielaw.org/*", "*cdnjs.cloudflare.com/ajax/libs/clipboard.js/*", "*clarity.ms/*", "*cloudfront.com/*", "*cms.analytics.yahoo.com/*", "*e2elog.fetnet.net/*", "*fundingchoicesmessages.google.com/*", "*ghtinc.com/*", "*google-analytics.com/*", "*googletagmanager.com/*", "*googletagservices.com/*", "*img.uniicreative.com/*", "*lndata.com/*", "*match.adsrvr.org/*", "*onead.onevision.com.tw/*", "*play.google.com/log?*", "*popin.cc/*", "*rollbar.com/*", "*sb.scorecardresearch.com/*", "*tagtoo.co/*", "*ticketmaster.sg/js/adblock*", "*ticketmaster.sg/js/adblock.js*", "*tixcraft.com/js/analytics.js*", "*tixcraft.com/js/common.js*", "*tixcraft.com/js/custom.js*", "*treasuredata.com/*", "*www.youtube.com/youtubei/v1/player/heartbeat*"]}
|
|
@ -153,6 +153,48 @@ async function ocr(data_url, image_data, tabId)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function post(data_url, post_body, tabId)
|
||||||
|
{
|
||||||
|
//console.log("data_url:"+data_url);
|
||||||
|
fetch(data_url,{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: post_body
|
||||||
|
})
|
||||||
|
.then(response =>
|
||||||
|
{
|
||||||
|
if (response.ok)
|
||||||
|
{
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
else if (response.status === 404)
|
||||||
|
{
|
||||||
|
let result_json={"answer": "", "fail": 'error 404'};
|
||||||
|
//console.log(result_json);
|
||||||
|
//sendResponse(result_json);
|
||||||
|
return Promise.reject('error 404')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((data) =>
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
let result_json=data;
|
||||||
|
console.log(result_json);
|
||||||
|
chrome.tabs.sendMessage(tabId, result_json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.catch(error =>
|
||||||
|
{
|
||||||
|
console.log('error is', error)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// for avoid overheat.
|
// for avoid overheat.
|
||||||
chrome.storage.local.set(
|
chrome.storage.local.set(
|
||||||
{
|
{
|
||||||
|
@ -179,6 +221,11 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||||
ocr(request_json.data.url, request_json.data.image_data, tabId);
|
ocr(request_json.data.url, request_json.data.image_data, tabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(request_json.action=="post") {
|
||||||
|
const tabId = sender.tab.id;
|
||||||
|
post(request_json.data.url, request_json.data.post_data, tabId);
|
||||||
|
}
|
||||||
|
|
||||||
if(request_json.action=="status") {
|
if(request_json.action=="status") {
|
||||||
result_json={"status": answer};
|
result_json={"status": answer};
|
||||||
const tabId = sender.tab.id;
|
const tabId = sender.tab.id;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"homepage": "about:blank", "browser": "chrome", "language": "English", "ticket_number": 2, "ocr_captcha": {"enable": true, "beta": true, "force_submit": true, "image_source": "canvas"}, "webdriver_type": "undetected_chromedriver", "date_auto_select": {"enable": true, "date_keyword": "", "mode": "random"}, "area_auto_select": {"enable": true, "mode": "random", "area_keyword": ""}, "keyword_exclude": "\"\u8f2a\u6905\",\"\u8eab\u969c\",\"\u8eab\u5fc3 \u969c\u7919\",\"Restricted View\",\"\u71c8\u67f1\u906e\u853d\",\"\u8996\u7dda\u4e0d\u5b8c\u6574\"", "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true, "max_dwell_time": 60}, "cityline": {"cityline_queue_retry": true}, "tixcraft": {"pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true}, "advanced": {"play_sound": {"ticket": true, "order": true, "filename": "ding-dong.wav"}, "tixcraft_sid": "", "ibonqware": "", "facebook_account": "", "kktix_account": "", "fami_account": "", "cityline_account": "", "urbtix_account": "", "hkticketing_account": "", "kham_account": "", "ticket_account": "", "udn_account": "", "ticketplus_account": "", "facebook_password": "", "kktix_password": "", "fami_password": "", "urbtix_password": "", "cityline_password": "", "hkticketing_password": "", "kham_password": "", "ticket_password": "", "udn_password": "", "ticketplus_password": "", "facebook_password_plaintext": "", "kktix_password_plaintext": "", "fami_password_plaintext": "", "urbtix_password_plaintext": "", "cityline_password_plaintext": "", "hkticketing_password_plaintext": "", "kham_password_plaintext": "", "ticket_password_plaintext": "", "udn_password_plaintext": "", "ticketplus_password_plaintext": "", "chrome_extension": true, "disable_adjacent_seat": false, "hide_some_image": false, "block_facebook_network": false, "headless": false, "verbose": false, "auto_guess_options": true, "user_guess_string": "", "remote_url": "\"http://127.0.0.1:16888/\"", "auto_reload_page_interval": 0.1, "auto_reload_overheat_count": 4, "auto_reload_overheat_cd": 1, "reset_browser_interval": 0, "proxy_server_port": "", "window_size": "480,1024,0", "idle_keyword": "", "resume_keyword": "", "idle_keyword_second": "", "resume_keyword_second": ""}}
|
{"homepage": "about:blank", "browser": "chrome", "language": "English", "ticket_number": 2, "refresh_datetime": "", "ocr_captcha": {"enable": true, "beta": true, "force_submit": true, "image_source": "canvas"}, "webdriver_type": "undetected_chromedriver", "date_auto_select": {"enable": true, "date_keyword": "", "mode": "random"}, "area_auto_select": {"enable": true, "mode": "random", "area_keyword": ""}, "keyword_exclude": "\"\u8f2a\u6905\",\"\u8eab\u969c\",\"\u8eab\u5fc3 \u969c\u7919\",\"Restricted View\",\"\u71c8\u67f1\u906e\u853d\",\"\u8996\u7dda\u4e0d\u5b8c\u6574\"", "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true, "max_dwell_time": 90}, "cityline": {"cityline_queue_retry": true}, "tixcraft": {"pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true}, "advanced": {"play_sound": {"ticket": true, "order": true, "filename": "ding-dong.wav"}, "tixcraft_sid": "", "ibonqware": "", "facebook_account": "", "kktix_account": "", "fami_account": "", "cityline_account": "", "urbtix_account": "", "hkticketing_account": "", "kham_account": "", "ticket_account": "", "udn_account": "", "ticketplus_account": "", "facebook_password": "", "kktix_password": "", "fami_password": "", "urbtix_password": "", "cityline_password": "", "hkticketing_password": "", "kham_password": "", "ticket_password": "", "udn_password": "", "ticketplus_password": "", "facebook_password_plaintext": "", "kktix_password_plaintext": "", "fami_password_plaintext": "", "urbtix_password_plaintext": "", "cityline_password_plaintext": "", "hkticketing_password_plaintext": "", "kham_password_plaintext": "", "ticket_password_plaintext": "", "udn_password_plaintext": "", "ticketplus_password_plaintext": "", "chrome_extension": true, "disable_adjacent_seat": false, "hide_some_image": false, "block_facebook_network": false, "headless": false, "verbose": false, "auto_guess_options": false, "user_guess_string": "", "remote_url": "\"http://127.0.0.1:16888/\"", "auto_reload_page_interval": 0.1, "auto_reload_overheat_count": 4, "auto_reload_overheat_cd": 1, "reset_browser_interval": 0, "proxy_server_port": "", "window_size": "480,1024,1", "idle_keyword": "", "resume_keyword": "", "idle_keyword_second": "", "resume_keyword_second": ""}, "token": "3fbc8123327e468b8ac6e9280cf0653a"}
|
|
@ -0,0 +1,218 @@
|
||||||
|
const storage = chrome.storage.local;
|
||||||
|
var settings = null;
|
||||||
|
$("footer").remove();
|
||||||
|
|
||||||
|
function ibon_assign_ticket_number(ticket_number) {
|
||||||
|
let $main_table = $("div > table.table[id] > tbody");
|
||||||
|
if ($main_table.length > 0) {
|
||||||
|
//console.log("found main table");
|
||||||
|
let $ticket_tr = $main_table.find("tr");
|
||||||
|
if ($ticket_tr.length) {
|
||||||
|
let $ticket_options = $main_table.find("select:first option");
|
||||||
|
if ($ticket_options.length) {
|
||||||
|
let is_ticket_number_assign = false;
|
||||||
|
if (ticket_number > 0) {
|
||||||
|
console.log("target ticket_number:" + ticket_number);
|
||||||
|
$ticket_options.each(function() {
|
||||||
|
if ($(this).val() == ticket_number) {
|
||||||
|
$(this).prop('selected', true);
|
||||||
|
$(this).trigger("change");
|
||||||
|
is_ticket_number_assign = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//console.log("is_ticket_number_assign:"+is_ticket_number_assign);
|
||||||
|
if (!is_ticket_number_assign) {
|
||||||
|
$ticket_options.last().prop('selected', true);
|
||||||
|
$ticket_options.trigger("change");
|
||||||
|
is_ticket_number_assign = true;
|
||||||
|
}
|
||||||
|
if (is_ticket_number_assign) {
|
||||||
|
let select_tag = document.querySelector("div > table.table[id] > tbody select");
|
||||||
|
if(select_tag) {
|
||||||
|
//console.log("trigger select click");
|
||||||
|
select_tag.dispatchEvent(new Event('change'));
|
||||||
|
}
|
||||||
|
|
||||||
|
start_ibon_ocr();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//console.log("target option empty");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setTimeout(function() {
|
||||||
|
ibon_assign_ticket_number(ticket_number)
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ibon_assign_adjacent_seat(flag) {
|
||||||
|
//console.log("disable_adjacent_seat flag:"+flag);
|
||||||
|
if (flag) {
|
||||||
|
$('input[type=checkbox]').each(function() {
|
||||||
|
$(this).prop('checked', true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ibon_focus_on_captcha() {
|
||||||
|
$("div.editor-box > div > input[type='text']").focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
var myInterval = null;
|
||||||
|
|
||||||
|
function ibon_get_ocr_image() {
|
||||||
|
//console.log("get_ocr_image");
|
||||||
|
let image_data = "";
|
||||||
|
|
||||||
|
// PS: tixcraft have different domain to use the same content script.
|
||||||
|
const currentUrl = window.location.href;
|
||||||
|
const domain = currentUrl.split('/')[2];
|
||||||
|
|
||||||
|
let canvas = document.querySelector("div.editor-box > div > canvas");
|
||||||
|
if (canvas != null) {
|
||||||
|
let img_data = canvas.toDataURL();
|
||||||
|
if (img_data) {
|
||||||
|
image_data = img_data.split(",")[1];
|
||||||
|
//console.log(image_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return image_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
chrome.runtime.onMessage.addListener((message) => {
|
||||||
|
//console.log('sent from background', message);
|
||||||
|
if(message.answer) {
|
||||||
|
ibon_set_ocr_answer(message.answer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function ibon_set_ocr_answer(answer) {
|
||||||
|
console.log("answer:" + answer);
|
||||||
|
if (answer.length > 0) {
|
||||||
|
//$("div.editor-box > div > input[type='text']").val(answer);
|
||||||
|
|
||||||
|
let input_tag = document.querySelector("div.editor-box > div > input[type='text']");
|
||||||
|
if(input_tag) {
|
||||||
|
//console.log("click on captcha input.")
|
||||||
|
//input_tag.click();
|
||||||
|
//input_tag.value=answer;
|
||||||
|
//input_tag.dispatchEvent(new Event('change'));
|
||||||
|
if(input_tag.value != answer) {
|
||||||
|
console.log("set new answer as:" + answer);
|
||||||
|
ibon_set_ocr_answer_api(answer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ibon_set_ocr_answer_api(answer) {
|
||||||
|
let api_url = get_remote_url(settings);
|
||||||
|
if(api_url.indexOf("127.0.0.")>-1) {
|
||||||
|
let body = {
|
||||||
|
token: settings.token,
|
||||||
|
command: [
|
||||||
|
{type: 'sendkey', selector: "div.editor-box > div > input[type='text']", text: answer},
|
||||||
|
{type: 'click', selector: 'div#ticket-wrap a.btn.btn-primary[href]'}
|
||||||
|
]};
|
||||||
|
body = JSON.stringify(body);
|
||||||
|
|
||||||
|
let bundle = {
|
||||||
|
action: 'post',
|
||||||
|
data: {
|
||||||
|
'url': api_url + 'sendkey',
|
||||||
|
'post_data': body,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let bundle_string = JSON.stringify(bundle);
|
||||||
|
const return_answer = await chrome.runtime.sendMessage(bundle);
|
||||||
|
//console.log(return_answer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ibon_get_ocr_answer(api_url, image_data) {
|
||||||
|
let bundle = {
|
||||||
|
action: 'ocr',
|
||||||
|
data: {
|
||||||
|
'url': api_url + 'ocr',
|
||||||
|
'image_data': image_data,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let bundle_string = JSON.stringify(bundle);
|
||||||
|
const return_answer = await chrome.runtime.sendMessage(bundle);
|
||||||
|
//console.log(return_answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ibon_orc_image_ready(api_url) {
|
||||||
|
let ret = false;
|
||||||
|
let image_data = ibon_get_ocr_image();
|
||||||
|
if (image_data.length > 0) {
|
||||||
|
ret = true;
|
||||||
|
if (myInterval) clearInterval(myInterval);
|
||||||
|
ibon_get_ocr_answer(api_url, image_data);
|
||||||
|
}
|
||||||
|
console.log("ibon_orc_image_ready:" + ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
storage.get('settings', function(items) {
|
||||||
|
if (items.settings) {
|
||||||
|
settings = items.settings;
|
||||||
|
} else {
|
||||||
|
console.log('no settings found');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
storage.get('settings', function(items) {
|
||||||
|
if (items.settings) {
|
||||||
|
settings = items.settings;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function get_remote_url(settings) {
|
||||||
|
let remote_url_string = "";
|
||||||
|
if (settings) {
|
||||||
|
let remote_url_array = [];
|
||||||
|
if (settings.advanced.remote_url.length > 0) {
|
||||||
|
remote_url_array = JSON.parse('[' + settings.advanced.remote_url + ']');
|
||||||
|
}
|
||||||
|
if (remote_url_array.length) {
|
||||||
|
remote_url_string = remote_url_array[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return remote_url_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function start_ibon_ocr() {
|
||||||
|
// ocr
|
||||||
|
if (settings.ocr_captcha.enable) {
|
||||||
|
let remote_url_string = get_remote_url(settings);
|
||||||
|
if (!ibon_orc_image_ready(remote_url_string)) {
|
||||||
|
myInterval = setInterval(() => {
|
||||||
|
ibon_orc_image_ready(remote_url_string);
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no orc, just focus;
|
||||||
|
ibon_focus_on_captcha();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
storage.get('status', function(items) {
|
||||||
|
if (items.status && items.status == 'ON') {
|
||||||
|
//console.log("ticket_number:"+ settings.ticket_number);
|
||||||
|
// ajax.
|
||||||
|
setTimeout(function() {
|
||||||
|
ibon_assign_ticket_number(settings.ticket_number);
|
||||||
|
ibon_assign_adjacent_seat(settings.advanced.disable_adjacent_seat);
|
||||||
|
}, 100);
|
||||||
|
} else {
|
||||||
|
console.log('no status found');
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,5 +1,4 @@
|
||||||
var myInterval = null;
|
var myInterval = null;
|
||||||
|
|
||||||
function dom_ready()
|
function dom_ready()
|
||||||
{
|
{
|
||||||
let ret=false;
|
let ret=false;
|
||||||
|
@ -8,15 +7,29 @@ function dom_ready()
|
||||||
ret=true;
|
ret=true;
|
||||||
if(myInterval) clearInterval(myInterval);
|
if(myInterval) clearInterval(myInterval);
|
||||||
(function () {
|
(function () {
|
||||||
$("div#ticket-wrap a[onclick]").click();
|
var btn_e = document.createEvent('MouseEvents');
|
||||||
|
btn_e.initEvent('click', true, true );
|
||||||
|
|
||||||
|
let btn1 = document.querySelector("div#ticket-wrap > a[onclick]");
|
||||||
|
if(btn1 > 0) {
|
||||||
|
console.log("trigger btn1 click");
|
||||||
|
//btn1.click();
|
||||||
|
let btn1 = document.querySelector("div#ticket-wrap > a[onclick]");
|
||||||
|
btn1.dispatchEvent(btn_e);
|
||||||
|
} else {
|
||||||
|
let btn2 = document.querySelector("div#ticket-wrap > a[href]");
|
||||||
|
if(btn2) {
|
||||||
|
console.log("trigger btn2 click");
|
||||||
|
//btn2.click();
|
||||||
|
btn2.dispatchEvent(btn_e);
|
||||||
|
}
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
//console.log("dom_ready:"+ret);
|
console.log("dom_ready:"+ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!dom_ready()) {
|
myInterval = setInterval(() => {
|
||||||
myInterval = setInterval(() => {
|
dom_ready();
|
||||||
dom_ready();
|
}, 1000);
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
const storage = chrome.storage.local;
|
const storage = chrome.storage.local;
|
||||||
|
|
||||||
$("div.description").remove();
|
|
||||||
$("footer").remove();
|
|
||||||
|
|
||||||
function kktix_event_redirect()
|
function kktix_event_redirect()
|
||||||
{
|
{
|
||||||
const currentUrl = window.location.href;
|
const currentUrl = window.location.href;
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
$("div.headlines").remove();
|
|
||||||
$("section.app-intro").remove();
|
|
||||||
$("section.copywriting").remove();
|
|
||||||
$("section.partner-venues").remove();
|
|
||||||
$("footer").remove();
|
|
|
@ -1,6 +1,4 @@
|
||||||
var myInterval = null;
|
var myInterval = null;
|
||||||
var checkboxInterval = null;
|
|
||||||
//console.log("assign appear");
|
|
||||||
|
|
||||||
function kktix_verification_conditions(settings)
|
function kktix_verification_conditions(settings)
|
||||||
{
|
{
|
||||||
|
@ -35,14 +33,6 @@ function kktix_verification_conditions(settings)
|
||||||
return is_text_sent;
|
return is_text_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
function kktix_agree()
|
|
||||||
{
|
|
||||||
$('input[type=checkbox]:not(:checked)').each(function() {
|
|
||||||
$(this).click();
|
|
||||||
if(checkboxInterval) clearInterval(checkboxInterval);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function kktix_area_keyword(settings)
|
function kktix_area_keyword(settings)
|
||||||
{
|
{
|
||||||
let area_keyword_array = [];
|
let area_keyword_array = [];
|
||||||
|
@ -91,20 +81,6 @@ function kktix_area_keyword(settings)
|
||||||
let ticket_number = settings.ticket_number;
|
let ticket_number = settings.ticket_number;
|
||||||
|
|
||||||
if(ticket_number>0) {
|
if(ticket_number>0) {
|
||||||
/*
|
|
||||||
// trigger events by jQuery.
|
|
||||||
let target_input = target_area.find("input");
|
|
||||||
target_input.click();
|
|
||||||
target_input.prop("value", ticket_number);
|
|
||||||
let down = $.Event('keydown');
|
|
||||||
down.key=""+ticket_number;
|
|
||||||
target_input.trigger(down);
|
|
||||||
|
|
||||||
let up = $.Event('keyup');
|
|
||||||
up.key=""+ticket_number;
|
|
||||||
target_input.trigger(up);
|
|
||||||
*/
|
|
||||||
|
|
||||||
//console.log(base_info);
|
//console.log(base_info);
|
||||||
let is_verification_conditions_popup = false;
|
let is_verification_conditions_popup = false;
|
||||||
|
|
||||||
|
@ -176,20 +152,8 @@ function dom_ready()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rootElement = document.documentElement;
|
if(!dom_ready()) {
|
||||||
if(rootElement) {
|
myInterval = setInterval(() => {
|
||||||
if(!dom_ready()) {
|
dom_ready();
|
||||||
myInterval = setInterval(() => {
|
}, 200);
|
||||||
dom_ready();
|
|
||||||
}, 200);
|
|
||||||
|
|
||||||
checkboxInterval= setInterval(() => {
|
|
||||||
//console.log("kktix_agree")
|
|
||||||
kktix_agree();
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
$("footer").remove();
|
|
||||||
$("div.banner-wrapper div.img-wrapper img").remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,19 @@
|
||||||
const storage = chrome.storage.local;
|
const storage = chrome.storage.local;
|
||||||
var settings = null;
|
var settings = null;
|
||||||
var myInterval = null;
|
var checkboxInterval = null;
|
||||||
|
var notNowInterval = null;
|
||||||
|
|
||||||
|
function kktix_agree()
|
||||||
|
{
|
||||||
|
$('input[type=checkbox]:not(:checked)').each(function() {
|
||||||
|
$(this).click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function kktix_not_now()
|
||||||
|
{
|
||||||
|
$("#guestModal.modal.in > div.modal-dialog > div > div.modal-footer > button.btn-default.pull-right").click();
|
||||||
|
}
|
||||||
|
|
||||||
function kktix_clean_exclude(settings)
|
function kktix_clean_exclude(settings)
|
||||||
{
|
{
|
||||||
|
@ -42,7 +55,7 @@ function kktix_force_auto_reload_by_timer()
|
||||||
if(max_dwell_time <= 10) {
|
if(max_dwell_time <= 10) {
|
||||||
max_dwell_time = 10;
|
max_dwell_time = 10;
|
||||||
}
|
}
|
||||||
console.log('We are going to force reload after few seconeds.');
|
console.log('We are going to force reload after '+ max_dwell_time +' seconeds.');
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
location.reload();
|
location.reload();
|
||||||
}, max_dwell_time * 1000);
|
}, max_dwell_time * 1000);
|
||||||
|
@ -62,6 +75,13 @@ storage.get('status', function (items)
|
||||||
{
|
{
|
||||||
if (items.status && items.status=='ON')
|
if (items.status && items.status=='ON')
|
||||||
{
|
{
|
||||||
|
checkboxInterval = setInterval(() => {
|
||||||
|
kktix_agree();
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
notNowInterval = setInterval(() => {
|
||||||
|
kktix_not_now();
|
||||||
|
}, 200);
|
||||||
|
|
||||||
kktix_force_auto_reload_by_timer();
|
kktix_force_auto_reload_by_timer();
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
|
|
|
@ -291,6 +291,16 @@
|
||||||
"js/ibon_ticket_next.js"
|
"js/ibon_ticket_next.js"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"matches": [
|
||||||
|
"https://ticket.ibon.com.tw/EventBuy/*/*/*"
|
||||||
|
],
|
||||||
|
"run_at": "document_end",
|
||||||
|
"js": [
|
||||||
|
"jquery.min.js",
|
||||||
|
"js/ibon_eventbuy.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"matches": [
|
"matches": [
|
||||||
"https://orders.ibon.com.tw/application/utk02/UTK0201_0.aspx?*PERFORMANCE_ID=*PRODUCT_ID=*",
|
"https://orders.ibon.com.tw/application/utk02/UTK0201_0.aspx?*PERFORMANCE_ID=*PRODUCT_ID=*",
|
||||||
|
@ -415,16 +425,6 @@
|
||||||
"js/ticketplus_order.js"
|
"js/ticketplus_order.js"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
"https://kktix.com/"
|
|
||||||
],
|
|
||||||
"run_at": "document_end",
|
|
||||||
"js": [
|
|
||||||
"jquery.min.js",
|
|
||||||
"js/kktix_home.js"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"matches": [
|
"matches": [
|
||||||
"https://*.kktix.cc/events/*"
|
"https://*.kktix.cc/events/*"
|
||||||
|
@ -435,17 +435,6 @@
|
||||||
"js/kktix_events.js"
|
"js/kktix_events.js"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
"https://kktix.com/events/*/registrations/new"
|
|
||||||
],
|
|
||||||
"world": "MAIN",
|
|
||||||
"run_at": "document_end",
|
|
||||||
"js": [
|
|
||||||
"js/common.js",
|
|
||||||
"js/kktix_registrations_assign.js"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"matches": [
|
"matches": [
|
||||||
"https://kktix.com/events/*/registrations/new"
|
"https://kktix.com/events/*/registrations/new"
|
||||||
|
@ -476,7 +465,7 @@
|
||||||
"js/fantopia_fill.js"
|
"js/fantopia_fill.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
],
|
],
|
||||||
"version": "1.0.28"
|
"version": "1.0.29"
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
<button class="nav-link" id="home-tab" data-bs-toggle="tab" data-bs-target="#home-tab-pane" type="button" role="tab" aria-controls="home-tab-pane" aria-selected="false">偏好設定</button>
|
<button class="nav-link" id="home-tab" data-bs-toggle="tab" data-bs-target="#home-tab-pane" type="button" role="tab" aria-controls="home-tab-pane" aria-selected="false" onclick="home_tab_clicked();">偏好設定</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
|
@ -176,6 +176,19 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="refresh_datetime" class="col-sm-2 col-form-label">刷新在指定時間</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" id="refresh_datetime" value="" />
|
||||||
|
|
||||||
|
<div class="bd-callout bd-callout-info">
|
||||||
|
<strong>提示:</strong>
|
||||||
|
時間格式 <code>HH:MM:SS</code> (小時:分鐘:秒數)。在設定介面修改並存檔,並不會套用在「已經」開出的瀏覽器,只會套用在存檔之後按「搶票」所開出的瀏覽器。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="date_select_mode" class="col-sm-2 col-form-label">日期排序方式</label>
|
<label for="date_select_mode" class="col-sm-2 col-form-label">日期排序方式</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
|
@ -419,6 +432,14 @@
|
||||||
<textarea class="form-control" id="user_guess_string" rows="3"></textarea>
|
<textarea class="form-control" id="user_guess_string" rows="3"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label class="col-sm-2 col-form-label form-check-label" for="auto_guess_options">自動猜測驗證問題</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-check-input" type="checkbox" id="auto_guess_options" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- tab 5 -->
|
<!-- tab 5 -->
|
||||||
|
|
|
@ -10,6 +10,7 @@ const resume_button = document.querySelector('#resume_btn');
|
||||||
// preference
|
// preference
|
||||||
const homepage = document.querySelector('#homepage');
|
const homepage = document.querySelector('#homepage');
|
||||||
const ticket_number = document.querySelector('#ticket_number');
|
const ticket_number = document.querySelector('#ticket_number');
|
||||||
|
const refresh_datetime = document.querySelector('#refresh_datetime');
|
||||||
const date_select_mode = document.querySelector('#date_select_mode');
|
const date_select_mode = document.querySelector('#date_select_mode');
|
||||||
const date_keyword = document.querySelector('#date_keyword');
|
const date_keyword = document.querySelector('#date_keyword');
|
||||||
const area_select_mode = document.querySelector('#area_select_mode');
|
const area_select_mode = document.querySelector('#area_select_mode');
|
||||||
|
@ -51,6 +52,7 @@ const PUBLIC_SERVER_URL = "http://maxbot.dropboxlike.com:16888/";
|
||||||
|
|
||||||
// dictionary
|
// dictionary
|
||||||
const user_guess_string = document.querySelector('#user_guess_string');
|
const user_guess_string = document.querySelector('#user_guess_string');
|
||||||
|
const auto_guess_options = document.querySelector('#auto_guess_options');
|
||||||
|
|
||||||
|
|
||||||
// auto fill
|
// auto fill
|
||||||
|
@ -95,6 +97,7 @@ function load_settins_to_form(settings)
|
||||||
// preference
|
// preference
|
||||||
homepage.value = settings.homepage;
|
homepage.value = settings.homepage;
|
||||||
ticket_number.value = settings.ticket_number;
|
ticket_number.value = settings.ticket_number;
|
||||||
|
refresh_datetime.value = settings.refresh_datetime;
|
||||||
date_select_mode.value = settings.date_auto_select.mode;
|
date_select_mode.value = settings.date_auto_select.mode;
|
||||||
date_keyword.value = settings.date_auto_select.date_keyword;
|
date_keyword.value = settings.date_auto_select.date_keyword;
|
||||||
if(date_keyword.value=='""') {
|
if(date_keyword.value=='""') {
|
||||||
|
@ -156,6 +159,7 @@ function load_settins_to_form(settings)
|
||||||
if(user_guess_string.value=='""') {
|
if(user_guess_string.value=='""') {
|
||||||
user_guess_string.value='';
|
user_guess_string.value='';
|
||||||
}
|
}
|
||||||
|
auto_guess_options.checked = settings.advanced.auto_guess_options;
|
||||||
|
|
||||||
// auto fill
|
// auto fill
|
||||||
tixcraft_sid.value = settings.advanced.tixcraft_sid;
|
tixcraft_sid.value = settings.advanced.tixcraft_sid;
|
||||||
|
@ -235,6 +239,7 @@ function maxbot_reset_api()
|
||||||
settings = data;
|
settings = data;
|
||||||
load_settins_to_form(data);
|
load_settins_to_form(data);
|
||||||
check_unsaved_fields();
|
check_unsaved_fields();
|
||||||
|
run_message("已重設為預設值");
|
||||||
})
|
})
|
||||||
.fail(function() {
|
.fail(function() {
|
||||||
//alert( "error" );
|
//alert( "error" );
|
||||||
|
@ -327,6 +332,7 @@ function save_changes_to_dict(silent_flag)
|
||||||
// preference
|
// preference
|
||||||
settings.homepage = homepage.value;
|
settings.homepage = homepage.value;
|
||||||
settings.ticket_number = ticket_number_value;
|
settings.ticket_number = ticket_number_value;
|
||||||
|
settings.refresh_datetime = refresh_datetime.value;
|
||||||
settings.date_auto_select.mode = date_select_mode.value;
|
settings.date_auto_select.mode = date_select_mode.value;
|
||||||
|
|
||||||
let date_keyword_string = date_keyword.value;
|
let date_keyword_string = date_keyword.value;
|
||||||
|
@ -401,6 +407,8 @@ function save_changes_to_dict(silent_flag)
|
||||||
}
|
}
|
||||||
settings.advanced.user_guess_string = user_guess_string_string;
|
settings.advanced.user_guess_string = user_guess_string_string;
|
||||||
|
|
||||||
|
settings.advanced.auto_guess_options = auto_guess_options.checked;
|
||||||
|
|
||||||
// auto fill
|
// auto fill
|
||||||
settings.advanced.tixcraft_sid = tixcraft_sid.value;
|
settings.advanced.tixcraft_sid = tixcraft_sid.value;
|
||||||
settings.advanced.ibonqware = ibonqware.value;
|
settings.advanced.ibonqware = ibonqware.value;
|
||||||
|
@ -506,7 +514,7 @@ function maxbot_save()
|
||||||
function check_unsaved_fields()
|
function check_unsaved_fields()
|
||||||
{
|
{
|
||||||
if(settings) {
|
if(settings) {
|
||||||
const field_list_basic = ["homepage","ticket_number","browser","webdriver_type"];
|
const field_list_basic = ["homepage","ticket_number","refresh_datetime","browser","webdriver_type"];
|
||||||
field_list_basic.forEach(f => {
|
field_list_basic.forEach(f => {
|
||||||
const field = document.querySelector('#'+f);
|
const field = document.querySelector('#'+f);
|
||||||
if(field.value != settings[f]) {
|
if(field.value != settings[f]) {
|
||||||
|
@ -699,3 +707,8 @@ function run_message(msg)
|
||||||
message.innerText = '';
|
message.innerText = '';
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function home_tab_clicked() {
|
||||||
|
console.log("clicked");
|
||||||
|
document.getElementById("homepage").focus();
|
||||||
|
}
|
Loading…
Reference in New Issue