183 lines
8.2 KiB
Python
183 lines
8.2 KiB
Python
import pyautogui
|
|
import time
|
|
import os
|
|
import subprocess
|
|
import win32gui, win32con, win32process
|
|
|
|
class WhaleTranslator:
|
|
def __init__(self, logger, error_image_filenames=['fail_translated1.png', 'fail_translated2.png'], pixel_check_interval=0.1, secret_mode=True, timeout=20, color_tolerance=20):
|
|
self.logger = logger
|
|
self.error_image_paths = [os.path.join(os.path.dirname(__file__), filename) for filename in error_image_filenames]
|
|
self.page_loading_icon_path = os.path.join(os.path.dirname(__file__), 'page_loading.png')
|
|
|
|
self.pixel_check_interval = pixel_check_interval
|
|
self.whale_window_name = "새 시크릿 탭 - Whale" if secret_mode else "새 탭 - Whale"
|
|
self.whale_pid = None
|
|
self.timeout = timeout # 번역 성공 여부를 판단하기 위한 시간 제한 설정
|
|
self.color_tolerance = color_tolerance # 색상 허용 오차
|
|
self.colors = {'before': None, 'during': None, 'after': None} # 색상 기록
|
|
|
|
def start_whale_browser(self, url):
|
|
whale_path = r"C:\\Program Files\\Naver\\Naver Whale\\Application\\whale.exe"
|
|
process = subprocess.Popen([whale_path, '--incognito'])
|
|
time.sleep(2)
|
|
self.whale_pid = process.pid
|
|
self.logger.debug(f"Whale 브라우저 실행, PID: {self.whale_pid}")
|
|
|
|
hwnd = self.find_whale_window()
|
|
if hwnd:
|
|
self.set_window_position(hwnd, 100, 100, 1280, 720) # 위치 (100, 100), 크기 (1280x720)
|
|
|
|
if hwnd:
|
|
win32gui.SetForegroundWindow(hwnd)
|
|
pyautogui.hotkey('ctrl', 'l')
|
|
time.sleep(0.5)
|
|
pyautogui.typewrite(url)
|
|
pyautogui.press('enter')
|
|
time.sleep(2)
|
|
|
|
# 페이지 로딩 완료 대기
|
|
self.wait_for_loading_icon_to_disappear()
|
|
|
|
self.move_mouse_to_center(hwnd) # 마우스 중앙으로 이동
|
|
time.sleep(0.5) # 마우스 이동 후 대기
|
|
|
|
original_color = self.get_mouse_position_color() # 현재 색상 가져오기
|
|
self.colors['before'] = original_color
|
|
self.logger.debug(f"번역 전 색상: {original_color}")
|
|
|
|
# 우클릭 및 번역 시작
|
|
pyautogui.rightClick()
|
|
time.sleep(1)
|
|
pyautogui.press('r')
|
|
time.sleep(1)
|
|
|
|
# 번역 성공 여부 확인
|
|
result = self.check_translation_by_color_change(original_color)
|
|
if result == "success":
|
|
print("번역이 성공적으로 완료되었습니다!")
|
|
elif result == "error":
|
|
print("번역에 실패했습니다.")
|
|
else:
|
|
print("번역 상태를 확인하지 못했습니다.")
|
|
|
|
# 최종 색상 출력
|
|
self.logger.debug(f"번역 전 색상: {self.colors['before']}")
|
|
self.logger.debug(f"번역 중 색상: {self.colors['during']}")
|
|
self.logger.debug(f"번역 후 색상: {self.colors['after']}")
|
|
|
|
def wait_for_loading_icon_to_disappear(self, max_wait=20):
|
|
"""
|
|
로딩 아이콘이 화면에서 사라질 때까지 대기합니다.
|
|
max_wait: 최대 대기 시간 (초)
|
|
"""
|
|
start_time = time.time()
|
|
while time.time() - start_time < max_wait:
|
|
try:
|
|
# 화면에서 아이콘 위치 확인 시도
|
|
icon_location = pyautogui.locateOnScreen(self.page_loading_icon_path, confidence=0.9)
|
|
if icon_location:
|
|
print("페이지 로딩 중...")
|
|
time.sleep(0.5) # 간격을 두고 다시 확인
|
|
|
|
except pyautogui.ImageNotFoundException:
|
|
# 아이콘이 화면에 없으면 로딩 완료로 간주
|
|
print("페이지 로딩이 완료되었습니다.")
|
|
return True # 로딩 완료
|
|
|
|
print("로딩 완료 대기 시간이 초과되었습니다.")
|
|
return False
|
|
|
|
def find_whale_window(self):
|
|
"""웨일 창을 제목을 기준으로 찾는 메서드"""
|
|
def callback(hwnd, extra):
|
|
if win32gui.IsWindowVisible(hwnd):
|
|
title = win32gui.GetWindowText(hwnd)
|
|
if self.whale_window_name in title:
|
|
extra.append(hwnd)
|
|
|
|
hwnd_list = []
|
|
win32gui.EnumWindows(callback, hwnd_list)
|
|
if hwnd_list:
|
|
self.logger.debug(f"웨일 창을 찾았습니다: {hwnd_list[0]}")
|
|
return hwnd_list[0]
|
|
else:
|
|
self.logger.debug("웨일 창을 찾지 못했습니다.")
|
|
return None
|
|
|
|
def set_window_position(self, hwnd, x, y, width, height):
|
|
"""지정된 위치와 크기로 창을 조정"""
|
|
win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
|
|
win32gui.SetWindowPos(hwnd, None, x, y, width, height, win32con.SWP_NOZORDER | win32con.SWP_NOACTIVATE)
|
|
self.logger.debug(f"창 위치 및 크기 설정: 위치({x}, {y}), 크기({width}x{height})")
|
|
|
|
def move_mouse_to_center(self, hwnd):
|
|
"""웨일 브라우저 창의 중앙으로 마우스 커서를 이동"""
|
|
rect = win32gui.GetWindowRect(hwnd) # 창 위치 및 크기 가져오기
|
|
center_x = (rect[0] + rect[2]) // 2 # 가로 중앙 계산
|
|
center_y = (rect[1] + rect[3]) // 2 # 세로 중앙 계산
|
|
pyautogui.moveTo(center_x, center_y)
|
|
self.logger.debug(f"마우스 커서를 창 중앙으로 이동: ({center_x}, {center_y})")
|
|
|
|
def check_translation_by_color_change(self, original_color):
|
|
start_time = time.time()
|
|
while time.time() - start_time < self.timeout:
|
|
current_color = self.get_mouse_position_color()
|
|
if self.colors['during'] is None: # 번역 중 첫 색상 기록
|
|
self.colors['during'] = current_color
|
|
self.logger.debug(f"현재 색상: {current_color}")
|
|
|
|
if self.is_similar_color(current_color, original_color):
|
|
self.colors['after'] = current_color
|
|
self.logger.debug("번역 성공 감지 (원래 색상과 유사)")
|
|
return "success"
|
|
|
|
if not self.is_similar_color(current_color, original_color):
|
|
self.logger.debug("번역 중 상태 감지 (필터 색상)")
|
|
|
|
if self.is_translation_failed():
|
|
self.colors['after'] = current_color
|
|
return "error"
|
|
|
|
time.sleep(self.pixel_check_interval)
|
|
|
|
# 타임아웃 발생 시, 번역 성공으로 간주
|
|
self.colors['after'] = current_color
|
|
self.logger.debug("번역 성공으로 간주 (타임아웃)")
|
|
return "success"
|
|
|
|
def is_similar_color(self, color1, color2):
|
|
"""색상이 유사한지 확인 (허용 오차 적용)"""
|
|
r_diff = abs(color1[0] - color2[0])
|
|
g_diff = abs(color1[1] - color2[1])
|
|
b_diff = abs(color1[2] - color2[2])
|
|
return r_diff < self.color_tolerance and g_diff < self.color_tolerance and b_diff < self.color_tolerance
|
|
|
|
def get_mouse_position_color(self):
|
|
x, y = pyautogui.position()
|
|
return pyautogui.pixel(x, y)
|
|
|
|
def is_translation_failed(self):
|
|
"""번역 실패 이미지 확인"""
|
|
for image_path in self.error_image_paths:
|
|
try:
|
|
if pyautogui.locateOnScreen(image_path, confidence=0.8):
|
|
self.logger.error(f"번역 실패: '{os.path.basename(image_path)}' 메시지가 감지되었습니다.")
|
|
return True
|
|
except pyautogui.ImageNotFoundException:
|
|
self.logger.debug(f"번역 실패 이미지가 화면에 없습니다: {os.path.basename(image_path)}")
|
|
return False
|
|
|
|
# 예제 사용법
|
|
import logging
|
|
|
|
# 로거 설정
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# 클래스 인스턴스 생성 및 브라우저 실행 후 번역 상태 확인
|
|
translator = WhaleTranslator(logger, ['fail_translated1.png', 'fail_translated2.png'])
|
|
|
|
# 브라우저 실행 후 URL로 이동 및 번역 성공 여부 확인
|
|
translator.start_whale_browser("https://file.percenty.co.kr/public/652bed8e865b1f32ea62bf1f/products/66ff967773994c46d388bb36/82d07178-ae60-49f7-a489-e02801ff7b06.jpg")
|