diff --git a/.gitignore b/.gitignore index 45528fa..4d718ff 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,9 @@ build/ *.log *.log.* pyvenv.cfg -search_history.json \ No newline at end of file +search_history.json +# user_data 디렉터리 무시 +user_data/ + +# user_data/Default/Extensions 디렉터리만 추적 +!user_data/Default/Extensions/ diff --git a/config.json b/config.json index f215ed7..1f2b8ed 100644 --- a/config.json +++ b/config.json @@ -5,8 +5,8 @@ "maxVolumeSet": 160, "addFeeInterval": 5, "addFeeSetting": 20, - "addFee": 1000, - "fontSize": 12, + "addFee": 5000, + "fontSize": 13, "weightInterval": 0.5, "setSaveSetting": true, "favoriteDelv": "\ub178\ube60\uafb8\ud574\uc6b4(\ubc30\uc1a1\ube44)" diff --git a/delv.py b/delv.py index ec52d67..aa5cbe4 100644 --- a/delv.py +++ b/delv.py @@ -1,9 +1,11 @@ import sys import configparser -import os +import os, signal import pandas as pd import logging from PyQt5.QtCore import Qt +from qasync import QEventLoop # qasync 이벤트 루프 임포트 + from PyQt5 import QtWidgets, QtCore from PyQt5.QtGui import QFont 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.kiprisThread import * # from src.search_display import TrademarkSearchDisplay +from src.OptionTranslator import optionTrans 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(): # """ 콘솔 창을 최소화하는 함수 """ @@ -32,6 +38,9 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): # self.config = configparser.ConfigParser() self.config_path = 'config.ini' + self.is_dark_theme = False # 다크 테마 상태 저장 + self.dialogs = [] # 열린 다이얼로그와 창들을 저장할 리스트 + self.use_kipris = False self.usage_mode = "web" self.api_key = "" @@ -43,6 +52,7 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): self.web_scraper = None # 웹방식 Playwright 객체 미리 초기화 self.currentURL = "" self.config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.json') + self.history_model = QtCore.QStringListModel() self.maxWeightSet = 25 self.maxLengthSet = 100 @@ -64,7 +74,10 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): self.currentCurrency = None # self.searchDisplay = TrademarkSearchDisplay() self.searchDisplayWidget = ResultWidget() - self.currencyInfoObject = ExchangeRateScraper() + self.currencyInfo = CurrencyRates() + self.currencyConv = CurrencyConverter() + + self.favoriteDelv = "" @@ -110,14 +123,39 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): self.settingDialog = SettingsDialog(parent=self, initial_settings=self.user_settings) - currencis = ['USD','CNY'] - self.currencyInfoObject.getCurrency(currencis) - self.setUSD = self.currencyInfoObject.currencyInfo['USD']['basePrice'] - logger.debug(f"setUSD : {self.setUSD}") - self.setCNY = self.currencyInfoObject.currencyInfo['CNY']['basePrice'] - logger.debug(f"setCNY : {self.setCNY}") + currencis = ['USD', 'CNY'] + try: + # CurrencyConverter로 환율 정보 가져오기 + self.setUSD = int(self.currencyConv.convert(1, 'USD', 'KRW')) + logger.debug(f"CurrencyConverter USD to KRW: {self.setUSD}") + + 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 + + def saveSettings(self): """ 설정을 JSON 파일에 저장합니다. """ try: @@ -208,111 +246,35 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): 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}") - # 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) : + def add_history(self, keyword): if keyword: - if keyword and keyword not in self.history: # 중복된 검색어가 아니면 추가 - self.history.append(keyword) + current_history = self.history_model.stringList() + if keyword not in current_history: # 중복된 검색어가 아니면 추가 + current_history.append(keyword) + self.history_model.setStringList(current_history) logger.debug(f"검색어 [{keyword}] 히스토리에 추가") def load_history(self): try: with open("search_history.json", "r") as file: - self.history = json.load(file) - logger.debug(f"self.history file loaded{self.history}") + history_list = json.load(file) + self.history_model.setStringList(history_list) + logger.debug(f"self.history file loaded: {history_list}") except (FileNotFoundError, json.JSONDecodeError): - self.history = [] - logger.debug(f"self.history{self.history}") + self.history_model.setStringList([]) + logger.debug(f"self.history: []") def save_history(self): 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): - if self.history: + current_history = self.history_model.stringList() + if current_history: 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.exec_(self.kipris_edit.mapToGlobal(event.pos())) @@ -334,6 +296,16 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): # 이벤트 처리 완료를 알림 event.accept() + # 프로그램 완전히 종료 + QtWidgets.QApplication.quit() # Qt 애플리케이션 종료 + + # 프로세스 강제 종료 (필요 시 사용) + os.kill(os.getpid(), signal.SIGTERM) + + def add_dialog(self, dialog): + """열린 다이얼로그나 창을 리스트에 추가""" + self.dialogs.append(dialog) + def initUI(self): self.resize(300, 600) # 창 크기 조정 self.center() @@ -610,11 +582,28 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): self.kiprisWidget.setLayout(self.kipris_layout) self.kiprisWidget.setVisible(False) 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 = LineEditWithHistory(self.kipris_completer, self) + self.kipris_edit.setCompleter(self.kipris_completer) + self.kipris_btn = QtWidgets.QPushButton("검색") self.kipris_btn.clicked.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_edit) 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.addInfo_h2layout.addWidget(self.addInfo3_btn) 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.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(1,6) # self.addInfo_layout.setStretch(2,3) @@ -727,25 +725,24 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): self.setWindowTitle('배송비 계산기') - # def initSettings_for_kipris_ori(self): - # if self.kiprisAPI: - # # 현재 객체가 적절한 타입인지 확인 - # current_type = type(self.kiprisAPI) - # target_type = Kipris_API if self.usage_mode == 'api' else Kipris_WEB - - # if current_type is not target_type: - # # 기존 객체가 다른 타입이면 삭제하고 새로 생성 - # logger.debug(f"기존 {self.kiprisAPI} 객체를 삭제하고 새 객체를 생성합니다.") - # self.kiprisAPI.close_Kipris() # 기존객체 리소스 정리 - # del self.kiprisAPI # 기존 객체 참조 제거 - # self.kiprisAPI = target_type(self.api_key) # 새 객체 생성 - # logger.debug(f"{self.usage_mode.upper()} 방식 kiprisAPI 객체 생성: {self.kiprisAPI}") - # else: - # logger.debug(f"기존에 적절한 {self.kiprisAPI} 객체가 이미 존재합니다.") - # else: - # # 객체가 없으면 새로 생성 - # self.kiprisAPI = Kipris_API(self.api_key) if self.usage_mode == 'api' else Kipris_WEB(self.api_key) - # logger.debug(f"{self.usage_mode.upper()} 방식 kiprisAPI 객체 생성: {self.kiprisAPI}") + def toggle_theme(self): + if self.is_dark_theme: + try: + # setTheme(Theme.LIGHT) + toggleTheme() + print("라이트 토글") + self.is_dark_theme = False + except Exception as e: + print(f"라이트 토글 중 에러 : {e}") + else: + try: + # setTheme(Theme.DARK) + toggleTheme() + + print("다크 토글") + self.is_dark_theme = True + except Exception as e: + print(f"다크 토글 중 에러 : {e}") def initSettings_for_kipris(self): if self.kiprisAPI: @@ -788,7 +785,10 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): pass 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): @@ -797,6 +797,7 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): self.usage_mode = self.settingDialog.usage_mode self.api_key = self.settingDialog.api_key self.set_status = self.settingDialog.set_status + self.add_dialog(self.settingDialog) # 열린 다이얼로그를 리스트에 추가 self.kipris_Visible() @@ -1142,6 +1143,8 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): # logger.debug(f"result {result}") if self.search_keyword.strip(): # 검색어가 비어있지 않은 경우에만 검색 수행 + self.spinner.setVisible(True) # Show spinner + logger.debug(f"검색 호출방식 : {self.usage_mode}") if self.usage_mode == 'web': self.handle_search_for_web(self.search_keyword) @@ -1163,6 +1166,9 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): # logger.debug(f"result : {result}") searchType = 'web' 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.searchDisplay.display_web_results(result, elapsed_time) @@ -1200,6 +1206,10 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): def display_results_for_api(self, result, elapsed_time): searchType = 'api' 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) message = f"검색 결과 : {result}\n검색에 걸린 시간: {elapsed_time:.1f}초" # QtWidgets.QMessageBox.information(self, "Search Results", message) @@ -1208,6 +1218,7 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): self.lengthInput.setValue(1) self.widthInput.setValue(1) self.heightInput.setValue(1) + self.weightInput.setValue(1) def showHelp(self): # 도움말 내용 표시 @@ -1238,9 +1249,26 @@ class DeliveryFeeCalculator(QtWidgets.QWidget): if __name__ == '__main__': # 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) + + # qasync 이벤트 루프를 생성하여 PyQt5의 이벤트 루프와 결합 + loop = QEventLoop(app) + asyncio.set_event_loop(loop) # asyncio의 이벤트 루프를 qasync로 설정 + + app.setStyle('Fusion') logger = setup_logger('default_logger', 'delivery_calc.log', level=logging.DEBUG) ex = DeliveryFeeCalculator(logger) ex.show() + # 이벤트 루프 시작 + with loop: + loop.run_forever() + sys.exit(app.exec_()) diff --git a/requirements.txt b/requirements.txt index 3c3ac2d..33bc523 100644 Binary files a/requirements.txt and b/requirements.txt differ diff --git a/search_history.json b/search_history.json index 7f6bb17..f37b974 100644 --- a/search_history.json +++ b/search_history.json @@ -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"] \ No newline at end of file +["\uc2a4\ud0a4\uc5d0\uc774\ud2b8", "123", "\ub098\uc774\ud0a4", "\ub274\uc2dc\uc2a4"] \ No newline at end of file diff --git a/setup.py b/setup.py index 5da5196..44b8688 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ target = Executable( # Setup configuration setup( name="Deliver_Calc", - version="1.3", + version="1.4", description="Delivery Calculation Tool", options={"build_exe": build_exe_options}, executables=[target] diff --git a/src/OptionTranslator.py b/src/OptionTranslator.py new file mode 100644 index 0000000..2f72b02 --- /dev/null +++ b/src/OptionTranslator.py @@ -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 diff --git a/src/currencyInfo.py b/src/currencyInfo.py deleted file mode 100644 index b05f4f1..0000000 --- a/src/currencyInfo.py +++ /dev/null @@ -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') diff --git a/src/kiprisEvent.py b/src/kiprisEvent.py new file mode 100644 index 0000000..f2e009a --- /dev/null +++ b/src/kiprisEvent.py @@ -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) diff --git a/src/kipris_settingUI.py b/src/kipris_settingUI.py index adecc8a..a617ece 100644 --- a/src/kipris_settingUI.py +++ b/src/kipris_settingUI.py @@ -1,7 +1,6 @@ from PyQt5 import QtWidgets, QtCore from PyQt5.QtCore import QUrl from PyQt5.QtGui import QDesktopServices - from src.toggleSwitch import ToggleSwitch import logging diff --git a/src/result_widget.py b/src/result_widget.py index d9210a8..94c051a 100644 --- a/src/result_widget.py +++ b/src/result_widget.py @@ -21,6 +21,9 @@ class ResultWidget(QWidget): self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint) def show_results(self, results, searchType, elapsed_time, currentURL=''): + # 결과를 표시하기 전에 이전 결과를 지웁니다. + self.clear_results() + searchType = searchType elapsed_time = elapsed_time currentURL = currentURL @@ -138,6 +141,12 @@ class ResultWidget(QWidget): # except Exception as 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): # 결과 위젯닫기 함수를 호출할 때 사용하는 메서드 self.results_widget.close()