forked from kinoshitakenta/auto_login_EIP
feature: basic features
This commit is contained in:
parent
d89ee00308
commit
e0afd876b6
|
@ -0,0 +1,11 @@
|
||||||
|
# module cache
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
|
# selenium driver
|
||||||
|
chromedriver.exe
|
||||||
|
|
||||||
|
# log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# config file
|
||||||
|
config.toml
|
|
@ -0,0 +1,96 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
__author__ = 'kinoshitakenta'
|
||||||
|
__email__ = "ybs0306748@gmail.com"
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from utils.cli import cli
|
||||||
|
from utils.driver import get_driver
|
||||||
|
from utils.EIP_action import ActionType, Action
|
||||||
|
from utils.utils import keep_login_status, LoginInfo
|
||||||
|
|
||||||
|
|
||||||
|
def get_usage() -> list[tuple]:
|
||||||
|
cmd_list = []
|
||||||
|
for e in ActionType:
|
||||||
|
cmd_list.append((f"{e.value}", f"{e.name}"))
|
||||||
|
|
||||||
|
cmd_list.append(("99", "重新輸入登入資訊"))
|
||||||
|
cmd_list.append(("exit", "關閉"))
|
||||||
|
|
||||||
|
return cmd_list
|
||||||
|
|
||||||
|
|
||||||
|
def display_usage():
|
||||||
|
if os.name == 'nt':
|
||||||
|
os.system('cls')
|
||||||
|
else:
|
||||||
|
os.system('clear')
|
||||||
|
|
||||||
|
for cmd, msg in get_usage():
|
||||||
|
print(f"{cmd}: {msg}")
|
||||||
|
|
||||||
|
|
||||||
|
def main(opt):
|
||||||
|
login_info = LoginInfo(Path(opt.config_path))
|
||||||
|
|
||||||
|
driver = get_driver()
|
||||||
|
keep_login_status(driver, login_info)
|
||||||
|
action_agent = Action(driver)
|
||||||
|
|
||||||
|
display_usage()
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
cmd = input("\nInput action code: ").strip()
|
||||||
|
print(f"Retrieve cmd: {cmd}")
|
||||||
|
|
||||||
|
# * command parse
|
||||||
|
if cmd == "exit":
|
||||||
|
print("Program is closing...")
|
||||||
|
break
|
||||||
|
elif cmd == "99":
|
||||||
|
login_info = LoginInfo(Path(opt.config_path))
|
||||||
|
keep_login_status(driver, login_info)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not cmd.isdigit():
|
||||||
|
print("Input format error, please try again.")
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
action_code = int(cmd)
|
||||||
|
|
||||||
|
if not ActionType.has_value(action_code):
|
||||||
|
print("Please enter an existing action code.")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# * run command
|
||||||
|
keep_login_status(driver, login_info)
|
||||||
|
action_agent.run(action_code)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from rich.console import Console
|
||||||
|
from rich.traceback import install
|
||||||
|
|
||||||
|
install(show_locals=True)
|
||||||
|
console = Console(tab_size=4, log_path=False)
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
filename='log.log',
|
||||||
|
filemode='a+',
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format='%(asctime)s %(levelname)-8s : %(message)s'
|
||||||
|
)
|
||||||
|
|
||||||
|
opt = cli()
|
||||||
|
main(opt)
|
|
@ -0,0 +1,136 @@
|
||||||
|
import time
|
||||||
|
from enum import IntEnum
|
||||||
|
|
||||||
|
from selenium import webdriver
|
||||||
|
from selenium.common.exceptions import NoSuchElementException
|
||||||
|
from selenium.common.exceptions import ElementClickInterceptedException
|
||||||
|
from selenium.webdriver.common.action_chains import ActionChains
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.support.ui import Select
|
||||||
|
|
||||||
|
|
||||||
|
class ActionType(IntEnum):
|
||||||
|
登入 = 0
|
||||||
|
請假 = 1
|
||||||
|
補卡 = 2
|
||||||
|
訂便當 = 3
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def has_value(cls, value):
|
||||||
|
return value in cls._value2member_map_
|
||||||
|
|
||||||
|
|
||||||
|
class Action():
|
||||||
|
def __init__(self, driver: webdriver.Chrome):
|
||||||
|
self.action_list = {ActionType.登入: self.__登入,
|
||||||
|
ActionType.請假: self.__請假,
|
||||||
|
ActionType.補卡: self.__補卡,
|
||||||
|
ActionType.訂便當: self.__訂便當
|
||||||
|
}
|
||||||
|
self.driver = driver
|
||||||
|
|
||||||
|
def run(self, action_type) -> None:
|
||||||
|
self.action_list[action_type]()
|
||||||
|
|
||||||
|
def __登入(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __請假(self):
|
||||||
|
"""開啟請假單頁面"""
|
||||||
|
|
||||||
|
# self.driver.find_element(By.ID, "ddlMenuTypes_DIV").click()
|
||||||
|
# time.sleep(0.05)
|
||||||
|
|
||||||
|
# dropdown_element = self.driver.find_element(By.ID, "CopyOfComboBox")
|
||||||
|
# select = Select(dropdown_element)
|
||||||
|
# select.select_by_value("1") # 人力資源
|
||||||
|
# time.sleep(0.05)
|
||||||
|
|
||||||
|
# self.driver.find_element(By.ID, "ddlMenuItems1_DIV").click()
|
||||||
|
# time.sleep(0.05)
|
||||||
|
|
||||||
|
# dropdown_element = self.driver.find_element(By.ID, "CopyOfComboBox")
|
||||||
|
# # * 因沒有更換值,所以無法收回選單
|
||||||
|
# # // select = Select(dropdown_element)
|
||||||
|
# # // select.select_by_value("1_0") # 考勤管理作業
|
||||||
|
# # * 以下列方式替代
|
||||||
|
# dropdown_element.find_element(
|
||||||
|
# By.XPATH, ".//option[@value='1_0']").click() # 考勤管理作業
|
||||||
|
# time.sleep(0.05)
|
||||||
|
|
||||||
|
# menu = self.driver.find_element(By.ID, "BtnMenu") # 選單
|
||||||
|
|
||||||
|
# btn_root = self.driver.find_element(
|
||||||
|
# By.XPATH, ".//ul[@id='Stage1']")
|
||||||
|
# btn_list = btn_root.find_elements(
|
||||||
|
# By.XPATH, ".//li[@class='dropdown 1_0']")
|
||||||
|
|
||||||
|
# btn = btn_list[0] # 請假單
|
||||||
|
|
||||||
|
# ActionChains(self.driver).move_to_element(
|
||||||
|
# menu).move_to_element(btn).click(btn).perform()
|
||||||
|
|
||||||
|
self.driver.execute_script(
|
||||||
|
u"javascript:MenuItemClick('/MotorWeb/CHIPage/FuncTagPage.aspx?PageUrl=%7e%2fCHIHumrs%2fwHumrsExcuse.aspx&Form_FuncTag=CHIHumrs.Excuse', false, false, false)")
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
def __補卡(self):
|
||||||
|
"""開啟刷卡補卡單頁面"""
|
||||||
|
|
||||||
|
# self.driver.find_element(By.ID, "ddlMenuTypes_DIV").click()
|
||||||
|
# time.sleep(0.05)
|
||||||
|
|
||||||
|
# dropdown_element = self.driver.find_element(By.ID, "CopyOfComboBox")
|
||||||
|
# select = Select(dropdown_element)
|
||||||
|
# select.select_by_value("1") # 人力資源
|
||||||
|
# time.sleep(0.05)
|
||||||
|
|
||||||
|
# self.driver.find_element(By.ID, "ddlMenuItems1_DIV").click()
|
||||||
|
# time.sleep(0.05)
|
||||||
|
|
||||||
|
# dropdown_element = self.driver.find_element(By.ID, "CopyOfComboBox")
|
||||||
|
# dropdown_element.find_element(
|
||||||
|
# By.XPATH, ".//option[@value='1_0']").click() # 考勤管理作業
|
||||||
|
# time.sleep(0.05)
|
||||||
|
|
||||||
|
# menu = self.driver.find_element(By.ID, "BtnMenu") # 選單
|
||||||
|
|
||||||
|
# btn_root = self.driver.find_element(
|
||||||
|
# By.XPATH, ".//ul[@id='Stage1']")
|
||||||
|
# btn_list = btn_root.find_elements(
|
||||||
|
# By.XPATH, ".//li[@class='dropdown 1_0']")
|
||||||
|
|
||||||
|
# btn = btn_list[2] # 刷卡補卡單
|
||||||
|
|
||||||
|
# ActionChains(self.driver).move_to_element(
|
||||||
|
# menu).move_to_element(btn).click(btn).perform()
|
||||||
|
|
||||||
|
self.driver.execute_script(
|
||||||
|
u"javascript:MenuItemClick('/MotorWeb/CHIPage/FuncTagPage.aspx?PageUrl=%7e%2fCHIHumrs%2fwHumrsAppendClk.aspx&Form_FuncTag=CHIHumrs.AppendClk', false, false, false)")
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
def __訂便當(self):
|
||||||
|
"""開啟所有未訂購的便當訂購頁面"""
|
||||||
|
|
||||||
|
self.driver.switch_to.frame(self.driver.find_element(By.ID, "main"))
|
||||||
|
all_orders = self.driver.find_elements(
|
||||||
|
By.XPATH, ".//table[@id='WPMyOrder_tbMyOrder']/tbody/tr")
|
||||||
|
|
||||||
|
open_page_num = 0
|
||||||
|
for order in all_orders:
|
||||||
|
a_tag = order.find_elements(
|
||||||
|
By.XPATH, ".//td[@valign='baseline']/a")
|
||||||
|
assert len(a_tag) == 3
|
||||||
|
|
||||||
|
order_title, img, order_status = a_tag
|
||||||
|
if order_status.text != "【已訂購】":
|
||||||
|
order_title.click()
|
||||||
|
open_page_num += 1
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
if open_page_num > 0:
|
||||||
|
print(f"已開啟 {open_page_num} 個訂購頁面")
|
||||||
|
else:
|
||||||
|
print("沒有尚未訂購的團購訂單")
|
||||||
|
|
||||||
|
self.driver.switch_to.default_content()
|
|
@ -0,0 +1,9 @@
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
def cli():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--config_path", type=str, default="config.toml",
|
||||||
|
help="Specify config file path.")
|
||||||
|
|
||||||
|
return parser.parse_args()
|
|
@ -0,0 +1,16 @@
|
||||||
|
from selenium import webdriver
|
||||||
|
from selenium.webdriver.chrome.service import Service
|
||||||
|
from selenium.webdriver.chrome.webdriver import WebDriver
|
||||||
|
|
||||||
|
|
||||||
|
def get_driver() -> WebDriver:
|
||||||
|
service = Service(executable_path='./chromedriver.exe')
|
||||||
|
|
||||||
|
options = webdriver.ChromeOptions()
|
||||||
|
# options.add_argument("--headless")
|
||||||
|
options.add_argument('--disable-gpu')
|
||||||
|
options.add_experimental_option('excludeSwitches', ['enable-logging'])
|
||||||
|
driver = webdriver.Chrome(service=service, options=options)
|
||||||
|
driver.implicitly_wait(4)
|
||||||
|
|
||||||
|
return driver
|
|
@ -0,0 +1,77 @@
|
||||||
|
import getpass
|
||||||
|
import time
|
||||||
|
from pathlib import WindowsPath
|
||||||
|
|
||||||
|
import tomli
|
||||||
|
from selenium import webdriver
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.support.ui import Select
|
||||||
|
|
||||||
|
|
||||||
|
class LoginInfo():
|
||||||
|
def __init__(self, config_path: WindowsPath):
|
||||||
|
with open(config_path, mode="rb") as f:
|
||||||
|
config = tomli.load(f)
|
||||||
|
|
||||||
|
self.lang = config["login_info"]["lang"]
|
||||||
|
self.login_ID = config["login_info"]["login_ID"]
|
||||||
|
self.login_passwd = config["login_info"]["login_passwd"]
|
||||||
|
self.company_ID = config["login_info"]["company_ID"]
|
||||||
|
|
||||||
|
if self.login_ID == "":
|
||||||
|
self.login_ID = getpass.getpass(
|
||||||
|
"please enter your ID: ").strip()
|
||||||
|
|
||||||
|
if self.login_passwd == "":
|
||||||
|
self.login_passwd = getpass.getpass(
|
||||||
|
"please enter your passwd: ")
|
||||||
|
|
||||||
|
|
||||||
|
def keep_login_status(driver: webdriver.Chrome, login_info: LoginInfo):
|
||||||
|
EIP_url = "https://eip.techmation.com.tw/MotorWeb/MotorFaceDefaultNew.aspx"
|
||||||
|
|
||||||
|
# * Close all windows except the main window.
|
||||||
|
while len(driver.window_handles) > 1:
|
||||||
|
driver.switch_to.window(driver.window_handles[1])
|
||||||
|
time.sleep(0.05)
|
||||||
|
driver.close()
|
||||||
|
driver.switch_to.window(driver.window_handles[0])
|
||||||
|
|
||||||
|
top_page = driver.current_window_handle
|
||||||
|
driver.get(EIP_url)
|
||||||
|
time.sleep(0.3)
|
||||||
|
|
||||||
|
if driver.title == "CHI MOTOR WEB ERP 登入":
|
||||||
|
# * Fill in all login information.
|
||||||
|
dropdown_element = driver.find_element(By.ID, "ddlLang")
|
||||||
|
select = Select(dropdown_element)
|
||||||
|
select.select_by_value(login_info.lang)
|
||||||
|
|
||||||
|
input_text_element = driver.find_element(By.ID, "txtLoginID")
|
||||||
|
input_text_element.clear()
|
||||||
|
input_text_element.send_keys(login_info.login_ID)
|
||||||
|
|
||||||
|
input_text_element = driver.find_element(By.ID, "txtLoginPwd")
|
||||||
|
input_text_element.clear()
|
||||||
|
input_text_element.send_keys(login_info.login_passwd)
|
||||||
|
|
||||||
|
dropdown_element = driver.find_element(By.ID, "ddlCompanyID")
|
||||||
|
select = Select(dropdown_element)
|
||||||
|
select.select_by_value(login_info.company_ID)
|
||||||
|
|
||||||
|
# * Press the submit button.
|
||||||
|
submit_btn = driver.find_element(By.ID, "btnLogin")
|
||||||
|
submit_btn.click()
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
# * If login has pop a new window, switch main window to the new one.
|
||||||
|
for handle in driver.window_handles:
|
||||||
|
if handle != top_page:
|
||||||
|
new_page = handle
|
||||||
|
|
||||||
|
driver.switch_to.window(top_page)
|
||||||
|
driver.close()
|
||||||
|
|
||||||
|
driver.switch_to.window(new_page)
|
||||||
|
driver.maximize_window()
|
Loading…
Reference in New Issue