Files
MeBox/internal/handler/system_handler.go
T
truewhile 44ca451cd4 优化
优化
2026-08-24 17:40:43 +08:00

145 lines
3.5 KiB
Go

// Package handler — system tools detection.
package handler
import (
"net/http"
"os/exec"
"strings"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"github.com/ShukeBta/MMTL/internal/config"
"github.com/ShukeBta/MMTL/internal/service"
)
// SystemHandler handles system-related endpoints.
type SystemHandler struct {
cfg *config.Config
log *zap.Logger
svc *service.Container
}
// NewSystemHandler is the constructor.
func NewSystemHandler(cfg *config.Config, log *zap.Logger, svc *service.Container) *SystemHandler {
return &SystemHandler{cfg: cfg, log: log, svc: svc}
}
// ToolStatus represents the detection status of a system tool.
type ToolStatus struct {
Name string `json:"name"`
DisplayName string `json:"display_name"`
ConfigKey string `json:"config_key"`
Path string `json:"path,omitempty"`
Detected bool `json:"detected"`
Version string `json:"version,omitempty"`
}
// GetToolsStatus returns the status of system tools.
func (h *SystemHandler) GetToolsStatus(c *gin.Context) {
tools := []ToolStatus{
{Name: "ffprobe", DisplayName: "FFprobe", ConfigKey: "app.ffprobe_path"},
{Name: "ffmpeg", DisplayName: "FFmpeg", ConfigKey: "app.ffmpeg_path"},
}
for i := range tools {
// Check configured path first
var configuredPath string
switch tools[i].ConfigKey {
case "app.ffprobe_path":
configuredPath = h.cfg.App.FFprobePath
if configuredPath == "" {
configuredPath = "ffprobe"
}
case "app.ffmpeg_path":
configuredPath = h.cfg.App.FFmpegPath
if configuredPath == "" {
configuredPath = "ffmpeg"
}
}
// Try to find the tool
path, err := exec.LookPath(configuredPath)
if err == nil {
tools[i].Detected = true
tools[i].Path = path
// Try to get version
tools[i].Version = getToolVersion(path)
}
}
c.JSON(http.StatusOK, gin.H{
"tools": tools,
})
}
// getToolVersion attempts to get the version of a tool.
func getToolVersion(path string) string {
out, err := exec.Command(path, "-version").Output()
if err != nil {
return ""
}
// Extract first line as version info
lines := strings.Split(string(out), "\n")
if len(lines) > 0 {
return strings.TrimSpace(lines[0])
}
return ""
}
// InstallTools attempts to auto-install system tools (ffmpeg/ffprobe)
func (h *SystemHandler) InstallTools(c *gin.Context) {
h.log.Info("Received tools auto-install request")
// Call service layer to auto-install
ffprobePath, ffmpegPath := service.AutoInstallFFmpeg(h.log, h.cfg)
result := gin.H{
"installed": ffprobePath != "" || ffmpegPath != "",
}
if ffprobePath != "" {
result["ffprobe_path"] = ffprobePath
result["ffprobe_installed"] = true
}
if ffmpegPath != "" {
result["ffmpeg_path"] = ffmpegPath
result["ffmpeg_installed"] = true
}
// Re-detect tool status
tools := []ToolStatus{
{Name: "ffprobe", DisplayName: "FFprobe", ConfigKey: "app.ffprobe_path"},
{Name: "ffmpeg", DisplayName: "FFmpeg", ConfigKey: "app.ffmpeg_path"},
}
for i := range tools {
var configuredPath string
switch tools[i].ConfigKey {
case "app.ffprobe_path":
configuredPath = h.cfg.App.FFprobePath
if configuredPath == "" {
configuredPath = "ffprobe"
}
case "app.ffmpeg_path":
configuredPath = h.cfg.App.FFmpegPath
if configuredPath == "" {
configuredPath = "ffmpeg"
}
}
path, err := exec.LookPath(configuredPath)
if err == nil {
tools[i].Detected = true
tools[i].Path = path
tools[i].Version = getToolVersion(path)
}
}
result["tools"] = tools
h.log.Info("Tool installation completed", zap.Any("result", result))
c.JSON(http.StatusOK, result)
}