Go Bridge 開發 Skill
何時使用此 Skill
當需要:
- •新增 Go CLI 功能(如新增掃描模式、移動策略)
- •修改番號提取邏輯(新增正則模式、調整優先級)
- •整合 Go 功能到 Python GUI(新增按鈕呼叫 Go 功能)
- •處理 Python ↔ Go 資料傳遞問題(JSON 結構不匹配)
- •效能優化(將 Python 慢速操作遷移到 Go)
核心概念
架構設計
code
┌─────────────────┐
│ Python GUI │
│ (main_gui.py) │
└────────┬────────┘
│
▼
┌─────────────────┐ subprocess ┌──────────────────┐
│ GoBridge │ ──────────────────▶ │ classifier.exe │
│ (go_bridge.py) │ ◀────────────────── │ (Go CLI) │
└─────────────────┘ JSON I/O └──────────────────┘
│ │
│ ▼
│ ┌──────────────────┐
│ │ pkg/extractor/ │
│ │ pkg/mover/ │
│ │ pkg/database/ │
└────────────────────────────────│ pkg/studio/ │
共用資料檔案 └──────────────────┘
(data/json_db/data.json)
關鍵原則
- •
Go 負責效能敏感操作
- •檔案掃描(10-20x 加速)
- •批次移動(10x 加速)
- •番號提取(20x 加速)
- •片商識別(10x 加速)
- •
Python 負責業務邏輯與 GUI
- •使用者界面(Tkinter)
- •網路爬蟲(BeautifulSoup)
- •分類決策(女優配對)
- •設定管理(config.ini)
- •
GoBridge 自動 Fallback
pythonif bridge.is_available: result = bridge.scan_directory(dir) # Go 加速 else: result = python_scanner.scan(dir) # 降級到 Python
開發新功能的標準流程
流程 1: 新增 Go CLI 命令
範例:新增「驗證檔案」功能
Step 1: 實作 Go 核心邏輯
bash
# 建立新套件 mkdir pkg\validator
檔案:pkg/validator/validator.go
go
package validator
import (
"fmt"
"os"
"path/filepath"
)
type ValidationResult struct {
Path string `json:"path"`
Valid bool `json:"valid"`
Error string `json:"error,omitempty"`
}
func ValidateFile(path string) (*ValidationResult, error) {
info, err := os.Stat(path)
if err != nil {
return &ValidationResult{
Path: path,
Valid: false,
Error: err.Error(),
}, nil
}
// 驗證邏輯
valid := info.Size() > 0 && !info.IsDir()
return &ValidationResult{
Path: path,
Valid: valid,
}, nil
}
Step 2: 撰寫單元測試
檔案:pkg/validator/validator_test.go
go
package validator
import (
"testing"
)
func TestValidateFile(t *testing.T) {
// 測試有效檔案
result, err := ValidateFile("testdata/valid.mp4")
if err != nil {
t.Fatal(err)
}
if !result.Valid {
t.Errorf("Expected valid file")
}
}
執行測試:
bash
go test ./pkg/validator -v
Step 3: 整合到 CLI
檔案:cmd/scanner/main.go
go
import (
"your-project/pkg/validator"
)
func handleValidate(args []string) {
if len(args) < 1 {
fmt.Fprintln(os.Stderr, "Usage: classifier validate <file>")
os.Exit(1)
}
result, err := validator.ValidateFile(args[0])
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
// 輸出 JSON
enc := json.NewEncoder(os.Stdout)
enc.Encode(result)
}
func main() {
if len(os.Args) < 2 {
printUsage()
os.Exit(1)
}
command := os.Args[1]
switch command {
case "validate":
handleValidate(os.Args[2:])
// ... 其他命令
}
}
Step 4: 重新編譯
bash
# 從專案根目錄 go build -o classifier.exe cmd/scanner/main.go # 測試命令 classifier.exe validate "test.mp4"
Step 5: 整合到 Python
檔案:src/services/go_bridge.py
python
class GoBridge:
def validate_file(self, file_path: str) -> Dict[str, Any]:
"""驗證檔案"""
result = self._run_go_command([
"validate",
file_path
])
return json.loads(result.stdout)
Step 6: 測試 Python 整合
python
from services.go_bridge import GoBridge
bridge = GoBridge()
result = bridge.validate_file("test.mp4")
print(f"Valid: {result['valid']}")
流程 2: 修改番號提取邏輯
範例:新增支援 MGS 番號格式(259LUXU-1234)
Step 1: 編輯提取器
檔案:pkg/extractor/extractor.go
go
func ExtractCode(filename string) string {
patterns := []string{
`[A-Z]+-\d+`, // 標準格式 (STARS-707)
`FC2-PPV-\d+`, // FC2 格式
`\d+[A-Z]+-\d+`, // 新增: MGS 格式 (259LUXU-1234)
}
for _, pattern := range patterns {
re := regexp.MustCompile(pattern)
if match := re.FindString(filename); match != "" {
return strings.ToUpper(match)
}
}
return ""
}
Step 2: 測試
檔案:pkg/extractor/extractor_test.go
go
func TestExtractCodeMGS(t *testing.T) {
tests := []struct {
filename string
want string
}{
{"259LUXU-1234.mp4", "259LUXU-1234"},
{"259luxu-1234.mp4", "259LUXU-1234"},
}
for _, tt := range tests {
got := ExtractCode(tt.filename)
if got != tt.want {
t.Errorf("ExtractCode(%q) = %q; want %q",
tt.filename, got, tt.want)
}
}
}
Step 3: 重新編譯並測試
bash
# 執行測試 go test ./pkg/extractor -v # 重新編譯 go build -o classifier.exe cmd/scanner/main.go # 驗證 classifier.exe scan -dir "測試目錄" | findstr "259LUXU"
無需修改 Python 程式碼 - GoBridge 自動使用新版 CLI!
流程 3: 整合到 GUI
範例:在 GUI 新增「驗證檔案」按鈕
檔案:src/ui/main_gui.py
python
def create_validate_button(self):
"""建立驗證按鈕"""
btn = ttk.Button(
self.button_frame,
text="🔍 驗證檔案",
command=self.validate_files,
style='primary.TButton'
)
btn.pack(side='left', padx=5)
def validate_files(self):
"""驗證檔案(使用 Go 加速)"""
bridge = get_bridge()
if not bridge.is_available:
messagebox.showwarning("警告", "Go CLI 不可用")
return
# 背景執行緒執行
thread = threading.Thread(
target=self._validate_worker,
daemon=True
)
thread.start()
def _validate_worker(self):
"""驗證工作執行緒"""
bridge = get_bridge()
files = self.get_selected_files()
for file in files:
try:
result = bridge.validate_file(file)
# 回到主執行緒更新 UI
self.root.after(0, lambda r=result: self.show_result(r))
except Exception as e:
logger.error(f"❌ 驗證失敗: {e}")
JSON 結構規範
Go 輸出格式
掃描結果:
json
{
"files": [
{
"path": "D:\\Videos\\STARS-707.mp4",
"code": "STARS-707",
"size": 1024000000
}
],
"total": 1,
"duration_ms": 150
}
移動結果:
json
{
"operation_id": "abc123",
"timestamp": "2025-12-22T10:30:00Z",
"items": [
{
"source": "A.mp4",
"destination": "dest/A.mp4",
"success": true,
"error": ""
}
],
"total": 1,
"success": 1,
"failed": 0
}
Python 資料模型
檔案:src/models/go_types.py(建議建立)
python
from dataclasses import dataclass
from typing import List, Optional
@dataclass
class ScanResult:
path: str
code: str
size: int
@dataclass
class ScanResponse:
files: List[ScanResult]
total: int
duration_ms: int
@dataclass
class MoveItem:
source: str
destination: str
success: bool
error: Optional[str] = None
常見問題與解決方法
問題 1: classifier.exe 找不到
症狀:
code
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'classifier.exe'
解決:
bash
# 確認編譯 go build -o classifier.exe cmd/scanner/main.go # 確認位置(應在專案根目錄) dir classifier.exe # 測試 classifier.exe help
問題 2: JSON 解析失敗
症狀:
python
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
原因: Go 輸出到 stderr 而非 stdout
解決:
go
// ❌ 錯誤
fmt.Println("Error:", err) // 預設輸出到 stdout
// ✅ 正確
fmt.Fprintln(os.Stderr, "Error:", err) // 錯誤訊息到 stderr
json.NewEncoder(os.Stdout).Encode(result) // JSON 到 stdout
問題 3: 路徑編碼問題(Windows)
症狀: 中文路徑在 Go 中顯示亂碼
解決:
go
// Go 程式開頭
import (
"syscall"
)
func init() {
// Windows UTF-8 支援
if runtime.GOOS == "windows" {
syscall.LoadDLL("kernel32.dll").
MustFindProc("SetConsoleOutputCP").
Call(uintptr(65001)) // UTF-8
}
}
效能基準
| 操作 | Python | Go | 提升倍數 |
|---|---|---|---|
| 掃描 1000 個檔案 | ~2.5s | ~0.15s | 16.7x |
| 批次移動 100 個檔案 | ~3.0s | ~0.3s | 10x |
| 番號提取 (正則) | ~100 μs | ~5 μs | 20x |
| 片商識別 | ~1ms | ~0.1ms | 10x |
範例程式碼
檔案位置:
- •
src/services/go_bridge.py- Python 橋接層 - •
cmd/scanner/main.go- Go CLI 主程式 - •
pkg/extractor/extractor.go- 番號提取器 - •
pkg/mover/mover.go- 檔案移動器
開發前檢查清單
使用此功能前,確認:
- • 已安裝 Go 1.21+ (
go version) - • 專案根目錄有
classifier.exe - •
GoBridge.is_available回傳 True - • Go 單元測試通過 (
go test ./pkg/... -v) - • Python 整合測試通過
相關資源
- •
GO_MIGRATION_TODO.md- Go 遷移進度追蹤 - •
CLAUDE.md- 完整開發指南 - •
pkg/- Go 套件原始碼 - •
src/services/go_bridge.py- Python 橋接層實作