수정중

This commit is contained in:
Envy_PC 2024-09-12 13:08:57 +09:00
parent 4e5b7ffa34
commit 60f4d5cc4f
11 changed files with 295 additions and 191 deletions

7
.gitignore vendored
View File

@ -7,4 +7,9 @@ build/
*.log *.log
*.log.* *.log.*
pyvenv.cfg pyvenv.cfg
search_history.json search_history.json
# user_data 디렉터리 무시
user_data/
# user_data/Default/Extensions 디렉터리만 추적
!user_data/Default/Extensions/

View File

@ -5,8 +5,8 @@
"maxVolumeSet": 160, "maxVolumeSet": 160,
"addFeeInterval": 5, "addFeeInterval": 5,
"addFeeSetting": 20, "addFeeSetting": 20,
"addFee": 1000, "addFee": 5000,
"fontSize": 12, "fontSize": 13,
"weightInterval": 0.5, "weightInterval": 0.5,
"setSaveSetting": true, "setSaveSetting": true,
"favoriteDelv": "\ub178\ube60\uafb8\ud574\uc6b4(\ubc30\uc1a1\ube44)" "favoriteDelv": "\ub178\ube60\uafb8\ud574\uc6b4(\ubc30\uc1a1\ube44)"

272
delv.py
View File

