diff --git a/browser_control.py b/browser_control.py
index 7bd14897..088cda0e 100644
--- a/browser_control.py
+++ b/browser_control.py
@@ -137,7 +137,7 @@ class BrowserController(QThread):
# self.imageProcessor = ImageProcessor(self.logger, self.page, self.whale_translator, self.clipboardImageManager, self.TEMP_IMAGE_DIR, self.toggle_states)
# ImageProcessor를 포함하여 다른 핸들러들 초기화
- self.optionHandler = OptionHandler(self.locator_manager, self, self.TEMP_IMAGE_DIR, self.logger, self.gpt_client, self.update_detail_progress_signal, self.set_progress_visible_signal, toggle_states=self.toggle_states)
+ self.optionHandler = OptionHandler(self.locator_manager, self, self.TEMP_IMAGE_DIR, self.logger, self.gpt_client, update_detail_progress_signal=self.update_detail_progress_signal, set_progress_visible_signal=self.set_progress_visible_signal, toggle_states=self.toggle_states)
self.priceHandler = PriceHandler(self.locator_manager, self, self.logger, self.optionHandler, self.price_setting_diag, self.toggle_states, debug_flag=self.toggle_states['debug_mode'])
self.thumbnailHandler = ThumbnailHandler(self.locator_manager, self, self.logger, self.toggle_states, self.update_detail_progress_signal, self.set_progress_visible_signal, self.base_path)
# self.titleGenerator = TitleGenerator(self.locator_manager, self, self.logger, self.whale_translator, self.toggle_states, self.gpt_client, self.forbidden_word_manager, self.user_id, self.supabase_manager)
@@ -333,8 +333,8 @@ class BrowserController(QThread):
try:
close_btn = page.locator(self.welcome_popup_closeBTN_selector)
- close_btn.wait_for(state='visible', timeout=timeout_sec * 1000)
- close_btn.click()
+ await close_btn.wait_for(state='visible', timeout=timeout_sec * 1000)
+ await close_btn.click()
self.logger.log("환영 다이얼로그를 닫았습니다.", level=logging.INFO)
except TimeoutError:
@@ -342,9 +342,9 @@ class BrowserController(QThread):
self.logger.log("환영 다이얼로그가 감지되지 않았습니다.", level=logging.INFO)
finally:
- page.keyboard.press('Escape')
+ await page.keyboard.press('Escape')
await asyncio.sleep(0.53)
- page.keyboard.press('Escape')
+ await page.keyboard.press('Escape')
async def start_browser_async(self):
@@ -582,7 +582,7 @@ class BrowserController(QThread):
try:
# 각 핸들러에 초기화된 page 객체 전달.
self.titleGenerator.update_page(self.page ,self.toggle_states)
- self.titleGenerator.update_parsing_page(self.parsing_page)
+ # self.titleGenerator.update_parsing_page(self.parsing_page)
self.optionHandler.update_page(self.page ,self.toggle_states)
self.tagsHandler.update_page(self.page ,self.toggle_states)
self.thumbnailHandler.update_page(self.page ,self.toggle_states)
@@ -1917,7 +1917,6 @@ class BrowserController(QThread):
self.logger.log(f"현재페이지 : [{current_page_number}]", level=logging.INFO)
next_page_number = current_page_number + 1
-
# 다음 페이지 버튼을 찾음 (title 속성으로 다음 페이지를 찾음)
next_page_button_locator = self.next_page_button_template.format(page_number=next_page_number)
next_page_button = await self.page.query_selector(next_page_button_locator)
@@ -2168,35 +2167,35 @@ class BrowserController(QThread):
self.logger.log(f"detail_IMGTrans_type : {detail_IMGTrans_type}", level=logging.DEBUG)
self.logger.log(f"thumb_trans_type : {thumb_trans_type}", level=logging.DEBUG)
- if optionIMGTrans_type or detail_IMGTrans_type or thumb_trans_type:
- self.logger.log('이미지 번역 타입이 웨일로 설정되어 있습니다. 웨일 브라우저를 실행합니다...', level=logging.DEBUG)
+ # if optionIMGTrans_type or detail_IMGTrans_type or thumb_trans_type:
+ # self.logger.log('이미지 번역 타입이 웨일로 설정되어 있습니다. 웨일 브라우저를 실행합니다...', level=logging.DEBUG)
- # 웨일 브라우저 시작 - 최대 3번 재시도
- max_retries = 3
- retry_count = 0
- whale_window = None
+ # # 웨일 브라우저 시작 - 최대 3번 재시도
+ # max_retries = 3
+ # retry_count = 0
+ # whale_window = None
- while retry_count < max_retries:
- self.check_pause() # 일시중지 상태 확인
- self.logger.log(f'웨일 브라우저 시작 시도 {retry_count + 1}/{max_retries}...', level=logging.INFO)
- whale_window = self.whale_translator.start_trans_browser()
+ # while retry_count < max_retries:
+ # self.check_pause() # 일시중지 상태 확인
+ # self.logger.log(f'웨일 브라우저 시작 시도 {retry_count + 1}/{max_retries}...', level=logging.INFO)
+ # whale_window = self.whale_translator.start_trans_browser()
- if whale_window:
- self.logger.log('웨일 브라우저가 성공적으로 시작되었습니다.', level=logging.INFO)
- break
+ # if whale_window:
+ # self.logger.log('웨일 브라우저가 성공적으로 시작되었습니다.', level=logging.INFO)
+ # break
- retry_count += 1
- self.logger.log(f'웨일 브라우저 시작 실패. {retry_count}/{max_retries}', level=logging.WARNING)
- await asyncio.sleep(1) # 잠시 대기 후 재시도
+ # retry_count += 1
+ # self.logger.log(f'웨일 브라우저 시작 실패. {retry_count}/{max_retries}', level=logging.WARNING)
+ # await asyncio.sleep(1) # 잠시 대기 후 재시도
- if not whale_window:
- error_msg = "웨일 브라우저를 시작할 수 없습니다. 상품수정을 중단합니다."
- self.logger.log(error_msg, level=logging.ERROR)
- self.translation_error.emit(error_msg)
- return
+ # if not whale_window:
+ # error_msg = "웨일 브라우저를 시작할 수 없습니다. 상품수정을 중단합니다."
+ # self.logger.log(error_msg, level=logging.ERROR)
+ # self.translation_error.emit(error_msg)
+ # return
- if whale_window and self.toggle_states['collect_method_combo'] == "lens":
- self.whale_translator.check_capcha()
+ # if whale_window and self.toggle_states['collect_method_combo'] == "lens":
+ # self.whale_translator.check_capcha()
# 1. 총 상품 수 수집
self.check_pause() # 일시중지 상태 확인
@@ -3034,3 +3033,4 @@ class BrowserController(QThread):
# 약간의 랜덤 대기 후 포커스 복원
await asyncio.sleep(random.uniform(0.03, 0.13))
await self.restore_focus(page, orig_focus)
+
diff --git a/login_dialog.py b/login_dialog.py
index ba2d0114..db61e765 100644
--- a/login_dialog.py
+++ b/login_dialog.py
@@ -355,7 +355,8 @@ class LoginDialog(QDialog):
QMessageBox.warning(self, "오류", "사용자 정보를 가져오지 못했습니다.")
return
else:
- self.logger.log(f"로그인 성공 full_user_info : {full_user_info}", level=logging.DEBUG)
+ # self.logger.log(f"로그인 성공 full_user_info : {full_user_info}", level=logging.DEBUG)
+ self.logger.log(f"로그인 성공", level=logging.DEBUG)
# 멤버십 레벨에 따른 최대 세션 수 설정
membership_data = full_user_info.get("membership_level_data", {})
@@ -571,7 +572,7 @@ class LoginDialog(QDialog):
def get_user_info(self):
"""로그인 또는 회원가입에 성공한 사용자 정보를 반환합니다."""
- self.logger.log(f"full_user_info : {self.user}", level=logging.DEBUG)
+ # self.logger.log(f"full_user_info : {self.user}", level=logging.DEBUG)
return self.user
def get_update_selection_data(self):
diff --git a/mainUI_SP.py b/mainUI_SP.py
index 598a8873..58315c92 100644
--- a/mainUI_SP.py
+++ b/mainUI_SP.py
@@ -1065,24 +1065,24 @@ class MAIN_GUI(QMainWindow):
def on_detailIMGTrans_type_toggle_clicked(self, checked):
# False == "대체" (Off)
- if not checked:
- QMessageBox.information(self, "안내", "아직 대체 이미지 번역은 지원하지 않습니다.\nAPI 이미지 번역으로 자동 변경됩니다.")
- self.detail_IMGTrans_type_toggle.setChecked(True)
- self.universal_input_handler(self.detail_IMGTrans_type_toggle, True) # 항상 네(True)로 처리
+ # if not checked:
+ QMessageBox.information(self, "안내", "웨일 번역 패치로 인해 대체 이미지 번역만 사용가능합니다.")
+ self.detail_IMGTrans_type_toggle.setChecked(False)
+ # self.universal_input_handler(self.detail_IMGTrans_type_toggle, False) # 항상 네(True)로 처리
def on_thumb_trans_type_toggle_clicked(self, checked):
# False == "대체" (Off)
# if not checked:
- QMessageBox.information(self, "안내", "API 이미지 번역은 조기종료되었습니다.\n대체 이미지 번역으로 자동 변경됩니다.")
+ QMessageBox.information(self, "안내", "웨일 번역 패치로 인해 대체 이미지 번역만 사용가능합니다.")
self.thumb_trans_type_toggle.setChecked(False)
- self.universal_input_handler(self.thumb_trans_type_toggle, False) # 항상 대체(False)로 처리
+ # self.universal_input_handler(self.thumb_trans_type_toggle, False) # 항상 대체(False)로 처리
def on_optionIMGTrans_type_toggle_clicked(self, checked):
# False == "대체" (Off)
- if not checked:
- QMessageBox.information(self, "안내", "아직 대체 이미지 번역은 지원하지 않습니다.\nAPI 이미지 번역으로 자동 변경됩니다.")
- self.optionIMGTrans_type_toggle.setChecked(True)
- self.universal_input_handler(self.optionIMGTrans_type_toggle, True) # 항상 네(True)로 처리
+ # if not checked:
+ QMessageBox.information(self, "안내", "웨일 번역 패치로 인해 대체 이미지 번역만 사용가능합니다.")
+ self.optionIMGTrans_type_toggle.setChecked(False)
+ # self.universal_input_handler(self.optionIMGTrans_type_toggle, False) # 항상 네(True)로 처리
def universal_input_handler(self, widget, *args):
"""
@@ -1511,6 +1511,10 @@ class MAIN_GUI(QMainWindow):
# self.thumb_trans_type_toggle.setChecked(False)
self.load_unwanted_words()
+ self.optionIMGTrans_type_toggle.setChecked(False)
+ self.detail_IMGTrans_type_toggle.setChecked(False)
+ self.thumb_trans_type_toggle.setChecked(False)
+
# self.admin_toggle.setChecked(False)
# time.sleep(0.1)
# self.admin_toggle.setChecked(True)
@@ -2222,9 +2226,9 @@ class MAIN_GUI(QMainWindow):
# 토글 버튼 그룹
self.global_toggle_group = QGroupBox("기능")
self.global_toggle_layout = QVBoxLayout(self.global_toggle_group)
- self.set_group_style(self.global_toggle_group, self.global_toggle_layout, "neumorphism")
+ # self.set_group_style(self.global_toggle_group, self.global_toggle_layout, "neumorphism")
# self.global_toggle_layout.setContentsMargins(10, 10, 10, 10)
- self.global_toggle_layout.setSpacing(10)
+ # self.global_toggle_layout.setSpacing(10)
# 설명 그룹
self.global_manual_group = QGroupBox("기능 매뉴얼")
@@ -2356,7 +2360,7 @@ class MAIN_GUI(QMainWindow):
self.memo_widget2.enterEvent = lambda e: self.show_manual_html(
self.global_manual_group,
- "📜 메모 입력 옵션션",
+ "📜 메모 입력 옵션",
self.global_manual_label,
"메모 입력 옵션을 설정합니다.
"
"메모순서 : 기존 사용자메모가 있을경우 어떤 메모를 먼저 사용할지 선택합니다.
"
@@ -2418,7 +2422,7 @@ class MAIN_GUI(QMainWindow):
self.unwanted_words_button_label = QLabel('OCR 설정', self)
self.unwanted_words_button = QPushButton('OCR', self)
self.unwanted_words_button.setObjectName("unwanted_words_button")
- self.unwanted_words_button.setFixedWidth(30)
+ # self.unwanted_words_button.setFixedWidth(30)
self.set_PUSHBTN_style(self.unwanted_words_button,"modern")
self.unwanted_words_button.clicked.connect(self.on_unwanted_words_button_clicked)
self.unwanted_words_button.setEnabled(False) # 초기 상태는 비활성화
@@ -2443,9 +2447,9 @@ class MAIN_GUI(QMainWindow):
# 번역간 대기시간
self.interval_widget = QWidget()
self.interval_spinbox_layout = QHBoxLayout(self.interval_widget)
- self.interval_spinbox_label = QLabel("번역간 대기", self)# 작업 완료 메서드 수정
+ self.interval_spinbox_label = QLabel("번역간격", self)# 작업 완료 메서드 수정
self.interval_spinbox = QSpinBox(self)
- self.interval_spinbox.setFixedHeight(30)
+ # self.interval_spinbox.setFixedHeight(30)
self.interval_spinbox.setObjectName("interval")
self.interval_spinbox.setRange(2, 10)
self.interval_spinbox.setValue(3)
@@ -2456,27 +2460,27 @@ class MAIN_GUI(QMainWindow):
self.interval_spinbox.valueChanged.connect(lambda value: self.universal_input_handler(self.interval_spinbox, value))
self.interval_widget.enterEvent = lambda e: self.show_manual_html(
self.global_manual_group,
- "대체번역시 번역간 간격",
+ "번역 사이 간격 및 번역완료대기",
self.global_manual_label,
- "대체번역시 번역사이 시간간격을 설정합니다.
"
+ "번역간격
"
+ "번역간격 : 번역사이 시간간격을 설정합니다.
"
"최소 2초, 최대 10초까지 설정 가능합니다. 기본값은 3초입니다.
"
"설정된 시간의 50% ~ 200% 사이의 랜덤시간으로 휴식합니다.
"
"설정된 시간이 짧으면 서버에 많은 부담을 주어 매우매우 좋지않은 일이 일어날수 있습니다.
"
+ "번역완료대기
"
+ "대체번역시 번역이 완료될때까지 대기 시간을 설정합니다.
"
+ "최소 5초, 최대 60초까지 설정 가능합니다. 기본값은 20초입니다.
"
+ "설정된 시간이 길어도 번역이 끝나면 완료처리됩니다.
"
+ "그러나 서버에 부하가 몰리거나 번역속도가 느릴 경우 전체 번역 시간이 증가할 수 있습니다.
"
+
+
)
self.interval_widget.leaveEvent = lambda e: self.reset_manual(self.global_manual_group, self.global_manual_label)
- self.interval_spinbox_layout.addWidget(self.interval_spinbox_label)
- self.interval_spinbox_layout.addWidget(self.interval_spinbox)
-
- self.global_toggle_layout.addWidget(self.interval_widget)
-
- # 번역대기시간 스핀
- self.watingTime_widget = QWidget()
- self.watingTime_spinbox_layout = QHBoxLayout(self.watingTime_widget)
- self.watingTime_spinbox_label = QLabel("번역대기시간", self)# 작업 완료 메서드 수정
+ self.watingTime_spinbox_label = QLabel("번역대기", self)# 작업 완료 메서드 수정
self.watingTime_spinbox = QSpinBox(self)
- self.watingTime_spinbox.setFixedHeight(30)
+ # self.watingTime_spinbox.setFixedHeight(30)
self.watingTime_spinbox.setObjectName("watingTime")
self.watingTime_spinbox.setRange(5, 60)
self.watingTime_spinbox.setValue(20)
@@ -2485,43 +2489,78 @@ class MAIN_GUI(QMainWindow):
# 번역대기시간 스핀에 대한 독립적인 이벤트 핸들러 생성
self.watingTime_spinbox.valueChanged.connect(lambda value: self.universal_input_handler(self.watingTime_spinbox, value))
- self.watingTime_widget.enterEvent = lambda e: self.show_manual_html(
- self.global_manual_group,
- "번역시 대기기시간",
- self.global_manual_label,
- "대체번역시 번역이 완료될때까지 대기 시간을 설정합니다.
"
- "최소 5초, 최대 60초까지 설정 가능합니다. 기본값은 20초입니다.
"
- "설정된 시간이 길어도 번역이 끝나면 완료처리됩니다.
"
- "그러나 서버에 부하가 몰리거나 번역속도가 느릴 경우 전체 번역 시간이 증가할 수 있습니다.
"
+ # self.watingTime_widget.enterEvent = lambda e: self.show_manual_html(
+ # self.global_manual_group,
+ # "번역시 대기기시간",
+ # self.global_manual_label,
+ # "대체번역시 번역이 완료될때까지 대기 시간을 설정합니다.
"
+ # "최소 5초, 최대 60초까지 설정 가능합니다. 기본값은 20초입니다.
"
+ # "설정된 시간이 길어도 번역이 끝나면 완료처리됩니다.
"
+ # "그러나 서버에 부하가 몰리거나 번역속도가 느릴 경우 전체 번역 시간이 증가할 수 있습니다.
"
- )
- self.watingTime_widget.leaveEvent = lambda e: self.reset_manual(self.global_manual_group, self.global_manual_label)
+ # )
+ # self.watingTime_widget.leaveEvent = lambda e: self.reset_manual(self.global_manual_group, self.global_manual_label)
- self.watingTime_spinbox_layout.addWidget(self.watingTime_spinbox_label)
- self.watingTime_spinbox_layout.addWidget(self.watingTime_spinbox)
- self.global_toggle_layout.addWidget(self.watingTime_widget)
- # GPT 모델설정
- self.gpt_model_widget = QWidget()
- self.gpt_model_layout = QHBoxLayout(self.gpt_model_widget)
- self.gpt_model_label = QLabel("GPT 모델", self)
- self.gpt_model_combo = QComboBox(self)
- self.gpt_model_combo.addItems(["gpt-4o", "gpt-4o-mini"])
- self.gpt_model_combo.setCurrentIndex(0)
+ self.interval_spinbox_layout.addWidget(self.interval_spinbox_label)
+ self.interval_spinbox_layout.addWidget(self.interval_spinbox)
+ self.interval_spinbox_layout.addWidget(self.watingTime_spinbox_label)
+ self.interval_spinbox_layout.addWidget(self.watingTime_spinbox)
- self.gpt_model_widget.enterEvent = lambda e: self.show_manual_html(
- self.global_manual_group,
- "🔢 GPT 모델 설정",
- self.global_manual_label,
- "GPT 모델을 설정합니다."
- )
- self.gpt_model_widget.leaveEvent = lambda e: self.reset_manual(self.global_manual_group, self.global_manual_label)
+ self.global_toggle_layout.addWidget(self.interval_widget)
- self.gpt_model_layout.addWidget(self.gpt_model_label)
- self.gpt_model_layout.addWidget(self.gpt_model_combo)
+ # # 번역대기시간 스핀
+ # self.watingTime_widget = QWidget()
+ # self.watingTime_spinbox_layout = QHBoxLayout(self.watingTime_widget)
+ # self.watingTime_spinbox_label = QLabel("번역대기", self)# 작업 완료 메서드 수정
+ # self.watingTime_spinbox = QSpinBox(self)
+ # # self.watingTime_spinbox.setFixedHeight(30)
+ # self.watingTime_spinbox.setObjectName("watingTime")
+ # self.watingTime_spinbox.setRange(5, 60)
+ # self.watingTime_spinbox.setValue(20)
+ # self.watingTime_spinbox.setSuffix("Second")
+ # self.watingTime_spinbox.setFixedWidth(100)
+
+ # # 번역대기시간 스핀에 대한 독립적인 이벤트 핸들러 생성
+ # self.watingTime_spinbox.valueChanged.connect(lambda value: self.universal_input_handler(self.watingTime_spinbox, value))
+ # self.watingTime_widget.enterEvent = lambda e: self.show_manual_html(
+ # self.global_manual_group,
+ # "번역시 대기기시간",
+ # self.global_manual_label,
+ # "대체번역시 번역이 완료될때까지 대기 시간을 설정합니다.
"
+ # "최소 5초, 최대 60초까지 설정 가능합니다. 기본값은 20초입니다.
"
+ # "설정된 시간이 길어도 번역이 끝나면 완료처리됩니다.
"
+ # "그러나 서버에 부하가 몰리거나 번역속도가 느릴 경우 전체 번역 시간이 증가할 수 있습니다.
"
- self.global_toggle_layout.addWidget(self.gpt_model_widget)
+ # )
+ # self.watingTime_widget.leaveEvent = lambda e: self.reset_manual(self.global_manual_group, self.global_manual_label)
+
+ # self.watingTime_spinbox_layout.addWidget(self.watingTime_spinbox_label)
+ # self.watingTime_spinbox_layout.addWidget(self.watingTime_spinbox)
+
+ # self.global_toggle_layout.addWidget(self.watingTime_widget)
+
+ # # GPT 모델설정
+ # self.gpt_model_widget = QWidget()
+ # self.gpt_model_layout = QHBoxLayout(self.gpt_model_widget)
+ # self.gpt_model_label = QLabel("GPT 모델", self)
+ # self.gpt_model_combo = QComboBox(self)
+ # self.gpt_model_combo.addItems(["gpt-4o", "gpt-4o-mini"])
+ # self.gpt_model_combo.setCurrentIndex(0)
+
+ # self.gpt_model_widget.enterEvent = lambda e: self.show_manual_html(
+ # self.global_manual_group,
+ # "🔢 GPT 모델 설정",
+ # self.global_manual_label,
+ # "GPT 모델을 설정합니다."
+ # )
+ # self.gpt_model_widget.leaveEvent = lambda e: self.reset_manual(self.global_manual_group, self.global_manual_label)
+
+ # self.gpt_model_layout.addWidget(self.gpt_model_label)
+ # self.gpt_model_layout.addWidget(self.gpt_model_combo)
+
+ # self.global_toggle_layout.addWidget(self.gpt_model_widget)
# 디버그 모드 토글
@@ -2619,6 +2658,7 @@ class MAIN_GUI(QMainWindow):
이를 통해 각 마켓의 로직에 맞춘 최적의 상품명을 AI가 만들어 줍니다.
수집된 상품명의 키 고정을 지원하여 소싱키워드를 보존할 수 있습니다.
상품정보수집 결과를 사용하지 않을 경우, 소싱된 상품명을 AI를 이용해 가공합니다.
+상품명 가공 시 네이버 SEO 최적화를 지원합니다.
""" ) self.title_widget.leaveEvent = lambda e: self.reset_manual(self.product_name_manual_group, self.product_name_manual_label) @@ -2875,6 +2915,9 @@ class MAIN_GUI(QMainWindow): self.optionIMGTrans_toggle_label = QLabel("옵션 이미지번역", self) self.optionIMGTrans_toggle = ToggleSwitch(self) self.optionIMGTrans_toggle.setObjectName("optionIMGTrans_toggle") + self.optionIMGTrans_toggle.clicked.connect + + self.optionIMGTrans_toggle.clicked.connect(lambda checked: self.universal_input_handler(self.optionIMGTrans_toggle, checked)) self.optionIMGTrans_widget.enterEvent = lambda e: self.show_manual_html( self.option_manual_group, @@ -2899,12 +2942,12 @@ class MAIN_GUI(QMainWindow): self.optionIMGTrans_type_toggle_label = QLabel("옵션 이미지번역 타입", self) self.optionIMGTrans_type_toggle = ToggleSwitch(self) self.optionIMGTrans_type_toggle.setObjectName("optionIMGTrans_type_toggle") - self.optionIMGTrans_type_toggle.setChecked(True) - # self.optionIMGTrans_type_toggle.clicked.connect(self.on_optionIMGTrans_type_toggle_clicked) + self.optionIMGTrans_type_toggle.setChecked(False) + self.optionIMGTrans_type_toggle.clicked.connect(self.on_optionIMGTrans_type_toggle_clicked) # self.optionIMGTrans_type_toggle.clicked.connect(lambda checked: self.universal_input_handler(self.optionIMGTrans_type_toggle, checked)) self.optionIMGTrans_type_toggle.setOnText("API") self.optionIMGTrans_type_toggle.setOffText("대체") - self.optionIMGTrans_type_toggle.setEnabled(False) + # self.optionIMGTrans_type_toggle.setEnabled(False) self.optionIMGTrans_type_widget.enterEvent = lambda e: self.show_manual_html( self.option_manual_group, "🔄 옵션 이미지번역 타입", @@ -3310,11 +3353,12 @@ class MAIN_GUI(QMainWindow): self.thumb_trans_type_toggle_label = QLabel("썸네일번역 타입", self) self.thumb_trans_type_toggle = ToggleSwitch(self) self.thumb_trans_type_toggle.setObjectName("thumb_trans_type_toggle") - # self.thumb_trans_type_toggle.clicked.connect(self.on_thumb_trans_type_toggle_clicked) + self.thumb_trans_type_toggle.setChecked(False) + self.thumb_trans_type_toggle.clicked.connect(self.on_thumb_trans_type_toggle_clicked) # self.thumb_trans_type_toggle.clicked.connect(lambda checked: self.universal_input_handler(self.thumb_trans_type_toggle, checked)) self.thumb_trans_type_toggle.setOnText("API") self.thumb_trans_type_toggle.setOffText("대체") - self.thumb_trans_type_toggle.setEnabled(False) + # self.thumb_trans_type_toggle.setEnabled(False) self.thumb_trans_type_widget.enterEvent = lambda e: self.show_manual_html( self.thumbnail_manual_group, "🔄 썸네일 번역 타입", @@ -3522,11 +3566,11 @@ class MAIN_GUI(QMainWindow): self.detail_IMGTrans_type_toggle = ToggleSwitch(self) self.detail_IMGTrans_type_toggle.setChecked(True) self.detail_IMGTrans_type_toggle.setObjectName("detail_IMGTrans_type_toggle") - # self.detail_IMGTrans_type_toggle.clicked.connect(self.on_detailIMGTrans_type_toggle_clicked) + self.detail_IMGTrans_type_toggle.clicked.connect(self.on_detailIMGTrans_type_toggle_clicked) # self.detail_IMGTrans_type_toggle.clicked.connect(lambda checked: self.universal_input_handler(self.detail_IMGTrans_type_toggle, checked)) self.detail_IMGTrans_type_toggle.setOnText("API") self.detail_IMGTrans_type_toggle.setOffText("대체") - self.detail_IMGTrans_type_toggle.setEnabled(False) + # self.detail_IMGTrans_type_toggle.setEnabled(False) self.detail_IMGTrans_type_widget.enterEvent = lambda e: self.show_manual_html( self.detail_manual_group, "🔄 상세페이지 번역 타입", @@ -4636,6 +4680,32 @@ class MAIN_GUI(QMainWindow): self.pause_message_box = None self.logger.log("일시정지 확인 - 안내 메시지 닫힘", level=logging.DEBUG) + + + # def on_gpt_model_changed(self, idx): + # # 사용자가 선택한 값과 label + # selected_value = self.gpt_model_combo.currentData() + # selected_label = self.gpt_model_combo.currentText() + + # # 선택 모델의 min_level 구하기 + # for model in GPT_MODELS: + # if model["value"] == selected_value: + # min_level = model["min_level"] + # break + + # # 만약 사용자가 등급보다 높은 모델 선택 시 + # if MEMBERSHIP_LEVELS.index(self.user_level) < MEMBERSHIP_LEVELS.index(min_level): + # QMessageBox.warning(self, "권한 부족", f"{selected_label} 모델은 현재 등급({self.user_level})에서 사용할 수 없습니다.") + # # 본인 등급에서 선택 가능한 최상위 모델로 롤백 + # for i in reversed(range(self.gpt_model_combo.count())): + # allowed_value = self.gpt_model_combo.itemData(i) + # # 본인 등급 이하만 + # for model in GPT_MODELS: + # if model["value"] == allowed_value and MEMBERSHIP_LEVELS.index(self.user_level) >= MEMBERSHIP_LEVELS.index(model["min_level"]): + # self.gpt_model_combo.setCurrentIndex(i) + # return + + # def on_cmb_test_button_clicked(self, test_cat): # """크무비 설정 실행 버튼 클릭 시 호출""" # self.logger.log('크무비 테스트 버튼 클릭됨', level=logging.DEBUG) diff --git a/src/contents/details.py b/src/contents/details.py index d9afe668..036b30b7 100644 --- a/src/contents/details.py +++ b/src/contents/details.py @@ -375,9 +375,11 @@ class DetailHandler: return False # 상세페이지 옵션에 따라 처리 + self.logger.log(f"self.detail_Option : {self.detail_Option}", level=logging.DEBUG) + self.logger.log(f"self.detail_IMGTrans : {self.detail_IMGTrans}", level=logging.DEBUG) if self.detail_Option or self.detail_IMGTrans: - if self.detail_Option and not self.detail_IMGTrans: + if self.detail_Option: self.logger.log("소개글 입력 시작...", level=logging.INFO) await self.input_detail_text(optionHandler) diff --git a/src/contents/option.py b/src/contents/option.py index e7c5f34c..75a3bf69 100644 --- a/src/contents/option.py +++ b/src/contents/option.py @@ -5,7 +5,7 @@ import os import logging import random class OptionHandler: - def __init__(self, locator_manager, browser_controller, whale_translator, clipboardImageManager, TEMP_IMAGE_DIR, logger, gpt_client, update_detail_progress_signal, set_progress_visible_signal, toggle_states, imageProcessor): + def __init__(self, locator_manager, browser_controller, TEMP_IMAGE_DIR, logger, gpt_client, update_detail_progress_signal, set_progress_visible_signal, toggle_states): self.update_detail_progress_signal = update_detail_progress_signal self.set_progress_visible_signal = set_progress_visible_signal @@ -13,7 +13,7 @@ class OptionHandler: self.locator_manager = locator_manager self.browser_controller = browser_controller self.page = self.browser_controller.page - self.clipboardImageManager = clipboardImageManager + # self.clipboardImageManager = clipboardImageManager self.TEMP_IMAGE_DIR = TEMP_IMAGE_DIR self.logger = logger @@ -22,8 +22,8 @@ class OptionHandler: # self.interval = self.toggle_states['interval'] self.gpt_client = gpt_client - self.whale_translator = whale_translator - self.imageProcessor = imageProcessor + # self.whale_translator = whale_translator + # self.imageProcessor = imageProcessor self.is_percenty_success = False self.is_gpt_success = False @@ -92,8 +92,9 @@ class OptionHandler: self.price_inside_box = 'sup' - def update_page(self, page1): + def update_page(self, page1, toggle_states1): self.page = page1 + self.toggle_states = toggle_states1 self.logger.log(f"page객체 업데이트 : {page1}", level=logging.DEBUG) # def update_whale(self): @@ -347,15 +348,6 @@ class OptionHandler: self.is_gpt_success = False self.is_percenty_success = True - # except google.api_core.exceptions.ResourceExhausted as re: - # # 할당량 초과 예외 처리 - # self.logger.log(f"Vertex AI 할당량 초과: {re}", level=logging.ERROR) - # self.logger.log("퍼센티 자체 AI번역 사용 시도", level=logging.DEBUG) - # pyautogui.hotkey('alt', 'q') - # self.logger.log("번역을 위한 5초간 대기", level=logging.DEBUG) - # time.sleep(5) - # translation_success = False # 번역 실패 - except Exception as e: # 기타 예외 처리 self.logger.log(f"번역 처리 중 알 수 없는 오류 발생: {e}", level=logging.ERROR, exc_info=True) @@ -765,13 +757,6 @@ class OptionHandler: # 필터링된 옵션명만 추출 filtered_option_names = {option['name'] for option in filtered_options} - # # 필터링된 옵션들만 체크박스에서 남기고 나머지 체크박스 해제 - # checkboxes = [ - # self.option_info['checkboxes'][i] - # for i, name in enumerate(self.option_info['original_names'].values()) - # if name in filtered_option_names - # ] - # 체크박스 상태 조정 await self.adjust_options(filtered_option_names, max_option_count) @@ -858,163 +843,163 @@ class OptionHandler: await self.page.click(self.low_order_button_locator) - async def update_option_image_to_whale(self, toggle_states, debug_flag=False): - """ - 옵션 이미지가 존재할 경우, 제외된 옵션이 아닌 경우 번역하여 업데이트하는 메서드. + # async def update_option_image_to_whale(self, toggle_states, debug_flag=False): + # """ + # 옵션 이미지가 존재할 경우, 제외된 옵션이 아닌 경우 번역하여 업데이트하는 메서드. - :param debug_flag: 디버그 모드일 경우 임시 이미지를 삭제하지 않음 (기본값 False). - """ - # self.is_option_wm = False + # :param debug_flag: 디버그 모드일 경우 임시 이미지를 삭제하지 않음 (기본값 False). + # """ + # # self.is_option_wm = False - try: - # 모든 옵션 상자 요소 가져오기 - option_boxes = await self.page.query_selector_all(self.option_box_selector) + # try: + # # 모든 옵션 상자 요소 가져오기 + # option_boxes = await self.page.query_selector_all(self.option_box_selector) - # option_boxes = await self.page.query_selector_all("div#productMainContentContainerId li > div > div:nth-child(1) > div > div:nth-child(2) > div") + # # option_boxes = await self.page.query_selector_all("div#productMainContentContainerId li > div > div:nth-child(1) > div > div:nth-child(2) > div") - # option_image_element = await self.page.locator("xpath=//*[@id='productMainContentContainerId']/div[1]/div[2]/div/div/div[2]/div/div[1]/div/div/div[2]/div/div/div[5]/div[1]/div/div/ul/li[1]/div/div[1]/div/div[2]/div/img").element_handle() + # # option_image_element = await self.page.locator("xpath=//*[@id='productMainContentContainerId']/div[1]/div[2]/div/div/div[2]/div/div[1]/div/div/div[2]/div/div/div[5]/div[1]/div/div/ul/li[1]/div/div[1]/div/div[2]/div/img").element_handle() - total_options = len(option_boxes) - self.logger.log(f"총 {total_options}개의 옵션 이미지 번역을 시작합니다.", level=logging.DEBUG) + # total_options = len(option_boxes) + # self.logger.log(f"총 {total_options}개의 옵션 이미지 번역을 시작합니다.", level=logging.DEBUG) - # 실제 옵션 이미지가 존재하는 항목에만 인덱스를 적용하기 위해 별도 카운터 사용 - translated_index = 1 - total_option_boxes = len(option_boxes) + # # 실제 옵션 이미지가 존재하는 항목에만 인덱스를 적용하기 위해 별도 카운터 사용 + # translated_index = 1 + # total_option_boxes = len(option_boxes) - self.set_progress_visible_signal.emit(True) + # self.set_progress_visible_signal.emit(True) - # 각 옵션 상자를 순회 - for index, option_box in enumerate(option_boxes, start=1): - # 선택자에서 인덱스를 반영해 동적 선택자를 생성 - add_button_selector = self.add_button_selector.format(index=index) + # # 각 옵션 상자를 순회 + # for index, option_box in enumerate(option_boxes, start=1): + # # 선택자에서 인덱스를 반영해 동적 선택자를 생성 + # add_button_selector = self.add_button_selector.format(index=index) - # 옵션 박스 내부의 텍스트 확인하여 "제외된 옵션" 포함 여부 검사 - option_text_content = await option_box.inner_text() - if "제외된 옵션" in option_text_content: - self.logger.log(f"{index}번째 옵션은 제외된 옵션입니다. 번역을 생략합니다.", level=logging.DEBUG) - continue # 제외된 옵션이므로 다음 옵션으로 이동 + # # 옵션 박스 내부의 텍스트 확인하여 "제외된 옵션" 포함 여부 검사 + # option_text_content = await option_box.inner_text() + # if "제외된 옵션" in option_text_content: + # self.logger.log(f"{index}번째 옵션은 제외된 옵션입니다. 번역을 생략합니다.", level=logging.DEBUG) + # continue # 제외된 옵션이므로 다음 옵션으로 이동 - # 옵션 이미지가 존재하는지 확인 - option_image = await option_box.query_selector("img") - if option_image is None: - self.logger.log(f"{index}번째 옵션에 이미지가 없습니다. 다음 옵션으로 이동합니다.", level=logging.DEBUG) - continue + # # 옵션 이미지가 존재하는지 확인 + # option_image = await option_box.query_selector("img") + # if option_image is None: + # self.logger.log(f"{index}번째 옵션에 이미지가 없습니다. 다음 옵션으로 이동합니다.", level=logging.DEBUG) + # continue - option_image_url = await option_image.get_attribute("src") - self.logger.log(f"{index}번째 옵션 이미지 URL: {option_image_url}", level=logging.DEBUG) + # option_image_url = await option_image.get_attribute("src") + # self.logger.log(f"{index}번째 옵션 이미지 URL: {option_image_url}", level=logging.DEBUG) - # 이미지가 SVG 형식일 경우 번역을 건너뜀 - if option_image_url.endswith(".svg"): - self.logger.log(f"{index}번째 옵션은 SVG 이미지입니다. 번역을 생략합니다.", level=logging.DEBUG) - continue + # # 이미지가 SVG 형식일 경우 번역을 건너뜀 + # if option_image_url.endswith(".svg"): + # self.logger.log(f"{index}번째 옵션은 SVG 이미지입니다. 번역을 생략합니다.", level=logging.DEBUG) + # continue - try: - # ImageProcessor를 사용하여 이미지 처리 - self.logger.log(f"{index}번째 옵션의 이미지 처리 시도", level=logging.DEBUG) + # try: + # # ImageProcessor를 사용하여 이미지 처리 + # self.logger.log(f"{index}번째 옵션의 이미지 처리 시도", level=logging.DEBUG) - # option 구분자를 포함한 임시파일명으로 처리 - final_image_path = await self.imageProcessor.process_single_image( - option_image_url, translated_index-1, self.toggle_states.get('is_localServer', False), file_prefix="option" - ) + # # option 구분자를 포함한 임시파일명으로 처리 + # final_image_path = await self.imageProcessor.process_single_image( + # option_image_url, translated_index-1, self.toggle_states.get('is_localServer', False), file_prefix="option" + # ) - if final_image_path is False: - # 불필요한 키워드 포함으로 제외된 이미지 - self.logger.log(f"{index}번째 옵션 이미지 제외됨 (불필요한 키워드 포함)", level=logging.INFO) - continue + # if final_image_path is False: + # # 불필요한 키워드 포함으로 제외된 이미지 + # self.logger.log(f"{index}번째 옵션 이미지 제외됨 (불필요한 키워드 포함)", level=logging.INFO) + # continue - elif isinstance(final_image_path, str) and final_image_path and os.path.exists(final_image_path): - # 정상적으로 처리된 이미지 사용 - translated_image_path = final_image_path - self.logger.log(f"{index}번째 옵션의 이미지 처리 완료: {translated_image_path}", level=logging.DEBUG) - else: - # 예상하지 못한 반환값 또는 파일이 존재하지 않음 - self.logger.log(f"{index}번째 옵션 이미지 처리 결과 예상하지 못한 값: {final_image_path}", level=logging.WARNING) - continue + # elif isinstance(final_image_path, str) and final_image_path and os.path.exists(final_image_path): + # # 정상적으로 처리된 이미지 사용 + # translated_image_path = final_image_path + # self.logger.log(f"{index}번째 옵션의 이미지 처리 완료: {translated_image_path}", level=logging.DEBUG) + # else: + # # 예상하지 못한 반환값 또는 파일이 존재하지 않음 + # self.logger.log(f"{index}번째 옵션 이미지 처리 결과 예상하지 못한 값: {final_image_path}", level=logging.WARNING) + # continue - # self.browser_controller.switch_to_chrome() # 크롬으로 포커스 이동 + # # self.browser_controller.switch_to_chrome() # 크롬으로 포커스 이동 - if os.path.exists(translated_image_path): - # 삭제 버튼 클릭 - # delete_button = await self.page.query_selector(delete_button_selector) + # if os.path.exists(translated_image_path): + # # 삭제 버튼 클릭 + # # delete_button = await self.page.query_selector(delete_button_selector) - self.logger.log(f"{index}번째 옵션의 이미지 삭제 버튼 가져오기", level=logging.DEBUG) + # self.logger.log(f"{index}번째 옵션의 이미지 삭제 버튼 가져오기", level=logging.DEBUG) - try: - # 기본 선택자로 삭제 버튼 찾기 - delete_button = self.page.locator(f'{self.delete_button_selector_template.format(index=index)}') - await delete_button.wait_for(state="attached", timeout=5000) # 타임아웃 설정 + # try: + # # 기본 선택자로 삭제 버튼 찾기 + # delete_button = self.page.locator(f'{self.delete_button_selector_template.format(index=index)}') + # await delete_button.wait_for(state="attached", timeout=5000) # 타임아웃 설정 - if not await delete_button.is_visible(): - # fallback으로 재시도 - delete_button = self.page.locator(f'xpath={self.fallback1_delete_button_selector_template.format(index=index)}') - await delete_button.wait_for(state="attached", timeout=5000) + # if not await delete_button.is_visible(): + # # fallback으로 재시도 + # delete_button = self.page.locator(f'xpath={self.fallback1_delete_button_selector_template.format(index=index)}') + # await delete_button.wait_for(state="attached", timeout=5000) - if await delete_button.is_visible(): - await delete_button.click() - self.logger.log(f"{index}번째 옵션의 삭제 버튼 클릭", level=logging.DEBUG) + # if await delete_button.is_visible(): + # await delete_button.click() + # self.logger.log(f"{index}번째 옵션의 삭제 버튼 클릭", level=logging.DEBUG) - # 다이알로그 확인 후 삭제 버튼 클릭 - try: - self.logger.log(f"{index}번째 옵션의 삭제 다이알로그에서 삭제 버튼 클릭 시도...", level=logging.DEBUG) - deleted = await self.click_option_image_delete_button() - if deleted: - self.logger.log(f"{index}번째 옵션의 삭제 다이알로그 삭제버튼 클릭 성공", level=logging.DEBUG) - else: - self.logger.log(f"{index}번째 옵션의 삭제 다이알로그 삭제버튼 클릭 실패", level=logging.ERROR) - except Exception as e: - self.logger.log(f"{index}번째 옵션의 삭제 다이알로그를 찾거나 삭제버튼 클릭 중 오류: {e}", level=logging.ERROR, exc_info=True) + # # 다이알로그 확인 후 삭제 버튼 클릭 + # try: + # self.logger.log(f"{index}번째 옵션의 삭제 다이알로그에서 삭제 버튼 클릭 시도...", level=logging.DEBUG) + # deleted = await self.click_option_image_delete_button() + # if deleted: + # self.logger.log(f"{index}번째 옵션의 삭제 다이알로그 삭제버튼 클릭 성공", level=logging.DEBUG) + # else: + # self.logger.log(f"{index}번째 옵션의 삭제 다이알로그 삭제버튼 클릭 실패", level=logging.ERROR) + # except Exception as e: + # self.logger.log(f"{index}번째 옵션의 삭제 다이알로그를 찾거나 삭제버튼 클릭 중 오류: {e}", level=logging.ERROR, exc_info=True) - except Exception as e: - self.logger.log(f"{index}번째 옵션의 삭제 버튼을 찾는 중 오류 발생: {e}", level=logging.ERROR, exc_info=True) + # except Exception as e: + # self.logger.log(f"{index}번째 옵션의 삭제 버튼을 찾는 중 오류 발생: {e}", level=logging.ERROR, exc_info=True) - try: - # '+ 버튼' 클릭 후 파일 업로드 - self.logger.log(f"{index}번째 옵션의 이미지추가 버튼 가져오기", level=logging.DEBUG) - add_button = await self.page.query_selector(add_button_selector) + # try: + # # '+ 버튼' 클릭 후 파일 업로드 + # self.logger.log(f"{index}번째 옵션의 이미지추가 버튼 가져오기", level=logging.DEBUG) + # add_button = await self.page.query_selector(add_button_selector) - if add_button: - await add_button.click() - self.logger.log(f"{index}번째 옵션의 이미지추가 버튼 클릭", level=logging.DEBUG) + # if add_button: + # await add_button.click() + # self.logger.log(f"{index}번째 옵션의 이미지추가 버튼 클릭", level=logging.DEBUG) - # 파일 업로드 영역의 input 요소 직접 선택 (수정된 부분) - file_input = await self.page.query_selector(self.file_upload_button_selector) # Ant Design의 클래스 사용 + # # 파일 업로드 영역의 input 요소 직접 선택 (수정된 부분) + # file_input = await self.page.query_selector(self.file_upload_button_selector) # Ant Design의 클래스 사용 - if file_input: - # Playwright의 set_input_files를 사용하여 파일 업로드 처리 - await file_input.set_input_files(translated_image_path) - self.logger.log(f"{index}번째 옵션의 파일 업로드 완료", level=logging.DEBUG) + # if file_input: + # # Playwright의 set_input_files를 사용하여 파일 업로드 처리 + # await file_input.set_input_files(translated_image_path) + # self.logger.log(f"{index}번째 옵션의 파일 업로드 완료", level=logging.DEBUG) - # '이미지 삽입' 버튼 클릭 - confirm_upload_button = await self.page.wait_for_selector(self.confirm_upload_button_selector) - await confirm_upload_button.click() - self.logger.log(f"{index}번째 옵션에 이미지가 업로드되었습니다.", level=logging.DEBUG) - else: - self.logger.log(f"{index}번째 옵션의 파일 입력 요소를 찾을 수 없습니다.", level=logging.ERROR) - except Exception as e: - self.logger.log(f"{index}번째 옵션의 이미지를 추가하는 중 오류 발생: {e}", level=logging.ERROR, exc_info=True) + # # '이미지 삽입' 버튼 클릭 + # confirm_upload_button = await self.page.wait_for_selector(self.confirm_upload_button_selector) + # await confirm_upload_button.click() + # self.logger.log(f"{index}번째 옵션에 이미지가 업로드되었습니다.", level=logging.DEBUG) + # else: + # self.logger.log(f"{index}번째 옵션의 파일 입력 요소를 찾을 수 없습니다.", level=logging.ERROR) + # except Exception as e: + # self.logger.log(f"{index}번째 옵션의 이미지를 추가하는 중 오류 발생: {e}", level=logging.ERROR, exc_info=True) - except Exception as e: - self.logger.log(f"{index}번째 옵션 이미지 처리 중 오류 발생: {e}", level=logging.ERROR, exc_info=True) + # except Exception as e: + # self.logger.log(f"{index}번째 옵션 이미지 처리 중 오류 발생: {e}", level=logging.ERROR, exc_info=True) - finally: - # 파일 사용 후 0.5초 대기하여 접근 완료 보장 - time.sleep(0.5) + # finally: + # # 파일 사용 후 0.5초 대기하여 접근 완료 보장 + # time.sleep(0.5) - pywinauto.clipboard.EmptyClipboard() + # pywinauto.clipboard.EmptyClipboard() - time.sleep(0.5) - # 디버그 모드가 아닐 경우 임시 파일 삭제는 ImageProcessor에서 관리되므로 생략 - # (ImageProcessor가 자체적으로 임시 파일을 관리함) + # time.sleep(0.5) + # # 디버그 모드가 아닐 경우 임시 파일 삭제는 ImageProcessor에서 관리되므로 생략 + # # (ImageProcessor가 자체적으로 임시 파일을 관리함) - # 실제 번역이 완료된 경우에만 인덱스 증가 - translated_index += 1 - self.update_detail_progress_signal.emit(index, total_option_boxes) + # # 실제 번역이 완료된 경우에만 인덱스 증가 + # translated_index += 1 + # self.update_detail_progress_signal.emit(index, total_option_boxes) - self.set_progress_visible_signal.emit(False) + # self.set_progress_visible_signal.emit(False) - except Exception as e: - self.logger.log(f"옵션 이미지 업데이트 중 오류 발생: {e}", level=logging.ERROR, exc_info=True) + # except Exception as e: + # self.logger.log(f"옵션 이미지 업데이트 중 오류 발생: {e}", level=logging.ERROR, exc_info=True) # 파일 삭제를 위한 재시도 함수 def try_delete_file(self, file_path, retries=5, wait_time=0.5): diff --git a/src/contents/tags.py b/src/contents/tags.py index 0abe022b..98a1065c 100644 --- a/src/contents/tags.py +++ b/src/contents/tags.py @@ -71,7 +71,9 @@ class TagsHandler: self.logger.log(f"원본 keyword_tags List : {keyword_tags}", level=logging.DEBUG) if tag_ai and gpt_client: # 태그 키워드 리스트 추출 - keyword_tags = gpt_client.generate_product_name_and_tags(title_infos.get("keyword_tags", []), title_infos.get("original_name", ""), title_infos.get("top_titles", []), title_infos.get("category", ""), title_infos.get("base_prompt", "")) + # keyword_tags = gpt_client.generate_product_name_and_tags(title_infos.get("keyword_tags", []), title_infos.get("original_name", ""), title_infos.get("top_titles", []), title_infos.get("category", ""), title_infos.get("base_prompt", "")) + name, tags = gpt_client.generate_product_name_and_tags(title_infos.get("keyword_tags", []), title_infos.get("original_name", ""), title_infos.get("top_titles", []), title_infos.get("category", ""), title_infos.get("base_prompt", "")) + keyword_tags = tags # 튜플에서 태그 부분만 사용 if not keyword_tags: self.logger.log("gpt 태그가 비어 있습니다.", level=logging.WARNING) return diff --git a/src/contents/옵션.md b/src/contents/옵션.md index c98d2079..2cba9163 100644 --- a/src/contents/옵션.md +++ b/src/contents/옵션.md @@ -13,9 +13,44 @@ div#productMainContentContainerId div[aria-expanded='true'][role='button'] span. "옵션 타입 02" + + +self.checkbox_selector_template = #productMainContentContainerId li:nth-child({index}) input[type="checkbox"] +self.total_options_selector = #productMainContentContainerId label.ant-checkbox-wrapper +self.single_option_locator = //div[@id="productMainContentContainerId"]//label[contains(@class, 'ant-radio-button-wrapper-checked') and contains(., '단일 상품등록')] + + +self.original_name_selector_template =div#productMainContentContainerId li:nth-child({index}) > div > div:nth-child(1) > div > div:nth-child(3) > div:nth-child(3) > span +self.edit_field_selector_template = div#productMainContentContainerId li:nth-child({index}) > div > div:nth-child(1) > div > div:nth-child(3) > div:nth-child(2) > div:nth-child(1) > span > input +self.checkbox_selector_template = #productMainContentContainerId li:nth-child({index}) input[type="checkbox"] +self.image_selector_template = div#productMainContentContainerId li:nth-child({index}) > div > div:nth-child(1) > div > div:nth-child(2) > div > img +self.price_selector_template = //*[@id="productMainContentContainerId"]/div[1]/div[2]/div/div/div[2]/div/div[1]/div/div/div[2]/div/div/div[5]/div[1]/div/div/ul/li[{index}]/div/div[1]/div/div[3]/div[1]/div[2]/button/span/sup + + + 옵션타입1의 옵션 체크박스들의 셀럭터 div#productMainContentContainerId li[aria-describedby='DndDescribedBy-0'] input.ant-checkbox-input[type='checkbox'] +옵션타입2의 옵션 체크박스들의 셀럭터 +div#productMainContentContainerId li[aria-describedby='DndDescribedBy-1'] input.ant-checkbox-input[type='checkbox'] + +옵션타입3의 옵션 체크박스들의 셀럭터 +div#productMainContentContainerId li[aria-describedby='DndDescribedBy-2'] input.ant-checkbox-input[type='checkbox'] + + +옵션타입1의 옵션1의 요소(체크상태) +


