From 07a652c6f34e4d376c4c6a5fe6ae8f44c0e5537d Mon Sep 17 00:00:00 2001 From: ckh08045 Date: Mon, 18 Nov 2024 17:43:02 +0900 Subject: [PATCH] Update whale_new.py --- whale_new.py | 104 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 30 deletions(-) diff --git a/whale_new.py b/whale_new.py index 71c473c1..6bc2d128 100644 --- a/whale_new.py +++ b/whale_new.py @@ -1,10 +1,12 @@ import time -import os -import re +import os, sys import pyperclip from pywinauto import Application, findwindows, clipboard, timings from pywinauto.controls.hwndwrapper import HwndWrapper from PIL import ImageGrab +from pywinauto.findwindows import ElementNotFoundError +from pywinauto.timings import wait_until +import re class WhaleTranslator: def __init__(self, logger): @@ -20,10 +22,22 @@ class WhaleTranslator: self.min_image_width = 200 self.min_image_height = 150 + def get_base_dir(self): + """ + 실행 환경에 따라 base_dir을 설정하는 메서드. + cx_Freeze로 패키징된 경우 실행 파일의 경로, 일반 Python 환경일 경우 __file__을 기준으로 설정. + """ + if getattr(sys, 'frozen', False): # 패키징된 경우 + base_dir = os.path.dirname(sys.executable) + else: # 일반 Python 실행 환경 + base_dir = os.path.dirname(os.path.abspath(__file__)) + return base_dir + def start_whale_browser(self): - whale_exe_path = os.path.join(os.getcwd(), "browsers", "whale", "whale.exe") - user_data_dir = os.path.join(os.getcwd(), "browsers", "whale", "user_data") - cache_dir = os.path.join(os.getcwd(), "browsers", "whale", "cache") + base_path = self.get_base_dir() + whale_exe_path = os.path.join(base_path, "browsers", "whale", "whale.exe") + user_data_dir = os.path.join(base_path, "browsers", "whale", "user_data") + cache_dir = os.path.join(base_path, "browsers", "whale", "cache") self.whale_app = Application(backend="uia").start( f'"{whale_exe_path}" --incognito --user-data-dir="{user_data_dir}" --disk-cache-dir="{cache_dir}"' @@ -108,33 +122,61 @@ class WhaleTranslator: def navigate_to_url(self, url): """주소창에 URL을 입력하고 페이지 로딩을 대기""" - try: - # URL을 클립보드에 복사 - pyperclip.copy(url) + retry_count = 5 # 주소창 찾기 재시도 횟수 + for attempt in range(retry_count): + try: + # URL을 클립보드에 복사 + pyperclip.copy(url) - # 주소창을 클릭하여 URL 붙여넣기 - address_bar = self.whale_window.child_window(title="주소창 및 검색창", control_type="Edit") - address_bar.click_input() + # 주소창을 클릭하여 URL 붙여넣기 + address_bar = self.whale_window.child_window(title="주소창 및 검색창", control_type="Edit") + address_bar.click_input() - # Ctrl + V로 URL 붙여넣기 후 Enter 키 입력 - address_bar.type_keys("^v{ENTER}", with_spaces=True) - self.logger.debug(f"{url}로 이동 중...") + # Ctrl + V로 URL 붙여넣기 후 Enter 키 입력 + address_bar.type_keys("^v{ENTER}", with_spaces=True) + self.logger.debug(f"{url}로 이동 중...") - # 5초 동안 0.1초 간격으로 이미지 요소가 나타나는지 검사 - start_time = time.time() - while time.time() - start_time < 5: - try: - # 특정 이미지 요소를 찾으면 즉시 반환 - image_element = self.whale_window.child_window(title="누락된 이미지 설명을 확인하려면 컨텍스트 메뉴를 여세요.", control_type="Image") - if image_element.exists(timeout=0.5): - self.logger.debug("페이지 로딩 완료: 이미지 요소가 나타났습니다.") - return - except Exception: - pass # 요소가 아직 나타나지 않은 경우 대기 + # 10초 동안 0.5초 간격으로 이미지 요소가 나타나는지 검사 + start_time = time.time() + while time.time() - start_time < 10: + try: + # 이미지 요소를 찾으면 즉시 반환 + image_element = self.whale_window.child_window( + title="누락된 이미지 설명을 확인하려면 컨텍스트 메뉴를 여세요.", + control_type="Image" + ) + if image_element.exists(timeout=1): + self.logger.debug("페이지 로딩 완료: 이미지 요소가 나타났습니다.") + return + except Exception as e: + self.logger.debug(f"이미지 요소 확인 중 오류 발생: {e}") - self.logger.error("지정된 시간 내에 이미지 요소를 찾지 못했습니다.") - except Exception as e: - self.logger.error(f"주소창에 접근할 수 없습니다: {e}", exc_info=True) + # 안전장치 1: 현재 창 제목 확인 + window_title = self.whale_window.window_text() + if re.match(r".+\.(jpg|png|jpeg) \(\d+x\d+\)", window_title, re.IGNORECASE): + self.logger.info(f"창 제목에 이미지 파일과 해상도가 감지됨: {window_title}") + return + + # 안전장치 2: 현재 창의 컨트롤 핸들 요소 출력 + self.logger.error("지정된 시간 내에 이미지 요소를 찾지 못했습니다. 현재 창의 컨트롤 요소:") + with open("debug_controls.txt", "w", encoding="utf-8") as f: + original_stdout = os.sys.stdout + os.sys.stdout = f + self.whale_window.print_control_identifiers() + os.sys.stdout = original_stdout + self.logger.info("컨트롤 식별자가 debug_controls.txt에 저장되었습니다.") + + except ElementNotFoundError as e: + self.logger.error("주소창 요소를 찾을 수 없습니다. 창을 다시 검색합니다.", exc_info=True) + self.whale_window = self.find_whale_window() # 창을 다시 찾음 + if not self.whale_window: + self.logger.error("웨일 창을 다시 찾을 수 없습니다. 작업 중단.") + return + + except Exception as e: + self.logger.error(f"주소창 접근 중 오류 발생: {e}", exc_info=True) + + self.logger.error("주소창 찾기 및 URL 이동 시도 횟수를 초과했습니다.") def navigate_to_url_for_typing(self, url): """주소창에 URL을 입력하고 페이지 로딩을 대기""" @@ -239,6 +281,8 @@ class WhaleTranslator: """창 제목에서 이미지의 너비와 높이를 추출하여 반환합니다.""" try: window_title = self.whale_window.window_text() + self.logger.debug(f"Window Title: {window_title}") + # 창 제목에서 해상도 추출 시도 match = re.search(r"\((\d+)×(\d+)\)", window_title) if match: @@ -254,8 +298,8 @@ class WhaleTranslator: return True # 해상도 조건을 만족하면 작업을 진행 # 해상도가 없다면, 파일 확장자를 확인하여 번역 여부 결정 - elif window_title.endswith(".jpg") or window_title.endswith(".png"): - self.logger.info("이미지 해상도가 없지만, 파일 확장자가 .jpg 또는 .png입니다. 번역 작업을 진행합니다.") + elif ".jpg" in window_title or ".png" in window_title or ".jpeg" in window_title: + self.logger.info("이미지 해상도가 없지만, 파일 확장자가 .jpg 또는 .jpeg 또는 .png입니다. 번역 작업을 진행합니다.") return True # 해상도가 없어도 번역 작업을 수행 # 해상도도 없고, 파일 확장자도 매칭되지 않는 경우