Browse Source

Merge commit 'baa4c82cc04f03d4d4a4171eb351bcfa83100d6b' into develop

liuyuqi-cnb 3 months ago
parent
commit
7d5c95d1a5
3 changed files with 237 additions and 1 deletions
  1. 2 0
      repo_sync/__init__.py
  2. 232 0
      repo_sync/gui_main.py
  3. 3 1
      requirements.txt

+ 2 - 0
repo_sync/__init__.py

@@ -18,3 +18,5 @@ def main(argv=None):
         rs.run()
     except KeyboardInterrupt:
         sys.exit('\nERROR: Interrupted by user')
+
+# GUI入口预留

+ 232 - 0
repo_sync/gui_main.py

@@ -0,0 +1,232 @@
+import sys
+import os
+from PyQt5.QtWidgets import (
+    QApplication, QTabWidget, QWidget, QVBoxLayout, QHBoxLayout, QLabel, 
+    QRadioButton, QPushButton, QButtonGroup, QGroupBox, QMessageBox, 
+    QLineEdit, QScrollArea, QFileDialog, QFormLayout, QCheckBox
+)
+from PyQt5.QtCore import Qt
+from repo_sync import RepoSync, __version__
+from dotenv import load_dotenv, set_key, find_dotenv
+import json
+
+# Explorer路径获取
+try:
+    import win32com.client
+    def get_active_explorer_path():
+        shell = win32com.client.Dispatch("Shell.Application")
+        for window in shell.Windows():
+            if window.Name in ["文件资源管理器", "Windows Explorer"]:
+                return window.Document.Folder.Self.Path
+        return os.getcwd()
+except ImportError:
+    def get_active_explorer_path():
+        return os.getcwd()
+
+class MainTab(QWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent)
+        layout = QVBoxLayout()
+        
+        # 路径选择
+        path_layout = QHBoxLayout()
+        self.path_label = QLabel("Local Path: ")
+        self.path_edit = QLineEdit()
+        self.path_edit.setText(get_active_explorer_path())
+        self.path_btn = QPushButton("Browse...")
+        self.path_btn.clicked.connect(self.choose_path)
+        path_layout.addWidget(self.path_label)
+        path_layout.addWidget(self.path_edit)
+        path_layout.addWidget(self.path_btn)
+        layout.addLayout(path_layout)
+        
+        # 操作
+        op_group = QGroupBox("Operation:")
+        op_layout = QHBoxLayout()
+        self.op_buttons = QButtonGroup(self)
+        for i, op in enumerate(["create", "push", "pull", "clone", "delete"]):
+            btn = QRadioButton(op.capitalize())
+            if i == 0:
+                btn.setChecked(True)
+            self.op_buttons.addButton(btn, i)
+            op_layout.addWidget(btn)
+        op_group.setLayout(op_layout)
+        layout.addWidget(op_group)
+        
+        # 平台
+        pf_group = QGroupBox("Platform:")
+        pf_layout = QHBoxLayout()
+        self.pf_buttons = QButtonGroup(self)
+        self.platforms = ["github", "gitlab", "gitee", "gitcode", "git.yoq.me", "coding", "aliyun", "cnb"]
+        for i, pf in enumerate(self.platforms):
+            btn = QRadioButton(pf.capitalize())
+            if i == 0:
+                btn.setChecked(True)
+            self.pf_buttons.addButton(btn, i)
+            pf_layout.addWidget(btn)
+        pf_group.setLayout(pf_layout)
+        layout.addWidget(pf_group)
+        
+        # run按钮
+        self.run_btn = QPushButton("run it")
+        self.run_btn.clicked.connect(self.run_repo_sync)
+        layout.addWidget(self.run_btn, alignment=Qt.AlignCenter)
+        self.setLayout(layout)
+
+    def choose_path(self):
+        path = QFileDialog.getExistingDirectory(self, "Select Directory")
+        if path:
+            self.path_edit.setText(path)
+
+    def run_repo_sync(self):
+        repo_path = self.path_edit.text().strip()
+        if not repo_path:
+            QMessageBox.warning(self, "Warning", "Please select a local path.")
+            return
+            
+        op_id = self.op_buttons.checkedId()
+        pf_id = self.pf_buttons.checkedId()
+        op = ["create", "push", "pull", "clone", "delete"][op_id]
+        pf = self.platforms[pf_id]
+        
+        # 检查平台配置
+        load_dotenv()
+        if not os.getenv(f"{pf}_token"):
+            QMessageBox.warning(self, "Warning", f"Please configure {pf} token in Settings tab first.")
+            return
+            
+        params = {
+            "command": op,
+            "platform": pf,
+            "repo_path": repo_path,
+            f"{pf}_token": os.getenv(f"{pf}_token"),
+            f"{pf}_username": os.getenv(f"{pf}_username"),
+            f"{pf}_private": os.getenv(f"{pf}_private", "true")
+        }
+        
+        try:
+            rs = RepoSync(params)
+            rs.run()
+            QMessageBox.information(self, "Success", f"Operation '{op}' on '{pf}' finished.")
+        except Exception as e:
+            QMessageBox.critical(self, "Error", str(e))
+
+class SettingsTab(QWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent)
+        self.init_ui()
+        self.load_settings()
+
+    def init_ui(self):
+        layout = QVBoxLayout()
+        
+        # 创建滚动区域
+        scroll = QScrollArea()
+        scroll.setWidgetResizable(True)
+        content = QWidget()
+        self.form_layout = QFormLayout()
+        
+        # 平台配置
+        self.platform_configs = {
+            "github": ["username", "token", "private"],
+            "gitlab": ["host", "username", "token", "private"],
+            "gitee": ["username", "token", "private"],
+            "gitcode": ["username", "token", "private"],
+            "git.yoq.me": ["username", "token", "private"],
+            "coding": ["username", "token", "project", "private"],
+            "aliyun": ["compoanyid", "group_id", "username", "token", "private"],
+            "cnb": ["username", "token", "private"]
+        }
+        
+        self.config_widgets = {}
+        for platform, fields in self.platform_configs.items():
+            group = QGroupBox(platform.capitalize())
+            group_layout = QFormLayout()
+            
+            platform_widgets = {}
+            for field in fields:
+                if field == "private":
+                    widget = QCheckBox()
+                    widget.setChecked(True)
+                else:
+                    widget = QLineEdit()
+                    if field in ["token", "password"]:
+                        widget.setEchoMode(QLineEdit.Password)
+                
+                field_name = f"{platform}_{field}"
+                platform_widgets[field_name] = widget
+                group_layout.addRow(f"{field.capitalize()}:", widget)
+            
+            self.config_widgets.update(platform_widgets)
+            group.setLayout(group_layout)
+            self.form_layout.addRow(group)
+        
+        # 保存按钮
+        self.save_btn = QPushButton("Save Settings")
+        self.save_btn.clicked.connect(self.save_settings)
+        
+        content.setLayout(self.form_layout)
+        scroll.setWidget(content)
+        layout.addWidget(scroll)
+        layout.addWidget(self.save_btn, alignment=Qt.AlignCenter)
+        self.setLayout(layout)
+
+    def load_settings(self):
+        load_dotenv()
+        for field_name, widget in self.config_widgets.items():
+            value = os.getenv(field_name)
+            if isinstance(widget, QCheckBox):
+                widget.setChecked(value != "false")
+            elif value:
+                widget.setText(value)
+
+    def save_settings(self):
+        env_file = find_dotenv()
+        if not env_file:
+            env_file = os.path.join(os.path.dirname(os.path.dirname(__file__)), '.env')
+        
+        for field_name, widget in self.config_widgets.items():
+            if isinstance(widget, QCheckBox):
+                value = str(widget.isChecked()).lower()
+            else:
+                value = widget.text().strip()
+            
+            if value:
+                set_key(env_file, field_name, value)
+        
+        QMessageBox.information(self, "Success", "Settings saved successfully!")
+
+class AboutTab(QWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent)
+        layout = QVBoxLayout()
+        layout.addWidget(QLabel(f"repo_sync tools v{__version__}"))
+        layout.addWidget(QLabel("作者: liuyuqi.gov@msn.cn"))
+        layout.addWidget(QLabel("GitHub: https://github.com/jianboy/repo_sync"))
+        layout.addWidget(QLabel("\n功能说明:"))
+        layout.addWidget(QLabel("- 支持多个代码托管平台"))
+        layout.addWidget(QLabel("- 支持创建/推送/拉取/克隆/删除操作"))
+        layout.addWidget(QLabel("- 自动获取资源管理器当前路径"))
+        layout.addWidget(QLabel("- 配置信息保存在.env文件中"))
+        self.setLayout(layout)
+
+class RepoSyncMainWindow(QTabWidget):
+    def __init__(self):
+        super().__init__()
+        self.setWindowTitle('repo_sync tools v1.12')
+        self.resize(800, 600)
+        self.main_tab = MainTab()
+        self.addTab(self.main_tab, '主界面')
+        self.settings_tab = SettingsTab()
+        self.addTab(self.settings_tab, '设置')
+        self.about_tab = AboutTab()
+        self.addTab(self.about_tab, '关于')
+
+def main():
+    app = QApplication(sys.argv)
+    window = RepoSyncMainWindow()
+    window.show()
+    sys.exit(app.exec_())
+
+if __name__ == '__main__':
+    main() 

+ 3 - 1
requirements.txt

@@ -1,2 +1,4 @@
 requests==2.27.1
-python-dotenv==1.0.0
+python-dotenv==1.0.0
+PyQt5
+pywin32