直接上我的一个web播放器的样例代码片段
主要是 LoadTemplate 方法
然后打包的时候需要用packr2工具:
#安装编译工具,用于打包html到二进制 go get -u github.com/gobuffalo/packr/v2/packr2 #build和go build一样,交叉编译的方式也是一样的 CGO_ENABLED=0 GOOS=linux GOARCH=arm packr2 build -o 115_player #简单点的 packr2 build -o 115_player
代码片段:
package web
import (
"crypto/md5"
"encoding/hex"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gobuffalo/packr/v2"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"html/template"
"net"
"net/http"
"os"
"runtime"
"strings"
"time"
)
var MainConsole = make(chan os.Signal, 1)
type webServer struct {
Engine *gin.Engine
}
type Conf struct {
User string
Password string
}
var Webserver = &webServer{}
type MSG map[string]interface{}
func OK(data interface{}) MSG {
return MSG{"data": data, "code": 0, "msg": "ok"}
}
func Failed(code int, msg string) MSG {
return MSG{"data": nil, "code": code, "msg": msg}
}
func (s *webServer) Run(addr string) {
gin.SetMode(gin.ReleaseMode)
s.Engine = gin.New()
// 自动加载模板
t := template.New("tmp")
//func 函数映射 全局模板可用
t.Funcs(template.FuncMap{
"getYear": GetYear,
"formatAsDate": FormatAsDate,
"getConf": GetConf,
"getDate": GetDate,
"getavator": Getavator,
"getServerInfo": GetServerInfo,
"formatFileSize": FormatFileSize,
})
//从二进制中加载模板(后缀必须.html)
t, _ = s.LoadTemplate(t)
s.Engine.SetHTMLTemplate(t)
//静态资源
assets := packr.New("assets", "../template/assets")
//s.Engine.Static("/assets", "./template/assets")
s.Engine.StaticFS("/assets", assets)
s.Engine.GET("/", func(c *gin.Context) {
c.Redirect(302, "/index/login")
})
//通用路由
s.Engine.Any("/m3u8/*action", s.AdminM3u8) // 用于代理m3u8的文件和ts文件的全局访问
s.Engine.Any("/admin/:action", AuthMiddleWare(), s.admin)
s.Engine.Any("/index/:action", s.index)
go func() {
log.Infof("115 player webui 服务器已启动: %v", addr)
err := s.Engine.Run(addr)
if err != nil {
log.Error(err)
log.Infof("请检查端口是否被占用.")
time.Sleep(time.Second * 5)
os.Exit(1)
}
}()
return
}
// loadTemplate loads templates by packr 将html 打包到二进制包
func (s *webServer) LoadTemplate(t *template.Template) (*template.Template, error) {
box := packr.New("tmp", "../template/html")
for _, file := range box.List() {
if !strings.HasSuffix(file, ".html") {
continue
}
h, err := box.FindString(file)
if err != nil {
return nil, err
}
//拼接方式,组装模板 admin/index.html 这种,方便调用
t, err = t.New(strings.Replace(file, "html/", "", 1)).Parse(h)
if err != nil {
return nil, err
}
}
return t, nil
}
//格式化年月日
func FormatAsDate(t time.Time) string {
year, month, day := t.Date()
return fmt.Sprintf("%d%02d/%02d", year, month, day)
}
// 获取年份
func GetYear() string {
t := time.Now()
year, _, _ := t.Date()
return fmt.Sprintf("%d", year)
}
// 获取当前年月日
func GetDate() string {
t := time.Now()
year, month, day := t.Date()
return fmt.Sprintf("%d-%02d-%02d", year, month, day)
}
// 随机获取一个头像
func Getavator() string {
Uuid := uuid.New().String()
grav_url := "https://www.gravatar.com/avatar/" + Uuid
return grav_url
}
type info struct {
Root string
Version string
Hostname string
Interfaces interface{}
Goarch string
Goos string
//VirtualMemory *mem.VirtualMemoryStat
Sys uint64
CpuInfoStat struct {
Count int
Percent []float64
}
}
func GetServerInfo() *info {
root := runtime.GOROOT() // GO 路径
version := runtime.Version() //GO 版本信息
hostname, _ := os.Hostname() //获得PC名
interfaces, _ := net.Interfaces() //获得网卡信息
goarch := runtime.GOARCH //系统构架 386、amd64
goos := runtime.GOOS //系统版本 windows
Info := &info{
Root: root,
Version: version,
Hostname: hostname,
Interfaces: interfaces,
Goarch: goarch,
Goos: goos,
}
//v, _ := mem.VirtualMemory()
//Info.VirtualMemory = v
var ms runtime.MemStats
runtime.ReadMemStats(&ms)
Info.Sys = ms.Sys
//Info.CpuInfoStat.Count, _ = cpu.Counts(true)
//Info.CpuInfoStat.Percent, _ = cpu.Percent(0, true)
return Info
}
// 字节的单位转换 保留两位小数
func FormatFileSize(fileSize uint64) (size string) {
if fileSize < 1024 {
//return strconv.FormatInt(fileSize, 10) + "B"
return fmt.Sprintf("%.2fB", float64(fileSize)/float64(1))
} else if fileSize < (1024 * 1024) {
return fmt.Sprintf("%.2fKB", float64(fileSize)/float64(1024))
} else if fileSize < (1024 * 1024 * 1024) {
return fmt.Sprintf("%.2fMB", float64(fileSize)/float64(1024*1024))
} else if fileSize < (1024 * 1024 * 1024 * 1024) {
return fmt.Sprintf("%.2fGB", float64(fileSize)/float64(1024*1024*1024))
} else if fileSize < (1024 * 1024 * 1024 * 1024 * 1024) {
return fmt.Sprintf("%.2fTB", float64(fileSize)/float64(1024*1024*1024*1024))
} else { //if fileSize < (1024 * 1024 * 1024 * 1024 * 1024 * 1024)
return fmt.Sprintf("%.2fEB", float64(fileSize)/float64(1024*1024*1024*1024*1024))
}
}
// admin 控制器 登录验证
func AuthMiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
//conf := GetConf()
user := "admin"
password := "admin"
str1 := user + password
h := md5.New()
h.Write([]byte(str1))
md51 := hex.EncodeToString(h.Sum(nil))
if cookie, err := c.Request.Cookie("userinfo"); err == nil {
value := cookie.Value
if value == md51 {
c.Next()
return
}
}
c.HTML(http.StatusOK, "index/jump.html", gin.H{
"url": "/index/login",
"timeout": "3",
"code": 0, //1为success,0为error
"msg": "请登录后再访问",
})
//c.Redirect(http.StatusMovedPermanently, "/index/login")
c.Abort()
return
}
}
func (s *webServer) admin(c *gin.Context) {
action := c.Param("action")
log.Debugf("webServer接收到cgi调用: %v", action)
if f, ok := HttpuriAdmin[action]; ok {
f(s, c)
} else {
c.JSON(200, Failed(404, "没有相关页面"))
}
}
func (s *webServer) index(c *gin.Context) {
action := c.Param("action")
log.Debugf("webServer接收到cgi调用: %v", action)
if f, ok := HttpuriIndex[action]; ok {
f(s, c)
} else {
c.JSON(200, Failed(404, "没有相关页面"))
}
}
// 获取当前配置文件信息
func GetConf() Conf {
conf := Conf{User: "admin", Password: "admin"}
return conf
}
func Error(c *gin.Context, msg string, timeout int, url string) {
c.HTML(http.StatusOK, "index/jump.html", gin.H{
"url": url,
"timeout": timeout,
"code": 0, //1为success,0为error
"msg": msg,
})
c.Abort()
return
}
微信扫一扫,打赏作者吧~