videoplayer/handler/cid.go

278 lines
8.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handler
import (
"bytes"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"os/exec"
"strconv"
"strings"
"videoplayer/dao"
"videoplayer/proto"
"videoplayer/worker"
)
type CIDCreateReq struct {
Name string `json:"name" form:"name"`
Url string `json:"url" form:"url"`
Time int `json:"time" form:"time"` // 定时任务单位秒大于0表示定时任务
Script string `json:"script" form:"script"`
}
type CIDDeleteReq struct {
ID int `json:"id" form:"id"`
}
type CIDRunReq struct {
ID int `json:"id" form:"id"`
}
type CIDLogReq struct {
ID int `json:"id" form:"id"`
}
type CIDUpdateReq struct {
ID int `json:"id" form:"id"`
Name string `json:"name" form:"name"`
Url string `json:"url" form:"url"`
Time int `json:"time" form:"time"` // 定时任务单位秒大于0表示定时任务
Script string `json:"script" form:"script"`
Token string `json:"cidtoken" form:"cidtoken"`
}
func SetUpCIDGroup(router *gin.Engine) {
cidGroup := router.Group("/cid") //持续集成、部署
cidGroup.POST("/create", CreateCID)
cidGroup.POST("/delete", DeleteCID)
cidGroup.POST("/update", UpdateCID)
cidGroup.POST("/list", GetCIDList)
cidGroup.POST("/run", RunCID)
cidGroup.POST("/log", GetCIDLogList) //获取执行日志
cidGroup.POST("/log/detail", GetCIDLog) //获取执行日志详情
cidGroup.POST("/callback", CIDCallback)
}
func RunCID(c *gin.Context) {
var req CIDRunReq
id, _ := c.Get("id")
authID := int(id.(float64))
//获取权限
user := dao.FindUserByUserID(authID)
if user.Run == false {
c.JSON(200, gin.H{"error": "no run Permissions", "code": proto.NoRunPermissions, "message": "no run Permissions"})
return
}
if err := c.ShouldBind(&req); err == nil {
// 获取用户ID
username, _ := c.Get("username")
cid := dao.FindCIDByID(req.ID, authID)
if cid.ID == 0 {
c.JSON(200, gin.H{"error": "CID not found", "code": proto.OperationFailed, "message": "failed"})
return
} else {
go RunShell(username.(string), cid.Url, cid.Script, req.ID, authID)
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": "success"})
}
} else {
c.JSON(200, gin.H{"error": err.Error(), "code": proto.ParameterError, "message": "failed"})
}
}
func CreateCID(c *gin.Context) {
var req CIDCreateReq
if err := c.ShouldBind(&req); err == nil {
// 获取用户ID
id, _ := c.Get("id")
authID := int(id.(float64))
token, _ := generateRandomHexString(32)
res := dao.CreateCID(req.Name, req.Url, req.Script, token, req.Time, authID)
if res != 0 {
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": res})
} else {
c.JSON(200, gin.H{"error": "CreateCID failed", "code": proto.OperationFailed, "message": "failed"})
}
} else {
c.JSON(200, gin.H{"error": err.Error(), "code": proto.ParameterError, "message": "failed"})
}
}
func DeleteCID(c *gin.Context) {
var req CIDDeleteReq
if err := c.ShouldBind(&req); err == nil {
// 获取用户ID
id, _ := c.Get("id")
authID := int(id.(float64))
cid := dao.DeleteCIDByID(req.ID, authID)
if cid == false {
c.JSON(200, gin.H{"error": "CID not found", "code": proto.OperationFailed, "message": "failed"})
return
} else {
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": "success"})
}
} else {
c.JSON(200, gin.H{"error": err.Error(), "code": proto.ParameterError, "message": "failed"})
}
}
func UpdateCID(c *gin.Context) {
var req CIDUpdateReq
if err := c.ShouldBind(&req); err == nil {
// 获取用户ID
id, _ := c.Get("id")
authID := int(id.(float64))
cid := dao.UpdateCIDByID(req.ID, authID, req.Time, req.Name, req.Url, req.Script, req.Token)
if cid == false {
c.JSON(200, gin.H{"error": "CID not found", "code": proto.OperationFailed, "message": "failed"})
return
} else {
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": "success"})
}
} else {
c.JSON(200, gin.H{"error": err.Error(), "code": proto.ParameterError, "message": "failed"})
}
}
func GetCIDList(c *gin.Context) {
// 获取用户ID
id, _ := c.Get("id")
authID := int(id.(float64))
cids := dao.FindCIDByAuthID(authID)
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": cids})
}
func GetCIDLog(c *gin.Context) {
var req CIDRunReq
if err := c.ShouldBind(&req); err == nil {
// 获取用户ID
id, _ := c.Get("id")
authID := int(id.(float64))
cidLogs := dao.FindRunLogByCIDLogID(req.ID, authID)
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": cidLogs})
} else {
c.JSON(200, gin.H{"error": err.Error(), "code": proto.ParameterError, "message": "failed"})
}
}
func GetCIDLogList(c *gin.Context) {
// 获取用户ID
id, _ := c.Get("id")
authID := int(id.(float64))
var req CIDLogReq
if err := c.ShouldBind(&req); err == nil {
cidLogs := dao.FindRunLogByID(authID, req.ID)
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": cidLogs})
} else {
c.JSON(200, gin.H{"error": err.Error(), "code": proto.ParameterError, "message": "failed"})
}
}
func CIDCallback(c *gin.Context) {
// 获取用户ID
token := c.Query("token")
cid_id := c.Query("id")
fmt.Println("token:", token, "cid_id:", cid_id)
//将cid转换为int
cid, _ := strconv.Atoi(cid_id)
if token == "" || cid == 0 {
c.JSON(200, gin.H{"error": "parameter error", "code": proto.ParameterError, "message": "failed"})
return
}
res := dao.FindCIDByIDAndToken(cid, token)
if res.ID == 0 {
c.JSON(200, gin.H{"error": "CID not found by id and token", "code": proto.OperationFailed, "message": "failed"})
return
}
user := dao.FindUserByUserID(res.Auth_id)
if user.Run == false {
c.JSON(200, gin.H{"error": "no run Permissions", "code": proto.NoRunPermissions, "message": "the user has no run Permissions"})
return
}
if res.ID != 0 {
user := dao.FindUserByID(res.Auth_id)
go RunShell(user[0].Name, res.Url, res.Script, int(res.ID), res.Auth_id)
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": "success"})
} else {
c.JSON(200, gin.H{"error": "CID not found by id and token", "code": proto.OperationFailed, "message": "failed"})
return
}
}
func RunShell(username, url, script string, id, authID int) {
strs := strings.Split(url, "/")
name := strs[len(strs)-1]
names := strings.Split(name, ".")
name = names[0]
//脚本内容,不同用户的持续集成、部署目录不同
scriptContent := `
echo "start"
` + script + `
echo "end"`
//执行脚本
cmd := exec.Command("/bin/bash", "-c", scriptContent)
// 使用bytes.Buffer捕获输出
var out bytes.Buffer
cmd.Stdout = &out
err3 := cmd.Run()
err3_info := ""
if err3 != nil {
err3_info = err3.Error()
}
//fmt.Println("bash content:", scriptContent)
dao.CreateRunLog(id, authID, scriptContent, out.String(), err3_info) //添加执行日志
}
// 定时任务处理逻辑
func RunCron() {
//从redis查看是否有定时任务
//如果有定时任务,执行定时任务
//如果没有定时任务查找数据库是否有定时任务如果有则加入redis如果没有则不做任何操作
key := "cron_cid_runs"
res := worker.GetRedis(key)
if res == "" {
cids := dao.FindCIDByTime()
cid_workers := make([]proto.CIDRUN, 0)
for _, v := range cids {
cid_worker := proto.CIDRUN{CID: v.ID, Curr: v.Time, Every: v.Time}
cid_workers = append(cid_workers, cid_worker)
}
if len(cid_workers) > 0 {
//将定时任务加入redis
json_data, err := json.Marshal(cid_workers)
if err != nil {
fmt.Println("json marshal failed")
}
worker.SetRedis(key, string(json_data))
}
} else {
var cid_workers []proto.CIDRUN
cid_redis_workers := worker.GetRedis(key)
err := json.Unmarshal([]byte(cid_redis_workers), &cid_workers)
if err != nil {
fmt.Println("json unmarshal failed")
}
for _, v := range cid_workers {
//查找定时任务
if v.Curr-10 <= 0 {
cid := dao.FindCIDByCID(v.CID)
if cid.ID != 0 {
go RunShell("cron", cid.Url, cid.Script, int(cid.ID), cid.Auth_id)
}
} else {
v.Curr = v.Curr - 10
}
}
//将定时任务加入redis
json_data, err := json.Marshal(cid_workers)
if err != nil {
fmt.Println("json marshal failed")
}
worker.SetRedis(key, string(json_data))
}
}