fix
This commit is contained in:
559
docs/multi-command-integration.md
Normal file
559
docs/multi-command-integration.md
Normal file
@@ -0,0 +1,559 @@
|
||||
# 多命令集成设计方案
|
||||
|
||||
## 🎯 设计目标
|
||||
|
||||
将所有服务的命令集成到一个统一的CLI中,提供一致的用户体验和管理界面。
|
||||
|
||||
## 🏗️ 架构设计
|
||||
|
||||
### **方案1: 主CLI + 子命令组**
|
||||
```
|
||||
mixvideo
|
||||
├── media # 媒体管理命令组
|
||||
│ ├── upload
|
||||
│ ├── batch-upload
|
||||
│ ├── list
|
||||
│ └── status
|
||||
├── scene # 场景检测命令组
|
||||
│ ├── detect
|
||||
│ ├── batch-detect
|
||||
│ ├── compare
|
||||
│ └── analyze
|
||||
├── template # 模板管理命令组
|
||||
│ ├── import
|
||||
│ ├── export
|
||||
│ ├── list
|
||||
│ └── validate
|
||||
└── system # 系统管理命令组
|
||||
├── status
|
||||
├── config
|
||||
├── storage
|
||||
└── logs
|
||||
```
|
||||
|
||||
### **方案2: 扁平化命令**
|
||||
```
|
||||
mixvideo
|
||||
├── media-upload
|
||||
├── media-batch-upload
|
||||
├── scene-detect
|
||||
├── scene-batch-detect
|
||||
├── template-import
|
||||
├── template-export
|
||||
├── system-status
|
||||
└── system-config
|
||||
```
|
||||
|
||||
### **方案3: 混合方案(推荐)**
|
||||
```
|
||||
mixvideo
|
||||
├── upload # 常用命令提升到顶层
|
||||
├── batch-upload
|
||||
├── detect
|
||||
├── batch-detect
|
||||
├── media # 完整的媒体管理命令组
|
||||
├── scene # 完整的场景检测命令组
|
||||
├── template # 模板管理命令组
|
||||
└── system # 系统管理命令组
|
||||
```
|
||||
|
||||
## 📁 文件结构设计
|
||||
|
||||
```
|
||||
python_core/
|
||||
├── cli/ # 统一CLI模块
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py # 主CLI入口
|
||||
│ ├── commands/ # 命令组织
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── media.py # 媒体管理命令组
|
||||
│ │ ├── scene.py # 场景检测命令组
|
||||
│ │ ├── template.py # 模板管理命令组
|
||||
│ │ └── system.py # 系统管理命令组
|
||||
│ └── utils/ # CLI工具
|
||||
│ ├── __init__.py
|
||||
│ ├── common.py # 通用CLI工具
|
||||
│ └── decorators.py # CLI装饰器
|
||||
├── services/ # 现有服务保持不变
|
||||
└── __main__.py # 项目入口
|
||||
```
|
||||
|
||||
## 🔧 实现方案
|
||||
|
||||
### **1. 主CLI框架**
|
||||
```python
|
||||
# python_core/cli/main.py
|
||||
import typer
|
||||
from rich.console import Console
|
||||
from typing import Optional
|
||||
|
||||
from .commands import media, scene, template, system
|
||||
from python_core.utils.progress import ProgressJSONRPCCommander
|
||||
|
||||
console = Console()
|
||||
|
||||
class MixVideoCommander(ProgressJSONRPCCommander):
|
||||
"""MixVideo 统一命令行接口"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("mixvideo")
|
||||
self.app = typer.Typer(
|
||||
name="mixvideo",
|
||||
help="""
|
||||
🎬 MixVideo - 智能视频处理平台
|
||||
|
||||
功能完整的视频处理和管理工具套件:
|
||||
• 📤 媒体管理 - 上传、处理、组织视频文件
|
||||
• 🎯 场景检测 - 智能识别视频场景变化
|
||||
• 📋 模板管理 - 视频模板导入导出
|
||||
• ⚙️ 系统管理 - 配置、状态、存储管理
|
||||
|
||||
快速开始:
|
||||
mixvideo upload video.mp4 # 上传视频
|
||||
mixvideo detect video.mp4 # 检测场景
|
||||
mixvideo system status # 查看状态
|
||||
""",
|
||||
rich_markup_mode="rich",
|
||||
no_args_is_help=True
|
||||
)
|
||||
self._setup_commands()
|
||||
|
||||
def _register_commands(self):
|
||||
"""注册命令(继承要求)"""
|
||||
pass
|
||||
|
||||
def _is_progressive_command(self, command: str) -> bool:
|
||||
"""判断是否需要进度报告"""
|
||||
return command.startswith(("batch-", "import-", "export-", "analyze-"))
|
||||
|
||||
def _execute_with_progress(self, command: str, args: dict):
|
||||
"""执行带进度的命令"""
|
||||
pass
|
||||
|
||||
def _execute_simple_command(self, command: str, args: dict):
|
||||
"""执行简单命令"""
|
||||
pass
|
||||
|
||||
def _setup_commands(self):
|
||||
"""设置命令结构"""
|
||||
# 添加子命令组
|
||||
self.app.add_typer(media.app, name="media", help="📤 媒体管理")
|
||||
self.app.add_typer(scene.app, name="scene", help="🎯 场景检测")
|
||||
self.app.add_typer(template.app, name="template", help="📋 模板管理")
|
||||
self.app.add_typer(system.app, name="system", help="⚙️ 系统管理")
|
||||
|
||||
# 添加常用命令到顶层(快捷方式)
|
||||
self._add_shortcuts()
|
||||
|
||||
def _add_shortcuts(self):
|
||||
"""添加常用命令的快捷方式"""
|
||||
|
||||
@self.app.command()
|
||||
def upload(
|
||||
video_path: Path = typer.Argument(..., help="📹 视频文件路径"),
|
||||
tags: Optional[str] = typer.Option(None, "--tags", "-t", help="🏷️ 标签")
|
||||
):
|
||||
"""📤 快速上传视频(media upload 的快捷方式)"""
|
||||
# 调用媒体管理的上传命令
|
||||
return media.upload_video(video_path, tags)
|
||||
|
||||
@self.app.command()
|
||||
def detect(
|
||||
video_path: Path = typer.Argument(..., help="📹 视频文件路径"),
|
||||
threshold: float = typer.Option(30.0, help="🎚️ 检测阈值")
|
||||
):
|
||||
"""🎯 快速场景检测(scene detect 的快捷方式)"""
|
||||
# 调用场景检测的检测命令
|
||||
return scene.detect_scenes(video_path, threshold)
|
||||
|
||||
@self.app.command()
|
||||
def status():
|
||||
"""📊 快速状态查看(system status 的快捷方式)"""
|
||||
# 调用系统状态命令
|
||||
return system.show_status()
|
||||
|
||||
def run(self):
|
||||
"""运行CLI"""
|
||||
self.app()
|
||||
|
||||
def main():
|
||||
"""主入口函数"""
|
||||
commander = MixVideoCommander()
|
||||
commander.run()
|
||||
```
|
||||
|
||||
### **2. 媒体管理命令组**
|
||||
```python
|
||||
# python_core/cli/commands/media.py
|
||||
import typer
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from rich.console import Console
|
||||
|
||||
from python_core.services.media_manager import MediaManagerService
|
||||
from ..utils.common import create_progress_task, parse_tags
|
||||
|
||||
console = Console()
|
||||
app = typer.Typer(help="📤 媒体管理命令")
|
||||
|
||||
# 全局服务实例
|
||||
media_service = MediaManagerService()
|
||||
|
||||
@app.command()
|
||||
def upload(
|
||||
video_path: Path = typer.Argument(..., help="📹 视频文件路径", exists=True),
|
||||
tags: Optional[str] = typer.Option(None, "--tags", "-t", help="🏷️ 标签列表"),
|
||||
filename: Optional[str] = typer.Option(None, "--filename", "-f", help="📝 自定义文件名")
|
||||
):
|
||||
"""📤 上传单个视频文件"""
|
||||
return upload_video(video_path, tags, filename)
|
||||
|
||||
@app.command()
|
||||
def batch_upload(
|
||||
directory: Path = typer.Argument(..., help="📁 视频目录", exists=True),
|
||||
tags: Optional[str] = typer.Option(None, "--tags", "-t", help="🏷️ 标签列表"),
|
||||
recursive: bool = typer.Option(False, "--recursive", "-r", help="🔄 递归扫描")
|
||||
):
|
||||
"""📦 批量上传视频文件"""
|
||||
tag_list = parse_tags(tags)
|
||||
|
||||
with create_progress_task("批量上传") as task:
|
||||
result = media_service.batch_upload(directory, tag_list, recursive)
|
||||
task.finish(f"上传完成: {result['successful']}/{result['total']} 成功")
|
||||
|
||||
return result
|
||||
|
||||
@app.command()
|
||||
def list_videos(
|
||||
limit: int = typer.Option(10, "--limit", "-l", help="📊 显示数量"),
|
||||
tags: Optional[str] = typer.Option(None, "--tags", "-t", help="🏷️ 标签过滤")
|
||||
):
|
||||
"""📋 列出视频文件"""
|
||||
# 实现列表逻辑
|
||||
pass
|
||||
|
||||
@app.command()
|
||||
def delete(
|
||||
video_id: str = typer.Argument(..., help="🗑️ 视频ID"),
|
||||
confirm: bool = typer.Option(False, "--yes", "-y", help="✅ 确认删除")
|
||||
):
|
||||
"""🗑️ 删除视频文件"""
|
||||
if not confirm:
|
||||
confirm = typer.confirm("确定要删除这个视频吗?")
|
||||
|
||||
if confirm:
|
||||
# 实现删除逻辑
|
||||
console.print("✅ 视频已删除")
|
||||
else:
|
||||
console.print("❌ 取消删除")
|
||||
|
||||
# 共享函数
|
||||
def upload_video(video_path: Path, tags: str = None, filename: str = None):
|
||||
"""上传视频的共享实现"""
|
||||
tag_list = parse_tags(tags)
|
||||
|
||||
console.print(f"🚀 开始上传: [bold blue]{video_path}[/bold blue]")
|
||||
|
||||
result = media_service.upload_video(video_path, tag_list, filename)
|
||||
|
||||
console.print("✅ [bold green]上传完成[/bold green]")
|
||||
return result
|
||||
```
|
||||
|
||||
### **3. 场景检测命令组**
|
||||
```python
|
||||
# python_core/cli/commands/scene.py
|
||||
import typer
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from rich.console import Console
|
||||
|
||||
from python_core.services.scene_detection import SceneDetectionService
|
||||
from ..utils.common import create_progress_task
|
||||
|
||||
console = Console()
|
||||
app = typer.Typer(help="🎯 场景检测命令")
|
||||
|
||||
# 全局服务实例
|
||||
scene_service = SceneDetectionService()
|
||||
|
||||
@app.command()
|
||||
def detect(
|
||||
video_path: Path = typer.Argument(..., help="📹 视频文件路径", exists=True),
|
||||
threshold: float = typer.Option(30.0, help="🎚️ 检测阈值"),
|
||||
output: Optional[Path] = typer.Option(None, "--output", "-o", help="📄 输出文件")
|
||||
):
|
||||
"""🎯 检测单个视频的场景"""
|
||||
return detect_scenes(video_path, threshold, output)
|
||||
|
||||
@app.command()
|
||||
def batch_detect(
|
||||
directory: Path = typer.Argument(..., help="📁 视频目录", exists=True),
|
||||
threshold: float = typer.Option(30.0, help="🎚️ 检测阈值"),
|
||||
output: Optional[Path] = typer.Option(None, "--output", "-o", help="📄 输出文件")
|
||||
):
|
||||
"""📦 批量检测场景"""
|
||||
with create_progress_task("批量检测") as task:
|
||||
result = scene_service.batch_detect(directory, threshold)
|
||||
task.finish(f"检测完成: {result['processed']} 个文件")
|
||||
|
||||
return result
|
||||
|
||||
@app.command()
|
||||
def compare(
|
||||
video_path: Path = typer.Argument(..., help="📹 视频文件路径", exists=True),
|
||||
thresholds: str = typer.Option("20,30,40", help="🎚️ 阈值列表")
|
||||
):
|
||||
"""🔬 比较不同检测器效果"""
|
||||
with create_progress_task("检测器比较") as task:
|
||||
result = scene_service.compare_detectors(video_path, thresholds)
|
||||
task.finish("比较完成")
|
||||
|
||||
return result
|
||||
|
||||
# 共享函数
|
||||
def detect_scenes(video_path: Path, threshold: float = 30.0, output: Path = None):
|
||||
"""场景检测的共享实现"""
|
||||
console.print(f"🎯 开始检测: [bold blue]{video_path}[/bold blue]")
|
||||
|
||||
result = scene_service.detect_single(video_path, threshold)
|
||||
|
||||
if output:
|
||||
scene_service.save_result(result, output)
|
||||
console.print(f"📄 结果已保存: {output}")
|
||||
|
||||
console.print("✅ [bold green]检测完成[/bold green]")
|
||||
return result
|
||||
```
|
||||
|
||||
### **4. 系统管理命令组**
|
||||
```python
|
||||
# python_core/cli/commands/system.py
|
||||
import typer
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
from rich.panel import Panel
|
||||
|
||||
from python_core.storage import get_storage
|
||||
from python_core.config import settings
|
||||
|
||||
console = Console()
|
||||
app = typer.Typer(help="⚙️ 系统管理命令")
|
||||
|
||||
@app.command()
|
||||
def status():
|
||||
"""📊 显示系统状态"""
|
||||
return show_status()
|
||||
|
||||
@app.command()
|
||||
def config(
|
||||
show: bool = typer.Option(False, "--show", help="📋 显示配置"),
|
||||
set_key: Optional[str] = typer.Option(None, "--set", help="⚙️ 设置配置项"),
|
||||
value: Optional[str] = typer.Option(None, "--value", help="💾 配置值")
|
||||
):
|
||||
"""⚙️ 配置管理"""
|
||||
if show:
|
||||
show_config()
|
||||
elif set_key and value:
|
||||
set_config(set_key, value)
|
||||
else:
|
||||
console.print("❌ 请指定 --show 或 --set 和 --value")
|
||||
|
||||
@app.command()
|
||||
def storage(
|
||||
action: str = typer.Argument(..., help="📦 操作类型 (info/clean/migrate)"),
|
||||
target: Optional[str] = typer.Option(None, help="🎯 目标存储类型")
|
||||
):
|
||||
"""📦 存储管理"""
|
||||
if action == "info":
|
||||
show_storage_info()
|
||||
elif action == "clean":
|
||||
clean_storage()
|
||||
elif action == "migrate":
|
||||
migrate_storage(target)
|
||||
else:
|
||||
console.print("❌ 未知操作类型")
|
||||
|
||||
@app.command()
|
||||
def logs(
|
||||
lines: int = typer.Option(50, "--lines", "-n", help="📄 显示行数"),
|
||||
follow: bool = typer.Option(False, "--follow", "-f", help="🔄 实时跟踪")
|
||||
):
|
||||
"""📄 查看日志"""
|
||||
# 实现日志查看逻辑
|
||||
pass
|
||||
|
||||
# 共享函数
|
||||
def show_status():
|
||||
"""显示系统状态的共享实现"""
|
||||
console.print("📊 MixVideo 系统状态")
|
||||
|
||||
# 创建状态表格
|
||||
table = Table(title="系统组件状态")
|
||||
table.add_column("组件", style="cyan")
|
||||
table.add_column("状态", style="green")
|
||||
table.add_column("详情", style="yellow")
|
||||
|
||||
# 检查各组件状态
|
||||
storage = get_storage()
|
||||
collections = storage.get_collections()
|
||||
|
||||
table.add_row("存储系统", "✅ 正常", f"{len(collections)} 个集合")
|
||||
table.add_row("媒体管理", "✅ 就绪", "服务正常")
|
||||
table.add_row("场景检测", "✅ 就绪", "服务正常")
|
||||
table.add_row("模板管理", "✅ 就绪", "服务正常")
|
||||
|
||||
console.print(table)
|
||||
|
||||
# 系统信息面板
|
||||
info_panel = Panel(
|
||||
"[bold blue]MixVideo 运行正常[/bold blue]\n"
|
||||
"所有核心组件状态良好,系统准备就绪。",
|
||||
title="📊 系统摘要",
|
||||
border_style="green"
|
||||
)
|
||||
console.print(info_panel)
|
||||
|
||||
def show_config():
|
||||
"""显示配置信息"""
|
||||
# 实现配置显示逻辑
|
||||
pass
|
||||
|
||||
def set_config(key: str, value: str):
|
||||
"""设置配置项"""
|
||||
# 实现配置设置逻辑
|
||||
pass
|
||||
```
|
||||
|
||||
### **5. 通用工具**
|
||||
```python
|
||||
# python_core/cli/utils/common.py
|
||||
from contextlib import contextmanager
|
||||
from typing import List, Optional
|
||||
from rich.console import Console
|
||||
|
||||
console = Console()
|
||||
|
||||
def parse_tags(tags_str: Optional[str]) -> List[str]:
|
||||
"""解析标签字符串"""
|
||||
if not tags_str:
|
||||
return []
|
||||
return [tag.strip() for tag in tags_str.split(",") if tag.strip()]
|
||||
|
||||
@contextmanager
|
||||
def create_progress_task(name: str):
|
||||
"""创建进度任务的上下文管理器"""
|
||||
class MockTask:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
console.print(f"🚀 开始{name}...")
|
||||
|
||||
def update(self, message: str):
|
||||
console.print(f"📊 {message}")
|
||||
|
||||
def finish(self, message: str):
|
||||
console.print(f"✅ {message}")
|
||||
|
||||
yield MockTask(name)
|
||||
|
||||
def confirm_action(message: str, default: bool = False) -> bool:
|
||||
"""确认操作"""
|
||||
import typer
|
||||
return typer.confirm(message, default=default)
|
||||
|
||||
def show_error(message: str):
|
||||
"""显示错误信息"""
|
||||
console.print(f"❌ [red]{message}[/red]")
|
||||
|
||||
def show_success(message: str):
|
||||
"""显示成功信息"""
|
||||
console.print(f"✅ [green]{message}[/green]")
|
||||
|
||||
def show_warning(message: str):
|
||||
"""显示警告信息"""
|
||||
console.print(f"⚠️ [yellow]{message}[/yellow]")
|
||||
```
|
||||
|
||||
### **6. 项目入口**
|
||||
```python
|
||||
# python_core/__main__.py
|
||||
"""
|
||||
MixVideo 项目主入口
|
||||
支持: python -m python_core
|
||||
"""
|
||||
|
||||
from .cli.main import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
## 🎯 使用示例
|
||||
|
||||
### **命令组方式**
|
||||
```bash
|
||||
# 媒体管理
|
||||
mixvideo media upload video.mp4 --tags "demo,test"
|
||||
mixvideo media batch-upload /videos --recursive
|
||||
mixvideo media list --limit 20
|
||||
|
||||
# 场景检测
|
||||
mixvideo scene detect video.mp4 --threshold 25
|
||||
mixvideo scene batch-detect /videos --output results.json
|
||||
mixvideo scene compare video.mp4 --thresholds "20,30,40"
|
||||
|
||||
# 模板管理
|
||||
mixvideo template import /templates --batch
|
||||
mixvideo template export template_id --output template.json
|
||||
|
||||
# 系统管理
|
||||
mixvideo system status
|
||||
mixvideo system config --show
|
||||
mixvideo system storage info
|
||||
```
|
||||
|
||||
### **快捷命令方式**
|
||||
```bash
|
||||
# 常用命令的快捷方式
|
||||
mixvideo upload video.mp4 --tags "demo"
|
||||
mixvideo detect video.mp4 --threshold 30
|
||||
mixvideo status
|
||||
```
|
||||
|
||||
### **帮助系统**
|
||||
```bash
|
||||
# 查看主帮助
|
||||
mixvideo --help
|
||||
|
||||
# 查看命令组帮助
|
||||
mixvideo media --help
|
||||
mixvideo scene --help
|
||||
|
||||
# 查看具体命令帮助
|
||||
mixvideo media upload --help
|
||||
mixvideo scene detect --help
|
||||
```
|
||||
|
||||
## 🎉 方案优势
|
||||
|
||||
### **1. 统一体验**
|
||||
- 🎯 一个入口点,所有功能
|
||||
- 📋 一致的命令风格和参数
|
||||
- 🎨 统一的输出格式和样式
|
||||
|
||||
### **2. 灵活使用**
|
||||
- ⚡ 快捷命令满足日常需求
|
||||
- 🔧 完整命令组满足专业需求
|
||||
- 📚 清晰的帮助系统
|
||||
|
||||
### **3. 易于扩展**
|
||||
- 🔌 新服务易于集成
|
||||
- 📦 模块化的命令组织
|
||||
- 🔄 向后兼容的设计
|
||||
|
||||
### **4. 开发友好**
|
||||
- 🧩 清晰的代码组织
|
||||
- 🔧 共享的工具函数
|
||||
- 📝 统一的开发规范
|
||||
|
||||
这个设计方案提供了完整的多命令集成解决方案,既保持了各服务的独立性,又提供了统一的用户体验!
|
||||
Reference in New Issue
Block a user