219 lines
11 KiB
Python
219 lines
11 KiB
Python
import sys
|
|
from PyQt5.QtWidgets import QSizePolicy, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QGridLayout
|
|
from PyQt5.QtGui import QPixmap
|
|
from PyQt5.QtCore import Qt
|
|
# from PyQt5.Qt import QDesktopServices
|
|
import webbrowser
|
|
import requests
|
|
from PIL import Image
|
|
from io import BytesIO
|
|
import asyncio, aiofiles, aiohttp
|
|
import logging
|
|
|
|
# 로거 인스턴스 가져오기
|
|
logger = logging.getLogger('default_logger')
|
|
class ResultWidget(QWidget):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.initUI()
|
|
|
|
def initUI(self):
|
|
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
|
|
|
|
def show_results(self, results, searchType, elapsed_time, currentURL=''):
|
|
searchType = searchType
|
|
elapsed_time = elapsed_time
|
|
currentURL = currentURL
|
|
logger.debug(f"show_results - searchType : {searchType}")
|
|
logger.debug(f"show_results - elapsed_time : {elapsed_time}")
|
|
# try:
|
|
# 결과 위젯 생성
|
|
self.results_widget = QWidget()
|
|
layout = QVBoxLayout()
|
|
self.results_widget.setLayout(layout)
|
|
|
|
# 결과 갯수 확인 및 레이아웃 동적 생성
|
|
total_count = int(results['total_count'])
|
|
set_count = min(total_count, 10)
|
|
grid_layout = QGridLayout()
|
|
layout.addLayout(grid_layout)
|
|
grid_index = 0
|
|
grid_columns = 5
|
|
logger.debug(f"show_results - set_count : {set_count}")
|
|
|
|
for i in range(1, set_count + 1):
|
|
result_key = f"result_{i}"
|
|
if result_key in results:
|
|
result = results[result_key]
|
|
logger.debug(f"show_results - result_key : {result_key}")
|
|
|
|
# 테두리 설정
|
|
border_style = ''
|
|
if result['application_status'] == '등록':
|
|
border_style = 'border: 4px solid red;'
|
|
elif result['application_status'] == '공고':
|
|
border_style = 'border: 3px solid black;'
|
|
|
|
# 각 결과에 대한 레이아웃 생성
|
|
item_layout = QVBoxLayout()
|
|
item_widget = QWidget() # 위젯 생성
|
|
|
|
# item_layout의 크기 정책 설정
|
|
item_widget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding)
|
|
|
|
# 이미지 처리
|
|
image_label = QLabel()
|
|
image_label.setFixedSize(150, 150)
|
|
image_data = self.fetch_image_data(result['drawing_url'])
|
|
pixmap = QPixmap()
|
|
pixmap.loadFromData(image_data)
|
|
# QLabel의 크기에 맞게 이미지 크기 조정
|
|
scaled_pixmap = pixmap.scaled(image_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
image_label.setPixmap(scaled_pixmap)
|
|
# QLabel의 가로 세로 중앙에 이미지 표시
|
|
image_label.setAlignment(Qt.AlignCenter)
|
|
# 이미지 표시 위젯의 크기 조정 정책 설정
|
|
image_label.setScaledContents(True)
|
|
|
|
#이미지 중앙배치를 위해
|
|
horizontal_layout = QHBoxLayout()
|
|
horizontal_layout.addWidget(image_label)
|
|
horizontal_layout.setAlignment(Qt.AlignCenter)
|
|
item_layout.addLayout(horizontal_layout)
|
|
|
|
# item_layout.addWidget(image_label)
|
|
|
|
if searchType =='api':
|
|
# API 정보 텍스트
|
|
# info_text = f"상표권명: {result['title']}\n등록상태: {result['admin_status']}\nCategory: {result['product_category']}\nApplicant: {result['applicant']}\nPublication Date: {result['publication_date']}\nRegistration Date: {result['registration_date']}"
|
|
info_text = f"<span style='font-size: 11pt; font-weight: bold; text-decoration: underline;'>상표권명: {result['title']}</span><br>\n" \
|
|
f"<span style='font-size: 11pt; font-weight: bold; text-decoration: underline;'>등록상태: {result['application_status']}</span><br>\n" \
|
|
f"<span style='font-size: 9pt;'>카테고리: {result['classification_code']}</span><br>\n" \
|
|
f"<span style='font-size: 9pt;'>권리자: {result['applicant_name']}</span><br>\n" \
|
|
f"<span style='font-size: 9pt;'>출원일자 {result['application_date']}</span><br>\n" \
|
|
f"<span style='font-size: 9pt;'>공고일자 {result['publication_date']}</span><br>\n" \
|
|
f"<span style='font-size: 9pt;'>등록일자 {result['registration_date']}</span>\n" \
|
|
f"<span style='font-size: 9pt;'>전문 {result['full_text']}</span><br>\n"
|
|
elif searchType =='web':
|
|
# WEB 정보 텍스트
|
|
# info_text = f"상표권명: {result['title']}\n등록상태: {result['admin_status']}\nCategory: {result['product_category']}\nApplicant: {result['applicant']}\nPublication Date: {result['publication_date']}\nRegistration Date: {result['registration_date']}"
|
|
info_text = f"<span style='font-size: 11pt; font-weight: bold; text-decoration: underline;'>상표권명: {result['title']}</span><br>\n" \
|
|
f"<span style='font-size: 11pt; font-weight: bold; text-decoration: underline;'>등록상태: {result['application_status']}</span><br>\n" \
|
|
f"<span style='font-size: 9pt;'>카테고리: {result['product_category']}</span><br>\n" \
|
|
f"<span style='font-size: 9pt;'>권리자: {result['applicant_name']}</span><br>\n" \
|
|
f"<span style='font-size: 9pt;'> {result['publication_date']}</span><br>\n" \
|
|
f"<span style='font-size: 9pt;'> {result['registration_date']}</span>"
|
|
|
|
info_label = QLabel(info_text)
|
|
if searchType =='web':
|
|
currentURL_btn = QPushButton("웹 열기")
|
|
# currentURL_btn.clicked.connect(self.openCurrentPage(currentURL))
|
|
info_label.setToolTip(self.wrap_text(result['category_description'], 50))
|
|
image_label.setToolTip(self.wrap_text(result['category_description'], 50))
|
|
item_layout.addWidget(info_label)
|
|
|
|
image_label.setStyleSheet(border_style)
|
|
info_label.setStyleSheet(border_style)
|
|
|
|
# 레이아웃에 위젯 추가
|
|
row = grid_index // grid_columns
|
|
col = grid_index % grid_columns
|
|
grid_layout.addLayout(item_layout, row, col)
|
|
grid_index += 1
|
|
|
|
# 결과 위젯에 닫기 버튼 추가
|
|
close_button = QPushButton("Close")
|
|
close_button.clicked.connect(self.close_results_widget)
|
|
layout.addWidget(close_button)
|
|
|
|
# e
|
|
elapsed_time_Label = QLabel(f"Elapsed Time : {elapsed_time}")
|
|
layout.addWidget(elapsed_time_Label)
|
|
|
|
# 결과 위젯을 메인 윈도우에 추가
|
|
self.results_widget.setGeometry(300, 300, 600, 300) # 위치와 크기 설정
|
|
self.results_widget.setWindowTitle('Search Results') # 타이틀 설정
|
|
self.results_widget.show()
|
|
|
|
# except Exception as e:
|
|
# logger.debug(f"Error displaying results: {e}")
|
|
|
|
def close_results_widget(self):
|
|
# 결과 위젯닫기 함수를 호출할 때 사용하는 메서드
|
|
self.results_widget.close()
|
|
|
|
def openCurrentPage(self, currentURL):
|
|
logger.debug(f"open the page : {currentURL}")
|
|
webbrowser.open('currentURL')
|
|
pass
|
|
# QDesktopServices.openUrl(self.currentURL)
|
|
|
|
def wrap_text(self, text, width=40):
|
|
"""주어진 너비에 맞게 텍스트를 줄바꿈합니다."""
|
|
words = text.split()
|
|
wrapped_text = ''
|
|
line_length = 0
|
|
|
|
for word in words:
|
|
if line_length + len(word) + 1 > width:
|
|
wrapped_text += '\n'
|
|
line_length = 0
|
|
wrapped_text += word + ' '
|
|
line_length += len(word) + 1
|
|
|
|
return wrapped_text.strip()
|
|
|
|
|
|
async def fetch_image_data_async(self, url):
|
|
"""주어진 URL로부터 이미지 데이터를 비동기적으로 가져와 반환합니다."""
|
|
async with aiohttp.ClientSession() as session:
|
|
# logger.debug(f"download_image session Start!!")
|
|
async with session.get(url) as response:
|
|
logger.debug(f"download_image url : {url}")
|
|
if response.status == 200:
|
|
# logger.debug(f"response : {response}")
|
|
content_type = response.headers.get('Content-Type', '') # await 제거
|
|
logger.debug(f"content_type : {content_type}")
|
|
if 'image' in content_type or 'octet-stream' in content_type:
|
|
# logger.debug(f"image content type or octet-stream : {content_type}")
|
|
return await response.read()
|
|
else:
|
|
try:
|
|
# Content-Type이 이미지가 아니면, 데이터를 이미지로 변환
|
|
data = await response.read()
|
|
# logger.debug(f"Content-Type이 이미지가 아님 : {data}")
|
|
image = Image.open(BytesIO(data))
|
|
with BytesIO() as buffer:
|
|
image.save(buffer, 'JPEG')
|
|
logger.debug(f"image 를 JPEG로 저장")
|
|
return buffer.getvalue()
|
|
except Exception as e:
|
|
logger.debug(f"이미지 변환 실패: {e}")
|
|
return None
|
|
else:
|
|
logger.debug(f"이미지 다운로드 실패: HTTP {response.status}")
|
|
return None
|
|
|
|
|
|
def fetch_image_data(self, url):
|
|
"""주어진 URL로부터 이미지 데이터를 가져와 반환합니다."""
|
|
response = requests.get(url)
|
|
if response.status_code == 200:
|
|
# 서버 응답 헤더에서 Content-Type 확인
|
|
content_type = response.headers.get('Content-Type', '')
|
|
if 'image' in content_type:
|
|
return response.content
|
|
else:
|
|
# Content-Type이 이미지가 아니면, 데이터를 이미지로 변환
|
|
try:
|
|
image = Image.open(BytesIO(response.content))
|
|
with BytesIO() as buffer:
|
|
image.save(buffer, 'JPEG') # 예시로 JPEG 포맷을 사용
|
|
return buffer.getvalue()
|
|
except Exception as e:
|
|
logger.debug(f"이미지 변환 실패: {e}")
|
|
return None
|
|
else:
|
|
logger.debug(f"이미지 다운로드 실패: HTTP {response.status_code}")
|
|
return None
|