diff --git a/main.py b/main.py
index ceed7c8..a9766c0 100644
--- a/main.py
+++ b/main.py
@@ -156,7 +156,7 @@ class MainApp(QWidget):
self.paused = False
@pyqtSlot()
- def load_excel(self):
+ def load_excel_ini(self):
fileName, _ = QFileDialog.getOpenFileName(self, 'Open Excel File', '', 'Excel Files (*.xlsx *.xls)')
if fileName:
byte_size = self.byteSizeSpinBox.value()
@@ -179,9 +179,41 @@ class MainApp(QWidget):
self.logger.error(f"파일을 불러오는 중 오류가 발생했습니다: {e}")
QMessageBox.critical(self, "오류", "파일을 불러오는 중 오류가 발생했습니다. 파일 형식을 확인해주세요.")
+
+ @pyqtSlot()
+ def load_excel(self):
+ fileName, _ = QFileDialog.getOpenFileName(self, 'Open Excel File', '', 'Excel Files (*.xlsx *.xls)')
+ if fileName:
+ byte_size = self.byteSizeSpinBox.value()
+ try:
+ df = pd.read_excel(fileName, sheet_name=0)
+ first_column_name = df.columns[0]
+ non_empty_data = df[first_column_name].dropna()
+ unique_data = non_empty_data.drop_duplicates()
+ filtered_data = [data for data in unique_data if len(str(data).encode('utf-8')) >= byte_size]
+
+ # 데이터를 QTextEdit 위젯에 표시
+ self.dataDisplay.clear()
+ self.dataDisplay.append("\n".join([str(data) for data in filtered_data]))
+
+ # 프로그레스바와 레이블 업데이트
+ self.progressBar.setMaximum(len(unique_data))
+ self.loadedCountLabel.setText(f"불러온 갯수: {len(filtered_data)}")
+
+ self.deleting_data = filtered_data
+ self.logger.debug(f'{fileName} 파일에서 중복 제거 후 {len(filtered_data)}개의 적합한 데이터를 성공적으로 불러왔습니다.')
+ except Exception as e:
+ self.logger.error(f"파일을 불러오는 중 오류가 발생했습니다: {e}")
+ QMessageBox.critical(self, "오류", "파일을 불러오는 중 오류가 발생했습니다. 파일 형식을 확인해주세요.")
+
+
@pyqtSlot()
def start_browser_action(self):
selected_market = next((btn.text() for btn in self.marketButtons.values() if btn.isChecked()), None)
+ if not selected_market: # 마켓이 선택되지 않았을 경우
+ QMessageBox.warning(self, "경고", "마켓을 선택해주세요.")
+ return # 경고창을 표시하고 함수를 더 이상 진행하지 않음
+
if selected_market:
urls = {
"쿠팡": "https://xauth.coupang.com/auth/realms/seller/protocol/openid-connect/auth?response_type=code&client_id=wing&redirect_uri=https%3A%2F%2Fwing.coupang.com%2Fsso%2Flogin?returnUrl%3D%252F&state=794abcff-4d9d-4460-86d8-e0efba1b97c2&login=true&scope=openid",
@@ -191,15 +223,16 @@ class MainApp(QWidget):
"ESM": "https://signin.esmplus.com/login"
}
url = urls.get(selected_market)
- if not selected_market:
- QMessageBox.warning(self, "경고", "마켓을 선택해 주세요.")
+ if url:
+ if self.browser_thread and self.browser_thread.isRunning():
+ QMessageBox.warning(self, "경고", "이미 실행 중인 작업이 있습니다.")
else:
- if self.browser_thread and self.browser_thread.isRunning():
- QMessageBox.warning(self, "경고", "이미 실행 중인 작업이 있습니다.")
- else:
- self.browser_thread = BrowserThread(url, selected_market, self.deleting_data, self.logger)
- self.browser_thread.progress_updated.connect(self.update_progress_bar)
- self.browser_thread.start()
+ self.browser_thread = BrowserThread(url, selected_market, self.deleting_data, self.logger)
+ self.browser_thread.progress_updated.connect(self.update_progress_bar)
+ self.browser_thread.start()
+ else:
+ QMessageBox.critical(self, "오류", "선택한 마켓의 URL 정보가 없습니다.")
+
@pyqtSlot()
def delete_products(self):
diff --git a/prompt.txt b/prompt.txt
new file mode 100644
index 0000000..332b9dc
--- /dev/null
+++ b/prompt.txt
@@ -0,0 +1,148 @@
+너는 파이썬 프로그래밍 전문가지? 나는 아래의 동작을 하는 간단한 프로그램을 만들고 싶어하는 사업가야. 내게 친절하고 자세하게 설명해 주면서 프로그램을 만드는데 도와줄꺼지??
+하나하나 차근차근 단계별로 만들어가보자.
+
+pyqt5로 gui인터페이스를 가진 간단한 프로그램을 만들어줘.
+디버깅을 위해 아래에 첨부한 로깅모듈을 넣고, 레벨은 디버그로 설정, 각 동작마다 디버그메세지를 출력해줘. 콘솔과 파일 모두 출력되어야 해.
+그리고 예외처리를 위해 모든 동작들은 강건하게 처리되어야 하고, 로그메세지에는 exc_info=true 설정이 되어있어야 해.
+playwright동작 부분은 별도의 클래스와 클래스 메서드로 만들어져서 모듈화를 시키고 유지보수성을 향상시켜야 해.
+
+GUI구성
+화면구성은 간단해.
+1. 엑셀파일 불러오기 버튼으로 엑셀파일을 불러와.
+2. 라디오 박스가 5개 있어. 각 라벨은 "쿠팡, 스스, 11번가, 롯데온, ESM"이야.
+3. 브라우저 실행 버튼이 있고, 이걸 누르면 비동기 playwright가 실행되. 이때 접속하는 url은 라디오 박스에서 선택한 사이트의 판매자센터로 접속해.
+4. 삭제실행 버튼이 있고, 이걸 누르면 삭제메서드를 불러와 실행되.
+5. 중지버튼이 있고, 이 버튼은 삭제실행의 메서드를 중지시켜. 이렇게 되면 중지 버튼의 텍스트는 "계속"으로 바껴.
+6. 진행상태 프로그레스바 가 있어.
+7. 항상위 버튼 체크박스가 있어. 이걸 체크하면 현재 실행중인 프로그램이 항상위로 설정되.
+8. 인증요청 버튼이 있고, 해당 버튼을 누르면 서버에서 인증키를 발급하고 해당 키를 프로그램 설정에 자동으로 입력되.
+
+
+# 로그 및 서버설정
+프로그램이 실행되면 mongoDB를 이용해 사용자 인증을 거치고, 인증된 PC는 로그를 기록해야 해. 인증 콜렉션은
+SideProject 데이터베이스에 WRMC_DeleteProduct_Log 콜렉션에 접속한 PC의 IP와 PC이름, 접속한 시간이 기록되어야 해.
+(데이터베이스와 콜렉션이 존재하지 않으면 생성해야 해)
+그리고 프로그램이 종료되면 (사용자가 종료하든, 예외발생이나 강제종료로 종료되든) 프로그램 로그를 해당 PC에 기록해 줘.
+
+
+동작구성
+1. 엑셀파일 불러오기 버튼을 누르면 파일 다이알로그가 열리고, 엑셀파일을 선택해.
+그리고 입력받은 엑셀파일의 첫 열에서 값들을 가져와 일정 바이트 이상의 길이인 셀값을 deleting_data 리스트 변수로 넣어줘.
+
+2. 보통 해당값은 10개~200개 사이의 값이 될꺼야. 이 전체 갯수는 진행상태 프로그레스 바에 사용될꺼야.
+
+3. 라디오박스에서 선택되는 마켓들마다 playwright에서 접속하는 주소가 달라져.
+쿠팡 : https://xauth.coupang.com/auth/realms/seller/protocol/openid-connect/auth?response_type=code&client_id=wing&redirect_uri=https%3A%2F%2Fwing.coupang.com%2Fsso%2Flogin?returnUrl%3D%252F&state=794abcff-4d9d-4460-86d8-e0efba1b97c2&login=true&scope=openid
+스스 : https://accounts.commerce.naver.com/login?url=https%3A%2F%2Fsell.smartstore.naver.com%2F%23%2Flogin-callback
+11번가 : https://login.11st.co.kr/auth/front/selleroffice/login.tmall?returnURL=https%3A%2F%2Fsoffice.11st.co.kr%2F
+롯데온 : https://store.lotteon.com/cm/main/login_SO.wsp
+ESM : https://signin.esmplus.com/login
+
+4. 브라우저 실행버튼을 누르면 playwright는 비동기로 실행되어서 라디오 버튼에서 선택된 사이트로 접속되. 이때 gui프로그램의 응답성을 위해 비동기로 실행되고 사용자와 상호작용하도록 해야해. 실행모드는 headless=False야.
+5. 브라우저가 실행되어 해당 마켓에 접속되면 사용자는 아이디와 비밀번호를 입력하고 해당 마켓에 접속 후, 상품수정페이지로 접속할 꺼야.
+6. 상품수정 페이지에 접속완료되면 사용자는 삭제실행 버튼을 누를꺼야.
+7. 삭제 실행 메서드의 동작은 playwright에서 접속된 사이트의 상품수정 페이지에서 동작해. deleting_data 리스트의 값을 순차적으로 "검색어" xpath에 넣고, "검색" xpath 버튼을 눌러. 그리고 검색결과가 나오면 "체크박스" xpath를 클릭하고, "삭제" xpath 버튼을 누를꺼야. 그럼 "검색결과" xpath에는 아무 데이터가 없어.
+8. 7의 동작은 리스트에 있는 모든 값을 순차적으로 실행하면되. 1건 삭제동작이 성공하면 진행상태 프로그레스 바를 업데이트 시켜줘.
+9. 동작 중 사용자가 중지버튼을 누르면 7의 동작은 중지되어야 해. 그리고 중지버튼의 텍스트는 "계속"으로 바껴. 그리고 사용자가 다시 "계속"텍스트로 바뀐 중지버튼을 누르면 7의 동작이 멈춘 부분부터 다시 재개되.
+10. deleting_data 리스트의 끝에 다다르면 프로그레스바는 100%가 되어있을 것이고, 사용자에게 작업완료 라는 텍스트 메세지를 띄워줘.
+
+11. 웹요소는 아래와 같아.
+[ESM]
+1.검색어 입력 박스
+ - 웹 요소 :
+ - XPATH : /html/body/div[1]/div[3]/div[3]/div/div[1]/div[1]/dl[1]/dd/div/textarea
+
+2.검색버튼
+ - 웹 요소 :
+
+
+ - XPATH : /html/body/div[1]/div[3]/div[3]/div/div[3]/div[2]/a[1]
+
+3. 체크박스
+ - 웹 요소 체크상태 :