@ -1,9 +1,11 @@
import sys import sys
import configparser import configparser
import os import os, signal
import pandas as pd import pandas as pd
import logging import logging
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from qasync import QEventLoop # qasync 이벤트 루프 임포트
from PyQt5 import QtWidgets, QtCore from PyQt5 import QtWidgets, QtCore
from PyQt5.QtGui import QFont from PyQt5.QtGui import QFont
import re, json import re, json
@ -15,8 +17,12 @@ from src.kipris_api_from_publicdata import Kipris_API
# from src.kipris_web_from_playwright import Kipris_WEB # from src.kipris_web_from_playwright import Kipris_WEB
from src.kiprisThread import * from src.kiprisThread import *
# from src.search_display import TrademarkSearchDisplay # from src.search_display import TrademarkSearchDisplay
from src.OptionTranslator import optionTrans
from src.result_widget import ResultWidget from src.result_widget import ResultWidget
from src.currencyInfo import ExchangeRateScraper from forex_python.converter import CurrencyRates
from currency_converter import CurrencyConverter
from src.kiprisEvent import LineEditWithHistory
from qfluentwidgets import IndeterminateProgressRing, setTheme, toggleTheme, Theme
# def minimize_console(): # def minimize_console():
# """ 콘솔 창을 최소화하는 함수 """ # """ 콘솔 창을 최소화하는 함수 """
@ -32,6 +38,9 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
# self.config = configparser.ConfigParser() # self.config = configparser.ConfigParser()
self.config_path = 'config.ini' self.config_path = 'config.ini'
self.is_dark_theme = False # 다크 테마 상태 저장
self.dialogs = [] # 열린 다이얼로그와 창들을 저장할 리스트
self.use_kipris = False self.use_kipris = False
self.usage_mode = "web" self.usage_mode = "web"
self.api_key = "" self.api_key = ""
@ -43,6 +52,7 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.web_scraper = None # 웹방식 Playwright 객체 미리 초기화 self.web_scraper = None # 웹방식 Playwright 객체 미리 초기화
self.currentURL = "" self.currentURL = ""
self.config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.json') self.config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.json')
self.history_model = QtCore.QStringListModel()
self.maxWeightSet = 25 self.maxWeightSet = 25
self.maxLengthSet = 100 self.maxLengthSet = 100
@ -64,7 +74,10 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.currentCurrency = None self.currentCurrency = None
# self.searchDisplay = TrademarkSearchDisplay() # self.searchDisplay = TrademarkSearchDisplay()
self.searchDisplayWidget = ResultWidget() self.searchDisplayWidget = ResultWidget()
self.currencyInfoObject = ExchangeRateScraper() self.currencyInfo = CurrencyRates()
self.currencyConv = CurrencyConverter()
self.favoriteDelv = "" self.favoriteDelv = ""
@ -110,14 +123,39 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.settingDialog = SettingsDialog(parent=self, initial_settings=self.user_settings) self.settingDialog = SettingsDialog(parent=self, initial_settings=self.user_settings)
currencis = ['USD','CNY'] currencis = ['USD', 'CNY']
self.currencyInfoObject.getCurrency(currencis) try:
self.setUSD = self.currencyInfoObject.currencyInfo['USD']['basePrice'] # CurrencyConverter로 환율 정보 가져오기
logger.debug(f"setUSD : {self.setUSD}") self.setUSD = int(self.currencyConv.convert(1, 'USD', 'KRW'))
self.setCNY = self.currencyInfoObject.currencyInfo['CNY']['basePrice'] logger.debug(f"CurrencyConverter USD to KRW: {self.setUSD}")
logger.debug(f"setCNY : {self.setCNY}")
self.setCNY = int(self.currencyConv.convert(1, 'CNY', 'KRW'))
logger.debug(f"CurrencyConverter CNY to KRW: {self.setCNY}")
except Exception as e:
logger.error(f"CurrencyConverter 에서 환율 조회 중 에러발생: {e}")
print(f"CurrencyConverter 에러, forex-python에서 값을 가져옵니다.")
try:
# forex-python으로 환율 정보 가져오기
self.setUSD = int(self.currencyRates.get_rate('USD', 'KRW'))
logger.debug(f"forex-python USD to KRW: {self.setUSD}")
self.setCNY = int(self.currencyRates.get_rate('CNY', 'KRW'))
logger.debug(f"forex-python CNY to KRW: {self.setCNY}")
except Exception as e2:
logger.error(f"forex-python 에서 환율 조회 중 에러발생: {e2}")
print(f"forex-python 에러, 기본값을 사용합니다.")
# 기본 환율 설정
self.setUSD = 1350
self.setCNY = 195
logger.debug(f"기본 USD: {self.setUSD}, 기본 CNY: {self.setCNY}")
# 현재 통화를 CNY로 설정
self.currentCurrency = self.setCNY self.currentCurrency = self.setCNY
def saveSettings(self): def saveSettings(self):
""" 설정을 JSON 파일에 저장합니다. """ """ 설정을 JSON 파일에 저장합니다. """
try: try:
@ -208,111 +246,35 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
logger.info("기본 설정이 생성되었습니다.") logger.info("기본 설정이 생성되었습니다.")
# def loadSettings_ini(self):
# """ 설정 파일을 불러옵니다. """
# try:
# if not os.path.exists(self.config_path):
# self.create_default_settings()
# self.config.read(self.config_path)
# self.maxWeightSet = self.config.getint('Settings', 'maxWeightSet', fallback=25)
# self.maxLengthSet = self.config.getint('Settings', 'maxLengthSet', fallback=100)
# self.maxVolumeSet = self.config.getint('Settings', 'maxVolumeSet', fallback=160)
# self.addFeeInterval = self.config.getint('Settings', 'addFeeInterval', fallback=5)
# self.addFeeSetting = self.config.getint('Settings', 'addFeeSetting', fallback=20)
# self.addFee = self.config.getint('Settings', 'addFee', fallback=1000)
# self.fontSize = self.config.getint('Settings', 'fontSize', fallback=14)
# self.weightInterval = self.config.getfloat('Settings', 'weightInterval', fallback=0.5)
# self.setSaveSetting = self.config.getboolean('Settings', 'setSaveSetting', fallback=False)
# self.favoriteDelv = self.config.get('Settings', 'favoriteDelv', fallback="노빠꾸해운(배송비)")
# self.use_kipris = self.config.getboolean('Kipris', 'use_Kipris', fallback=False)
# self.usage_mode = self.config.get('Kipris', 'usage_mode', fallback="web")
# self.api_key = self.config.get('Kipris', 'api_key', fallback="")
# self.set_status = self.config.get('Kipris', 'set_status', fallback="[등록]")
# # logger.debug(f"use_kipris : {self.use_kipris}, usage_mode : {self.usage_mode}, api_key : {self.api_key}") def add_history(self, keyword):
# except Exception as e:
# logger.error(f"설정을 불러오는 중 오류가 발생했습니다: {e}", exc_info=True)
# def saveSettings_ini(self):
# """ 설정을 config.ini 파일에 저장합니다. """
# try:
# if not self.config.has_section('Settings'):
# self.config.add_section('Settings')
# self.config.set('Settings', 'maxWeightSet', str(self.maxWeightSet))
# self.config.set('Settings', 'maxLengthSet', str(self.maxLengthSet))
# self.config.set('Settings', 'maxVolumeSet', str(self.maxVolumeSet))
# self.config.set('Settings', 'addFeeInterval', str(self.addFeeInterval))
# self.config.set('Settings', 'addFeeSetting', str(self.addFeeSetting))
# self.config.set('Settings', 'addFee', str(self.addFee))
# self.config.set('Settings', 'fontSize', str(self.fontSize))
# self.config.set('Settings', 'weightInterval', str(self.weightInterval))
# self.config.set('Settings', 'setSaveSetting', str(self.setSaveSetting))
# self.config.set('Settings', 'favoriteDelv', str(self.favoriteDelv))
# if not self.config.has_section('Kipris'):
# self.config.add_section('Kipris')
# self.config.set('Kipris', 'use_kipris', str(self.use_kipris))
# self.config.set('Kipris', 'usage_mode', str(self.usage_mode))
# self.config.set('Kipris', 'api_key', str(self.api_key))
# self.config.set('Kipris', 'set_status', str(self.set_status))
# with open(self.config_path, 'w') as configfile:
# self.config.write(configfile)
# except Exception as e:
# logger.error(f"설정을 저장하는 중 오류가 발생했습니다: {e}", exc_info=True)
# def create_default_settings_ini(self):
# """ 기본 설정을 생성합니다. """
# self.config['Settings'] = {
# 'maxWeightSet': '25',
# 'maxLengthSet': '100',
# 'maxVolumeSet': '160',
# 'addFeeInterval': '5',
# 'addFeeSetting': '20',
# 'addFee': '1000',
# 'fontSize': '14',
# 'weightInterval': '0.5',
# 'setSaveSetting': 'False',
# 'favoriteDelv': "노빠꾸해운(배송비)",
# }
# self.config['Kipris'] = {
# 'use_kipris': 'False',
# 'usage_mode': 'web',
# 'api_key': '',
# 'set_status': '[등록]',
# }
# with open(self.config_path, 'w') as configfile:
# self.config.write(configfile)
def add_history(self, keyword) :
if keyword: if keyword:
if keyword and keyword not in self.history: # 중복된 검색어가 아니면 추가 current_history = self.history_model.stringList()
self.history.append(keyword) if keyword not in current_history: # 중복된 검색어가 아니면 추가
current_history.append(keyword)
self.history_model.setStringList(current_history)
logger.debug(f"검색어 [{keyword}] 히스토리에 추가") logger.debug(f"검색어 [{keyword}] 히스토리에 추가")
def load_history(self): def load_history(self):
try: try:
with open("search_history.json", "r") as file: with open("search_history.json", "r") as file:
self.history = json.load(file) history_list = json.load(file)
logger.debug(f"self.history file loaded{self.history}") self.history_model.setStringList(history_list)
logger.debug(f"self.history file loaded: {history_list}")
except (FileNotFoundError, json.JSONDecodeError): except (FileNotFoundError, json.JSONDecodeError):
self.history = [] self.history_model.setStringList([])
logger.debug(f"self.history{self.history}") logger.debug(f"self.history: []")
def save_history(self): def save_history(self):
with open("search_history.json", "w") as file: with open("search_history.json", "w") as file:
json.dump(self.history, file) json.dump(self.history_model.stringList(), file)
def show_history_menu(self, event): def show_history_menu(self, event):
if self.history: current_history = self.history_model.stringList()
if current_history:
menu = QtWidgets.QMenu(self) menu = QtWidgets.QMenu(self)
for keyword in self.history: for keyword in current_history:
menu.addAction(keyword, lambda k=keyword: self.kipris_edit.setText(k)) menu.addAction(keyword, lambda k=keyword: self.kipris_edit.setText(k))
menu.exec_(self.kipris_edit.mapToGlobal(event.pos())) menu.exec_(self.kipris_edit.mapToGlobal(event.pos()))
@ -334,6 +296,16 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
# 이벤트 처리 완료를 알림 # 이벤트 처리 완료를 알림
event.accept() event.accept()
# 프로그램 완전히 종료
QtWidgets.QApplication.quit() # Qt 애플리케이션 종료
# 프로세스 강제 종료 (필요 시 사용)
os.kill(os.getpid(), signal.SIGTERM)
def add_dialog(self, dialog):
"""열린 다이얼로그나 창을 리스트에 추가"""
self.dialogs.append(dialog)
def initUI(self): def initUI(self):
self.resize(300, 600) # 창 크기 조정 self.resize(300, 600) # 창 크기 조정
self.center() self.center()
@ -610,11 +582,28 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.kiprisWidget.setLayout(self.kipris_layout) self.kiprisWidget.setLayout(self.kipris_layout)
self.kiprisWidget.setVisible(False) self.kiprisWidget.setVisible(False)
self.kipris_label = QtWidgets.QLabel(f"키프리스 검색") self.kipris_label = QtWidgets.QLabel(f"키프리스 검색")
self.kipris_completer = QtWidgets.QCompleter(self.history_model, self)
self.kipris_completer.setCaseSensitivity(Qt.CaseInsensitive)
self.kipris_completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
self.kipris_edit = QtWidgets.QLineEdit() self.kipris_edit = QtWidgets.QLineEdit()
self.kipris_edit = LineEditWithHistory(self.kipris_completer, self)
self.kipris_edit.setCompleter(self.kipris_completer)
self.kipris_btn = QtWidgets.QPushButton("검색") self.kipris_btn = QtWidgets.QPushButton("검색")
self.kipris_btn.clicked.connect(self.kipris_btn_clicked) self.kipris_btn.clicked.connect(self.kipris_btn_clicked)
self.kipris_edit.returnPressed.connect(self.kipris_btn_clicked) self.kipris_edit.returnPressed.connect(self.kipris_btn_clicked)
self.kipris_edit.mousePressEvent = self.show_history_menu
self.spinner = IndeterminateProgressRing(self)
self.spinner.setFixedSize(50, 50)
self.spinner.setVisible(False)
self.kipris_layout.addWidget(self.spinner)
# self.kipris_edit.mousePressEvent = self.show_history_menu
self.kipris_layout.addWidget(self.kipris_label) self.kipris_layout.addWidget(self.kipris_label)
self.kipris_layout.addWidget(self.kipris_edit) self.kipris_layout.addWidget(self.kipris_edit)
self.kipris_layout.addWidget(self.kipris_btn) self.kipris_layout.addWidget(self.kipris_btn)
@ -661,9 +650,18 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.addInfo3_btn.clicked.connect(self.addInfo3_btn_clicked) self.addInfo3_btn.clicked.connect(self.addInfo3_btn_clicked)
self.addInfo_h2layout.addWidget(self.addInfo3_btn) self.addInfo_h2layout.addWidget(self.addInfo3_btn)
self.addInfo4_btn = QtWidgets.QPushButton("딥러닝번역") self.addInfo4_btn = QtWidgets.QPushButton("딥러닝번역")
self.addInfo4_btn.setEnabled(False) self.addInfo4_btn.setEnabled(True)
self.addInfo4_btn.clicked.connect(self.addInfo4_btn_clicked) self.addInfo4_btn.clicked.connect(self.addInfo4_btn_clicked)
self.addInfo_h2layout.addWidget(self.addInfo4_btn) self.addInfo_h2layout.addWidget(self.addInfo4_btn)
# 다크 테마 토글 버튼 추가
self.theme_button = QtWidgets.QPushButton("Dark Theme", self)
self.theme_button.setEnabled(False)
self.theme_button.clicked.connect(self.toggle_theme)
self.addInfo_h2layout.addWidget(self.theme_button, 0, Qt.AlignHCenter)
# self.addInfo_layout.setStretch(0,3) # self.addInfo_layout.setStretch(0,3)
# self.addInfo_layout.setStretch(1,6) # self.addInfo_layout.setStretch(1,6)
# self.addInfo_layout.setStretch(2,3) # self.addInfo_layout.setStretch(2,3)
@ -727,25 +725,24 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.setWindowTitle('배송비 계산기') self.setWindowTitle('배송비 계산기')
# def initSettings_for_kipris_ori(self): def toggle_theme(self):
# if self.kiprisAPI: if self.is_dark_theme:
# # 현재 객체가 적절한 타입인지 확인 try:
# current_type = type(self.kiprisAPI) # setTheme(Theme.LIGHT)
# target_type = Kipris_API if self.usage_mode == 'api' else Kipris_WEB toggleTheme()
print("라이트 토글")
# if current_type is not target_type: self.is_dark_theme = False
# # 기존 객체가 다른 타입이면 삭제하고 새로 생성 except Exception as e:
# logger.debug(f"기존 {self.kiprisAPI} 객체를 삭제하고 새 객체를 생성합니다.") print(f"라이트 토글 중 에러 : {e}")
# self.kiprisAPI.close_Kipris() # 기존객체 리소스 정리 else:
# del self.kiprisAPI # 기존 객체 참조 제거 try:
# self.kiprisAPI = target_type(self.api_key) # 새 객체 생성 # setTheme(Theme.DARK)
# logger.debug(f"{self.usage_mode.upper()} 방식 kiprisAPI 객체 생성: {self.kiprisAPI}") toggleTheme()
# else:
# logger.debug(f"기존에 적절한 {self.kiprisAPI} 객체가 이미 존재합니다.") print("다크 토글")
# else: self.is_dark_theme = True
# # 객체가 없으면 새로 생성 except Exception as e:
# self.kiprisAPI = Kipris_API(self.api_key) if self.usage_mode == 'api' else Kipris_WEB(self.api_key) print(f"다크 토글 중 에러 : {e}")
# logger.debug(f"{self.usage_mode.upper()} 방식 kiprisAPI 객체 생성: {self.kiprisAPI}")
def initSettings_for_kipris(self): def initSettings_for_kipris(self):
if self.kiprisAPI: if self.kiprisAPI:
@ -788,7 +785,10 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
pass pass
def addInfo4_btn_clicked(self): def addInfo4_btn_clicked(self):
pass # optionTrans 클래스를 사용해 다이얼로그 창을 띄움
self.trans_dialog = optionTrans(self)
self.trans_dialog.show()
self.add_dialog(self.trans_dialog) # 열린 다이얼로그를 리스트에 추가
def showSettingsDialog(self): def showSettingsDialog(self):
@ -797,6 +797,7 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.usage_mode = self.settingDialog.usage_mode self.usage_mode = self.settingDialog.usage_mode
self.api_key = self.settingDialog.api_key self.api_key = self.settingDialog.api_key
self.set_status = self.settingDialog.set_status self.set_status = self.settingDialog.set_status
self.add_dialog(self.settingDialog) # 열린 다이얼로그를 리스트에 추가
self.kipris_Visible() self.kipris_Visible()
@ -1142,6 +1143,8 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
# logger.debug(f"result {result}") # logger.debug(f"result {result}")
if self.search_keyword.strip(): # 검색어가 비어있지 않은 경우에만 검색 수행 if self.search_keyword.strip(): # 검색어가 비어있지 않은 경우에만 검색 수행
self.spinner.setVisible(True) # Show spinner
logger.debug(f"검색 호출방식 : {self.usage_mode}") logger.debug(f"검색 호출방식 : {self.usage_mode}")
if self.usage_mode == 'web': if self.usage_mode == 'web':
self.handle_search_for_web(self.search_keyword) self.handle_search_for_web(self.search_keyword)
@ -1163,6 +1166,9 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
# logger.debug(f"result : {result}") # logger.debug(f"result : {result}")
searchType = 'web' searchType = 'web'
logger.debug(f"display_results_for_web - currentURL : {self.web_scraper.currentURL}") logger.debug(f"display_results_for_web - currentURL : {self.web_scraper.currentURL}")
self.spinner.setVisible(False) # Hide spinner
self.searchDisplayWidget.clear_results()
self.add_dialog(self.searchDisplayWidget) # 열린 다이얼로그를 리스트에 추가
self.searchDisplayWidget.show_results(result, searchType, elapsed_time, self.web_scraper.currentURL) self.searchDisplayWidget.show_results(result, searchType, elapsed_time, self.web_scraper.currentURL)
# self.searchDisplay.display_web_results(result, elapsed_time) # self.searchDisplay.display_web_results(result, elapsed_time)
@ -1200,6 +1206,10 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
def display_results_for_api(self, result, elapsed_time): def display_results_for_api(self, result, elapsed_time):
searchType = 'api' searchType = 'api'
logger.debug(f"display_results_for_api result: {result}") logger.debug(f"display_results_for_api result: {result}")
self.spinner.setVisible(False) # Hide spinner
self.searchDisplayWidget.clear_results()
self.add_dialog(self.searchDisplayWidget) # 열린 다이얼로그를 리스트에 추가
self.searchDisplayWidget.show_results(result, searchType, elapsed_time) self.searchDisplayWidget.show_results(result, searchType, elapsed_time)
message = f"검색 결과 : {result}\n검색에 걸린 시간: {elapsed_time:.1f}" message = f"검색 결과 : {result}\n검색에 걸린 시간: {elapsed_time:.1f}"
# QtWidgets.QMessageBox.information(self, "Search Results", message) # QtWidgets.QMessageBox.information(self, "Search Results", message)
@ -1208,6 +1218,7 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.lengthInput.setValue(1) self.lengthInput.setValue(1)
self.widthInput.setValue(1) self.widthInput.setValue(1)
self.heightInput.setValue(1) self.heightInput.setValue(1)
self.weightInput.setValue(1)
def showHelp(self): def showHelp(self):
# 도움말 내용 표시 # 도움말 내용 표시
@ -1238,9 +1249,26 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
if __name__ == '__main__': if __name__ == '__main__':
# minimize_console() # minimize_console()
# enable dpi scale
QtWidgets.QApplication.setHighDpiScaleFactorRoundingPolicy(
Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
QtWidgets.QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QtWidgets.QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QtWidgets.QApplication(sys.argv) app = QtWidgets.QApplication(sys.argv)
# qasync 이벤트 루프를 생성하여 PyQt5의 이벤트 루프와 결합
loop = QEventLoop(app)
asyncio.set_event_loop(loop) # asyncio의 이벤트 루프를 qasync로 설정
app.setStyle('Fusion') app.setStyle('Fusion')
logger = setup_logger('default_logger', 'delivery_calc.log', level=logging.DEBUG) logger = setup_logger('default_logger', 'delivery_calc.log', level=logging.DEBUG)
ex = DeliveryFeeCalculator(logger) ex = DeliveryFeeCalculator(logger)
ex.show() ex.show()
# 이벤트 루프 시작
with loop:
loop.run_forever()
sys.exit(app.exec_()) sys.exit(app.exec_())

Binary file not shown.

View File

@ -1 +1 @@
["\uc2a4\ud0a4\uc5d0\uc774\ud2b8", "\ub86f\ub370", "\uc2a4\ud0a4\uc5d0\uc774\ud2b8", "\ub86f\ub370", "\uc2a4\ud0a4\uc5d0\uc774\ud2b8", "\ub86f\ub370", "\uc368\uc9c0\uc624"] ["\uc2a4\ud0a4\uc5d0\uc774\ud2b8", "123", "\ub098\uc774\ud0a4", "\ub274\uc2dc\uc2a4"]

View File

@ -19,7 +19,7 @@ target = Executable(
# Setup configuration # Setup configuration
setup( setup(
name="Deliver_Calc", name="Deliver_Calc",
version="1.3", version="1.4",
description="Delivery Calculation Tool", description="Delivery Calculation Tool",
options={"build_exe": build_exe_options}, options={"build_exe": build_exe_options},
executables=[target] executables=[target]

110
src/OptionTranslator.py Normal file
View File

@ -0,0 +1,110 @@
import os
import asyncio
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QPushButton
from playwright.async_api import async_playwright
class optionTrans(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.browser = None
self.page = None
self.macro_running = False
self.init_ui()
def init_ui(self):
self.setWindowTitle("Macro Control")
layout = QVBoxLayout()
# 실행 버튼
self.start_button = QPushButton("실행")
self.start_button.clicked.connect(self.start_browser_task) # 실행 버튼을 비동기 작업과 연결
layout.addWidget(self.start_button)
# 중지 버튼
self.stop_button = QPushButton("중지")
self.stop_button.clicked.connect(self.stop_browser_task)
layout.addWidget(self.stop_button)
# 매크로 1 버튼
self.macro1_button = QPushButton("매크로 1 실행")
self.macro1_button.clicked.connect(self.start_macro1_task)
layout.addWidget(self.macro1_button)
# 매크로 2 버튼 (아직 구현하지 않음)
self.macro2_button = QPushButton("매크로 2 실행")
layout.addWidget(self.macro2_button)
self.setLayout(layout)
def start_browser_task(self):
# 비동기 작업을 생성하고 이벤트 루프에 실행
asyncio.create_task(self.run_browser())
def stop_browser_task(self):
asyncio.create_task(self.stop_macro())
def start_macro1_task(self):
asyncio.create_task(self.run_macro1())
def get_latest_version(self, directory):
# 디렉터리 내에서 버전 폴더를 찾아서 숫자로 정렬한 뒤 최신 버전을 반환
versions = os.listdir(directory)
versions.sort(key=lambda s: [int(part) for part in s.replace('_', '.').split('.')])
return versions[-1] # 최신 버전 반환
async def run_browser(self):
if self.browser is None:
# main.py가 위치한 디렉터리 경로
current_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # OptionTranslator.py 기준 상위 폴더로 이동
user_data_dir = os.path.join(current_dir, "user_data")
# 확장 프로그램 경로 설정 (동적으로 최신 버전의 확장 프로그램 폴더를 찾음)
extension_dir1 = os.path.join(user_data_dir, "Default", "Extensions", "jlcdjppbpplpdgfeknhioedbhfceaben")
# 확장 프로그램이 존재하는지 확인
if not os.path.exists(extension_dir1):
raise FileNotFoundError(f"확장 프로그램 디렉터리가 존재하지 않습니다: {extension_dir1}")
# 최신 버전 폴더 찾기 (숫자 기반 비교)
extension_version1 = self.get_latest_version(extension_dir1)
extension_path1 = os.path.join(extension_dir1, extension_version1)
# 최신 버전 폴더 찾기 (숫자 기반 비교)
extension_version1 = self.get_latest_version(extension_dir1) # self로 메서드 호출
extension_path1 = os.path.join(extension_dir1, extension_version1)
self.playwright = await async_playwright().start()
self.browser = await self.playwright.chromium.launch_persistent_context(
user_data_dir=user_data_dir,
headless=False,
args=[
f'--disable-extensions-except={extension_path1}',
f'--load-extension={extension_path1}'
]
)
self.page = await self.browser.new_page()
await self.page.goto('https://percenty.co.kr')
async def stop_macro(self):
if self.browser:
await self.browser.close()
self.browser = None
async def run_macro1(self):
if self.page and not self.macro_running:
self.macro_running = True
try:
element_to_right_click = await self.page.query_selector('css_selector_for_element')
await element_to_right_click.click(button="right") # 우클릭
translate_button = await self.page.query_selector('css_selector_for_translate')
await translate_button.click() # 번역 버튼 클릭
second_element = await self.page.query_selector('css_selector_for_drag')
await second_element.hover() # 요소 위에 마우스 올리기
await self.page.mouse.down()
await self.page.mouse.move(150, 0) # 오른쪽으로 150픽셀 이동
await self.page.mouse.up()
finally:
self.macro_running = False

View File

@ -1,63 +0,0 @@
import requests
import logging
# 로거 인스턴스 가져오기
logger = logging.getLogger('default_logger')
class ExchangeRateScraper:
def __init__(self):
super().__init__()
self.currencyInfo = {}
self.initUI()
def initUI(self):
pass
def getCurrency(self, currencies):
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'
}
# 동적으로 URL 구성하기
codes = ','.join([f'FRX.KRW{currency}' for currency in currencies])
url = f'https://quotation-api-cdn.dunamu.com/v1/forex/recent?codes={codes}'
# url = 'https://quotation-api-cdn.dunamu.com/v1/forex/recent?codes=FRX.KRWUSD,FRX.KRWCNY'
response = requests.get(url, headers=headers)
if response.status_code == 200:
exchange_rates = response.json()
for rate in exchange_rates:
currency_code = rate['currencyCode']
if currency_code in currencies:
# 해당 통화 정보 저장
self.currencyInfo[currency_code] = {
'basePrice': rate['basePrice'],
'modifiedAt': rate['modifiedAt'],
'provider': rate['provider']
}
logger.debug("Exchange rates updated.")
else:
logger.error("Failed to retrieve data")
def get_Currency_Info(self, currency):
# 특정 통화 정보 출력 메서드
if currency in self.currencyInfo:
info = self.currencyInfo[currency]
logger.debug(f"Currency: {currency}")
logger.debug(f"Base Price: {info['basePrice']}")
logger.debug(f"Modified At: {info['modifiedAt']}")
logger.debug(f"Provider: {info['provider']}")
else:
logger.debug(f"No data available for {currency}")
# # 클래스 메서드 사용 예제
# scraper = ExchangeRateScraper()
# scraper.getCurrency(['USD', 'CNY']) # USD와 CNY 환율 정보를 요청
# scraper.get_Currency_Info('USD')
# scraper.get_Currency_Info('CNY')

16
src/kiprisEvent.py Normal file
View File

@ -0,0 +1,16 @@
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtCore import Qt
class LineEditWithHistory(QLineEdit):
def __init__(self, completer, parent=None):
super().__init__(parent)
self.completer = completer
def keyPressEvent(self, event):
if event.key() == Qt.Key_Down:
if self.completer.popup().isVisible():
event.ignore()
else:
self.completer.complete()
else:
super().keyPressEvent(event)

View File

@ -1,7 +1,6 @@
from PyQt5 import QtWidgets, QtCore from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import QUrl from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QDesktopServices from PyQt5.QtGui import QDesktopServices
from src.toggleSwitch import ToggleSwitch from src.toggleSwitch import ToggleSwitch
import logging import logging

View File

@ -21,6 +21,9 @@ class ResultWidget(QWidget):
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint) self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
def show_results(self, results, searchType, elapsed_time, currentURL=''): def show_results(self, results, searchType, elapsed_time, currentURL=''):
# 결과를 표시하기 전에 이전 결과를 지웁니다.
self.clear_results()
searchType = searchType searchType = searchType
elapsed_time = elapsed_time elapsed_time = elapsed_time
currentURL = currentURL currentURL = currentURL
@ -138,6 +141,12 @@ class ResultWidget(QWidget):
# except Exception as e: # except Exception as e:
# logger.debug(f"Error displaying results: {e}") # logger.debug(f"Error displaying results: {e}")
def clear_results(self):
# 기존 텍스트를 초기화
if hasattr(self, 'results_widget'):
self.results_widget.deleteLater()
def close_results_widget(self): def close_results_widget(self):
# 결과 위젯닫기 함수를 호출할 때 사용하는 메서드 # 결과 위젯닫기 함수를 호출할 때 사용하는 메서드
self.results_widget.close() self.results_widget.close()