From bd73ac0b92cc779a70557640b47fd2e807e78f1e Mon Sep 17 00:00:00 2001 From: Yudaotor Date: Sat, 25 Mar 2023 13:33:47 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC2=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EsportsHelper/Config.py | 5 +- EsportsHelper/LoginHandler.py | 74 +++++++++++++---------- EsportsHelper/Match.py | 73 ++++++++++++++--------- EsportsHelper/Twitch.py | 4 +- EsportsHelper/VersionManager.py | 3 + EsportsHelper/Webdriver.py | 3 +- EsportsHelper/Youtube.py | 5 +- main.py | 102 +++++++++++++++++--------------- 8 files changed, 156 insertions(+), 113 deletions(-) diff --git a/EsportsHelper/Config.py b/EsportsHelper/Config.py index 928e9d0..23cb94d 100644 --- a/EsportsHelper/Config.py +++ b/EsportsHelper/Config.py @@ -1,3 +1,4 @@ +import traceback from pathlib import Path from yaml.parser import ParserError from rich import print @@ -35,8 +36,8 @@ def __init__(self, log, configPath: str) -> None: print("[red]配置文件格式错误") raise ex except Exception as ex: - log.error(ex) - print(ex) + traceback.print_exc() + self.log.error(traceback.format_exc()) raise ex def __findConfig(self, configPath): diff --git a/EsportsHelper/LoginHandler.py b/EsportsHelper/LoginHandler.py index 2040ef5..3ee51af 100644 --- a/EsportsHelper/LoginHandler.py +++ b/EsportsHelper/LoginHandler.py @@ -1,44 +1,56 @@ import time +import traceback + from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as ec from rich import print + class LoginHandler: def __init__(self, log, driver) -> None: self.log = log self.driver = driver def automaticLogIn(self, username, password): - self.driver.get("https://lolesports.com/schedule") - time.sleep(2) - el = self.driver.find_element(by=By.CSS_SELECTOR, value="a[data-riotbar-link-id=login]") - self.driver.execute_script("arguments[0].click();", el) - self.log.info("登录中...") - print("[yellow]登录中...") - wait = WebDriverWait(self.driver, 20) - usernameInput = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "input[name=username]"))) - usernameInput.send_keys(username) - passwordInput = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "input[name=password]"))) - passwordInput.send_keys(password) - submitButton = wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, "button[type=submit]"))) - self.driver.execute_script("arguments[0].click();", submitButton) - self.log.debug("账密 提交成功") - print("[green]账密 提交成功") - time.sleep(5) - if len(self.driver.find_elements(by=By.CSS_SELECTOR, value="div.text__web-code")) > 0: - self.insertTwoFactorCode() - wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "div.riotbar-summoner-name"))) + try: + self.driver.get("https://lolesports.com/schedule") + time.sleep(2) + loginButton = self.driver.find_element(by=By.CSS_SELECTOR, value="a[data-riotbar-link-id=login]") + self.driver.execute_script("arguments[0].click();", loginButton) + self.log.info("登录中...") + print("[yellow]登录中...") + time.sleep(3) + wait = WebDriverWait(self.driver, 15) + usernameInput = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "input[name=username]"))) + usernameInput.send_keys(username) + passwordInput = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "input[name=password]"))) + passwordInput.send_keys(password) + submitButton = wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, "button[type=submit]"))) + self.driver.execute_script("arguments[0].click();", submitButton) + self.log.debug("账密 提交成功") + print("[green]账密 提交成功") + time.sleep(5) + if len(self.driver.find_elements(by=By.CSS_SELECTOR, value="div.text__web-code")) > 0: + self.insertCode() + wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "div.riotbar-summoner-name"))) + except Exception as e: + traceback.print_exc() + self.log.error(traceback.format_exc()) - def insertTwoFactorCode(self): - wait = WebDriverWait(self.driver, 20) - authText = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "h5.grid-panel__subtitle"))) - self.log.info(f'请输入二级验证代码 ({authText.text})') - print(f'[yellow]请输入二级验证代码 ({authText.text}') - code = input('二级验证代码: ') - codeInput = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "div.codefield__code--empty > div > input"))) - codeInput.send_keys(code) - submitButton = wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, "button[type=submit]"))) - self.driver.execute_script("arguments[0].click();", submitButton) - self.log.debug("二级验证代码 提交成功") - print("[green]二级验证代码 提交成功") + def insertCode(self): + try: + wait = WebDriverWait(self.driver, 20) + authText = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "h5.grid-panel__subtitle"))) + self.log.info(f'请输入二级验证代码 ({authText.text})') + print(f'[yellow]请输入二级验证代码 ({authText.text}') + code = input('二级验证代码: ') + codeInput = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "div.codefield__code--empty > div > input"))) + codeInput.send_keys(code) + submitButton = wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, "button[type=submit]"))) + self.driver.execute_script("arguments[0].click();", submitButton) + self.log.debug("二级验证代码 提交成功") + print("[green]二级验证代码 提交成功") + except Exception as e: + traceback.print_exc() + self.log.error(traceback.format_exc()) diff --git a/EsportsHelper/Match.py b/EsportsHelper/Match.py index 2927d1f..209ae93 100644 --- a/EsportsHelper/Match.py +++ b/EsportsHelper/Match.py @@ -39,38 +39,44 @@ def __init__(self, log, driver, config) -> None: self.driver = driver self.config = config self.rewards = Rewards(log=log, driver=driver, config=config) - self.twitch = Twitch(driver=driver) + self.twitch = Twitch(driver=driver, log=log) + self.youtube = Youtube(driver=driver, log=log) self.currentWindows = {} - self.originalWindow = self.driver.current_window_handle - self.youtube = Youtube(driver=driver) + self.mainWindow = self.driver.current_window_handle - def watchForMatches(self, delay): + def watchMatches(self, delay): self.currentWindows = {} - self.originalWindow = self.driver.current_window_handle + self.mainWindow = self.driver.current_window_handle while True: try: - self.driver.switch_to.window(self.originalWindow) + self.driver.switch_to.window(self.mainWindow) time.sleep(3) + # raise Exception("测试") self.driver.get("https://lolesports.com/schedule") time.sleep(5) - liveMatches = self.getLiveMatches() - self.log.info(f"现在有 {len(liveMatches)} 场比赛正在直播中") - print(f"[green]现在有 {len(liveMatches)} 场比赛正在直播中[/green]") - self.closeFinishedMatches(liveMatches=liveMatches) + liveMatches = self.getMatches() + if len(liveMatches) == 0: + self.log.info("没有赛区正在直播") + print(f"[green]没有赛区正在直播[/green]") + else: + self.log.info(f"现在有 {len(liveMatches)} 个赛区正在直播中") + print(f"[green]现在有 {len(liveMatches)} 个赛区正在直播中[/green]") + self.closeTabs(liveMatches=liveMatches) self.openNewMatches(liveMatches=liveMatches, disWatchMatches=self.config.disWatchMatches) time.sleep(3) - self.driver.switch_to.window(self.originalWindow) + self.driver.switch_to.window(self.mainWindow) self.log.info(f"下一次检查在: {datetime.now() + timedelta(seconds=delay)}") self.log.debug("============================================") - print(f"[green]下一次检查在: {datetime.now() + timedelta(seconds=delay)}[/green]") + print(f"[green]下一次检查在: {(datetime.now() + timedelta(seconds=delay)).strftime('%m月%d日%H时%M分%S秒')}[/green]") print(f"[green]============================================[/green]") time.sleep(delay) except Exception as e: self.log.error("发生错误") print(f"[red]发生错误[/red]") traceback.print_exc() + self.log.error(traceback.format_exc()) - def getLiveMatches(self): + def getMatches(self): try: matches = [] elements = self.driver.find_elements(by=By.CSS_SELECTOR, value=".EventMatch .event.live") @@ -81,24 +87,29 @@ def getLiveMatches(self): self.log.error("获取比赛列表失败") print(f"[red]获取比赛列表失败[/red]") traceback.print_exc() + self.log.error(traceback.format_exc()) return [] - def closeFinishedMatches(self, liveMatches): - toRemove = [] - for k in self.currentWindows.keys(): - self.driver.switch_to.window(self.currentWindows[k]) - if k not in liveMatches: - self.log.info(f"{k} 比赛结束") - print(f"[green]{k} 比赛结束[/green]") - self.driver.close() - toRemove.append(k) - self.driver.switch_to.window(self.originalWindow) - time.sleep(5) - else: - self.rewards.checkRewards(k) - for k in toRemove: - self.currentWindows.pop(k, None) - self.driver.switch_to.window(self.originalWindow) + def closeTabs(self, liveMatches): + try: + removeList = [] + for k in self.currentWindows.keys(): + self.driver.switch_to.window(self.currentWindows[k]) + if k not in liveMatches: + self.log.info(f"{k} 比赛结束") + print(f"[green]{k} 比赛结束[/green]") + self.driver.close() + removeList.append(k) + self.driver.switch_to.window(self.mainWindow) + time.sleep(5) + else: + self.rewards.checkRewards(k) + for k in removeList: + self.currentWindows.pop(k, None) + self.driver.switch_to.window(self.mainWindow) + except Exception as e: + traceback.print_exc() + self.log.error(traceback.format_exc()) def openNewMatches(self, liveMatches, disWatchMatches): newLiveMatches = set(liveMatches) - set(self.currentWindows.keys()) @@ -131,6 +142,8 @@ def openNewMatches(self, liveMatches, disWatchMatches): except TimeoutException: self.log.critical("无法设置 Twitch 清晰度. 这场比赛是在 Twitch 上吗?") print("[red]无法设置 Twitch 清晰度. 这场比赛是在 Twitch 上吗?") + traceback.print_exc() + self.log.error(traceback.format_exc()) else: url = match self.driver.get(url) @@ -142,4 +155,6 @@ def openNewMatches(self, liveMatches, disWatchMatches): except TimeoutException: self.log.critical(f"无法设置 Youtube 清晰度. 这场比赛是在 Youtube 上吗?") print("[red]无法设置 Youtube 清晰度. 这场比赛是在 Youtube 上吗?") + traceback.print_exc() + self.log.error(traceback.format_exc()) time.sleep(5) diff --git a/EsportsHelper/Twitch.py b/EsportsHelper/Twitch.py index f2b2376..26c2446 100644 --- a/EsportsHelper/Twitch.py +++ b/EsportsHelper/Twitch.py @@ -7,8 +7,9 @@ class Twitch: - def __init__(self, driver) -> None: + def __init__(self, driver, log) -> None: self.driver = driver + self.log = log def setTwitchQuality(self): try: @@ -29,3 +30,4 @@ def setTwitchQuality(self): self.driver.switch_to.default_content() except Exception as e: traceback.print_exc() + self.log.error(traceback.format_exc()) diff --git a/EsportsHelper/VersionManager.py b/EsportsHelper/VersionManager.py index d235a62..1972a06 100644 --- a/EsportsHelper/VersionManager.py +++ b/EsportsHelper/VersionManager.py @@ -1,6 +1,8 @@ +import traceback import requests as req from rich import print + class VersionManager: @staticmethod @@ -14,6 +16,7 @@ def getLatestTag(): return 0.0 except Exception as e: print("[red]从github获取最新版信息失败!") + traceback.print_exc() return 0.0 @staticmethod diff --git a/EsportsHelper/Webdriver.py b/EsportsHelper/Webdriver.py index b957bea..597d9e5 100644 --- a/EsportsHelper/Webdriver.py +++ b/EsportsHelper/Webdriver.py @@ -1,13 +1,14 @@ import undetected_chromedriver as uc from rich import print + class Webdriver: def __init__(self, headless) -> None: self.headless = headless def createWebdriver(self): options = self.addWebdriverOptions(uc.ChromeOptions()) - print("[green]正在创建浏览器...") + print("[green]正在准备中...") return uc.Chrome(options=options) def addWebdriverOptions(self, options): diff --git a/EsportsHelper/Youtube.py b/EsportsHelper/Youtube.py index 7e2b234..a48b46f 100644 --- a/EsportsHelper/Youtube.py +++ b/EsportsHelper/Youtube.py @@ -5,9 +5,11 @@ from selenium.webdriver.support import expected_conditions as ec from selenium.webdriver.common.by import By + class Youtube: - def __init__(self, driver) -> None: + def __init__(self, driver, log) -> None: self.driver = driver + self.log = log def setYoutubeQuality(self): try: @@ -29,3 +31,4 @@ def setYoutubeQuality(self): self.driver.switch_to.default_content() except Exception as e: traceback.print_exc() + self.log.error(traceback.format_exc()) diff --git a/main.py b/main.py index 3272161..ae2ffea 100644 --- a/main.py +++ b/main.py @@ -1,12 +1,11 @@ +import sys import traceback from pathlib import Path - from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException import time import argparse from rich import print -# Classes from EsportsHelper.LoginHandler import LoginHandler from EsportsHelper.VersionManager import VersionManager from EsportsHelper.Webdriver import Webdriver @@ -14,58 +13,65 @@ from EsportsHelper.Config import Config from EsportsHelper.Match import Match + CURRENT_VERSION = 1.0 -parser = argparse.ArgumentParser(prog='CapsuleFarmer.exe', description='Farm Esports Capsules by watching lolesports.com.') -parser.add_argument('-c', '--config', dest="configPath", default="./config.yaml", - help='config file path') -args = parser.parse_args() -print("[green]=========================================================") -print(f"========= 感谢使用 [blue]电竞助手 v{CURRENT_VERSION}[/blue]! =========") -print("============ 本程序开源于github链接地址如下: ============") -print("= =") -print("==== 请在使用前[red]阅读教程文件[/red], 以确保你的配置符合要求! ====") -print("[green]=========================================================") -print() +def info(): + print("[green]=========================================================") + print(f"========= 感谢使用 [blue]电竞助手 v{CURRENT_VERSION}[/blue]! =========") + print("============ 本程序开源于github链接地址如下: ============") + print("==== https://github.com/Yudaotor/EsportsHelper ====") + print("==== 请在使用前[red]阅读教程文件[/red], 以确保你的配置符合要求! ====") + print("[green]=========================================================") + print() -Path("./logs/").mkdir(parents=True, exist_ok=True) -log = Logger().createLogger() -config = Config(log, args.configPath) -if not VersionManager.isLatestVersion(CURRENT_VERSION): - log.warning("\n==!!! 新版本可用 !!!==\n ==请从此处下载: ==") +def main(): + info() + parser = argparse.ArgumentParser(prog='CapsuleFarmer.exe', description='Farm Esports Capsules by watching lolesports.com.') + parser.add_argument('-c', '--config', dest="configPath", default="./config.yaml", + help='config file path') + args = parser.parse_args() + Path("./logs/").mkdir(parents=True, exist_ok=True) + log = Logger().createLogger() + config = Config(log, args.configPath) + if not VersionManager.isLatestVersion(CURRENT_VERSION): + log.warning("\n==!!! 新版本可用 !!!==\n ==请从此处下载: ==") print("[yellow]\n==!!! 新版本可用 !!!==\n ==请从此处下载: ==[/yellow]") -driver = None -try: - driver = Webdriver(headless=config.headless).createWebdriver() -except Exception as ex: - traceback.print_exc() - print("[red]生成WEBDRIVER失败! 你是否使用的是最新版浏览器? 为你配置的浏览器检查一下更新吧\n按任意键退出...") - input() - exit() - -loginHandler = LoginHandler(log=log, driver=driver) - -driver.get("https://lolesports.com/schedule") - -# Handle login -try: - loginHandler.automaticLogIn(config.username, config.password) -except TimeoutException: - log.error("自动登录失败,账号密码是否正确?") - print("[red]自动登录失败,账号密码是否正确?[/red]") - if config.headless: - driver.quit() - log.info("退出中...") - print("[green]退出中...[/green]") + driver = None + try: + driver = Webdriver(headless=config.headless).createWebdriver() + except Exception as ex: + traceback.print_exc() + log.error(traceback.format_exc()) + print("[red]生成WEBDRIVER失败! 你是否使用的是最新版浏览器? 为你配置的浏览器检查一下更新吧\n按任意键退出...") + input() exit() + loginHandler = LoginHandler(log=log, driver=driver) + driver.get("https://lolesports.com/schedule") + try: + loginHandler.automaticLogIn(config.username, config.password) + except TimeoutException: + log.error("自动登录失败,账号密码是否正确?") + print("[red]自动登录失败,账号密码是否正确?[/red]") + if config.headless: + driver.quit() + log.info("退出中...") + print("[green]退出中...[/green]") + exit() + while not driver.find_elements(by=By.CSS_SELECTOR, value="div.riotbar-summoner-name"): + log.info("等待登录中...") + print("[yellow]等待登录中...[/yellow]") + time.sleep(5) + log.info("好嘞 登录成功!") + print("[green]好嘞 登录成功![/green]") + Match(log=log, driver=driver, config=config).watchMatches(delay=config.delay) -while not driver.find_elements(by=By.CSS_SELECTOR, value="div.riotbar-summoner-name"): - log.info("等待登录中...") - print("[yellow]等待登录中...[/yellow]") - time.sleep(5) -log.debug("好嘞 登录成功!") -print("[green]好嘞 登录成功![/green]") -Match(log=log, driver=driver, config=config).watchForMatches(delay=config.delay) +if __name__ == '__main__': + try: + main() + except (KeyboardInterrupt, SystemExit): + print("[red]------程序退出------") + sys.exit() \ No newline at end of file