Compare commits
9 Commits
env/migrat
...
main
Author | SHA1 | Date |
---|---|---|
|
f9792b99e0 | |
|
42ca15bfbd | |
|
82fb61ec26 | |
|
982e70a4e4 | |
|
e1ec580ce1 | |
|
5b87c86223 | |
|
2c5ca3c3d3 | |
|
86bd790f1c | |
|
ccd5dee807 |
|
@ -0,0 +1,8 @@
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||||
|
* <ybs0306748@gmail.com> wrote this file. As long as you retain this notice you
|
||||||
|
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||||
|
* this stuff is worth it, you can buy me a beer in return Kinoshita Kenta
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
47
README.md
47
README.md
|
@ -1,7 +1,50 @@
|
||||||
# auto_login_EIP
|
# auto_login_EIP
|
||||||
|
|
||||||
- 執行
|
太常要訂便當了,所以寫個自動登入 EIP 的東西
|
||||||
|
省的每次都要找 EIP 的網址是什麼
|
||||||
|
|
||||||
|
## env
|
||||||
|
|
||||||
|
* Python
|
||||||
|
* uv
|
||||||
|
* 剩下的 uv 會幫你裝
|
||||||
|
|
||||||
|
## repository structure
|
||||||
|
|
||||||
|
```text
|
||||||
|
./auto_login_EIP/
|
||||||
|
├── main.py # main file
|
||||||
|
├── config.toml # config file
|
||||||
|
│
|
||||||
|
├── utils/
|
||||||
|
│
|
||||||
|
├── pyproject.toml
|
||||||
|
├── .gitignore
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## usage
|
||||||
|
|
||||||
|
### 配置
|
||||||
|
|
||||||
|
在 `config.toml` 設定好登入資訊,如果員工 ID 與密碼留空則會在登入時詢問你
|
||||||
|
專案路徑下有一個 `config.toml.example` 提供作為修改模板
|
||||||
|
|
||||||
|
### 執行
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# uv run python main.py --config_path .\config.toml.example
|
# uv run python main.py
|
||||||
```
|
```
|
||||||
|
|
||||||
|
或指定 config 檔
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# uv run python main.py --config_path .\YOUR_CONFIG.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
如果要酷一點的話串個 Windows 工作排程器或 Linux crontab
|
||||||
|
這樣每天早上就會自動幫你把 EIP 開起來,就能當個認真的模範打工仔了
|
||||||
|
|
||||||
|
我要繼續去 coding ㄌ,各位88
|
||||||
|
|
9
main.py
9
main.py
|
@ -4,10 +4,12 @@
|
||||||
__author__ = 'kinoshitakenta'
|
__author__ = 'kinoshitakenta'
|
||||||
__email__ = "ybs0306748@gmail.com"
|
__email__ = "ybs0306748@gmail.com"
|
||||||
|
|
||||||
|
import ctypes
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from selenium.common.exceptions import InvalidSessionIdException
|
||||||
from utils.cli import cli
|
from utils.cli import cli
|
||||||
from utils.driver import get_driver
|
from utils.driver import get_driver
|
||||||
from utils.EIP_action import ActionType, Action
|
from utils.EIP_action import ActionType, Action
|
||||||
|
@ -51,6 +53,7 @@ def display_usage():
|
||||||
clear_screen()
|
clear_screen()
|
||||||
for cmd, msg in get_usage():
|
for cmd, msg in get_usage():
|
||||||
print(f"{cmd}: {msg}")
|
print(f"{cmd}: {msg}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
def main(opt):
|
def main(opt):
|
||||||
|
@ -62,11 +65,12 @@ def main(opt):
|
||||||
login_info = LoginInfo(config_path)
|
login_info = LoginInfo(config_path)
|
||||||
|
|
||||||
driver = get_driver()
|
driver = get_driver()
|
||||||
keep_login_status(driver, login_info)
|
|
||||||
action_agent = Action(driver)
|
action_agent = Action(driver)
|
||||||
|
|
||||||
display_usage()
|
display_usage()
|
||||||
|
|
||||||
|
keep_login_status(driver, login_info)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
cmd = input("\nInput action code: ").strip()
|
cmd = input("\nInput action code: ").strip()
|
||||||
|
@ -95,6 +99,9 @@ def main(opt):
|
||||||
if keep_login_status(driver, login_info):
|
if keep_login_status(driver, login_info):
|
||||||
action_agent.run(action_code)
|
action_agent.run(action_code)
|
||||||
|
|
||||||
|
except InvalidSessionIdException:
|
||||||
|
print("Session has expired, please re-login.")
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ class ActionType(IntEnum):
|
||||||
請假 = 1
|
請假 = 1
|
||||||
補卡 = 2
|
補卡 = 2
|
||||||
訂便當 = 3
|
訂便當 = 3
|
||||||
|
訂會議室 = 4
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def has_value(cls, value):
|
def has_value(cls, value):
|
||||||
|
@ -25,7 +26,8 @@ class Action():
|
||||||
self.action_list = {ActionType.登入: self.__登入,
|
self.action_list = {ActionType.登入: self.__登入,
|
||||||
ActionType.請假: self.__請假,
|
ActionType.請假: self.__請假,
|
||||||
ActionType.補卡: self.__補卡,
|
ActionType.補卡: self.__補卡,
|
||||||
ActionType.訂便當: self.__訂便當
|
ActionType.訂便當: self.__訂便當,
|
||||||
|
ActionType.訂會議室: self.__訂會議室
|
||||||
}
|
}
|
||||||
self.driver = driver
|
self.driver = driver
|
||||||
|
|
||||||
|
@ -143,3 +145,16 @@ class Action():
|
||||||
print("沒有尚未訂購的團購訂單")
|
print("沒有尚未訂購的團購訂單")
|
||||||
|
|
||||||
self.driver.switch_to.default_content()
|
self.driver.switch_to.default_content()
|
||||||
|
|
||||||
|
def __訂會議室(self):
|
||||||
|
"""訂會議室"""
|
||||||
|
|
||||||
|
self.driver.switch_to.frame(self.driver.find_element(By.ID, "main"))
|
||||||
|
all_meeting_room_tag = self.driver.find_element(By.ID, "WPPublicResource_TreeTagt0") # 會議室
|
||||||
|
ActionChains(self.driver).move_to_element(all_meeting_room_tag).move_to_element(all_meeting_room_tag).click(all_meeting_room_tag).perform()
|
||||||
|
|
||||||
|
Zhubei_tag = self.driver.find_element(By.ID, "WPPublicResource_TreeTagt1") # 竹北
|
||||||
|
ActionChains(self.driver).move_to_element(Zhubei_tag).move_to_element(Zhubei_tag).click(Zhubei_tag).perform()
|
||||||
|
|
||||||
|
meeting_room_500_tag = self.driver.find_element(By.ID, "WPPublicResource_TreeTagt2") # 500會議室
|
||||||
|
ActionChains(self.driver).move_to_element(meeting_room_500_tag).move_to_element(meeting_room_500_tag).click(meeting_room_500_tag).perform()
|
||||||
|
|
|
@ -8,7 +8,7 @@ if sys.version_info >= (3, 11):
|
||||||
else:
|
else:
|
||||||
import tomli as tomllib
|
import tomli as tomllib
|
||||||
from selenium import webdriver
|
from selenium import webdriver
|
||||||
from selenium.common.exceptions import NoAlertPresentException, UnexpectedAlertPresentException
|
from selenium.common.exceptions import NoAlertPresentException, NoSuchWindowException, UnexpectedAlertPresentException
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.webdriver.support.ui import Select
|
from selenium.webdriver.support.ui import Select
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ def keep_login_status(driver: webdriver.Chrome, login_info: LoginInfo) -> bool:
|
||||||
"""
|
"""
|
||||||
Attempt to log into the CHI MotorWeb ERP system using the provided login information.
|
Attempt to log into the CHI MotorWeb ERP system using the provided login information.
|
||||||
|
|
||||||
This function navigates to the login page, fills in the login form with the user’s credentials,
|
This function navigates to the login page, fills in the login form with the user's credentials,
|
||||||
and attempts to log in. It handles unexpected alert pop-ups that indicate login failure,
|
and attempts to log in. It handles unexpected alert pop-ups that indicate login failure,
|
||||||
and manages browser windows to ensure only the relevant page remains open.
|
and manages browser windows to ensure only the relevant page remains open.
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ def keep_login_status(driver: webdriver.Chrome, login_info: LoginInfo) -> bool:
|
||||||
print(f"Login error message: {alert.text}")
|
print(f"Login error message: {alert.text}")
|
||||||
alert.accept()
|
alert.accept()
|
||||||
return False # Skip remaining logic, login failed
|
return False # Skip remaining logic, login failed
|
||||||
except NoAlertPresentException:
|
except (NoAlertPresentException, NoSuchWindowException):
|
||||||
pass # No alert, proceed
|
pass # No alert, proceed
|
||||||
|
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
@ -119,7 +119,7 @@ def keep_login_status(driver: webdriver.Chrome, login_info: LoginInfo) -> bool:
|
||||||
print(f"Unexpected alert: {alert.text}")
|
print(f"Unexpected alert: {alert.text}")
|
||||||
alert.accept()
|
alert.accept()
|
||||||
continue
|
continue
|
||||||
except NoAlertPresentException:
|
except (NoAlertPresentException, NoSuchWindowException):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if "CHI MotorWeb - " in title:
|
if "CHI MotorWeb - " in title:
|
||||||
|
|
Loading…
Reference in New Issue