ChangePercenty2/main2.py

352 lines
17 KiB
Python

# main.py
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QTextBrowser, QLineEdit, QLabel, QCheckBox,
QComboBox, QProgressBar, QWidget, QMessageBox, QTabWidget)
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from playwright.async_api import async_playwright
import configparser
import logging
import json
from cryptography.fernet import Fernet
import asyncio
# 설정 로드 및 저장
def load_config():
config = configparser.ConfigParser()
config.read('config.ini')
return config
def save_config(config):
with open('config.ini', 'w') as configfile:
config.write(configfile)
# 암호화 키 생성 및 로드
def generate_key():
return Fernet.generate_key()
def load_key():
try:
with open("secret.key", "rb") as key_file:
return key_file.read()
except FileNotFoundError:
key = generate_key()
with open("secret.key", "wb") as key_file:
key_file.write(key)
return key
# 암호화 및 복호화 함수
def encrypt_data(data, key):
fernet = Fernet(key)
return fernet.encrypt(data.encode())
def decrypt_data(data, key):
fernet = Fernet(key)
return fernet.decrypt(data).decode()
# 로그 설정
def setup_logging():
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.info("Logging setup complete.")
class LicenseAgreement(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('License Agreement')
layout = QVBoxLayout()
self.licenseText = QTextBrowser()
self.licenseText.setPlainText("License Agreement Text Here...")
layout.addWidget(self.licenseText)
self.acceptCheckbox = QCheckBox("I accept the terms and conditions.")
self.acceptCheckbox.stateChanged.connect(self.toggleAcceptButton)
layout.addWidget(self.acceptCheckbox)
self.acceptButton = QPushButton("Accept")
self.acceptButton.setEnabled(False)
self.acceptButton.clicked.connect(self.accept)
layout.addWidget(self.acceptButton)
self.cancelButton = QPushButton("Cancel")
self.cancelButton.clicked.connect(self.cancel)
layout.addWidget(self.cancelButton)
self.setLayout(layout)
def toggleAcceptButton(self, state):
self.acceptButton.setEnabled(state == Qt.Checked)
def accept(self):
self.accepted = True
self.close()
def cancel(self):
self.accepted = False
self.close()
class FetchSettingsThread(QThread):
result_ready = pyqtSignal(dict)
def run(self):
asyncio.run(self.fetch_market_settings())
async def fetch_market_settings(self):
async with async_playwright() as p:
browser = await p.chromium.launch(headless=False)
page = await browser.new_page()
await page.goto("https://percenty.co.kr")
await page.click(".signList > .ant-btn-default > span")
await page.fill(".ant-input:nth-child(4)", "your_username")
await page.fill(".ant-input:nth-child(1)", "your_password")
await page.click(".ant-btn-primary")
# 팝업 다이얼로그 닫기
try:
await page.click('xpath=body > div:nth-child(10) > div > div.ant-modal-wrap.ant-modal-centered > div > div.ant-modal-content > div.ant-modal-footer > button.ant-btn.css-1li46mu.ant-btn-primary')
except:
pass
await page.click('xpath=/html/body/div[1]/div/div/div/div/aside/div/ul/li[7]/ul/li[2]')
market_data = {}
# 각 마켓의 API key를 가져오는 로직
markets = {
"쿠팡": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[1]",
"스마트스토어": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[2]",
"옥션지마켓": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[3]",
"11번가-일반": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[4]",
"11번가-글로벌": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[5]",
"롯데온": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[6]",
}
for market, xpath in markets.items():
await page.click(f'xpath={xpath}')
if market == "쿠팡":
market_data[market] = {
"쿠팡ID": await page.get_attribute('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div/div/div[1]/div/div[2]/div/div[2]/div[1]/input', 'value'),
"업체코드": await page.get_attribute('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div/div/div[1]/div/div[2]/div/div[2]/div[2]/input', 'value'),
"Access Key": await page.get_attribute('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div/div/div[1]/div/div[2]/div/div[2]/div[3]/input', 'value'),
"Secret Key": await page.get_attribute('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div/div/div[1]/div/div[2]/div/div[2]/div[4]/input', 'value')
}
elif market == "스마트스토어":
market_data[market] = {
"애플리케이션 ID": await page.get_attribute('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[2]/div/div[1]/div/div[2]/div/div/div[2]/input', 'value'),
"애플리케이션 시크릿": await page.get_attribute('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[2]/div/div[1]/div/div[2]/div/div/div[3]/input', 'value')
}
elif market == "옥션지마켓":
market_data[market] = {
"옥션ID": await page.get_attribute('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[3]/div/div[1]/div/div[2]/div/div/div[1]/input', 'value'),
"G마켓ID": await page.get_attribute('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[3]/div/div[1]/div/div[2]/div/div/div[2]/input', 'value')
}
elif market == "11번가-일반":
market_data[market] = {
"API KEY": await page.get_attribute('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[4]/div/div[1]/div/div[2]/div/div/div[1]/input', 'value')
}
elif market == "11번가-글로벌":
market_data[market] = {
"API KEY": await page.get_attribute('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[5]/div/div[1]/div/div[2]/div/div/div[1]/input', 'value')
}
elif market == "롯데온":
market_data[market] = {
"API KEY": await page.get_attribute('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[6]/div/div[1]/div/div[2]/div/div/div[1]/input', 'value')
}
await browser.close()
self.result_ready.emit(market_data)
class ChangeBusinessThread(QThread):
progress_update = pyqtSignal(int)
def __init__(self, market_data):
super().__init__()
self.market_data = market_data
def run(self):
asyncio.run(self.change_business())
async def change_business(self):
async with async_playwright() as p:
browser = await p.chromium.launch(headless=False)
page = await browser.new_page()
await page.goto("https://percenty.co.kr")
await page.click(".signList > .ant-btn-default > span")
await page.fill(".ant-input:nth-child(4)", "your_username")
await page.fill(".ant-input:nth-child(1)", "your_password")
await page.click(".ant-btn-primary")
# 팝업 다이얼로그 닫기
try:
await page.click('xpath=body > div:nth-child(10) > div > div.ant-modal-wrap.ant-modal-centered > div > div.ant-modal-content > div.ant-modal-footer > button.ant-btn.css-1li46mu.ant-btn-primary')
except:
pass
await page.click('xpath=/html/body/div[1]/div/div/div/div/aside/div/ul/li[7]/ul/li[2]')
markets = self.market_data.keys()
progress_step = 100 // len(markets)
progress = 0
for market in markets:
market_xpath = {
"쿠팡": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[1]",
"스마트스토어": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[2]",
"옥션지마켓": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[3]",
"11번가-일반": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[4]",
"11번가-글로벌": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[5]",
"롯데온": "/html/body/div[1]/div/div/div/div/main/div[2]/div/div[1]/div[1]/div/div[6]"
}[market]
await page.click(f'xpath={market_xpath}')
data = self.market_data[market]
if market == "쿠팡":
await page.fill('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div/div/div[1]/div/div[2]/div/div[2]/div[1]/input', data["쿠팡ID"])
await page.fill('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div/div/div[1]/div/div[2]/div/div[2]/div[2]/input', data["업체코드"])
await page.fill('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div/div/div[1]/div/div[2]/div/div[2]/div[3]/input', data["Access Key"])
await page.fill('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div/div/div[1]/div/div[2]/div/div[2]/div[4]/input', data["Secret Key"])
elif market == "스마트스토어":
await page.fill('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[2]/div/div[1]/div/div[2]/div/div/div[2]/input', data["애플리케이션 ID"])
await page.fill('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[2]/div/div[1]/div/div[2]/div/div/div[3]/input', data["애플리케이션 시크릿"])
elif market == "옥션지마켓":
await page.fill('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[3]/div/div[1]/div/div[2]/div/div/div[1]/input', data["옥션ID"])
await page.fill('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[3]/div/div[1]/div/div[2]/div/div/div[2]/input', data["G마켓ID"])
elif market == "11번가-일반":
await page.fill('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[4]/div/div[1]/div/div[2]/div/div/div[1]/input', data["API KEY"])
elif market == "11번가-글로벌":
await page.fill('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[5]/div/div[1]/div/div[2]/div/div/div[1]/input', data["API KEY"])
elif market == "롯데온":
await page.fill('xpath=/html/body/div[1]/div/div/div/div/main/div[2]/div/div[2]/div/div[6]/div/div[1]/div/div[2]/div/div/div[1]/input', data["API KEY"])
progress += progress_step
self.progress_update.emit(progress)
await browser.close()
self.progress_update.emit(100)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.config = load_config()
self.key = load_key()
self.fetch_thread = FetchSettingsThread()
self.fetch_thread.result_ready.connect(self.updateStatus)
self.load_business_data()
def initUI(self):
self.setWindowTitle('Percenty API Manager')
mainLayout = QVBoxLayout()
self.settingButtonLayout = QHBoxLayout()
self.currentSettingButton = QPushButton("현재 설정 가져오기")
self.saveSettingButton = QPushButton("현재 설정 저장하기")
self.currentSettingButton.clicked.connect(self.fetch_current_settings)
self.saveSettingButton.clicked.connect(self.save_current_settings)
self.settingButtonLayout.addWidget(self.currentSettingButton)
self.settingButtonLayout.addWidget(self.saveSettingButton)
mainLayout.addLayout(self.settingButtonLayout)
self.currentStatusLayout = QHBoxLayout()
self.statusBox1 = QLabel("사업자 현황")
self.statusBox2 = QLabel("마켓 현황")
self.statusBox3 = QLabel("빈 박스")
self.currentStatusLayout.addWidget(self.statusBox1)
self.currentStatusLayout.addWidget(self.statusBox2)
self.currentStatusLayout.addWidget(self.statusBox3)
mainLayout.addLayout(self.currentStatusLayout)
self.selectSettingLayout = QVBoxLayout()
self.businessDropdown = QComboBox()
self.businessDropdown.currentIndexChanged.connect(self.update_market_checkboxes)
self.marketCheckboxLayout = QVBoxLayout()
self.changeBusinessButton = QPushButton("사업자 바꾸기")
self.changeBusinessButton.clicked.connect(self.change_business)
self.progressBar = QProgressBar()
self.selectSettingLayout.addWidget(self.businessDropdown)
self.selectSettingLayout.addLayout(self.marketCheckboxLayout)
self.selectSettingLayout.addWidget(self.changeBusinessButton)
self.selectSettingLayout.addWidget(self.progressBar)
mainLayout.addLayout(self.selectSettingLayout)
widget = QWidget()
widget.setLayout(mainLayout)
self.setCentralWidget(widget)
def load_business_data(self):
try:
loaded_data = self.config['BUSINESS_DATA']['data']
decrypted_data = decrypt_data(loaded_data, self.key)
self.business_data = json.loads(decrypted_data)
self.update_business_dropdown()
except KeyError:
self.business_data = {}
def update_business_dropdown(self):
self.businessDropdown.clear()
for business_name in self.business_data.keys():
self.businessDropdown.addItem(business_name)
self.update_market_checkboxes()
def fetch_current_settings(self):
self.fetch_thread.start()
def save_current_settings(self):
encrypted_data = encrypt_data(json.dumps(self.business_data), self.key)
self.config['BUSINESS_DATA'] = {'data': encrypted_data}
save_config(self.config)
QMessageBox.information(self, "Success", "Current settings have been saved.")
def updateStatus(self, market_data):
business_name = self.businessDropdown.currentText()
if business_name:
self.business_data[business_name]["markets"] = market_data
self.update_market_checkboxes()
self.statusBox1.setText(f"사업자 현황: {business_name}")
self.statusBox2.setText(json.dumps(market_data, indent=4, ensure_ascii=False))
def update_market_checkboxes(self):
business_name = self.businessDropdown.currentText()
if not business_name:
return
self.clear_layout(self.marketCheckboxLayout)
markets = self.business_data[business_name]["markets"]
for market, details in markets.items():
market_checkbox = QCheckBox(market)
market_checkbox.setChecked(details["api_key"] != "")
self.marketCheckboxLayout.addWidget(market_checkbox)
def clear_layout(self, layout):
while layout.count():
child = layout.takeAt(0)
if child.widget():
child.widget().deleteLater()
def change_business(self):
business_name = self.businessDropdown.currentText()
selected_markets = [checkbox.text() for checkbox in self.findChildren(QCheckBox) if checkbox.isChecked()]
if business_name:
market_data = {market: self.business_data[business_name]["markets"][market] for market in selected_markets}
self.change_thread = ChangeBusinessThread(market_data)
self.change_thread.progress_update.connect(self.update_progress)
self.change_thread.start()
def update_progress(self, value):
self.progressBar.setValue(value)
if __name__ == "__main__":
setup_logging()
app = QApplication(sys.argv)
licenseWindow = LicenseAgreement()
licenseWindow.show()
app.exec_()
if licenseWindow.accepted:
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())