워터마크 텍스트 기본값을 빈 문자열로 변경하고, 옵션 핸들러에서 라벨 클릭 시 detach 문제를 완화하기 위한 재시도 로직을 추가하였습니다. 이미지 프로세서에서 워터마크 텍스트 크기가 0일 경우 추가를 건너뛰도록 수정하였습니다.

This commit is contained in:
Envy_PC 2025-07-25 08:25:14 +09:00
parent c5d8d4ee4d
commit fc5cef689b
4 changed files with 53 additions and 30 deletions

View File

@ -1088,7 +1088,7 @@ class MAIN_GUI(QMainWindow):
'clientID': "",
'clientSecret': "",
'discord_webhook': "",
'watermark_text': "구대",
'watermark_text': "",
'thumb_rmb_count': 1,
'max_option_count': 20,
'opacity_percent': 20,

View File

@ -1147,20 +1147,28 @@ class OptionHandler:
if should_checked and is_excluded:
label_elem = await element.query_selector("label.ant-checkbox-wrapper")
if label_elem:
await label_elem.click()
# ElementHandle 대신 Locator를 사용하여 detach 문제를 완화하고, 실패 시 재시도
if label_elem:
# Locator 재생성 함수
async def _get_label_locator(idx: int):
return self.page.locator(
"div#productMainContentContainerId div.ant-collapse-content-box li.ant-list-item[aria-roledescription='sortable']"
).nth(idx).locator("label.ant-checkbox-wrapper")
# 상태 변화 기다리며, 최대 1초 대기
for _ in range(5):
await asyncio.sleep(0.2)
span_elems = await element.query_selector_all("span")
after_is_excluded = False
for span in span_elems:
text = (await span.inner_text()).strip()
if text == "제외된 옵션":
after_is_excluded = True
break
if not after_is_excluded:
break
retries = 3
for attempt in range(retries):
try:
label_locator = await _get_label_locator(idx)
await label_locator.scroll_into_view_if_needed()
await label_locator.click(timeout=2000)
break # 성공
except Exception as e:
if "not attached" in str(e) or "detached" in str(e):
self.logger.log(f"옵션[{idx}] 라벨 클릭 실패(detached) 재시도 {attempt+1}/{retries}", level=logging.WARNING)
await asyncio.sleep(0.3)
continue # 재시도
else:
raise
item["is_excluded"] = after_is_excluded
if after_is_excluded:
@ -1172,20 +1180,28 @@ class OptionHandler:
elif should_excluded and not is_excluded:
label_elem = await element.query_selector("label.ant-checkbox-wrapper")
if label_elem:
await label_elem.click()
# ElementHandle 대신 Locator를 사용하여 detach 문제를 완화하고, 실패 시 재시도
if label_elem:
# Locator 재생성 함수
async def _get_label_locator(idx: int):
return self.page.locator(
"div#productMainContentContainerId div.ant-collapse-content-box li.ant-list-item[aria-roledescription='sortable']"
).nth(idx).locator("label.ant-checkbox-wrapper")
# 상태 변화 기다리며, 최대 1초 대기
for _ in range(5):
await asyncio.sleep(0.2)
span_elems = await element.query_selector_all("span")
after_is_excluded = False
for span in span_elems:
text = (await span.inner_text()).strip()
if text == "제외된 옵션":
after_is_excluded = True
break
if after_is_excluded:
break
retries = 3
for attempt in range(retries):
try:
label_locator = await _get_label_locator(idx)
await label_locator.scroll_into_view_if_needed()
await label_locator.click(timeout=2000)
break # 성공
except Exception as e:
if "not attached" in str(e) or "detached" in str(e):
self.logger.log(f"옵션[{idx}] 라벨 클릭 실패(detached) 재시도 {attempt+1}/{retries}", level=logging.WARNING)
await asyncio.sleep(0.3)
continue # 재시도
else:
raise
item["is_excluded"] = after_is_excluded
if not after_is_excluded:

View File

@ -107,13 +107,19 @@ class PostImageManager:
# 이미지 크기
width, height = image_data.size
# 지그재그 간격 설정
zigzag_step = int(text_height * 2) # Y축의 지그재그 간격
# 텍스트 크기가 0이면 워터마크를 건너뜀 (range 스텝 0 방지)
if text_width == 0 or text_height == 0:
self.logger.log("워터마크 텍스트 크기가 0으로 계산되어 워터마크 추가를 건너뜁니다.", level=logging.WARNING)
return image_data
# 지그재그 간격 및 반복 간격 설정 (최소 1 보장)
zigzag_step = max(1, int(text_height * 2)) # Y축 간격
x_step = max(1, int(text_width * 3)) # X축 간격
# 이미지 전체에 반복적으로 워터마크 텍스트 그리기 (지그재그 형태)
for y in range(0, height, zigzag_step):
for x in range(0, width, int(text_width * 3)): # 3배 너비 간격으로 반복
for x in range(0, width, x_step): # 반복 간격에 x_step 사용
# 텍스트가 한 줄씩 지그재그 형태로 X축을 교차하여 이동
x_offset = (y // zigzag_step) % 2 * int(text_width * 1.5) # 짝수 행에서는 X축을 약간 이동

View File

@ -14,6 +14,7 @@
### 기능 추가
- 이미지번역(옵션/섬네일/상세페이지)에서 대체번역 완전제외
- 가격설정(크무비포함)의 가격범위 최대 100만원 -> 1000만원 으로 변경
- 기본 워터마크 글자제거