웨일 추가

This commit is contained in:
Envy_PC 2025-01-06 23:10:01 +09:00
parent 562c88aa8e
commit 4426a3b978
4 changed files with 437 additions and 18 deletions

64
cp.py Normal file
View File

@ -0,0 +1,64 @@
import psutil
import os
import subprocess
import pygetwindow as gw
import glob # glob 모듈 import
def is_program_running(process_name):
"""프로세스 이름을 기준으로 프로그램 실행 여부 확인"""
for proc in psutil.process_iter(attrs=["pid", "name"]):
if process_name.lower() in proc.info["name"].lower():
return proc.info["pid"]
return None
def focus_window_by_title(title_start):
"""창 제목이 특정 문자열로 시작하는 창을 찾아 활성화"""
for window in gw.getAllWindows():
if window.title and window.title.startswith(title_start): # 창 제목이 조건에 맞는 경우
try:
window.activate()
print(f"프로그램 창으로 전환: {window.title}")
return True
except Exception as e:
print(f"창 활성화 실패: {e}")
return False
return False
def find_shortcut_in_start_menu(shortcut_name):
"""시작 메뉴에서 바로가기 찾기"""
user_start_menu = os.path.expandvars(r"%APPDATA%\Microsoft\Windows\Start Menu\Programs")
all_users_start_menu = os.path.expandvars(r"%ProgramData%\Microsoft\Windows\Start Menu\Programs")
for start_menu_path in [user_start_menu, all_users_start_menu]:
shortcut_path = glob.glob(os.path.join(start_menu_path, f"**\\{shortcut_name}.lnk"), recursive=True)
if shortcut_path:
return shortcut_path[0]
return None
def run_program(shortcut_path):
"""프로그램 실행"""
try:
subprocess.Popen([shortcut_path], shell=True)
print(f"프로그램 실행: {shortcut_path}")
except Exception as e:
print(f"프로그램 실행 실패: {e}")
if __name__ == "__main__":
program_name = "@카피맨.exe"
shortcut_name = "@카피맨"
window_title_start = "카피맨" # 창 제목이 "카피맨"으로 시작하는지 확인
# 프로그램 실행 여부 확인
pid = is_program_running(program_name)
if pid:
print(f"{program_name} 실행 중 (PID: {pid})")
# 실행 중인 프로그램 창으로 전환
if not focus_window_by_title(window_title_start):
print(f"'{window_title_start}'로 시작하는 창을 찾을 수 없습니다.")
else:
print(f"{program_name} 실행 중이 아님. 실행 시도 중...")
# 바로가기를 찾아 실행
shortcut_path = find_shortcut_in_start_menu(shortcut_name)
if shortcut_path:
run_program(shortcut_path)
else:
print(f"'{shortcut_name}' 바로가기를 찾을 수 없습니다.")

304
main.py
View File

