옵션 관련 수정
This commit is contained in:
parent
447fea052c
commit
771dcd32b6
|
|
@ -483,41 +483,48 @@ class BrowserController:
|
|||
await input_field.press('Enter')
|
||||
self.logger.debug(f"{key} 텍스트 입력 완료: {leading_text}")
|
||||
|
||||
# 각 옵션을 한 줄씩 입력
|
||||
await input_field.press('Enter')
|
||||
await input_field.type("# > 옵션 목록")
|
||||
await input_field.press('Enter')
|
||||
await input_field.press('Enter')
|
||||
if not optionHandler.option_info['is_single_option']:
|
||||
self.logger.debug('단일옵션이 아니므로 옵션목록을 입력')
|
||||
|
||||
# 각 옵션을 한 줄씩 입력
|
||||
await input_field.type("# 옵션 목록")
|
||||
await input_field.press('Enter')
|
||||
|
||||
|
||||
# # 첫 번째 옵션에만 - 기호를 붙여 목록 시작
|
||||
# await input_field.type(f"- A. {option_data[0]}")
|
||||
# await input_field.press('Enter') # 첫 번째 옵션 이후 엔터로 줄바꿈
|
||||
# # 첫 번째 옵션에만 - 기호를 붙여 목록 시작
|
||||
# await input_field.type(f"- A. {option_data[0]}")
|
||||
# await input_field.press('Enter') # 첫 번째 옵션 이후 엔터로 줄바꿈
|
||||
|
||||
# # 나머지 옵션들은 - 없이 입력하여 마크다운 목록으로 표시
|
||||
# for i, option in enumerate(option_data[1:], start=2):
|
||||
# option_text = option[0] if isinstance(option, tuple) else option
|
||||
# option_prefix = f"{chr(64 + i)}. "
|
||||
# await input_field.type(option_prefix + option_text)
|
||||
# await input_field.press('Enter') # 엔터 키를 입력하여 줄바꿈
|
||||
# # 나머지 옵션들은 - 없이 입력하여 마크다운 목록으로 표시
|
||||
# for i, option in enumerate(option_data[1:], start=2):
|
||||
# option_text = option[0] if isinstance(option, tuple) else option
|
||||
# option_prefix = f"{chr(64 + i)}. "
|
||||
# await input_field.type(option_prefix + option_text)
|
||||
# await input_field.press('Enter') # 엔터 키를 입력하여 줄바꿈
|
||||
|
||||
|
||||
# 첫 번째 옵션에만 - 기호를 붙여 목록 시작
|
||||
await input_field.type(f"- 1. {option_data[0]}")
|
||||
await input_field.press('Enter') # 첫 번째 옵션 이후 엔터로 줄바꿈
|
||||
# 마크다운 형식
|
||||
md_prifix = "#### "
|
||||
# 첫 번째 옵션에만 - 기호를 붙여 목록 시작
|
||||
await input_field.type(f"{md_prifix}")
|
||||
|
||||
# 나머지 옵션들은 - 없이 숫자 접두사로 표시
|
||||
for i, option in enumerate(option_data[1:], start=2):
|
||||
option_text = option[0] if isinstance(option, tuple) else option
|
||||
# option_prefix = f"{i}. "
|
||||
option_prefix = ""
|
||||
await input_field.type(option_prefix + option_text)
|
||||
await input_field.press('Enter') # 엔터 키를 입력하여 줄바꿈
|
||||
await input_field.type(f"- 1. {option_data[0]}")
|
||||
await input_field.press('Enter') # 첫 번째 옵션 이후 엔터로 줄바꿈
|
||||
|
||||
# 나머지 옵션들은 - 없이 숫자 접두사로 표시
|
||||
for i, option in enumerate(option_data[1:], start=2):
|
||||
option_text = option[0] if isinstance(option, tuple) else option
|
||||
# option_prefix = f"{i}. "
|
||||
option_prefix = ""
|
||||
await input_field.type(f"{md_prifix}")
|
||||
await input_field.type(option_prefix + option_text)
|
||||
await input_field.press('Enter') # 엔터 키를 입력하여 줄바꿈
|
||||
|
||||
|
||||
# 목록 끝을 알리기 위해 엔터 두 번 입력
|
||||
await input_field.press('Enter')
|
||||
await input_field.press('Enter')
|
||||
await input_field.press('Enter')
|
||||
|
||||
|
||||
# 후두부 텍스트 입력
|
||||
|
|
|
|||
4
gui.py
4
gui.py
|
|
@ -72,6 +72,7 @@ class TranslationApp(QWidget):
|
|||
self.price_count = 0
|
||||
self.detail_image_count = 0
|
||||
self.thumb_image_count = 0
|
||||
self.current_options_info = {}
|
||||
|
||||
self.current_stage_index = 0 # 현재 진행 중인 단계 인덱스
|
||||
|
||||
|
|
@ -868,8 +869,7 @@ class TranslationApp(QWidget):
|
|||
|
||||
# 옵션 최대선택갯수
|
||||
max_option_count = 20
|
||||
option_image_trans = False
|
||||
await self.optionHandler.process_options(product_name, max_option_count, self.toggle_states)
|
||||
self.current_options_info = await self.optionHandler.process_options(product_name, max_option_count, self.toggle_states)
|
||||
|
||||
# 수정 후 저장
|
||||
# await self.optionHandler.save_option()
|
||||
|
|
|
|||
28
option.py
28
option.py
|
|
@ -42,6 +42,8 @@ class OptionHandler:
|
|||
|
||||
def init_option_info(self):
|
||||
self.option_info = {
|
||||
'is_single_option': False,
|
||||
'is_completed_option': False,
|
||||
'original_names': {},
|
||||
'translated_names': {},
|
||||
'selected_translated_options': {},
|
||||
|
|
@ -55,6 +57,7 @@ class OptionHandler:
|
|||
def get_selected_translated_options(self):
|
||||
"""클래스 변수에 저장된 선택된 번역된 옵션들을 반환"""
|
||||
return self.option_info.get('selected_translated_options', [])
|
||||
|
||||
|
||||
def filter_bait_items_with_price_distribution(self, options, lower_z=-0.9, upper_z=1.5, base_ratio=2):
|
||||
|
||||
|
|
@ -149,10 +152,13 @@ class OptionHandler:
|
|||
옵션 처리 로직. 옵션을 번역하고 이미지를 업데이트함.
|
||||
|
||||
:param product_name: 상품명 (str 형태).
|
||||
:param max_option_count: 최대 옵션 갯수 (기본값 10).
|
||||
:param max_option_count: 최대 옵션 갯수 (기본값 20).
|
||||
"""
|
||||
try:
|
||||
self.logger.debug(f"상품명: {product_name}에 대한 옵션을 처리 중...")
|
||||
|
||||
self.logger.debug(f"이전 상품의 옵션정보를 초기화합니다.")
|
||||
self.init_option_info()
|
||||
|
||||
# self.logger.debug(f"포커스를 위해 클릭1회")
|
||||
# self.low_order_click()
|
||||
|
|
@ -169,15 +175,23 @@ class OptionHandler:
|
|||
# 1. 단일 옵션인지 판단
|
||||
if await self.is_single_option():
|
||||
self.logger.debug("단일 옵션 상품입니다. 옵션 수정 과정을 생략합니다.")
|
||||
return
|
||||
self.option_info['is_single_option'] = True
|
||||
|
||||
return self.option_info
|
||||
|
||||
# 2. 전체 옵션 체크박스 상태 확인
|
||||
click_to_check_to_all = True
|
||||
self.logger.debug(f"언제나 전체체크에서 시작 - {click_to_check_to_all}")
|
||||
|
||||
if not await self.is_all_options_checked(click_to_check_to_all):
|
||||
self.logger.debug(f"일부 체크된 옵션상품에 대한 처리 방법 : {"전체체크에서 시작" if click_to_check_to_all else "일부 체크시 수정완료로 판단"}")
|
||||
|
||||
if click_to_check_to_all:
|
||||
self.logger.debug("옵션이 일부만 체크된 상태입니다. 전체 체크로 바꿉니다.")
|
||||
await self.is_all_options_checked(click_to_check_to_all)
|
||||
else:
|
||||
self.logger.debug("옵션이 일부만 체크된 상태입니다. 옵션 수정이 완료된 상품으로 판단하여 패스합니다.")
|
||||
return
|
||||
self.option_info['is_completed_option'] = True
|
||||
|
||||
return self.option_info
|
||||
|
||||
# 3. 가격 낮은 순 정렬 클릭
|
||||
await self.low_order_click()
|
||||
|
|
@ -266,10 +280,11 @@ class OptionHandler:
|
|||
await self.page.click('button:has-text("저장하기")')
|
||||
|
||||
self.logger.debug("옵션 처리 완료.")
|
||||
return self.option_info
|
||||
|
||||
except Exception as e:
|
||||
self.logger.debug(f"옵션 처리 중 오류 발생: {e}", exc_info=True)
|
||||
return
|
||||
return None
|
||||
|
||||
async def is_single_option(self):
|
||||
"""단일 상품 상태 여부를 확인하는 메서드"""
|
||||
|
|
@ -336,7 +351,6 @@ class OptionHandler:
|
|||
|
||||
async def collect_options_info(self):
|
||||
"""옵션 정보를 수집 (이미지, 옵션명, 편집 필드, 가격, 체크박스 정보 포함)"""
|
||||
self.init_option_info()
|
||||
try:
|
||||
# 총 옵션 갯수 수집
|
||||
total_options_element = await self.page.query_selector(self.total_options_selector)
|
||||
|
|
|
|||
|
|
@ -58,19 +58,19 @@ class WhaleTranslator:
|
|||
time.sleep(1)
|
||||
pyautogui.press('r')
|
||||
|
||||
# 번역 시작 감지 (translating.png 확인)
|
||||
if self.is_translating():
|
||||
self.logger.debug("번역 시작 감지 ('translating.png' 발견)")
|
||||
# # 번역 시작 감지 (translating.png 확인)
|
||||
# if self.is_translating():
|
||||
# self.logger.debug("번역 시작 감지 ('translating.png' 발견)")
|
||||
|
||||
# 번역 중 색상 지속 확인
|
||||
result = self.check_translation_by_color_change()
|
||||
# 번역 중 색상 지속 확인
|
||||
result = self.check_translation_by_color_change()
|
||||
|
||||
if result == "success":
|
||||
self.logger.debug(f"URL: {url} - 번역이 성공적으로 완료되었습니다!")
|
||||
elif result == "error":
|
||||
self.logger.debug(f"URL: {url} - 번역에 실패했습니다.")
|
||||
else:
|
||||
self.logger.debug(f"URL: {url} - 번역 상태를 확인하지 못했습니다.")
|
||||
if result == "success":
|
||||
self.logger.debug(f"URL: {url} - 번역이 성공적으로 완료되었습니다!")
|
||||
elif result == "error":
|
||||
self.logger.debug(f"URL: {url} - 번역에 실패했습니다.")
|
||||
else:
|
||||
self.logger.debug(f"URL: {url} - 번역 상태를 확인하지 못했습니다.")
|
||||
|
||||
# 최종 색상 출력
|
||||
self.logger.debug(f"URL: {url} - 번역 중 색상: {self.colors['during']}")
|
||||
|
|
@ -122,16 +122,16 @@ class WhaleTranslator:
|
|||
except pyscreeze.ImageNotFoundException as e:
|
||||
# 'Could not locate the image' 메시지 발생 시 최고 confidence 값 로그 출력
|
||||
if hasattr(e, 'args') and 'highest confidence' in str(e.args[0]):
|
||||
self.logger.error(f"이미지를 찾지 못했습니다만 유사한 부분을 찾았습니다. : [{e.args[0]}]")
|
||||
self.logger.error(f"{image_path} 이미지를 찾지 못했습니다만 유사한 부분을 찾았습니다. : [{e.args[0]}]")
|
||||
else:
|
||||
self.logger.error("이미지를 찾지 못했습니다. 이미지와 유사한 부분을 찾지 못했습니다.")
|
||||
self.logger.error(f"{image_path}이미지를 찾지 못했습니다. 이미지와 유사한 부분을 찾지 못했습니다.")
|
||||
return None
|
||||
|
||||
def is_translating(self):
|
||||
"""translating.png가 화면에 나타나는지 확인하여 번역 시작 여부를 판단"""
|
||||
try:
|
||||
# translating_location = pyautogui.locateOnScreen(self.translating_image_path, confidence=0.8)
|
||||
translating_location = self.find_image_with_confidence(self.translating_image_path, confidence=0.8)
|
||||
translating_location = self.find_image_with_confidence(self.translating_image_path, confidence=0.4)
|
||||
if translating_location:
|
||||
return True
|
||||
except pyautogui.ImageNotFoundException as e:
|
||||
|
|
@ -201,7 +201,7 @@ class WhaleTranslator:
|
|||
self.logger.debug("색상 변화 감지 (필터 제거됨)")
|
||||
|
||||
# translating.png가 여전히 존재하는지 확인하여 번역 성공 여부 판단
|
||||
result = self.find_image_with_confidence(self.translating_image_path, confidence=0.8)
|
||||
result = self.find_image_with_confidence(self.translating_image_path, confidence=0.4)
|
||||
if result:
|
||||
return "success"
|
||||
else:
|
||||
|
|
@ -216,7 +216,7 @@ class WhaleTranslator:
|
|||
|
||||
# 타임아웃 발생 시 translating.png 여부로 번역 성공/실패 판단
|
||||
self.colors['after'] = current_color
|
||||
result = self.find_image_with_confidence(self.translating_image_path, confidence=0.8)
|
||||
result = self.find_image_with_confidence(self.translating_image_path, confidence=0.4)
|
||||
if result:
|
||||
self.logger.debug("번역 성공으로 간주 (타임아웃 후 translating.png 존재)")
|
||||
return "success"
|
||||
|
|
@ -255,7 +255,7 @@ 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")
|
||||
translator.start_whale_browser("https://file.percenty.co.kr/public/652bed8e865b1f32ea62bf1f/products/66ff967773994c46d388bb36/82d07178-ae60-49f7-a489-e02801ff7b06.jpg")
|
||||
translator.start_whale_browser('https://img.alicdn.com/imgextra/i4/735691568/O1CN01sRUYqb1NSBuefMBlw_!!735691568.jpg_Q75.jpg')
|
||||
translator.start_whale_browser('https://img.alicdn.com/imgextra/i4/1773313923/O1CN01VMRs1Z1eqmfYSXQDu_!!1773313923.jpg_Q75.jpg')
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue