297 lines
14 KiB
Python
297 lines
14 KiB
Python
import sqlite3
|
|
from PyQt5 import QtWidgets, QtGui
|
|
from PyQt5.QtGui import QPixmap
|
|
from PyQt5.QtCore import QUrl
|
|
from PyQt5.QtWebEngineWidgets import QWebEngineView
|
|
from PyQt5.QtWidgets import QGraphicsScene, QGraphicsPixmapItem
|
|
from PyQt5 import QtCore
|
|
from PyQt5.Qt import QDesktopServices, QUrl
|
|
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
|
|
import os
|
|
from PyQt5.QtCore import QFile, QIODevice
|
|
from googletrans import Translator
|
|
import logging
|
|
|
|
# 로거 인스턴스 가져오기
|
|
logger = logging.getLogger('default_logger')
|
|
|
|
|
|
class TaoCard:
|
|
def __init__(self, ui):
|
|
self.ui = ui
|
|
self.setup()
|
|
self.itemUrl = None
|
|
self.itemID = None
|
|
|
|
self.translator = Translator()
|
|
|
|
def setup(self):
|
|
# link_btn_1, select_btn_1 등에 대한 이벤트 핸들러 연결
|
|
self.ui.link_btn_1.clicked.connect(lambda: self.on_link_btn_clicked(self.itemUrl))
|
|
self.ui.link_btn_2.clicked.connect(lambda: self.on_link_btn_clicked(self.itemUrl))
|
|
self.ui.link_btn_3.clicked.connect(lambda: self.on_link_btn_clicked(self.itemUrl))
|
|
self.ui.link_btn_4.clicked.connect(lambda: self.on_link_btn_clicked(self.itemUrl))
|
|
self.ui.link_btn_5.clicked.connect(lambda: self.on_link_btn_clicked(self.itemUrl))
|
|
self.ui.select_btn_1.clicked.connect(lambda: self.on_select_btn_clicked(self.itemID))
|
|
self.ui.select_btn_2.clicked.connect(lambda: self.on_select_btn_clicked(self.itemID))
|
|
self.ui.select_btn_3.clicked.connect(lambda: self.on_select_btn_clicked(self.itemID))
|
|
self.ui.select_btn_4.clicked.connect(lambda: self.on_select_btn_clicked(self.itemID))
|
|
self.ui.select_btn_5.clicked.connect(lambda: self.on_select_btn_clicked(self.itemID))
|
|
|
|
# 다른 컴포넌트들도 필요에 따라 이벤트 핸들러를 연결할 수 있습니다.
|
|
|
|
def load_images_by_keyword_ids(self, records):
|
|
"""
|
|
주어진 keyword_id에 해당하는 Taobao 테이블의 레코드를 가져와서
|
|
UI의 QLineEdit 및 QGraphicsView 위젯에 정보를 업데이트합니다.
|
|
"""
|
|
|
|
try:
|
|
self.initialize_ui_elements()
|
|
|
|
# # 아이템 이름들을 엔터로 구분하여 하나의 긴 텍스트로 합칩니다.
|
|
# item_names_combined = "\n".join(record[1] for record in records[:5])
|
|
|
|
# # 합친 텍스트를 번역합니다.
|
|
# translated_text = self.trans(item_names_combined)
|
|
|
|
# # 번역된 결과를 엔터 기준으로 분리하여 리스트로 변환합니다.
|
|
# trans_item_names = translated_text.split('\n')
|
|
|
|
|
|
for i, record in enumerate(records[:5]):
|
|
|
|
logger.debug(f"현재 인덱스 : {i}")
|
|
item_name, price, sales_volume, imageUrl, itemUrl, itemID, tao_localimage = record[1:8]
|
|
getattr(self.ui, f'sel_itembox_title_{i+1}').setText(item_name)
|
|
|
|
# trans_item_name = self.trans(item_name)
|
|
# getattr(self.ui, f'sel_itembox_title_{i+1}').setText(trans_item_name)
|
|
|
|
# getattr(self.ui, f'sel_itembox_title_{i+1}').setText(trans_item_names[i])
|
|
getattr(self.ui, f'sel_itembox_title_{i+1}').setCursorPosition(0)
|
|
getattr(self.ui, f'sel_itembox_price_{i+1}').setText(str(price))
|
|
getattr(self.ui, f'sel_itembox_price_{i+1}').setCursorPosition(0)
|
|
getattr(self.ui, f'sel_itembox_pur_{i+1}').setText(str(sales_volume))
|
|
getattr(self.ui, f'sel_itembox_pur_{i+1}').setCursorPosition(0)
|
|
getattr(self.ui, f'sel_itembox_id_{i+1}').setText(str(itemID))
|
|
getattr(self.ui, f'sel_itembox_id_{i+1}').setCursorPosition(0)
|
|
|
|
logger.debug(f"{i}번째 이미지 업데이트 시도 ")
|
|
# self.update_image_widget(getattr(self.ui, f'current_img_{i+1}'), tao_localimage)
|
|
|
|
if tao_localimage:
|
|
# tao_localimage에 저장된 이미지 경로를 사용하여 이미지를 표시
|
|
self.update_image_widget_from_path(getattr(self.ui, f'current_img_{i+1}'), tao_localimage)
|
|
else:
|
|
# tao_localimage가 비어있는 경우, 기본 이미지 표시 또는 경고 로그 출력
|
|
logger.debug(f"No local image path for item {record[6]}")
|
|
|
|
# 링크 버튼에 대한 클릭 이벤트 처리
|
|
link_btn = getattr(self.ui, f'link_btn_{i+1}')
|
|
# logger.debug(f"선택된 링크버튼 ID : {link_btn}")
|
|
|
|
try:
|
|
link_btn.clicked.disconnect() # 이전에 연결된 모든 시그널을 해제
|
|
except TypeError:
|
|
pass # 이미 연결된 시그널이 없는 경우 무시
|
|
link_btn.clicked.connect(lambda _, url=itemUrl: self.on_link_btn_clicked(url)) # 새로운 시그널 연결
|
|
# logger.debug(f"선택된 링크버튼 시그널 연결 완료")
|
|
|
|
# 선택 버튼에 대한 클릭 이벤트 처리
|
|
select_btn = getattr(self.ui, f'select_btn_{i+1}')
|
|
# logger.debug(f"선택된 선택버튼 ID : {select_btn}")
|
|
try:
|
|
select_btn.clicked.disconnect() # 이전에 연결된 모든 시그널을 해제
|
|
except TypeError:
|
|
pass # 이미 연결된 시그널이 없는 경우 무시
|
|
select_btn.clicked.connect(lambda _, id=itemID: self.on_select_btn_clicked(id)) # 새로운 시그널 연결
|
|
# logger.debug(f"선택된 선택버튼 시그널 연결 완료")
|
|
|
|
|
|
# conn.close()
|
|
except Exception as e:
|
|
logger.debug(f"데이터 로드 중 오류: {e}")
|
|
|
|
|
|
def initialize_ui_elements(self):
|
|
"""
|
|
UI의 QLineEdit 및 QGraphicsView 위젯을 초기 상태로 설정합니다.
|
|
"""
|
|
try:
|
|
# 최대 5개의 아이템을 처리한다고 가정하고, 각 아이템에 대한 위젯을 초기화합니다.
|
|
for i in range(1, 6): # 1부터 5까지의 인덱스 사용
|
|
getattr(self.ui, f'sel_itembox_title_{i}').clear() # 제목 초기화
|
|
getattr(self.ui, f'sel_itembox_price_{i}').clear() # 가격 초기화
|
|
getattr(self.ui, f'sel_itembox_pur_{i}').clear() # 구매량 초기화
|
|
getattr(self.ui, f'sel_itembox_id_{i}').clear() # 아이템 ID 초기화
|
|
# 이미지 위젯 초기화를 위한 추가적인 메서드가 필요할 수 있습니다.
|
|
# 예를 들어, `clear_image_widget`라는 메서드를 정의하고 호출할 수 있습니다.
|
|
self.clear_image_widget(getattr(self.ui, f'current_img_{i}'))
|
|
|
|
# 링크 버튼과 선택 버튼의 연결을 해제할 수도 있습니다.
|
|
# 하지만 이들은 데이터 로드 시마다 새로 연결되므로, 필요에 따라 선택적으로 수행합니다.
|
|
link_btn = getattr(self.ui, f'link_btn_{i}')
|
|
select_btn = getattr(self.ui, f'select_btn_{i}')
|
|
try:
|
|
link_btn.clicked.disconnect()
|
|
except TypeError:
|
|
pass # 연결된 시그널이 없으면 무시
|
|
try:
|
|
select_btn.clicked.disconnect()
|
|
except TypeError:
|
|
pass # 연결된 시그널이 없으면 무시
|
|
|
|
except Exception as e:
|
|
logger.debug(f"UI 요소 초기화 중 오류: {e}")
|
|
|
|
def clear_image_widget(self, image_widget):
|
|
"""
|
|
QGraphicsView 위젯을 초기화합니다.
|
|
|
|
Parameters:
|
|
image_widget (QGraphicsView): 초기화할 이미지 위젯
|
|
"""
|
|
# 새로운 빈 QGraphicsScene 생성
|
|
empty_scene = QGraphicsScene()
|
|
# QGraphicsView 위젯에 새로운 빈 scene 설정
|
|
image_widget.setScene(empty_scene)
|
|
|
|
def update_image_widget_1(self, widget, imageUrl):
|
|
"""
|
|
QGraphicsView 위젯에 이미지를 업데이트합니다.
|
|
imageUrl로부터 이미지를 로드하여 QGraphicsScene에 추가합니다.
|
|
"""
|
|
scene = QGraphicsScene(self)
|
|
pixmap = QPixmap(imageUrl)
|
|
item = QGraphicsPixmapItem(pixmap)
|
|
scene.addItem(item)
|
|
widget.setScene(scene)
|
|
widget.show()
|
|
|
|
def on_link_btn_clicked_for_webView2(self, itemUrl):
|
|
"""
|
|
link_btn이 클릭되었을 때 QWebEngineView 객체의 URL을 업데이트합니다.
|
|
"""
|
|
if itemUrl: # itemUrl이 설정되어 있는 경우에만 처리
|
|
logger.debug(f"Opening URL: {itemUrl}")
|
|
self.ui.webEngineView_2.setUrl(QUrl(itemUrl)) # webEngineView_2는 QWebEngineView의 인스턴스입니다.
|
|
self.ui.webEngineView_2.setFocus()
|
|
|
|
def on_select_btn_clicked(self, itemID):
|
|
"""
|
|
select_btn이 클릭되었을 때 match() 함수를 호출합니다.
|
|
"""
|
|
logger.debug(f"on_select_btn_clicked 동작 itemID: {itemID}")
|
|
if itemID: # itemID 설정되어 있는 경우에만 처리
|
|
logger.debug(f"Processing itemID: {itemID}")
|
|
self.ui.tao_card_match(itemID) # match는 이미 정의된 함수라고 가정합니다.
|
|
|
|
# def update_item_url(self, itemUrl):
|
|
# # 현재 선택된 항목의 URL을 업데이트하는 메소드
|
|
# self.itemUrl = itemUrl
|
|
|
|
# def update_item_ID(self, itemID):
|
|
# # 현재 선택된 항목의 URL을 업데이트하는 메소드
|
|
# self.itemID = itemID
|
|
|
|
def on_link_btn_clicked(self, itemUrl):
|
|
"""
|
|
링크 버튼 클릭 시 해당 URL을 웹 브라우저에서 열어줍니다.
|
|
"""
|
|
QDesktopServices.openUrl(QUrl(itemUrl))
|
|
|
|
def update_image_widget(self, widget, imageUrl):
|
|
"""
|
|
QGraphicsView 위젯에 이미지를 업데이트합니다.
|
|
imageUrl로부터 이미지를 로드하여 QGraphicsScene에 추가합니다.
|
|
HTTP 요청 시 헤더를 설정하여 이미지를 가져옵니다.
|
|
"""
|
|
manager = QNetworkAccessManager()
|
|
request = QNetworkRequest(QUrl(imageUrl))
|
|
|
|
|
|
# 주어진 헤더 정보를 사용하여 HTTP 요청 헤더 설정
|
|
headers = {
|
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36",
|
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
|
|
"Accept-Language": "en-US,en;q=0.9",
|
|
"Accept-Encoding": "gzip, deflate, br",
|
|
"DNT": "1", # Do Not Track 요청 헤더
|
|
"Connection": "keep-alive",
|
|
"Upgrade-Insecure-Requests": "1", # https로의 업그레이드를 요청
|
|
"Cache-Control": "max-age=0", # 캐시된 콘텐츠를 재사용하지 않도록 요청
|
|
}
|
|
|
|
for header, value in headers.items():
|
|
request.setRawHeader(header.encode('utf-8'), value.encode('utf-8'))
|
|
|
|
manager.finished.connect(lambda reply, w=widget, url=imageUrl: self.on_image_loaded(reply, w, url))
|
|
manager.get(request)
|
|
|
|
def on_image_loaded(self, reply, widget):
|
|
data = reply.readAll()
|
|
pixmap = QPixmap()
|
|
if pixmap.loadFromData(data):
|
|
scene = QGraphicsScene()
|
|
item = QGraphicsPixmapItem(pixmap)
|
|
scene.addItem(item)
|
|
widget.setScene(scene)
|
|
widget.fitInView(item, QtCore.Qt.KeepAspectRatio)
|
|
widget.show()
|
|
|
|
|
|
def download_image(self, imageUrl, savePath):
|
|
def on_finished(reply):
|
|
os.makedirs(os.path.dirname(savePath), exist_ok=True)
|
|
if reply.error():
|
|
logger.debug(f"Download error: {reply.errorString()}")
|
|
return
|
|
with open(savePath, 'wb') as file:
|
|
file.write(reply.readAll())
|
|
self.update_image_widget_from_path(getattr(self.ui, f'current_img_{i+1}'), savePath)
|
|
|
|
manager = QNetworkAccessManager()
|
|
request = QNetworkRequest(QUrl(imageUrl))
|
|
reply = manager.get(request)
|
|
reply.finished.connect(lambda: on_finished(reply))
|
|
|
|
def update_image_widget_from_path(self, widget, imagePath):
|
|
pixmap = QPixmap(imagePath)
|
|
if not pixmap.isNull():
|
|
scene = QGraphicsScene()
|
|
item = QGraphicsPixmapItem(pixmap)
|
|
scene.addItem(item)
|
|
widget.setScene(scene)
|
|
widget.fitInView(item, QtCore.Qt.KeepAspectRatio)
|
|
widget.show()
|
|
else:
|
|
logger.debug("Failed to load the image from path")
|
|
|
|
|
|
def update_image_widget_from_path(self, widget, imagePath):
|
|
"""
|
|
로컬 경로에서 이미지를 불러와 QGraphicsView 위젯에 표시합니다.
|
|
"""
|
|
pixmap = QPixmap(imagePath)
|
|
if not pixmap.isNull():
|
|
scene = QGraphicsScene()
|
|
item = QGraphicsPixmapItem(pixmap)
|
|
scene.addItem(item)
|
|
widget.setScene(scene)
|
|
widget.fitInView(item, QtCore.Qt.KeepAspectRatio)
|
|
widget.show()
|
|
else:
|
|
logger.debug(f"Failed to load the image from path: {imagePath}")
|
|
|
|
# def trans(self, itemName):
|
|
# logger.debug(f"번역대상 : {itemName}")
|
|
# return None
|
|
|
|
def trans(self, text):
|
|
# Initialize the Translator
|
|
# Translate the text from Chinese to Korean
|
|
translated = self.translator.translate(text, src='zh-cn', dest='ko')
|
|
|
|
# Return the translated text
|
|
return translated.text |