@ -1,15 +1,19 @@
import sys
import os
import sqlite3
import subprocess
import json
from datetime import datetime, time
import logging
import traceback
import os
import sys
import winreg
import psutil
import subprocess
import pygetwindow as gw
import glob
import pandas as pd
from PySide6.QtWidgets import (
QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QLineEdit,
QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QLineEdit, QButtonGroup, QRadioButton,
QComboBox, QSpinBox, QCheckBox, QProgressBar, QTextEdit, QFileDialog, QWidget, QMessageBox, QDialog, QTableWidget, QTableWidgetItem, QAbstractItemView, QDialogButtonBox
)
from PySide6.QtCore import Qt, QThread, Signal, QSettings
@ -19,12 +23,13 @@ class BookmarkWorker(QThread):
log = Signal(str)
completed = Signal() # 작업 완료 시 호출
def __init__(self, bookmarks, folder_name, bookmarks_path, chrome_path, remove_existing):
def __init__(self, bookmarks, folder_name, bookmarks_path, browser_path, selected_browser, remove_existing):
super().__init__()
self.bookmarks = bookmarks
self.folder_name = folder_name
self.bookmarks_path = bookmarks_path
self.chrome_path = chrome_path
self.browser_path = browser_path
self.selected_browser = selected_browser
self.remove_existing = remove_existing
def run(self):
@ -104,12 +109,11 @@ class BookmarkWorker(QThread):
self.log.emit("즐겨찾기 추가 작업이 완료되었습니다!")
# 작업 완료 시 크롬 실행
if os.path.exists(self.chrome_path):
subprocess.Popen([self.chrome_path, "chrome://bookmarks/"])
self.log.emit("크롬 북마크 관리 페이지를 열었습니다.")
else:
self.log.emit(f"크롬 실행 파일을 찾을 수 없습니다: {self.chrome_path}")
# 작업 완료 시 브라우저 실행
self.run_browser_with_profile(self.browser_path, self.bookmarks_path, browser_name=self.selected_browser)
# 작업 완료 후 '카피맨' 실행 및 창 활성화
self.run_and_focus_copyman()
self.completed.emit()
@ -117,6 +121,112 @@ class BookmarkWorker(QThread):
self.log.emit(f"오류 발생: {str(e)}", exc_info=True)
self.progress.emit(0)
# 작업 완료 시 브라우저 실행
def run_browser_with_profile(self, browser_path, bookmarks_path, browser_name="브라우저"):
if "웨일" in browser_name:
# 실행 중인 웨일 프로세스를 강제 종료
for proc in psutil.process_iter(attrs=["pid", "name"]):
if "whale" in proc.info["name"].lower():
try:
proc.terminate() # 프로세스 종료
proc.wait(timeout=5) # 종료 대기
self.log.emit("웨일 브라우저의 기존 프로세스를 종료했습니다.")
except Exception as e:
self.log.emit(f"웨일 브라우저 프로세스 종료 중 오류 발생: {str(e)}")
if os.path.exists(browser_path):
# 북마크 경로에서 프로필 이름 추출
profile_directory = os.path.basename(os.path.dirname(bookmarks_path))
# 접속 URL 설정
if "크롬" in browser_name.lower():
bookmark_page = "chrome://bookmarks/"
elif "웨일" in browser_name.lower():
bookmark_page = "whale://bookmarks/"
else:
bookmark_page = "about:blank" # 기본값 (알 수 없는 브라우저)
if profile_directory: # 유효한 프로필 디렉토리가 있는 경우
subprocess.Popen([
browser_path,
f"--profile-directory={profile_directory}",
bookmark_page
])
self.log.emit(f"{browser_name} 북마크 관리 페이지를 '{profile_directory}' 프로필로 열었습니다.")
else:
# 프로필 경로를 찾을 수 없는 경우 기본 실행
subprocess.Popen([browser_path, bookmark_page])
self.log.emit(f"{browser_name} 북마크 관리 페이지를 기본 프로필로 열었습니다.")
else:
self.log.emit(f"{browser_name} 실행 파일을 찾을 수 없습니다: {browser_path}")
def run_and_focus_copyman(self):
"""
'카피맨' 프로그램을 실행하고 해당 창으로 포커스를 전환하는 메서드
"""
program_name = "@카피맨.exe"
shortcut_name = "@카피맨"
window_title_start = "카피맨" # 창 제목이 "카피맨"으로 시작하는지 확인
try:
# 프로그램 실행 여부 확인
pid = self.is_program_running(program_name)
if pid:
self.log.emit(f"{program_name} 실행 중 (PID: {pid})")
# 실행 중인 프로그램 창으로 전환
if not self.focus_window_by_title(window_title_start):
self.log.emit(f"'{window_title_start}'로 시작하는 창을 찾을 수 없습니다.")
else:
self.log.emit(f"{program_name} 실행 중이 아님. 실행 시도 중...")
# 바로가기를 찾아 실행
shortcut_path = self.find_shortcut_in_start_menu(shortcut_name)
if shortcut_path:
self.run_program(shortcut_path)
else:
self.log.emit(f"'{shortcut_name}' 바로가기를 찾을 수 없습니다.")
except Exception as e:
error_traceback = traceback.format_exc()
self.log.emit(f"카피맨 실행 중 오류 발생: {str(e)}\n{error_traceback}")
def is_program_running(self, process_name):
"""프로세스 이름을 기준으로 프로그램 실행 여부 확인"""
for proc in psutil.process_iter(attrs=["pid", "name"]):
if process_name.lower() in proc.info["name"].lower():
return proc.info["pid"]
return None
def focus_window_by_title(self, title_start):
"""창 제목이 특정 문자열로 시작하는 창을 찾아 활성화"""
for window in gw.getAllWindows():
if window.title and window.title.startswith(title_start): # 창 제목이 조건에 맞는 경우
try:
window.activate()
self.log.emit(f"프로그램 창으로 전환: {window.title}")
return True
except Exception as e:
self.log.emit(f"창 활성화 실패: {e}")
return False
return False
def find_shortcut_in_start_menu(self, shortcut_name):
"""시작 메뉴에서 바로가기 찾기"""
user_start_menu = os.path.expandvars(r"%APPDATA%\Microsoft\Windows\Start Menu\Programs")
all_users_start_menu = os.path.expandvars(r"%ProgramData%\Microsoft\Windows\Start Menu\Programs")
for start_menu_path in [user_start_menu, all_users_start_menu]:
shortcut_path = glob.glob(os.path.join(start_menu_path, f"**\\{shortcut_name}.lnk"), recursive=True)
if shortcut_path:
return shortcut_path[0]
return None
def run_program(self, shortcut_path):
"""프로그램 실행"""
try:
subprocess.Popen([shortcut_path], shell=True)
self.log.emit(f"프로그램 실행: {shortcut_path}")
except Exception as e:
self.log.emit(f"프로그램 실행 실패: {e}")
def remove_existing_bookmarks(self, node):
"""
북마크 데이터를 재귀적으로 탐색하여 '거상북마크' 시작하는 모든 폴더를 제거합니다.
@ -175,6 +285,7 @@ class MainWindow(QMainWindow):
self.layout = QVBoxLayout()
self.buttons_layout = QHBoxLayout()
self.filter_layout = QHBoxLayout()
self.browser_selection_layout = QHBoxLayout()
# DB 입력 버튼
self.db_input_button = QPushButton("DB 입력")
@ -191,6 +302,22 @@ class MainWindow(QMainWindow):
self.view_data_button.setEnabled(False)
self.view_data_button.clicked.connect(self.view_data)
# 브라우저 경로 설정 버튼
self.chrome_path_button = QPushButton("크롬 경로 설정")
self.chrome_path_button.clicked.connect(self.set_chrome_path)
self.whale_path_button = QPushButton("웨일 경로 설정")
self.whale_path_button.clicked.connect(self.set_whale_path)
# 브라우저 선택 라디오버튼
self.chrome_radio = QRadioButton("크롬")
self.whale_radio = QRadioButton("웨일")
self.whale_radio.clicked.connect(self.whale_radio_clicked)
self.browser_group = QButtonGroup()
self.browser_group.addButton(self.chrome_radio)
self.browser_group.addButton(self.whale_radio)
self.chrome_radio.setChecked(True) # 기본값: 크롬
# 드롭다운: 국가
self.country_label = QLabel("국가")
self.country_dropdown = QComboBox()
@ -239,7 +366,19 @@ class MainWindow(QMainWindow):
self.filter_layout.addWidget(QLabel(" "))
self.filter_layout.addWidget(self.remove_existing_checkbox)
# 버튼 레이아웃 구성
# # 버튼 레이아웃 구성
# self.buttons_layout.addWidget(self.chrome_path_button)
# self.buttons_layout.addWidget(self.whale_path_button)
# 브라우저 선택 레이아웃 구성
self.browser_selection_layout.addWidget(QLabel("브라우저 선택:"))
self.browser_selection_layout.addWidget(self.chrome_radio)
self.browser_selection_layout.addWidget(self.whale_radio)
self.browser_selection_layout.addWidget(self.chrome_path_button)
self.browser_selection_layout.addWidget(self.whale_path_button)
self.buttons_layout.addWidget(self.db_input_button)
self.buttons_layout.addWidget(self.remove_db_checkbox)
self.buttons_layout.addWidget(self.view_data_button)
@ -248,6 +387,7 @@ class MainWindow(QMainWindow):
# 메인 레이아웃 구성
self.layout.addLayout(self.filter_layout)
self.layout.addLayout(self.buttons_layout)
self.layout.addLayout(self.browser_selection_layout)
self.layout.addWidget(self.log_box)
self.layout.addWidget(self.progress_bar)
@ -262,6 +402,89 @@ class MainWindow(QMainWindow):
# DB 파일 확인
self.check_db()
# 브라우저 선택 복원
self.restore_browser_selection()
# 브라우저 선택 상태 변경 시 QSettings에 저장
self.chrome_radio.toggled.connect(self.save_browser_selection)
self.whale_radio.toggled.connect(self.save_browser_selection)
# 크롬/웨일 경로 초기화
self.chrome_path = self.get_browser_path("chrome") or "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
self.chrome_bookmarks_path = os.path.join(
self.get_specific_profile_path("chrome"), "Bookmarks"
) if self.get_specific_profile_path("chrome") else ""
self.whale_path = self.get_browser_path("whale") or "C:\\Program Files\\Naver\\Naver Whale\\Application\\whale.exe"
self.whale_bookmarks_path = os.path.join(
self.get_specific_profile_path("whale"), "Bookmarks"
) if self.get_specific_profile_path("whale") else ""
self.log(f"크롬 실행 파일 경로가 설정되었습니다: {self.chrome_path}")
self.log(f"웨일 실행 파일 경로가 설정되었습니다: {self.whale_path}")
self.log(f"크롬 프로파일 경로가 설정되었습니다: {self.chrome_bookmarks_path}")
self.log(f"웨일 프로파일 경로가 설정되었습니다: {self.whale_bookmarks_path}")
# 브라우저 실행 파일 경로 가져오기
def get_browser_path(self, browser_name):
try:
reg_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths"
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, f"{reg_path}\\{browser_name}.exe") as key:
return winreg.QueryValue(key, None)
except FileNotFoundError:
return None
# 브라우저 프로파일 경로 가져오기
def get_browser_profile_path(self, browser_name):
if browser_name == "chrome":
return os.path.expandvars(r"%LOCALAPPDATA%\Google\Chrome\User Data")
elif browser_name == "whale":
return os.path.expandvars(r"%LOCALAPPDATA%\Naver\Naver Whale\User Data")
return None
# 기본 프로파일 경로 가져오기
def get_specific_profile_path(self, browser_name, profile_name="Default"):
"""
주어진 브라우저 이름에 따라 프로필 경로를 찾고 Bookmarks 파일이 존재하는 폴더를 반환합니다.
:param browser_name: 브라우저 이름 ("chrome" 또는 "whale")
:param profile_name: 기본 프로필 이름 (기본값은 "Default")
:return: Bookmarks 파일이 존재하는 프로필 경로 또는 None
"""
base_profile_path = self.get_browser_profile_path(browser_name)
if not base_profile_path:
return None
# 확인 순서: Default -> Profile 1 -> Profile 2 -> ...
profile_names = [profile_name] + [f"Profile {i}" for i in range(1, 10)] # 최대 10개의 프로필 확인
for profile in profile_names:
specific_profile_path = os.path.join(base_profile_path, profile)
bookmarks_file = os.path.join(specific_profile_path, "Bookmarks")
if os.path.exists(bookmarks_file):
self.log(f"'{profile}' 프로필에서 Bookmarks 파일을 찾았습니다: {bookmarks_file}")
return specific_profile_path
# Bookmarks 파일이 없는 경우 None 반환
self.log(f"'{browser_name}' 브라우저에서 유효한 Bookmarks 파일을 찾을 수 없습니다.")
return None
def set_chrome_path(self):
"""크롬 실행 파일 경로 설정"""
file_path, _ = QFileDialog.getOpenFileName(self, "크롬 실행 파일 선택", "", "Executable Files (*.exe)")
if file_path:
self.chrome_path = file_path
self.log(f"크롬 실행 파일 경로가 설정되었습니다: {file_path}")
def set_whale_path(self):
"""웨일 실행 파일 경로 설정"""
file_path, _ = QFileDialog.getOpenFileName(self, "웨일 실행 파일 선택", "", "Executable Files (*.exe)")
if file_path:
self.whale_path = file_path
self.log(f"웨일 실행 파일 경로가 설정되었습니다: {file_path}")
def show_password_dialog(self):
"""비밀번호 입력 창을 표시"""
dialog = QDialog(self)
@ -307,6 +530,24 @@ class MainWindow(QMainWindow):
else:
self.password = None
def save_browser_selection(self):
"""사용자가 선택한 브라우저를 QSettings에 저장"""
if self.chrome_radio.isChecked():
self.settings.setValue("selected_browser", "chrome")
self.log("사용자가 크롬 브라우저를 선택했습니다.")
elif self.whale_radio.isChecked():
self.settings.setValue("selected_browser", "whale")
self.log("사용자가 웨일 브라우저를 선택했습니다.")
def restore_browser_selection(self):
"""QSettings에서 저장된 브라우저 선택 상태를 복원"""
selected_browser = self.settings.value("selected_browser", "chrome") # 기본값은 크롬
if selected_browser == "chrome":
self.chrome_radio.setChecked(True)
elif selected_browser == "whale":
self.whale_radio.setChecked(True)
self.log(f"저장된 브라우저 선택을 복원했습니다: {selected_browser}")
def log(self, message, exc_info=False):
"""
메시지를 로그에 출력하고, GUI 로그 박스에도 표시
@ -466,6 +707,14 @@ class MainWindow(QMainWindow):
except Exception as e:
QMessageBox.critical(self, "오류", f"DB 데이터를 불러오는 중 오류 발생: {e}", exc_info=True)
# 웨일 라디오 버튼 클릭 이벤트 처리 메서드
def whale_radio_clicked(self):
# 메세지 창 띄우기
QMessageBox.warning(
self,
"주의!!",
"웨일의 경우 현재 실행된 웨일브라우저를 강제종료합니다."
)
def sort_table(self, table, column_index):
"""
@ -540,10 +789,33 @@ class MainWindow(QMainWindow):
return
folder_name = f"거상북마크-{grade}"
self.bookmarks_path = os.path.expanduser(r"~\AppData\Local\Google\Chrome\User Data\Default\Bookmarks")
self.chrome_path = r"C:\Program Files\Google\Chrome\Application\chrome.exe"
self.worker = BookmarkWorker(self.bookmarks, folder_name, self.bookmarks_path, self.chrome_path, remove_existing)
# 사용자가 선택한 브라우저에 따라 경로 설정
if self.chrome_radio.isChecked():
selected_bookmarks_path = self.chrome_bookmarks_path
selected_browser_path = self.chrome_path
selected_browser = '크롬'
self.log("크롬 브라우저가 선택되었습니다.")
elif self.whale_radio.isChecked():
selected_bookmarks_path = self.whale_bookmarks_path
selected_browser_path = self.whale_path
selected_browser = '웨일'
self.log("웨일 브라우저가 선택되었습니다.")
else:
QMessageBox.warning(self, "브라우저 선택 오류", "브라우저를 선택해주세요.")
return
# 선택된 브라우저 경로 유효성 확인
if not os.path.exists(selected_browser_path):
QMessageBox.warning(self, "브라우저 경로 오류", "선택된 브라우저 실행 파일 경로가 유효하지 않습니다. 경로를 설정해주세요.")
return
if not os.path.exists(selected_bookmarks_path):
QMessageBox.warning(self, "북마크 경로 오류", "선택된 브라우저의 북마크 경로가 유효하지 않습니다. 경로를 설정해주세요.")
return
self.worker = BookmarkWorker(self.bookmarks, folder_name, selected_bookmarks_path, selected_browser_path, selected_browser, remove_existing)
self.worker.progress.connect(self.progress_bar.setValue)
self.worker.log.connect(self.log)
self.worker.completed.connect(self.task_completed)

View File

@ -4,7 +4,7 @@ import sys
# 애플리케이션 이름과 버전
application_name = "크롬 즐겨찾기 추가 프로그램"
application_version = "1.0.0"
application_version = "1.1"
# 실행 파일 생성 설정
base = None
@ -21,7 +21,7 @@ include_files = [
# 빌드 옵션
build_options = {
"packages": ["os", "sys", "sqlite3", "subprocess", "json", "pandas", "datetime", "PySide6"],
"packages": ["os", "sys", "sqlite3", "subprocess", "psutil", "pygetwindow", "glob","json", "pandas", "datetime", "PySide6"],
"include_files": include_files,
"excludes": [], # tkinter 미사용 시 제외
}

83
test1.py Normal file
View File

@ -0,0 +1,83 @@
import winreg
import os
def get_browser_path(browser_name):
try:
# 레지스트리 경로 설정
reg_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths"
# 레지스트리 키 열기
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, f"{reg_path}\\{browser_name}.exe") as key:
# 브라우저 설치 경로 가져오기
browser_path = winreg.QueryValue(key, None)
return browser_path
except FileNotFoundError:
return None
def get_specific_profile_path(browser_name, profile_name="Default"):
base_profile_path = get_browser_profile_path(browser_name)
if base_profile_path:
# 기본 프로파일 확인
specific_profile_path = os.path.join(base_profile_path, profile_name)
if os.path.exists(specific_profile_path):
return specific_profile_path
else:
# 기본 프로파일이 없으면 Profile 1 확인
fallback_profile_path = os.path.join(base_profile_path, "Profile 1")
return fallback_profile_path if os.path.exists(fallback_profile_path) else None
return None
def get_browser_profile_path(browser_name):
try:
# 레지스트리 경로 설정
reg_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths"
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, f"{reg_path}\\{browser_name}.exe") as key:
# 브라우저 설치 경로 가져오기
browser_path = winreg.QueryValue(key, None)
# 설치 경로에서 기본 프로파일 경로 추정
if browser_name == "chrome":
profile_path = os.path.expandvars(r"%LOCALAPPDATA%\Google\Chrome\User Data")
elif browser_name == "whale":
profile_path = os.path.expandvars(r"%LOCALAPPDATA%\Naver\Naver Whale\User Data")
else:
return None
return profile_path if os.path.exists(profile_path) else None
except FileNotFoundError:
return None
if __name__ == "__main__":
# Chrome 브라우저 경로 가져오기
chrome_path = get_browser_path("chrome")
if chrome_path:
print(f"Chrome 설치 경로: {chrome_path}")
else:
print("Chrome 브라우저가 설치되어 있지 않습니다.")
# Whale 브라우저 경로 가져오기
whale_path = get_browser_path("whale")
if whale_path:
print(f"Whale 설치 경로: {whale_path}")
else:
print("Whale 브라우저가 설치되어 있지 않습니다.")
# Chrome 브라우저 프로파일 경로 가져오기
chrome_profile = get_browser_profile_path("chrome")
if chrome_profile:
print(f"Chrome 프로파일 경로: {chrome_profile}")
else:
print("Chrome 브라우저 프로파일 경로를 찾을 수 없습니다.")
# Whale 브라우저 프로파일 경로 가져오기
whale_profile = get_browser_profile_path("whale")
if whale_profile:
print(f"Whale 프로파일 경로: {whale_profile}")
else:
print("Whale 브라우저 프로파일 경로를 찾을 수 없습니다.")
# Chrome의 기본 프로파일 경로
chrome_default_profile = get_specific_profile_path("chrome")
print(f"Chrome 기본 프로파일 (Default 없으면 Profile 1): {chrome_default_profile}")
# Whale의 기본 프로파일 경로
whale_default_profile = get_specific_profile_path("whale")
print(f"Whale 기본 프로파일 (Default 없으면 Profile 1): {whale_default_profile}")