master
luziqi 3 years ago
parent 1090ed797a
commit 54791e3c2c

@ -2,33 +2,79 @@ package common
import (
"errors"
"fmt"
"goqs/dbsql"
"goqs/models"
"gorm.io/gorm"
)
type notify struct {
ID int `json:"id" gorm:"column:id"`
Section string `json:"section" gorm:"column:section"`
Name string `json:"name" gorm:"column:name"`
Token string `json:"token" gorm:"column:token"`
Secret string `json:"secret" gorm:"column:secret"`
IsDel int `json:"-" gorm:"column:is_del"`
}
var NotifyList []models.Notify
func (t *notify) TableName() string {
return "notify"
func InitNotifyInfos() error {
var list []models.Notify
db, err := dbsql.GetConn(dbsql.DSN)
if err != nil {
return err
}
defer dbsql.Close(db)
db.Find(&list)
if db.Error != nil {
return db.Error
}
NotifyList = list
return nil
}
func GetNotifyConfig(section, name string) (notify, error) {
// 根据section和name获取通知信息
func GetNotifyInfo(section, name string) (models.Notify, error) {
var n models.Notify
db, err := dbsql.GetConn(dbsql.DSN)
if err != nil {
fmt.Println(err)
return n, err
}
defer dbsql.Close(db)
var n notify
db.Model(notify{}).Where("section = ? AND name = ?", section, name).Last(&n)
if n.ID < 1 {
return n, errors.New("没找到对应的通知设置")
db.Where("section = ? AND name = ?", section, name).Last(&n)
if db.Error != nil {
return n, db.Error
}
if n.ID < 0 {
return n, errors.New("没有找到notify配置")
}
return n, nil
}
// 创建通知
func createNotify(db *gorm.DB, n *models.Notify) error {
return db.Create(n).Error
}
// 查询所有通知
func getAllNotifys(db *gorm.DB) ([]models.Notify, error) {
var ns []models.Notify
err := db.Find(&ns).Error
return ns, err
}
// 根据 ID 查询通知
func getNotifyByID(db *gorm.DB, id uint) (models.Notify, error) {
var n models.Notify
err := db.First(&n, id).Error
return n, err
}
// 更新通知
func updateNotify(db *gorm.DB, n *models.Notify) error {
return db.Updates(n).Error
}
// 删除通知
func deleteNotify(db *gorm.DB, id uint) error {
return db.Delete(&models.Notify{}, id).Error
}

@ -35,8 +35,9 @@ func PushCorntaskLog(str string) {
func PushMonkeyResult(task models.MonkeyTask) {
cli := dingtalk.InitDingTalkWithSecret(Bot_Test_Token, Bot_Test_Secret)
if task.Remark != "debug" {
if task.Project == "hising" {
cli = dingtalk.InitDingTalkWithSecret(Bot_Hising_Token, Bot_Hising_Secret)
n, err := GetNotifyInfo("monkey", task.Project)
if err == nil {
cli = dingtalk.InitDingTalkWithSecret(n.Token, n.Secret)
}
}

@ -27,4 +27,16 @@ func CheckMonkeyTasks() {
go monkey.RunAndroidMonkeyCmd(task, device.Udid)
common.PushCorntaskLog("执行Monkey任务" + task.Project + "-" + device.Udid)
}
db.Model(models.MonkeyTask{}).Where("status = ? AND is_del = 0", "RUNNING").Find(&list)
for _, task := range list {
var pids []models.MonkeyPid
db.Model(models.MonkeyPid{}).Where("task_id = ?", task.Id).Find(&pids)
if code := checkTaskPids(pids); code == 0 {
task.Status = "RUNNING"
} else if code == 1 {
task.Status = "FINISH"
db.Model(models.MonkeyTask{}).Where("id = ?", task.Id).Update("status", task.Status)
common.PushMonkeyResult(task)
}
}
}

@ -28,8 +28,8 @@ func GetDeviceByUdid(c *gin.Context) {
return
}
db, err := dbsql.GetConn(dbsql.DSN)
if rsp.CheckErr(err) {
c.JSON(http.StatusOK, rsp)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
defer dbsql.Close(db)
@ -62,21 +62,21 @@ func GetDevices(c *gin.Context) {
var p models.Page
pageIndex, err := strconv.Atoi(c.DefaultQuery("page_index", "1"))
if rsp.CheckErr(err) {
c.JSON(http.StatusOK, rsp)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
p.Index = pageIndex
pageSize, err := strconv.Atoi(c.DefaultQuery("page_size", "10"))
if rsp.CheckErr(err) {
c.JSON(http.StatusOK, rsp)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
p.Size = pageSize
db, err := dbsql.GetConn(dbsql.DSN)
if rsp.CheckErr(err) {
c.JSON(http.StatusOK, rsp)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
defer dbsql.Close(db)

@ -0,0 +1,115 @@
package device
import (
"goqs/controllers"
"goqs/dbsql"
"goqs/models"
"net/http"
"os/exec"
"time"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/spf13/cast"
)
// @Tags 设备相关 /api/device/v1/
// @Summary 安装应用
// @Description 传入安装包链接并指定设备安装
// @accept x-www-form-urlencoded
// @Param udid formData string true "设备udid"
// @Param pf formData string true "安装平台"
// @Param pkg_url formData string true "安装包下载链接"
// @Success 200 {object} models.Response "返回结果"
// @Router /api/device/v1/opt/install [post]
func InstallApp(c *gin.Context) {
rsp := controllers.NewResponse()
udid := c.PostForm("udid") // 获取 udid 参数
pf := c.PostForm("pf") // 获取 pf 参数
pkg_url := c.PostForm("pkg_url") // 获取 pkg_url 参数
if udid == "" {
rsp.Error("参数udid错误:" + udid)
c.JSON(http.StatusOK, rsp)
return
}
if pf == "" {
rsp.Error("参数pf错误:" + pf)
c.JSON(http.StatusOK, rsp)
return
}
if pkg_url == "" {
rsp.Error("参数pkgUrl错误:" + pkg_url)
c.JSON(http.StatusOK, rsp)
return
}
db, err := dbsql.GetConn(dbsql.DSN)
if err != nil {
rsp.Error(err.Error())
c.JSON(http.StatusOK, rsp)
}
defer dbsql.Close(db)
var device models.Device
db.Model(models.Device{}).Where("udid = ?", udid).Find(&device)
if device.ID < 1 {
rsp.Error("找不到该设备:" + udid)
c.JSON(http.StatusOK, rsp)
return
}
if device.Status == "offline" {
rsp.Error("设备不在线:" + udid)
c.JSON(http.StatusOK, rsp)
return
}
if device.Status == "busy" {
rsp.Error("设备正在被占用,无法执行安装操作")
c.JSON(http.StatusOK, rsp)
return
}
if pf == "adr" {
// 下载app到服务器
go DownloadAndInstallApp(udid, pkg_url)
} else {
rsp.Error("未支持的平台:" + pf)
c.JSON(http.StatusOK, rsp)
return
}
rsp.Success()
rsp.Data = "已执行"
c.JSON(http.StatusOK, rsp)
}
func DownloadAndInstallApp(udid, pkg_url string) error {
pkg_path := "/home/tmp/pkg/" + cast.ToString(time.Now().Unix()) + ".apk"
log.Debug("正在下载:", pkg_url)
err := exec.Command("wget", pkg_url, "-O", pkg_path).Run()
if err != nil {
log.Error(err)
return err
}
log.Debug("下载完毕,路径:", pkg_path)
err = AdbInstall(udid, pkg_path)
if err != nil {
log.Error(err)
return err
}
return nil
}
func AdbInstall(udid, filepath string) error {
// 通过 adb 安装 APK
cmd := exec.Command("adb", "-s", udid, "install", "-r", filepath)
output, err := cmd.CombinedOutput()
if err != nil {
log.Error("安装失败:", err)
return err
}
log.Debug("安装成功:", string(output))
return nil
}

@ -178,6 +178,49 @@ var doc = `{
}
}
},
"/api/device/v1/opt/install": {
"post": {
"description": "传入安装包链接并指定设备安装",
"consumes": [
"application/x-www-form-urlencoded"
],
"tags": [
"设备相关 /api/device/v1/"
],
"summary": "安装应用",
"parameters": [
{
"type": "string",
"description": "设备udid",
"name": "udid",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "安装平台",
"name": "pf",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "安装包下载链接",
"name": "pkg_url",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "返回结果",
"schema": {
"$ref": "#/definitions/models.Response"
}
}
}
}
},
"/api/device/v1/update": {
"post": {
"description": "根据主键更新设备",

@ -159,6 +159,49 @@
}
}
},
"/api/device/v1/opt/install": {
"post": {
"description": "传入安装包链接并指定设备安装",
"consumes": [
"application/x-www-form-urlencoded"
],
"tags": [
"设备相关 /api/device/v1/"
],
"summary": "安装应用",
"parameters": [
{
"type": "string",
"description": "设备udid",
"name": "udid",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "安装平台",
"name": "pf",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "安装包下载链接",
"name": "pkg_url",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "返回结果",
"schema": {
"$ref": "#/definitions/models.Response"
}
}
}
}
},
"/api/device/v1/update": {
"post": {
"description": "根据主键更新设备",

@ -113,6 +113,35 @@ paths:
summary: 获取设备列表
tags:
- 设备相关 /api/device/v1/
/api/device/v1/opt/install:
post:
consumes:
- application/x-www-form-urlencoded
description: 传入安装包链接并指定设备安装
parameters:
- description: 设备udid
in: formData
name: udid
required: true
type: string
- description: 安装平台
in: formData
name: pf
required: true
type: string
- description: 安装包下载链接
in: formData
name: pkg_url
required: true
type: string
responses:
"200":
description: 返回结果
schema:
$ref: '#/definitions/models.Response'
summary: 安装应用
tags:
- 设备相关 /api/device/v1/
/api/device/v1/update:
post:
consumes:

@ -28,6 +28,17 @@ func init() {
}
func main() {
// dbsql.DSN = dbsql.DSN_local
// db, err := dbsql.GetConn(dbsql.DSN)
// if err != nil {
// fmt.Println(err)
// return
// }
// defer dbsql.Close(db)
// var task models.MonkeyTask
// db.Last(&task)
// common.PushMonkeyResult(task)
// return
go crontask.Run()
env.InitDB()
@ -82,6 +93,7 @@ func main() {
r.POST("/api/device/v1/update", device.UpdateDevice)
r.DELETE("/api/device/v1/delete/:id", device.DeleteDevice)
r.POST("/api/device/v1/update_status", device.UpdateDeviceStatus)
r.POST("/api/device/v1/opt/install", device.InstallApp)
r.Run(port)

@ -6,26 +6,29 @@ type Response struct {
Data interface{} `form:"data" json:"data" uri:"data" xml:"data"`
}
func (r *Response) Init() {
func (r *Response) Init() *Response {
r.Code = 500
r.Msg = "none"
return r
}
func (r *Response) Success() {
func (r *Response) Success() *Response {
r.Code = 200
r.Msg = "success"
return r
}
func (r *Response) Error(msg string) {
func (r *Response) Error(msg string) *Response {
r.Code = 500
r.Msg = msg
return r
}
func (r *Response) CheckErr(err error) bool {
func (r *Response) CheckErr(err error) *Response {
if err != nil {
r.Code = 500
r.Msg = err.Error()
return true
return r
}
return false
return r
}

@ -0,0 +1,15 @@
package models
type Notify struct {
ID int `json:"id" gorm:"primaryKey;column:id;type:int unsigned;not null"`
Name string `json:"name" gorm:"column:name;type:varchar(255);not null"`
Section string `json:"section" gorm:"column:section;type:varchar(255);not null"`
Type string `json:"type" gorm:"column:type;type:varchar(255);not null"`
Token string `json:"token" gorm:"column:token;type:varchar(255);not null"`
Secret string `json:"secret" gorm:"column:secret;type:varchar(255);"`
IsDel int `json:"is_del" gorm:"column:is_del;type:int;not null"`
}
func (Notify) TableName() string {
return "notify"
}

@ -128,6 +128,7 @@ func UpdateTaskStatus(c *gin.Context) {
}
task.Status = status
db.Save(&task)
fmt.Println("更新设备状态为", status)
if status == "FINISH" {
common.PushMonkeyResult(task)
@ -198,21 +199,21 @@ func GetTasks(c *gin.Context) {
var p models.Page
pageIndex, err := strconv.Atoi(c.DefaultQuery("page_index", "1"))
if rsp.CheckErr(err) {
c.JSON(http.StatusOK, rsp)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
p.Index = pageIndex
pageSize, err := strconv.Atoi(c.DefaultQuery("page_size", "10"))
if rsp.CheckErr(err) {
c.JSON(http.StatusOK, rsp)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
p.Size = pageSize
db, err := dbsql.GetConn(dbsql.DSN)
if rsp.CheckErr(err) {
c.JSON(http.StatusOK, rsp)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
defer dbsql.Close(db)
@ -228,26 +229,26 @@ func GetTasks(c *gin.Context) {
dbsql.Close(db)
db, _ = dbsql.GetConn(dbsql.DSN)
for i, v := range list {
for i, _ := range list {
var count int64
db.Model(models.MonkeyActivity{}).Where("task_id = ?", list[i].Id).Count(&count)
list[i].CoveredAcitvities = int(count)
// 如果状态在 进行中 or 取消中,则检查进程状态
if v.Status == "RUNNING" || v.Status == "CANCELING" {
var pids []models.MonkeyPid
db.Model(models.MonkeyPid{}).Where("task_id = ?", v.Id).Find(&pids)
if code := checkTaskPids(pids); code == 0 {
list[i].Status = "RUNNING"
} else if code == 1 {
if v.Status == "CANCELING" {
list[i].Status = "CANCEL"
db.Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("status", list[i].Status)
} else if v.Status == "RUNNING" {
list[i].Status = "FINISH"
db.Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("status", list[i].Status)
}
}
}
// if v.Status == "RUNNING" || v.Status == "CANCELING" {
// var pids []models.MonkeyPid
// db.Model(models.MonkeyPid{}).Where("task_id = ?", v.Id).Find(&pids)
// if code := checkTaskPids(pids); code == 0 {
// list[i].Status = "RUNNING"
// } else if code == 1 {
// if v.Status == "CANCELING" {
// list[i].Status = "CANCEL"
// db.Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("status", list[i].Status)
// } else if v.Status == "RUNNING" {
// list[i].Status = "FINISH"
// db.Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("status", list[i].Status)
// }
// }
// }
}
dbsql.Close(db)
@ -275,8 +276,8 @@ func GetTaskById(c *gin.Context) {
var rsp models.Response
db, err := dbsql.GetConn(dbsql.DSN)
if rsp.CheckErr(err) {
c.JSON(http.StatusOK, rsp)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
defer dbsql.Close(db)
@ -340,8 +341,8 @@ func UpdatePids(c *gin.Context) {
var rsp models.Response
db, err := dbsql.GetConn(dbsql.DSN)
if rsp.CheckErr(err) {
c.JSON(http.StatusOK, rsp)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
defer dbsql.Close(db)
@ -392,8 +393,8 @@ func UpdateDevices(c *gin.Context) {
}
db, err := dbsql.GetConn(dbsql.DSN)
if rsp.CheckErr(err) {
c.JSON(http.StatusOK, rsp)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
defer dbsql.Close(db)
@ -429,8 +430,8 @@ func StopMonkeyTask(c *gin.Context) {
if task_id := cast.ToInt(c.PostForm("task_id")); task_id > 0 {
db, err := dbsql.GetConn(dbsql.DSN)
if rsp.CheckErr(err) {
c.JSON(http.StatusOK, rsp)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
defer dbsql.Close(db)
@ -462,6 +463,13 @@ func StopMonkeyTask(c *gin.Context) {
killPid(v.PId)
pids = append(pids, v.PId)
}
//判断是否停止成功
var pids []models.MonkeyPid
db.Table("monkey_pid").Model(models.MonkeyPid{}).Where("task_id = ?", task.Id).Find(&pids)
if code := checkTaskPids(pids); code == 1 {
task.Status = "CANCEL"
db.Model(models.MonkeyTask{}).Where("id = ?", task.Id).Update("status", task.Status)
}
}
rsp.Success()

@ -9,14 +9,6 @@ import (
)
func main() {
var task models.MonkeyTask
task.Project = "Hising"
task.Version = "1.00.04_10004006"
task.Platform = "adr"
task.Branch = "xxx/bbb/vasd_sdds"
task.PackageName = "music.hising.live.dev"
common.PushMonkeyResult(task)
return
dbsql.DSN = dbsql.DSN_local
db, err := dbsql.GetConn(dbsql.DSN)
if err != nil {
@ -24,6 +16,17 @@ func main() {
return
}
defer dbsql.Close(db)
var task models.MonkeyTask
db.Last(&task)
common.PushMonkeyResult(task)
return
// dbsql.DSN = dbsql.DSN_local
// db, err := dbsql.GetConn(dbsql.DSN)
// if err != nil {
// fmt.Println(err)
// return
// }
// defer dbsql.Close(db)
var list []models.MonkeyTask
db.Model(models.MonkeyTask{}).Order("id DESC").Find(&list)

Loading…
Cancel
Save