tao2/modules/tao_card.py

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