1106 lines
53 KiB
Python
1106 lines
53 KiB
Python
from PySide6.QtWidgets import QInputDialog, QWidget, QMessageBox, QSpinBox, QPushButton, QVBoxLayout, QGridLayout, QTextEdit, QLabel, QLineEdit, QHBoxLayout, QProgressBar, QSizePolicy
|
|
from PySide6.QtCore import Qt, Signal, Slot, QRect, QSettings, QTimer
|
|
from toggleSwitch import ToggleSwitch
|
|
from browser_control import BrowserController
|
|
# from whale_translator import WhaleTranslator
|
|
# from vertexAI import VertexAITranslator
|
|
from locatorManager import LocatorManager
|
|
from src.cmb_diag import CMBSettingsDialog
|
|
from src.DatabaseManager import DatabaseManager
|
|
from loggerModule import Logger # 추가
|
|
import logging
|
|
import sys
|
|
import os, shutil, time
|
|
|
|
class AutoPercentyGUI(QWidget):
|
|
|
|
start_stage_signal = Signal(int)
|
|
complete_stage_signal = Signal(int)
|
|
|
|
percentyJob_button_Signal = Signal(bool)
|
|
|
|
update_detail_progress_signal = Signal(int, int) # (현재 값, 총 값)
|
|
set_progress_visible_signal = Signal(bool) # ProgressBar 표시/숨김
|
|
|
|
def __init__(self, app=None):
|
|
super().__init__()
|
|
|
|
self.start_stage_signal.connect(self.start_stage)
|
|
self.complete_stage_signal.connect(self.complete_stage)
|
|
self.update_detail_progress_signal.connect(self.update_detail_progress_value) # 연결
|
|
self.set_progress_visible_signal.connect(self.set_progress_visibility)
|
|
|
|
self.percentyJob_button_Signal.connect(self.percentyJob_button_Enable)
|
|
|
|
self.initUI()
|
|
|
|
self.logger = Logger(gui_logger=self.log_message, log_file="AutoPercenty3.log", logger_name="AP3_Logger", level=logging.DEBUG)
|
|
self.logger.log(f"로그기록이 설정되었습니다.", level=logging.INFO)
|
|
|
|
self.debug = False
|
|
|
|
self.settings = QSettings("WhenRideMycar", "AutoPercenty3") # QSettings 초기화
|
|
self.locator_manager = LocatorManager()
|
|
# self.vertexAI = VertexAITranslator(self.logger)
|
|
|
|
# DB 파일 경로 설정
|
|
self.base_dir = self.get_base_dir()
|
|
self.user_db_path = os.path.join(self.base_dir, "userDB.db")
|
|
self.initial_db_path = os.path.join(self.base_dir, "src", "initialDB.db")
|
|
|
|
# userDB.db 생성 (없으면 initialDB.db 복사)
|
|
self.create_user_db_if_not_exists()
|
|
|
|
# 이전에 저장된 설정 불러오기
|
|
self.load_settings()
|
|
|
|
# # DatabaseManager 초기화
|
|
self.db_manager = DatabaseManager(db_url=f"sqlite:///{self.user_db_path}", logger=self.logger)
|
|
self.cmb_diag = CMBSettingsDialog(parent=self, logger=self.logger, db_manager=self.db_manager, initial_db_path=self.initial_db_path, user_db_path=self.user_db_path, debug=self.debug)
|
|
|
|
self.browser_controller = BrowserController(self, self.logger, self.locator_manager, self.cmb_diag, self.login_infos, self.toggle_states)
|
|
|
|
# 브라우저 시작 완료 및 오류 시그널 연결
|
|
self.browser_controller.browser_started.connect(self.on_browser_started)
|
|
self.browser_controller.browser_error.connect(self.on_browser_error)
|
|
# 브라우저 시작 완료 및 오류 시그널 연결
|
|
self.browser_controller.translation_started.connect(self.on_PercentyJob_started)
|
|
self.browser_controller.translation_completed.connect(self.on_PercentyJob_completed)
|
|
self.browser_controller.translation_error.connect(self.on_PercentyJob_error)
|
|
|
|
|
|
# self.clipboardImageManager = ClipboardImageManager(self, logger, self.browser_controller, watermark_font_size=36, debug=self.debug)
|
|
# self.optionHandler = OptionHandler(self.locator_manager, self.browser_controller, self.whale_translator, self.clipboardImageManager, self.logger, self.vertexAI, self.debug)
|
|
# self.priceHandler = PriceHandler(self.locator_manager, self.browser_controller, self.logger, self.optionHandler, self.vertexAI, self.cmb_diag, self.debug)
|
|
# self.titleHandler = TitleHandler(self.locator_manager, self.browser_controller, self.logger)
|
|
self.running = False
|
|
|
|
# 변수 설정
|
|
self.start_time = 0
|
|
self.finish_time = 0
|
|
|
|
self.total_product_count = 0
|
|
self.current_product_count = 0
|
|
|
|
self.title_count = 0
|
|
self.option_count = 0
|
|
self.price_count = 0
|
|
self.detail_image_count = 0
|
|
self.thumb_image_count = 0
|
|
self.current_options_info = {}
|
|
|
|
self.current_stage_index = 0 # 현재 진행 중인 단계 인덱스
|
|
|
|
# 프로그래스바 초기화
|
|
self.update_total_progress(0,0)
|
|
|
|
@Slot(str)
|
|
def log_message(self, message):
|
|
self.log.append(message)
|
|
|
|
def get_base_dir(self):
|
|
"""
|
|
실행 환경에 따라 base_dir을 설정하는 메서드.
|
|
cx_Freeze로 패키징된 경우 실행 파일의 경로, 일반 Python 환경일 경우 __file__을 기준으로 설정.
|
|
"""
|
|
if getattr(sys, 'frozen', False): # 패키징된 경우
|
|
base_dir = os.path.dirname(sys.executable)
|
|
internal_dir = os.path.join(base_dir, '_internal') # _internal 디렉토리 포함
|
|
if os.path.exists(internal_dir): # _internal 디렉토리가 존재하면 base_dir로 설정
|
|
return internal_dir
|
|
|
|
else: # 일반 Python 실행 환경
|
|
base_dir = os.path.dirname(os.path.abspath(__file__))
|
|
return base_dir
|
|
|
|
|
|
def create_user_db_if_not_exists(self):
|
|
"""
|
|
userDB.db 파일이 없으면 initialDB.db를 복사해서 생성하는 메서드.
|
|
"""
|
|
try:
|
|
if not os.path.exists(self.user_db_path):
|
|
self.logger.log(f"userDB.db 파일이 존재하지 않아 initialDB.db를 복사합니다.", level=logging.DEBUG)
|
|
if os.path.exists(self.initial_db_path):
|
|
shutil.copyfile(self.initial_db_path, self.user_db_path)
|
|
self.logger.log("initialDB.db를 userDB.db로 복사했습니다.", level=logging.DEBUG)
|
|
else:
|
|
raise FileNotFoundError(f"{self.initial_db_path} 파일이 없습니다. 초기 DB 파일이 존재하는지 확인해주세요.")
|
|
except FileNotFoundError as e:
|
|
self.logger.log(f"DB 초기화 실패: {e}", level=logging.ERROR, exc_info=True)
|
|
raise e
|
|
except Exception as e:
|
|
self.logger.log(f"DB 파일 복사 중 오류 발생: {e}", level=logging.ERROR, exc_info=True)
|
|
raise e
|
|
|
|
# def add_text_edit_logger(self):
|
|
# """QTextEdit에 로그를 출력하기 위한 핸들러 추가"""
|
|
# text_edit_logger = QTextEditLogger()
|
|
# text_edit_logger.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
|
|
# # text_edit_logger.appendHtml.connect(self.log.appendHtml)
|
|
# text_edit_logger.appendHtml.connect(self.log.append) # appendHtml 대신 append로 수정
|
|
# text_edit_logger.scrollToBottom.connect(lambda: self.log.verticalScrollBar().setValue(self.log.verticalScrollBar().maximum()))
|
|
# self.logger.addHandler(text_edit_logger)
|
|
# self.logger.debug('로그기록이 설정되었습니다.')
|
|
|
|
# def add_text_edit_logger(self):
|
|
# """QPlainTextEdit에 로그를 출력하기 위한 핸들러 추가"""
|
|
# try:
|
|
# # GUI 핸들러 추가
|
|
# self.plain_text_edit_logger = QTextEditLogger(self.log)
|
|
# self.plain_text_edit_logger.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
|
|
# self.logger.addHandler(self.plain_text_edit_logger)
|
|
# # self.inspect_logger_handlers(self.logger)
|
|
|
|
# for handler in self.logger.handlers:
|
|
# if isinstance(handler, QTextEditLogger):
|
|
# print(f"Handler: {handler}, Type: QTextEditLogger")
|
|
|
|
# self.logger.debug('로그기록이 설정되었습니다.')
|
|
# except Exception as e:
|
|
# print(f"Error in add_text_edit_logger: {e}")
|
|
|
|
@Slot(int)
|
|
def start_stage(self, stage_index):
|
|
"""지정한 단계에 깜빡임 효과 적용"""
|
|
if 0 <= stage_index < len(self.stage_labels):
|
|
self.timer = QTimer(self)
|
|
self.blink_status = True
|
|
self.timer.timeout.connect(lambda: self.blink_stage(stage_index))
|
|
self.timer.start(500) # 0.5초 간격으로 깜빡임
|
|
|
|
def blink_stage(self, stage_index):
|
|
"""지정한 단계의 색상을 주기적으로 변경하여 깜빡임 효과를 적용"""
|
|
label = self.stage_labels[stage_index]
|
|
if self.blink_status:
|
|
label.setStyleSheet("background-color: yellow; padding: 5px;")
|
|
else:
|
|
label.setStyleSheet("background-color: lightgray; padding: 5px;")
|
|
self.blink_status = not self.blink_status
|
|
|
|
def stop_blinking_effect(self):
|
|
"""깜빡임 효과 중지"""
|
|
self.timer.stop()
|
|
|
|
@Slot(int)
|
|
def complete_stage(self, stage_index):
|
|
"""단계 완료 시 깜빡임을 중지하고 완료 상태로 변경"""
|
|
if 0 <= stage_index < len(self.stage_labels):
|
|
self.stop_blinking_effect()
|
|
label = self.stage_labels[stage_index]
|
|
label.setStyleSheet("background-color: green; padding: 5px;")
|
|
self.current_stage_index += 1
|
|
|
|
# 다음 단계로 이동하여 깜빡임 시작
|
|
if self.current_stage_index < len(self.stages):
|
|
self.start_stage(self.current_stage_index)
|
|
|
|
def init_settings(self):
|
|
|
|
self.login_infos={
|
|
'admin_id' : None,
|
|
'admin_pw' : None,
|
|
'user_id' : None,
|
|
'user_pw' : None,
|
|
'is_admin' : False,
|
|
}
|
|
|
|
# 토글 상태를 저장할 딕셔너리 초기화
|
|
self.toggle_states = {
|
|
'title': False,
|
|
'use_API': False,
|
|
'clientID': "",
|
|
'clientSecret': "",
|
|
'optionTrnas': False,
|
|
'optionIMGTrans': False,
|
|
'optionAutoSelect': False,
|
|
'price': False,
|
|
'thumb': False,
|
|
'tag': False,
|
|
'detail_Option': False,
|
|
'detail_IMGTrans': False,
|
|
'debug_mode': False,
|
|
'recovery_mode': False,
|
|
'ed_mode': False, # 등록된 상품을 수정할때
|
|
'watermark': False, # 워터마크 토글 추가
|
|
'watermark_text': "", # 워터마크 텍스트 저장
|
|
'opacity_percent': 25, # 워터마크 투명도
|
|
'max_option_count': 20, # 최대 선택가능한 옵션 수
|
|
}
|
|
|
|
def initUI(self):
|
|
self.init_settings()
|
|
|
|
self.setWindowFlags(Qt.WindowStaysOnTopHint)
|
|
self.setGeometry(QRect(800, 200, 400, 700))
|
|
self.setWindowTitle('AutoPecenty3')
|
|
|
|
# 로그
|
|
self.log = QTextEdit(self)
|
|
self.log.setReadOnly(True)
|
|
|
|
# 전체 프로그레스바
|
|
self.total_progress_bar = QProgressBar(self)
|
|
self.total_progress_bar.setValue(0)
|
|
self.total_progress_bar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
|
|
# 스테이지 타임라인
|
|
self.stageTimeline_layout = QHBoxLayout()
|
|
# self.stages = ["상품명", "옵션", "가격", "썸네일", "상페"]
|
|
self.stages = ["상품명", "옵션", "가격", "썸네일", "키워드", "상페"]
|
|
self.stage_labels = []
|
|
|
|
for stage in self.stages:
|
|
# self.stage_layout = QHBoxLayout()
|
|
label = QLabel(stage)
|
|
label.setStyleSheet("background-color: lightgray; padding: 3px;")
|
|
self.stage_labels.append(label)
|
|
|
|
# self.stage_layout.addWidget(label)
|
|
# self.stageTimeline_layout.addLayout(self.stage_layout)
|
|
self.stageTimeline_layout.addWidget(label) # 수정: QLabel을 추가할 때 addWidget() 사용
|
|
|
|
# 디테일 프로그레스바
|
|
self.detail_progress_bar = QProgressBar(self)
|
|
self.detail_progress_bar.setValue(0)
|
|
self.detail_progress_bar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
self.detail_progress_bar.setVisible(False)
|
|
|
|
# 동작옵션 토글 및 레이블 설정
|
|
self.toggle_layout = QGridLayout()
|
|
|
|
# 상품명 수정 토글
|
|
self.title_toggle_label = QLabel("상품명 수정", self)
|
|
self.title_toggle = ToggleSwitch(self)
|
|
self.title_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('title', checked))
|
|
self.toggle_layout.addWidget(self.title_toggle_label, 0, 0)
|
|
self.toggle_layout.addWidget(self.title_toggle, 0, 1)
|
|
|
|
# API 사용 토글
|
|
self.use_API_toggle_label = QLabel("API 사용", self)
|
|
self.use_API_toggle = ToggleSwitch(self)
|
|
self.use_API_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('use_API', checked))
|
|
self.toggle_layout.addWidget(self.use_API_toggle_label, 0, 2)
|
|
self.toggle_layout.addWidget(self.use_API_toggle, 0, 3)
|
|
|
|
# API 관련 필드 초기화
|
|
self.client_id_label = QLabel("Client ID", self)
|
|
self.client_id_input = QLineEdit(self)
|
|
self.client_id_input.setPlaceholderText("Client ID 입력")
|
|
self.client_id_input.returnPressed.connect(self.update_client_id_input)
|
|
|
|
self.client_secret_label = QLabel("Client Secret", self)
|
|
self.client_secret_input = QLineEdit(self)
|
|
self.client_secret_input.setPlaceholderText("Client Secret 입력")
|
|
self.client_secret_input.returnPressed.connect(self.update_client_secret_input)
|
|
|
|
# 초기에는 숨김 상태
|
|
self.client_id_label.setVisible(False)
|
|
self.client_id_input.setVisible(False)
|
|
self.client_secret_label.setVisible(False)
|
|
self.client_secret_input.setVisible(False)
|
|
|
|
# 옵션명 AI번역 토글
|
|
self.optionTrnas_toggle_label = QLabel("옵션명 AI번역", self)
|
|
self.optionTrnas_toggle = ToggleSwitch(self)
|
|
self.optionTrnas_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('optionTrnas', checked))
|
|
|
|
# 옵션이미지 번역 토글
|
|
self.optionIMGTrans_toggle_label = QLabel("옵션이미지 번역", self)
|
|
self.optionIMGTrans_toggle = ToggleSwitch(self)
|
|
self.optionIMGTrans_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('optionIMGTrans', checked))
|
|
|
|
# 옵션Auto선택 토글
|
|
self.optionAutoSelect_toggle_label = QLabel("옵션 Auto선택", self)
|
|
self.optionAutoSelect_toggle = ToggleSwitch(self)
|
|
self.optionAutoSelect_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('optionAutoSelect', checked))
|
|
|
|
# 가격 수정 토글
|
|
self.price_toggle_label = QLabel("가격 수정", self)
|
|
self.price_toggle = ToggleSwitch(self)
|
|
self.price_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('price', checked))
|
|
|
|
# 태그 수정 토글
|
|
self.tag_toggle_label = QLabel("태그 수정", self)
|
|
self.tag_toggle = ToggleSwitch(self)
|
|
self.tag_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('tag', checked))
|
|
|
|
# 썸네일 AI수정 토글
|
|
self.thumb_toggle_label = QLabel("썸네일 AI수정", self)
|
|
self.thumb_toggle = ToggleSwitch(self)
|
|
self.thumb_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('thumb', checked))
|
|
|
|
# 상페 옵션명 삽입 토글
|
|
self.detail_Option_toggle_label = QLabel("상세 옵션명 삽입", self)
|
|
self.detail_Option_toggle = ToggleSwitch(self)
|
|
self.detail_Option_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('detail_Option', checked))
|
|
|
|
# 상페 이미지 번역 토글
|
|
self.detail_IMGTrans_toggle_label = QLabel("상세 이미지 번역", self)
|
|
self.detail_IMGTrans_toggle = ToggleSwitch(self)
|
|
self.detail_IMGTrans_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('detail_IMGTrans', checked))
|
|
|
|
# 디버그 모드 토글
|
|
self.debug_toggle_label = QLabel("디버그 모드", self)
|
|
self.debug_toggle = ToggleSwitch(self)
|
|
self.debug_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('debug_mode', checked))
|
|
|
|
# 수정등록 모드 토글
|
|
self.ed_mode_toggle_label = QLabel("수정등록 모드", self)
|
|
self.ed_mode_toggle = ToggleSwitch(self)
|
|
self.ed_mode_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('ed_mode', checked))
|
|
|
|
# # VD 모드 토글
|
|
# self.vd_mode_toggle_label = QLabel("VD 모드", self)
|
|
# self.vd_mode_toggle = ToggleSwitch(self)
|
|
# self.vd_mode_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('vd_mode', checked))
|
|
# self.toggle_layout.addWidget(self.vd_mode_toggle_label, 5, 2)
|
|
# self.toggle_layout.addWidget(self.vd_mode_toggle, 5, 3)
|
|
# self.vd_mode_toggle.setVisible(False)
|
|
# self.vd_mode_toggle_label.setVisible(False)
|
|
|
|
# recovery 모드 토글
|
|
self.recovery_mode_toggle_label = QLabel("복구 모드", self)
|
|
self.recovery_mode_toggle = ToggleSwitch(self)
|
|
self.recovery_mode_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('recovery_mode', checked))
|
|
|
|
# 워터마크 토글 추가
|
|
self.watermark_toggle_label = QLabel("워터마크", self)
|
|
self.watermark_toggle = ToggleSwitch(self)
|
|
self.watermark_toggle.clicked.connect(lambda checked: self.on_toggle_clicked_generic('watermark', checked))
|
|
|
|
# 워터마크 관련 UI 요소 생성
|
|
self.watermark_text_label = QLabel("회사 이름", self)
|
|
self.watermark_text_input = QLineEdit(self)
|
|
self.watermark_text_input.returnPressed.connect(self.update_watermark_text)
|
|
# self.watermark_confirm_button = QPushButton("확인", self)
|
|
|
|
# # 확인 버튼 클릭 시 watermark_text 업데이트
|
|
# self.watermark_confirm_button.clicked.connect(self.update_watermark_text)
|
|
|
|
# 최대 옵션수
|
|
self.max_option_count_label = QLabel("최대옵션수", self)
|
|
self.max_option_count_input = QSpinBox(self)
|
|
self.max_option_count_input.setMinimum(0) # 최소값 0
|
|
self.max_option_count_input.setMaximum(100) # 최대값 100
|
|
self.max_option_count_input.setValue(20) # 기본값 0
|
|
self.max_option_count_input.setToolTip("0으로 설정시 최대") # 툴팁 설정
|
|
self.max_option_count_input.valueChanged.connect(self.update_max_option_count) # 값 변경 시 update_max_option_count 메서드 호출
|
|
|
|
# 워터마크 투명도 설정
|
|
self.opacity_percent_label = QLabel("WM투명도", self)
|
|
self.opacity_percent_input = QSpinBox(self)
|
|
self.opacity_percent_input.setMinimum(0) # 최소값 0
|
|
self.opacity_percent_input.setMaximum(80) # 최대값 100
|
|
self.opacity_percent_input.setValue(25) # 기본값 0
|
|
self.opacity_percent_input.setToolTip("워터마크 투명도 설정: 낮을수록 투명") # 툴팁 설정
|
|
self.opacity_percent_input.valueChanged.connect(self.update_opacity_percent) # 값 변경 시 update_max_option_count 메서드 호출
|
|
|
|
# 워터마크 관련 요소들을 하나의 QHBoxLayout에 추가 (비율 2:3:1)
|
|
self.watermark_layout = QHBoxLayout()
|
|
|
|
# 초기 위치에서 배치
|
|
self.update_widget_positions(use_api_row=1)
|
|
|
|
|
|
# 초기에는 워터마크 입력창과 버튼 숨김
|
|
self.toggle_visibility(False, [(self.watermark_text_input, self.watermark_text_label), (self.opacity_percent_input, self.opacity_percent_label)])
|
|
|
|
|
|
# 관리자 토글
|
|
self.admin_toggle = ToggleSwitch(self)
|
|
self.admin_toggle.clicked.connect(self.on_admin_toggle_clicked)
|
|
|
|
# 관리자 ID 및 PW
|
|
self.admin_id_label = QLabel("관리자 ID:", self)
|
|
self.admin_id_input = QLineEdit(self)
|
|
|
|
# 관리자 PW
|
|
self.admin_pw_label = QLabel("관리자 PW:", self)
|
|
self.admin_pw_input = QLineEdit(self)
|
|
self.admin_pw_input.setEchoMode(QLineEdit.Password)
|
|
|
|
# 직원 ID 및 PW
|
|
self.user_id_label = QLabel("직원 ID:", self)
|
|
self.user_id_input = QLineEdit(self)
|
|
self.user_pw_label = QLabel("직원 PW:", self)
|
|
self.user_pw_input = QLineEdit(self)
|
|
self.user_pw_input.setEchoMode(QLineEdit.Password)
|
|
|
|
# 크롬 실행 버튼 및 번역 버튼
|
|
self.start_chrome_button = QPushButton('크롬 실행', self)
|
|
self.PercentyJob_button = QPushButton('상품수정 시작', self)
|
|
self.PercentyJob_button.setEnabled(False)
|
|
self.PercentyJob_button.setStyleSheet("""
|
|
QPushButton:disabled {
|
|
color: gray;
|
|
background-color: lightgray;
|
|
border: 1px solid gray;
|
|
}
|
|
""")
|
|
self.pause_button = QPushButton('일시정지', self)
|
|
self.pause_button.setEnabled(False)
|
|
self.pause_button.setStyleSheet("""
|
|
QPushButton:disabled {
|
|
color: gray;
|
|
background-color: lightgray;
|
|
border: 1px solid gray;
|
|
}
|
|
""")
|
|
self.cmb_button = QPushButton('크무비설정', self)
|
|
self.cmb_test_button = QPushButton('크무비테스트', self)
|
|
|
|
# 버튼 크기를 1.5배로 설정
|
|
button_height = int(self.start_chrome_button.sizeHint().height() * 1.5)
|
|
self.start_chrome_button.setFixedHeight(button_height)
|
|
self.PercentyJob_button.setFixedHeight(button_height)
|
|
self.pause_button.setFixedHeight(button_height)
|
|
self.cmb_button.setFixedHeight(button_height)
|
|
|
|
# 메인 레이아웃 설정
|
|
self.main_layout = QVBoxLayout()
|
|
|
|
# 관리자 토글 버튼 및 로그인 관련 필드 추가
|
|
self.admin_toggle_layout = QHBoxLayout()
|
|
self.admin_toggle_layout.addWidget(QLabel("관리자 여부:", self))
|
|
self.admin_toggle_layout.addWidget(self.admin_toggle)
|
|
self.main_layout.addLayout(self.admin_toggle_layout,1)
|
|
|
|
# 관리자 ID
|
|
self.main_layout.addWidget(self.admin_id_label)
|
|
self.main_layout.addWidget(self.admin_id_input)
|
|
|
|
# 관리자 PW
|
|
self.admin_layout = QVBoxLayout()
|
|
self.admin_layout.addWidget(self.admin_pw_label)
|
|
self.admin_layout.addWidget(self.admin_pw_input)
|
|
|
|
# 직원 ID/PW
|
|
self.user_layout = QVBoxLayout()
|
|
self.user_layout.addWidget(self.user_id_label)
|
|
self.user_layout.addWidget(self.user_id_input)
|
|
self.user_layout.addWidget(self.user_pw_label)
|
|
self.user_layout.addWidget(self.user_pw_input)
|
|
|
|
# 관리자와 직원 레이아웃을 메인 레이아웃에 추가
|
|
self.main_layout.addLayout(self.admin_layout,3)
|
|
self.main_layout.addLayout(self.user_layout,3)
|
|
|
|
# 크롬 및 번역 관련 버튼
|
|
self.button_layout = QHBoxLayout()
|
|
self.button_layout.addWidget(self.start_chrome_button)
|
|
self.button_layout.addWidget(self.PercentyJob_button)
|
|
self.button_layout.addWidget(self.pause_button)
|
|
self.button_layout.addWidget(self.cmb_button)
|
|
self.button_layout.addWidget(self.cmb_test_button)
|
|
|
|
# 로그 및 프로그레스바 레이아웃
|
|
self.log_layout = QVBoxLayout()
|
|
self.log_layout.addWidget(self.log)
|
|
self.log_layout.addWidget(self.total_progress_bar)
|
|
self.log_layout.addLayout(self.stageTimeline_layout)
|
|
self.log_layout.addWidget(self.detail_progress_bar)
|
|
|
|
# 메인 레이아웃에 버튼 레이아웃과 로그 레이아웃 추가
|
|
self.main_layout.addLayout(self.toggle_layout,2)
|
|
self.main_layout.addLayout(self.button_layout,2)
|
|
self.main_layout.addLayout(self.log_layout,5)
|
|
|
|
self.setLayout(self.main_layout)
|
|
|
|
# 기본 상태 설정
|
|
self.on_admin_toggle_clicked(False)
|
|
|
|
# 버튼 이벤트 연결
|
|
self.start_chrome_button.clicked.connect(self.start_browser_thread)
|
|
self.PercentyJob_button.clicked.connect(self.on_start_PercentyJob_clicked)
|
|
self.cmb_button.clicked.connect(self.on_cmb_button_clicked)
|
|
self.cmb_test_button.clicked.connect(self.on_cmb_test_button_clicked)
|
|
|
|
def load_toggle_settings(self):
|
|
"""QSettings에서 토글 상태 불러오기"""
|
|
for key, default_value in self.toggle_states.items():
|
|
|
|
# # opacity_percent와 max_option_count는 처리 제외
|
|
# if key in ["opacity_percent", "max_option_count"]:
|
|
# continue
|
|
|
|
# 데이터 타입을 각 항목의 기본값에 따라 결정
|
|
if isinstance(default_value, bool):
|
|
self.toggle_states[key] = self.settings.value(f"toggle/{key}", default_value, type=bool)
|
|
# elif isinstance(default_value, int):
|
|
# self.toggle_states[key] = self.settings.value(f"toggle/{key}", default_value, type=int)
|
|
# elif isinstance(default_value, str):
|
|
# self.toggle_states[key] = self.settings.value(f"toggle/{key}", default_value, type=str)
|
|
# else:
|
|
# # 기본값이 지정되지 않은 경우 bool로 처리
|
|
# self.toggle_states[key] = self.settings.value(f"toggle/{key}", False, type=bool)
|
|
|
|
self.update_toggle_ui(key)
|
|
|
|
def save_toggle_settings(self):
|
|
"""QSettings에 토글 상태 저장"""
|
|
for key, value in self.toggle_states.items():
|
|
self.settings.setValue(f"toggle/{key}", value)
|
|
# 상태가 변경되었을 때 UI를 업데이트
|
|
self.update_toggle_ui(key)
|
|
|
|
def update_toggle_ui(self, key):
|
|
"""토글 상태에 따라 UI 업데이트"""
|
|
# if hasattr(self, f"{key}_toggle"):
|
|
# toggle_widget = getattr(self, f"{key}_toggle")
|
|
|
|
toggle_widget = getattr(self, f"{key}_toggle", None)
|
|
|
|
# bool 타입인 경우
|
|
if isinstance(self.toggle_states[key], bool) and toggle_widget:
|
|
toggle_widget.setChecked(self.toggle_states[key])
|
|
|
|
# # int 타입인 경우
|
|
# elif isinstance(self.toggle_states[key], int):
|
|
# if hasattr(toggle_widget, "setValue"): # setValue 메서드 확인
|
|
# toggle_widget.setValue(self.toggle_states[key])
|
|
# print(f"int key : {key}")
|
|
|
|
# # str 타입인 경우
|
|
# elif isinstance(self.toggle_states[key], str):
|
|
# if key == "clientID":
|
|
# print(f"key : {key}, self.toggle_states[key] : {self.toggle_states[key]}")
|
|
# self.update_clientID(self.toggle_states[key])
|
|
# elif key == "clientSecret":
|
|
# # self.client_secret_input.setText(self.toggle_states[key])
|
|
# self.update_clientSecret(self.toggle_states[key])
|
|
# elif key == 'watermark':
|
|
# self.on_watermark_toggle_clicked(self.toggle_states[key])
|
|
# print(f"str key : {key}")
|
|
|
|
# # 워터마크와 관련된 추가 처리
|
|
# if key == 'watermark':
|
|
# self.on_watermark_toggle_clicked(self.toggle_states[key])
|
|
# elif key == 'opacity_percent':
|
|
# self.update_opacity_percent(self.toggle_states[key])
|
|
# elif key == 'max_option_count':
|
|
# self.update_max_option_count(self.toggle_states[key])
|
|
# elif key == 'clientID':
|
|
# print(f"self.toggle_states[clientID] : {self.toggle_states[key]}")
|
|
# self.update_clientID(self.toggle_states[key])
|
|
# elif key == 'clientSecret':
|
|
# print(f"self.toggle_states[clientSecret] : {self.toggle_states[key]}")
|
|
# self.update_clientSecret(self.toggle_states[key])
|
|
|
|
def on_watermark_toggle_clicked(self, is_checked):
|
|
"""워터마크 토글 여부에 따라 회사 이름 입력 필드와 확인 버튼을 표시/숨김"""
|
|
if is_checked:
|
|
self.watermark_text_label.setVisible(True)
|
|
self.watermark_text_input.setVisible(True)
|
|
self.opacity_percent_label.setVisible(True)
|
|
self.opacity_percent_input.setVisible(True)
|
|
|
|
# 워터마크 텍스트 입력 필드의 내용을 딕셔너리에 저장
|
|
self.toggle_states['watermark_text'] = self.watermark_text_input.text()
|
|
|
|
else:
|
|
self.watermark_text_label.setVisible(False)
|
|
self.watermark_text_input.setVisible(False)
|
|
self.opacity_percent_label.setVisible(False)
|
|
self.opacity_percent_input.setVisible(False)
|
|
|
|
def show_message(self, title: str, message: str):
|
|
"""
|
|
공통적으로 메시지 박스를 표시하는 메서드
|
|
:param title: 메시지 박스의 제목
|
|
:param message: 메시지 박스의 내용
|
|
"""
|
|
if not hasattr(self, "_message_box"):
|
|
self._message_box = QMessageBox(self) # 메시지 박스를 한 번만 생성
|
|
|
|
self._message_box.setIcon(QMessageBox.Information)
|
|
self._message_box.setWindowTitle(title)
|
|
self._message_box.setText(message)
|
|
self._message_box.setStandardButtons(QMessageBox.Ok)
|
|
self._message_box.exec_()
|
|
|
|
def update_client_id_input(self):
|
|
"""QLineEdit에 입력된 텍스트를 toggle_states['clientID']에 저장하고 메시지 표시"""
|
|
# clientID 저장
|
|
self.toggle_states['clientID'] = self.client_id_input.text()
|
|
self.logger.log(f"Updated client ID: {self.toggle_states['clientID']}", level=logging.DEBUG)
|
|
|
|
# 메시지 박스를 통해 업데이트 알림
|
|
self.show_message("클라이언트 ID 업데이트", "클라이언트 ID가 업데이트되었습니다.")
|
|
|
|
def update_client_secret_input(self):
|
|
"""QLineEdit에 입력된 텍스트를 toggle_states['clientSecret']에 저장하고 메시지 표시"""
|
|
# clientSecret 저장
|
|
self.toggle_states['clientSecret'] = self.client_secret_input.text()
|
|
self.logger.log(f"Updated client secret: {self.toggle_states['clientSecret']}", level=logging.DEBUG)
|
|
|
|
# 메시지 박스를 통해 업데이트 알림
|
|
self.show_message("클라이언트 Secret 업데이트", "클라이언트 Secret이 업데이트되었습니다.")
|
|
|
|
def update_watermark_text(self):
|
|
"""QLineEdit에 입력된 텍스트를 toggle_states['watermark_text']에 저장"""
|
|
self.toggle_states['watermark_text'] = self.watermark_text_input.text()
|
|
self.logger.log(f"Updated watermark text: {self.toggle_states['watermark_text']}", level=logging.DEBUG)
|
|
|
|
# 메시지 박스를 통해 업데이트 알림 (값 포함)
|
|
self.show_message(
|
|
"워터마크 텍스트 업데이트",
|
|
f"워터마크 텍스트가 업데이트되었습니다: {self.toggle_states['watermark_text']}"
|
|
)
|
|
|
|
def update_max_option_count(self, value):
|
|
"""QSpinBox에 입력된 값을 toggle_states['max_option_count']에 저장"""
|
|
self.toggle_states['max_option_count'] = value # 변경된 정수 값을 바로 저장
|
|
self.logger.log(f"최대 선택 가능 옵션 수 업데이트: {self.toggle_states['max_option_count']}", level=logging.DEBUG)
|
|
|
|
def update_opacity_percent(self, value):
|
|
"""QSpinBox에 입력된 값을 toggle_states['opacity_percent']에 저장"""
|
|
self.toggle_states['opacity_percent'] = value # 변경된 정수 값을 바로 저장
|
|
self.logger.log(f"워터마크 투명도 업데이트: {self.toggle_states['opacity_percent']}", level=logging.DEBUG)
|
|
|
|
def update_clientID(self, value):
|
|
self.toggle_states['clientID'] = value # 변경된 정수 값을 바로 저장
|
|
self.logger.log(f"clientID 업데이트: {self.toggle_states['clientID']}", level=logging.DEBUG)
|
|
|
|
def update_clientSecret(self, value):
|
|
# self.client_id_input.setText(self.toggle_states[value])
|
|
self.toggle_states['clientSecret'] = value # 변경된 정수 값을 바로 저장
|
|
self.logger.log(f"clientSecret 업데이트: {self.toggle_states['clientSecret']}", level=logging.DEBUG)
|
|
|
|
def update_watermark_visibility(self):
|
|
"""이미지 번역 토글 중 하나라도 켜져 있으면 워터마크 토글을 보이게 하고, visible이 되면 상태에 따라 레이아웃도 제어"""
|
|
if self.toggle_states['optionIMGTrans'] or self.toggle_states['detail_IMGTrans'] or self.toggle_states['thumb']:
|
|
# 이미지 번역 토글이 하나라도 켜져 있으면 워터마크 토글 보이기
|
|
self.toggle_visibility(True, [(self.watermark_toggle, self.watermark_toggle_label)])
|
|
|
|
# 워터마크 토글이 보이게 될 때 상태 확인
|
|
if self.watermark_toggle.isChecked():
|
|
# 워터마크 토글이 ON 상태이면 워터마크 레이아웃도 보이게 함
|
|
self.toggle_visibility(True, [(self.watermark_text_input, self.watermark_text_label), (self.opacity_percent_input, self.opacity_percent_label)])
|
|
else:
|
|
# 워터마크 토글이 OFF 상태이면 워터마크 레이아웃 숨김
|
|
self.toggle_visibility(False, [(self.watermark_text_input, self.watermark_text_label), (self.opacity_percent_input, self.opacity_percent_label)])
|
|
else:
|
|
# 모두 꺼져 있으면 워터마크 토글과 레이아웃 숨기기
|
|
self.toggle_visibility(False, [(self.watermark_toggle, self.watermark_toggle_label)])
|
|
self.toggle_visibility(False, [(self.watermark_text_input, self.watermark_text_label), (self.opacity_percent_input, self.opacity_percent_label)])
|
|
|
|
def toggle_visibility(self, is_checked, toggle_items):
|
|
"""
|
|
토글 상태에 따라 여러 필드의 visibility를 제어하는 범용 메서드
|
|
:param is_checked: 토글 상태 (True/False)
|
|
:param toggle_items: 토글 필드와 레이블 목록 [(필드, 레이블), ...]
|
|
"""
|
|
for item, label in toggle_items:
|
|
item.setVisible(is_checked)
|
|
if label:
|
|
label.setVisible(is_checked)
|
|
|
|
|
|
# def update_api_fields_visibility(self, is_checked):
|
|
# """
|
|
# use_API 토글 버튼 상태에 따라 clientID 및 clientSecretKey 필드를 보이거나 숨기는 메서드
|
|
# :param is_checked: use_API 토글 상태 (True/False)
|
|
# """
|
|
# self.toggle_visibility(is_checked, [
|
|
# (self.client_id_input, self.client_id_label),
|
|
# (self.client_secret_input, self.client_secret_label)
|
|
# ])
|
|
|
|
def update_widget_positions(self, use_api_row):
|
|
"""
|
|
위젯의 위치를 동적으로 업데이트 (재배치)
|
|
:param use_api_row: use_API 토글이 켜졌을 때 clientID와 clientSecret이 위치할 행
|
|
"""
|
|
current_row = use_api_row
|
|
|
|
# 1. use_API 관련 필드 위치 업데이트
|
|
self.toggle_layout.addWidget(self.client_id_label, current_row, 0)
|
|
self.toggle_layout.addWidget(self.client_id_input, current_row, 1, 1, 2)
|
|
self.toggle_layout.addWidget(self.client_secret_label, current_row, 3)
|
|
self.toggle_layout.addWidget(self.client_secret_input, current_row, 4, 1, 2)
|
|
|
|
current_row += 1
|
|
self.toggle_layout.addWidget(self.optionTrnas_toggle_label, current_row, 0)
|
|
self.toggle_layout.addWidget(self.optionTrnas_toggle, current_row, 1)
|
|
self.toggle_layout.addWidget(self.optionIMGTrans_toggle_label, current_row, 2)
|
|
self.toggle_layout.addWidget(self.optionIMGTrans_toggle, current_row, 3)
|
|
self.toggle_layout.addWidget(self.optionAutoSelect_toggle_label, current_row, 4)
|
|
self.toggle_layout.addWidget(self.optionAutoSelect_toggle, current_row, 5)
|
|
|
|
current_row += 1
|
|
self.toggle_layout.addWidget(self.price_toggle_label, current_row, 0)
|
|
self.toggle_layout.addWidget(self.price_toggle, current_row, 1)
|
|
self.toggle_layout.addWidget(self.tag_toggle_label, current_row, 2)
|
|
self.toggle_layout.addWidget(self.tag_toggle, current_row, 3)
|
|
self.toggle_layout.addWidget(self.thumb_toggle_label, current_row, 4)
|
|
self.toggle_layout.addWidget(self.thumb_toggle, current_row, 5)
|
|
|
|
current_row += 1
|
|
self.toggle_layout.addWidget(self.detail_Option_toggle_label, current_row, 0)
|
|
self.toggle_layout.addWidget(self.detail_Option_toggle, current_row, 1)
|
|
self.toggle_layout.addWidget(self.detail_IMGTrans_toggle_label, current_row, 2)
|
|
self.toggle_layout.addWidget(self.detail_IMGTrans_toggle, current_row, 3)
|
|
|
|
current_row += 1
|
|
self.toggle_layout.addWidget(self.debug_toggle_label, current_row, 0)
|
|
self.toggle_layout.addWidget(self.debug_toggle, current_row, 1)
|
|
self.toggle_layout.addWidget(self.ed_mode_toggle_label, current_row, 2)
|
|
self.toggle_layout.addWidget(self.ed_mode_toggle, current_row, 3)
|
|
|
|
current_row += 1
|
|
self.toggle_layout.addWidget(self.recovery_mode_toggle_label, current_row, 0)
|
|
self.toggle_layout.addWidget(self.recovery_mode_toggle, current_row, 1)
|
|
|
|
current_row += 1
|
|
self.toggle_layout.addWidget(self.watermark_toggle_label, current_row, 0)
|
|
self.toggle_layout.addWidget(self.watermark_toggle, current_row, 1)
|
|
self.toggle_layout.addWidget(self.watermark_text_label, current_row, 2)
|
|
self.toggle_layout.addWidget(self.watermark_text_input, current_row, 3)
|
|
self.toggle_layout.addWidget(self.opacity_percent_label, current_row, 4)
|
|
self.toggle_layout.addWidget(self.opacity_percent_input, current_row, 5)
|
|
# self.watermark_layout.addWidget(self.watermark_text_label, 2)
|
|
# self.watermark_layout.addWidget(self.watermark_text_input, 3)
|
|
# self.watermark_layout.addWidget(self.opacity_percent_label, 4)
|
|
# self.watermark_layout.addWidget(self.opacity_percent_input, 5)
|
|
# self.watermark_layout.addWidget(self.watermark_confirm_button, 1)
|
|
# self.toggle_layout.addWidget(self.opacity_percent_label, current_row, 2)
|
|
# self.toggle_layout.addWidget(self.opacity_percent_input, current_row, 3)
|
|
|
|
# self.toggle_layout.addLayout(self.watermark_layout, current_row, 0, 1, 4)
|
|
|
|
current_row += 1
|
|
self.toggle_layout.addWidget(self.max_option_count_label, current_row, 0)
|
|
self.toggle_layout.addWidget(self.max_option_count_input, current_row, 1)
|
|
|
|
def on_toggle_clicked_generic(self, key, is_checked):
|
|
"""토글 클릭 시 상태 업데이트 및 저장"""
|
|
self.toggle_states[key] = is_checked
|
|
|
|
if is_checked:
|
|
status_text = "활성화"
|
|
else:
|
|
status_text = "비활성화"
|
|
|
|
label_text = ""
|
|
|
|
# key에 따라 라벨 텍스트를 설정
|
|
if key == 'title':
|
|
label_text = self.title_toggle_label.text()
|
|
elif key == 'optionTrnas':
|
|
label_text = self.optionTrnas_toggle_label.text()
|
|
elif key == 'optionIMGTrans':
|
|
label_text = self.optionIMGTrans_toggle_label.text()
|
|
elif key == 'optionAutoSelect':
|
|
label_text = self.optionAutoSelect_toggle_label.text()
|
|
elif key == 'price':
|
|
label_text = self.price_toggle_label.text()
|
|
elif key == 'thumb':
|
|
label_text = self.thumb_toggle_label.text()
|
|
elif key == 'tag':
|
|
label_text = self.tag_toggle_label.text()
|
|
elif key == 'detail_Option':
|
|
label_text = self.detail_Option_toggle_label.text()
|
|
elif key == 'detail_IMGTrans':
|
|
label_text = self.detail_IMGTrans_toggle_label.text()
|
|
elif key == 'debug_mode':
|
|
label_text = self.debug_toggle_label.text()
|
|
# elif key == 'vd_mode':
|
|
# label_text = self.vd_mode_toggle_label.text()
|
|
elif key == 'recovery_mode':
|
|
label_text = self.recovery_mode_toggle_label.text()
|
|
elif key == 'ed_mode':
|
|
label_text = self.ed_mode_toggle_label.text()
|
|
elif key == 'use_API':
|
|
label_text = self.use_API_toggle_label.text()
|
|
elif key == 'watermark':
|
|
label_text = self.watermark_toggle_label.text()
|
|
|
|
# 이미지 번역 관련 토글이 하나라도 켜져 있으면 워터마크 토글 보이기
|
|
if key in ['optionIMGTrans', 'detail_IMGTrans', 'thumb']:
|
|
self.update_watermark_visibility()
|
|
|
|
# 워터마크 토글이 켜져 있으면 watermark_layout 보이기
|
|
if key == 'watermark':
|
|
self.toggle_visibility(is_checked, [
|
|
(self.watermark_text_input, self.watermark_text_label),
|
|
(self.opacity_percent_input, self.opacity_percent_label)
|
|
])
|
|
|
|
# key에 따라 라벨 텍스트를 설정
|
|
if key == 'use_API':
|
|
|
|
self.toggle_visibility(is_checked, [(self.client_id_input, self.client_id_label), (self.client_secret_input, self.client_secret_label)])
|
|
|
|
# label_text = self.use_API_toggle_label.text()
|
|
|
|
# use_API 토글 상태에 따라 clientID와 clientSecret 표시 여부
|
|
# self.client_id_label.setVisible(is_checked)
|
|
# self.client_id_input.setVisible(is_checked)
|
|
# self.client_secret_label.setVisible(is_checked)
|
|
# self.client_secret_input.setVisible(is_checked)
|
|
|
|
# 위젯 위치 업데이트
|
|
base_row = 1 if is_checked else 2
|
|
self.update_widget_positions(use_api_row=base_row)
|
|
|
|
self.logger.log(f"{label_text} 버튼 - {status_text} 선택", level=logging.DEBUG)
|
|
|
|
self.save_toggle_settings()
|
|
|
|
def on_admin_toggle_clicked(self, is_checked):
|
|
"""관리자 토글 상태에 따라 관리자와 직원 필드를 표시/숨김"""
|
|
if is_checked:
|
|
# 관리자 모드: 직원 레이아웃을 숨기고, 관리자 PW를 표시
|
|
self.set_layout_visibility(self.admin_layout, True)
|
|
self.set_layout_visibility(self.user_layout, False)
|
|
else:
|
|
# 직원 모드: 관리자 PW를 숨기고, 직원 레이아웃을 표시
|
|
self.set_layout_visibility(self.admin_layout, False)
|
|
self.set_layout_visibility(self.user_layout, True)
|
|
|
|
# def on_vd_mode_for_detail_imageTrans_clicked(self, is_checked):
|
|
# """상페이미지 번역여부에 따라 VD 모드 선택 필드를 표시/숨김"""
|
|
# if is_checked:
|
|
# self.vd_mode_toggle.setVisible(True)
|
|
# self.vd_mode_toggle_label.setVisible(True)
|
|
# else:
|
|
# self.vd_mode_toggle.setVisible(False)
|
|
# self.vd_mode_toggle_label.setVisible(False)
|
|
|
|
|
|
def set_layout_visibility(self, changelayout, visible):
|
|
"""레이아웃에 포함된 모든 위젯의 가시성을 설정"""
|
|
for i in range(changelayout.count()):
|
|
widget = changelayout.itemAt(i).widget()
|
|
if widget:
|
|
widget.setVisible(visible)
|
|
|
|
def on_cmb_test_button_clicked(self, test_cat):
|
|
"""크무비 설정 실행 버튼 클릭 시 호출"""
|
|
self.logger.log('크무비 테스트 버튼 클릭됨', level=logging.DEBUG)
|
|
|
|
text, ok = QInputDialog.getText(self, "카테고리 입력 테스트", "카테고리를 형식에 맞게 입력하세요:")
|
|
if ok and text: # 사용자가 확인 버튼을 누르고 텍스트를 입력한 경우
|
|
stage = self.cmb_diag.get_crmobi_stage(text)
|
|
self.logger.log(f"{stage}", level=logging.DEBUG)
|
|
|
|
def on_cmb_button_clicked(self):
|
|
"""크무비 설정 실행 버튼 클릭 시 호출"""
|
|
self.logger.log('크무비 설정 버튼 클릭됨', level=logging.DEBUG)
|
|
self.cmb_diag.show()
|
|
|
|
def save_settings(self):
|
|
"""QSettings에 사용자 정보 저장"""
|
|
self.logger.log(f"현재 설정을 저장합니다.", level=logging.DEBUG)
|
|
|
|
self.settings.setValue("admin/id", self.admin_id_input.text())
|
|
self.settings.setValue("admin/pw", self.admin_pw_input.text())
|
|
self.settings.setValue("user/id", self.user_id_input.text())
|
|
self.settings.setValue("user/pw", self.user_pw_input.text())
|
|
self.settings.setValue("admin/toggle", self.admin_toggle.isChecked())
|
|
self.settings.setValue("watermark_text", self.watermark_text_input.text())
|
|
self.settings.setValue("opacity_percent", self.opacity_percent_input.value())
|
|
self.settings.setValue("max_option_count", self.max_option_count_input.value())
|
|
|
|
self.settings.setValue("api/toggle", self.use_API_toggle.isChecked())
|
|
# API 필드 저장
|
|
if self.use_API_toggle.isChecked():
|
|
self.settings.setValue("api/client_id", self.client_id_input.text())
|
|
self.settings.setValue("api/client_secret", self.client_secret_input.text())
|
|
|
|
|
|
def load_settings(self):
|
|
"""QSettings에서 사용자 정보 불러오기"""
|
|
self.admin_id_input.setText(self.settings.value("admin/id", "", type=str))
|
|
self.admin_pw_input.setText(self.settings.value("admin/pw", "", type=str))
|
|
self.user_id_input.setText(self.settings.value("user/id", "", type=str))
|
|
self.user_pw_input.setText(self.settings.value("user/pw", "", type=str))
|
|
|
|
admin_toggle_state = self.settings.value("admin/toggle", False, type=bool)
|
|
self.admin_toggle.setChecked(admin_toggle_state)
|
|
self.on_admin_toggle_clicked(admin_toggle_state)
|
|
|
|
self.watermark_text_input.setText(self.settings.value("watermark_text", "", type=str))
|
|
self.toggle_states['watermark_text'] = self.watermark_text_input.text()
|
|
self.opacity_percent_input.setValue(self.settings.value("opacity_percent", 20, type=int))
|
|
self.toggle_states['opacity_percent'] = int(self.opacity_percent_input.text())
|
|
self.max_option_count_input.setValue(self.settings.value("max_option_count", 20, type=int))
|
|
self.toggle_states['max_option_count'] = int(self.max_option_count_input.text())
|
|
|
|
# self.update_opacity_percent(self.settings.value("opacity_percent", 20, type=int))
|
|
# self.update_max_option_count(self.settings.value("max_option_count", 10, type=int))
|
|
|
|
# use_API 토글 상태 로드
|
|
api_toggle_state = self.settings.value("api/toggle", False, type=bool)
|
|
self.use_API_toggle.setChecked(api_toggle_state)
|
|
|
|
# self.on_toggle_clicked_generic('use_API', api_toggle_state)
|
|
|
|
# API 필드 로드
|
|
self.client_id_input.setText(self.settings.value("api/client_id", "", type=str))
|
|
self.toggle_states['clientID'] = self.client_id_input.text()
|
|
self.client_secret_input.setText(self.settings.value("api/client_secret", "", type=str))
|
|
self.toggle_states['clientSecret'] = self.client_secret_input.text()
|
|
|
|
self.load_toggle_settings()
|
|
|
|
|
|
def get_toggle_states(self):
|
|
"""
|
|
현재 UI 상태를 기반으로 toggle_states를 업데이트하고 반환
|
|
:return: 업데이트된 toggle_states 딕셔너리
|
|
"""
|
|
# 각 토글 및 입력 필드 상태를 toggle_states에 업데이트
|
|
self.toggle_states['title'] = self.title_toggle.isChecked()
|
|
self.toggle_states['use_API'] = self.use_API_toggle.isChecked()
|
|
self.toggle_states['clientID'] = bool(self.client_id_input.text().strip())
|
|
self.toggle_states['clientSecret'] = bool(self.client_secret_input.text().strip())
|
|
self.toggle_states['optionTrnas'] = self.optionTrnas_toggle.isChecked()
|
|
self.toggle_states['optionIMGTrans'] = self.optionIMGTrans_toggle.isChecked()
|
|
self.toggle_states['optionAutoSelect'] = self.optionAutoSelect_toggle.isChecked()
|
|
self.toggle_states['price'] = self.price_toggle.isChecked()
|
|
self.toggle_states['thumb'] = self.thumb_toggle.isChecked()
|
|
self.toggle_states['tag'] = self.tag_toggle.isChecked()
|
|
self.toggle_states['detail_Option'] = self.detail_Option_toggle.isChecked()
|
|
self.toggle_states['detail_IMGTrans'] = self.detail_IMGTrans_toggle.isChecked()
|
|
self.toggle_states['debug_mode'] = self.debug_toggle.isChecked()
|
|
self.toggle_states['recovery_mode'] = self.recovery_mode_toggle.isChecked()
|
|
self.toggle_states['ed_mode'] = self.ed_mode_toggle.isChecked()
|
|
self.toggle_states['watermark'] = self.watermark_toggle.isChecked()
|
|
|
|
# 워터마크 텍스트, 투명도, 최대 옵션 수 업데이트
|
|
self.toggle_states['watermark_text'] = self.watermark_text_input.text()
|
|
self.toggle_states['opacity_percent'] = self.opacity_percent_input.value()
|
|
self.toggle_states['max_option_count'] = self.max_option_count_input.value()
|
|
|
|
# 업데이트된 toggle_states 반환
|
|
return self.toggle_states
|
|
|
|
|
|
|
|
def update_total_progress(self, current_value, total_value):
|
|
|
|
if current_value == 0:
|
|
self.total_progress_bar.setValue(0)
|
|
self.total_progress_bar.setFormat("상품 수정 대기") # current_value가 0일 때 표시될 텍스트
|
|
else:
|
|
# 프로그레스바의 값과 텍스트를 설정
|
|
percentage = int((current_value / total_value) * 100)
|
|
self.total_progress_bar.setValue(percentage)
|
|
self.total_progress_bar.setFormat(f"상품 {current_value}/{total_value}개 완료 [{percentage}%]")
|
|
|
|
def update_detail_progress(self, current_value, total_value):
|
|
|
|
if current_value == 0:
|
|
self.detail_progress_bar.setValue(0)
|
|
self.detail_progress_bar.setFormat("수정 대기") # current_value가 0일 때 표시될 텍스트
|
|
else:
|
|
# 프로그레스바의 값과 텍스트를 설정
|
|
percentage = int((current_value / total_value) * 100)
|
|
self.detail_progress_bar.setValue(percentage)
|
|
self.detail_progress_bar.setFormat(f"{current_value}/{total_value}개 완료 [{percentage}%]")
|
|
|
|
|
|
@Slot()
|
|
def start_browser_thread(self):
|
|
"""브라우저 스레드 시작 및 GUI 상태 전달"""
|
|
self.browser_controller.start()
|
|
|
|
time.sleep(1)
|
|
|
|
if self.browser_controller.isRunning():
|
|
# 스레드를 처음 시작하여 이벤트 루프를 실행
|
|
# self.browser_controller.start() # QThread의 start() 호출로 run() 실행
|
|
self.logger.log("브라우저 스레드가 시작되었습니다.", level=logging.DEBUG)
|
|
|
|
self.browser_controller.login_infos = {
|
|
'admin_id': self.admin_id_input.text(),
|
|
'admin_pw': self.admin_pw_input.text(),
|
|
'user_id': self.user_id_input.text(),
|
|
'user_pw': self.user_pw_input.text(),
|
|
'is_admin': self.admin_toggle.isChecked(),
|
|
}
|
|
|
|
# 로그인 정보 저장
|
|
self.save_settings()
|
|
|
|
# 스레드 시작
|
|
self.browser_controller.start_browser_task()
|
|
else:
|
|
self.logger.log("브라우저 스레드가 실행중이지 않습니다.", level=logging.WARNING)
|
|
|
|
@Slot()
|
|
def on_browser_started(self):
|
|
"""브라우저 시작 완료 시 처리할 로직"""
|
|
self.logger.log("브라우저가 성공적으로 시작되었습니다.", level=logging.INFO)
|
|
# 버튼 상태 활성화&비활성화
|
|
self.PercentyJob_button.setEnabled(True)
|
|
self.pause_button.setEnabled(True)
|
|
self.start_chrome_button.setEnabled(False)
|
|
|
|
@Slot(str)
|
|
def on_browser_error(self, error_message):
|
|
"""브라우저 오류 발생 시 처리할 로직"""
|
|
self.logger.log(f"브라우저 시작 중 오류 발생: {error_message}", level=logging.ERROR)
|
|
|
|
def closeEvent(self, event):
|
|
"""창 닫기 시 스레드 종료"""
|
|
self.logger.log('프로그램을 종료합니다...', level=logging.INFO)
|
|
self.save_settings()
|
|
|
|
if self.browser_controller.isRunning():
|
|
self.browser_controller.stop() # 리소스 정리
|
|
self.browser_controller.wait() # 스레드가 종료될 때까지 대기
|
|
event.accept()
|
|
|
|
# def close(self):
|
|
# self.logger.log('프로그램을 종료합니다...', level=logging.INFO)
|
|
# self.save_settings()
|
|
# asyncio.run(self.browser_controller.close_browser()) # 브라우저 종료
|
|
# super().close()
|
|
|
|
|
|
@Slot()
|
|
def on_start_PercentyJob_clicked(self):
|
|
"""상품수정 스레드 시작 및 상태 전달"""
|
|
if self.browser_controller.isRunning():
|
|
# 스레드 시작
|
|
self.browser_controller.start_PercentyJob_task()
|
|
self.logger.log("상품수정 작업 스레드가 시작되었습니다.", level=logging.INFO)
|
|
else:
|
|
self.logger.log("브라우저 스레드가 없습니다.", level=logging.INFO)
|
|
|
|
|
|
@Slot()
|
|
def on_PercentyJob_started(self):
|
|
"""상품수정 시작 완료 시 처리할 로직"""
|
|
self.logger.log("상품수정 작업이 성공적으로 시작되었습니다.", level=logging.INFO)
|
|
self.PercentyJob_button.setEnabled(False)
|
|
|
|
@Slot()
|
|
def on_PercentyJob_completed(self):
|
|
"""상품수정 완료 시 처리할 로직"""
|
|
self.logger.log("상품수정 작업이 완료되었습니다.", level=logging.INFO)
|
|
self.PercentyJob_button.setEnabled(True)
|
|
|
|
@Slot(str)
|
|
def on_PercentyJob_error(self, error_message):
|
|
"""상품수정 중 오류 발생 시 처리할 로직"""
|
|
self.logger.log(f"상품수정 작업 중 오류 발생: {error_message}", level=logging.ERROR)
|
|
self.PercentyJob_button.setEnabled(True)
|
|
|
|
@Slot(bool)
|
|
def set_progress_visibility(self, visible):
|
|
self.detail_progress_bar.setVisible(visible)
|
|
self.detail_progress_bar.setValue(0)
|
|
|
|
@Slot(bool)
|
|
def update_detail_progress_value(self, current, total):
|
|
self.update_detail_progress(current, total)
|
|
|
|
@Slot(bool)
|
|
def percentyJob_button_Enable(self, Enable):
|
|
self.PercentyJob_button.setEnabled(Enable)
|