mirror of
https://github.com/nezhahq/nezha.git
synced 2025-02-02 09:38:13 -05:00
Merge branch 'master' into l10n_master
This commit is contained in:
commit
71018b545c
@ -4,7 +4,7 @@
|
|||||||
<br>
|
<br>
|
||||||
<small><i>LOGO designed by <a href="https://xio.ng" target="_blank">熊大</a> .</i></small>
|
<small><i>LOGO designed by <a href="https://xio.ng" target="_blank">熊大</a> .</i></small>
|
||||||
<br><br>
|
<br><br>
|
||||||
<img src="https://img.shields.io/github/workflow/status/naiba/nezha/Dashboard%20image?label=Dash%20v0.12.30&logo=github&style=for-the-badge"> <img src="https://img.shields.io/github/v/release/naiba/nezha?color=brightgreen&label=Agent&style=for-the-badge&logo=github"> <img src="https://img.shields.io/github/workflow/status/naiba/nezha/Agent%20release?label=Agent%20CI&logo=github&style=for-the-badge"> <img src="https://img.shields.io/badge/Installer-v0.9.0-brightgreen?style=for-the-badge&logo=linux">
|
<img src="https://img.shields.io/github/workflow/status/naiba/nezha/Dashboard%20image?label=Dash%20v0.13.1&logo=github&style=for-the-badge"> <img src="https://img.shields.io/github/v/release/naiba/nezha?color=brightgreen&label=Agent&style=for-the-badge&logo=github"> <img src="https://img.shields.io/github/workflow/status/naiba/nezha/Agent%20release?label=Agent%20CI&logo=github&style=for-the-badge"> <img src="https://img.shields.io/badge/Installer-v0.9.1-brightgreen?style=for-the-badge&logo=linux"> <a title="Crowdin" target="_blank" href="https://crowdin.com/project/nezha"><img src="https://badges.crowdin.net/nezha/localized.svg"></a>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<p>:trollface: <b>Nezha Monitoring</b> One-stop light monitoring and light operation and maintenance system. Supports system status, HTTP (SSL certificate change, upcoming expiration, expiration), TCP, Ping monitoring and alarm, scheduled tasks and web terminal.</p>
|
<p>:trollface: <b>Nezha Monitoring</b> One-stop light monitoring and light operation and maintenance system. Supports system status, HTTP (SSL certificate change, upcoming expiration, expiration), TCP, Ping monitoring and alarm, scheduled tasks and web terminal.</p>
|
||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
\>> QQ 交流群:872069346 **加群要求:已搭建好哪吒监控 & 有 2+ 服务器, 机器人自动审核**
|
\>> QQ 交流群:872069346 **加群要求:已搭建好哪吒监控 & 有 2+ 服务器, 机器人自动审核**
|
||||||
|
|
||||||
\>> [Use Cases | 我们的用户](https://www.google.com/search?q="powered+by+哪吒监控"&filter=0) (Google)
|
\>> [Use Cases | 我们的用户](https://www.google.com/search?q=%22powered+by+%E5%93%AA%E5%90%92%E7%9B%91%E6%8E%A7%22+OR+%22powered+by+Nezha+Monitoring%22&filter=0) (Google)
|
||||||
|
|
||||||
| Default Theme | DayNight [@JackieSung](https://github.com/JackieSung4ev) | hotaru |
|
| Default Theme | DayNight [@JackieSung](https://github.com/JackieSung4ev) | hotaru |
|
||||||
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
|
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
|
||||||
@ -25,7 +25,7 @@
|
|||||||
## User Guide
|
## User Guide
|
||||||
|
|
||||||
- [中文文档](docs/UserGuide_zh.md)
|
- [中文文档](docs/UserGuide_zh.md)
|
||||||
- [English](docs/UserGuide_en.md)
|
- [English](docs/UserGuide_en.md) WIP
|
||||||
|
|
||||||
## Special Thanks
|
## Special Thanks
|
||||||
|
|
||||||
@ -33,6 +33,6 @@
|
|||||||
- [@Erope](https://github.com/JackieSung4ev) for contributed a lot to our installation scripts and community building.
|
- [@Erope](https://github.com/JackieSung4ev) for contributed a lot to our installation scripts and community building.
|
||||||
- [@MikoyChinese](https://github.com/MikoyChinese) for our second community-contributed front-end theme.
|
- [@MikoyChinese](https://github.com/MikoyChinese) for our second community-contributed front-end theme.
|
||||||
- [@AkkiaS7](https://github.com/Akkia) and [hhhkkk520](https://github.com/hhhkkk520) for the excellent contribution in the early days of globalization.
|
- [@AkkiaS7](https://github.com/Akkia) and [hhhkkk520](https://github.com/hhhkkk520) for the excellent contribution in the early days of globalization.
|
||||||
- [@dysf888](https://gitub.com/dysf888) for the installation script in windows.
|
- [@dysf888](https://gitub.com/dysf888) for the installation script in Windows.
|
||||||
- [@MartijnLindeman](https://github.com/MartijnLindeman) for his perseverance has taken us to the international market.
|
- [@MartijnLindeman](https://github.com/MartijnLindeman) for his perseverance has taken us to the international market.
|
||||||
- and other [contributors](https://github.com/naiba/nezha/graphs/contributors).
|
- and other [contributors](https://github.com/naiba/nezha/graphs/contributors).
|
||||||
|
@ -2,7 +2,6 @@ package controller
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -14,6 +13,7 @@ import (
|
|||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/hashicorp/go-uuid"
|
"github.com/hashicorp/go-uuid"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"golang.org/x/sync/singleflight"
|
"golang.org/x/sync/singleflight"
|
||||||
|
|
||||||
@ -60,16 +60,18 @@ func (p *commonPage) issueViewPassword(c *gin.Context) {
|
|||||||
err := c.ShouldBind(&vpf)
|
err := c.ShouldBind(&vpf)
|
||||||
var hash []byte
|
var hash []byte
|
||||||
if err == nil && vpf.Password != singleton.Conf.Site.ViewPassword {
|
if err == nil && vpf.Password != singleton.Conf.Site.ViewPassword {
|
||||||
err = errors.New("查看密码错误")
|
err = errors.New(singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "WrongAccessPassword"}))
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
hash, err = bcrypt.GenerateFromPassword([]byte(vpf.Password), bcrypt.DefaultCost)
|
hash, err = bcrypt.GenerateFromPassword([]byte(vpf.Password), bcrypt.DefaultCost)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
Title: "出现错误",
|
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||||
Msg: fmt.Sprintf("请求错误:%s", err),
|
MessageID: "AnErrorEccurred",
|
||||||
|
}),
|
||||||
|
Msg: err.Error(),
|
||||||
}, true)
|
}, true)
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
@ -92,7 +94,7 @@ func (p *commonPage) checkViewPassword(c *gin.Context) {
|
|||||||
viewPassword, _ := c.Cookie(singleton.Conf.Site.CookieName + "-vp")
|
viewPassword, _ := c.Cookie(singleton.Conf.Site.CookieName + "-vp")
|
||||||
if err := bcrypt.CompareHashAndPassword([]byte(viewPassword), []byte(singleton.Conf.Site.ViewPassword)); err != nil {
|
if err := bcrypt.CompareHashAndPassword([]byte(viewPassword), []byte(singleton.Conf.Site.ViewPassword)); err != nil {
|
||||||
c.HTML(http.StatusOK, "theme-"+singleton.Conf.Site.Theme+"/viewpassword", mygin.CommonEnvironment(c, gin.H{
|
c.HTML(http.StatusOK, "theme-"+singleton.Conf.Site.Theme+"/viewpassword", mygin.CommonEnvironment(c, gin.H{
|
||||||
"Title": "验证查看密码",
|
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "VerifyPassword"}),
|
||||||
"CustomCode": singleton.Conf.Site.CustomCode,
|
"CustomCode": singleton.Conf.Site.CustomCode,
|
||||||
}))
|
}))
|
||||||
c.Abort()
|
c.Abort()
|
||||||
@ -116,7 +118,7 @@ func (p *commonPage) service(c *gin.Context) {
|
|||||||
}, nil
|
}, nil
|
||||||
})
|
})
|
||||||
c.HTML(http.StatusOK, "theme-"+singleton.Conf.Site.Theme+"/service", mygin.CommonEnvironment(c, gin.H{
|
c.HTML(http.StatusOK, "theme-"+singleton.Conf.Site.Theme+"/service", mygin.CommonEnvironment(c, gin.H{
|
||||||
"Title": "服务状态",
|
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesStatus"}),
|
||||||
"Services": res.([]interface{})[0],
|
"Services": res.([]interface{})[0],
|
||||||
"CycleTransferStats": res.([]interface{})[1],
|
"CycleTransferStats": res.([]interface{})[1],
|
||||||
"CustomCode": singleton.Conf.Site.CustomCode,
|
"CustomCode": singleton.Conf.Site.CustomCode,
|
||||||
@ -139,11 +141,13 @@ func (cp *commonPage) home(c *gin.Context) {
|
|||||||
stat, err := cp.getServerStat()
|
stat, err := cp.getServerStat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||||
Code: http.StatusInternalServerError,
|
Code: http.StatusInternalServerError,
|
||||||
Title: "系统错误",
|
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||||
Msg: "服务器状态获取失败",
|
MessageID: "SystemError",
|
||||||
Link: "/",
|
}),
|
||||||
Btn: "返回首页",
|
Msg: "服务器状态获取失败",
|
||||||
|
Link: "/",
|
||||||
|
Btn: "返回首页",
|
||||||
}, true)
|
}, true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -167,11 +171,13 @@ func (cp *commonPage) ws(c *gin.Context) {
|
|||||||
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||||
Code: http.StatusInternalServerError,
|
Code: http.StatusInternalServerError,
|
||||||
Title: "网络错误",
|
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||||
Msg: "Websocket协议切换失败",
|
MessageID: "NetowrkError",
|
||||||
Link: "/",
|
}),
|
||||||
Btn: "返回首页",
|
Msg: "Websocket协议切换失败",
|
||||||
|
Link: "/",
|
||||||
|
Btn: "返回首页",
|
||||||
}, true)
|
}, true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -312,11 +318,13 @@ func (cp *commonPage) terminal(c *gin.Context) {
|
|||||||
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||||
Code: http.StatusInternalServerError,
|
Code: http.StatusInternalServerError,
|
||||||
Title: "网络错误",
|
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||||
Msg: "Websocket协议切换失败",
|
MessageID: "NetowrkError",
|
||||||
Link: "/",
|
}),
|
||||||
Btn: "返回首页",
|
Msg: "Websocket协议切换失败",
|
||||||
|
Link: "/",
|
||||||
|
Btn: "返回首页",
|
||||||
}, true)
|
}, true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -447,11 +455,13 @@ func (cp *commonPage) createTerminal(c *gin.Context) {
|
|||||||
id, err := uuid.GenerateUUID()
|
id, err := uuid.GenerateUUID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
mygin.ShowErrorPage(c, mygin.ErrInfo{
|
||||||
Code: http.StatusInternalServerError,
|
Code: http.StatusInternalServerError,
|
||||||
Title: "系统错误",
|
Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||||
Msg: "生成会话ID失败",
|
MessageID: "SystemError",
|
||||||
Link: "/server",
|
}),
|
||||||
Btn: "返回重试",
|
Msg: "生成会话ID失败",
|
||||||
|
Link: "/server",
|
||||||
|
Btn: "返回重试",
|
||||||
}, true)
|
}, true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -26,116 +26,7 @@ func ServeWeb(port uint) *http.Server {
|
|||||||
pprof.Register(r)
|
pprof.Register(r)
|
||||||
}
|
}
|
||||||
r.Use(mygin.RecordPath)
|
r.Use(mygin.RecordPath)
|
||||||
r.SetFuncMap(template.FuncMap{
|
r.SetFuncMap(funcMap)
|
||||||
"tr": func(id string, dataAndCount ...interface{}) string {
|
|
||||||
conf := i18n.LocalizeConfig{
|
|
||||||
MessageID: id,
|
|
||||||
}
|
|
||||||
if len(dataAndCount) > 0 {
|
|
||||||
conf.TemplateData = dataAndCount[0]
|
|
||||||
}
|
|
||||||
if len(dataAndCount) > 1 {
|
|
||||||
conf.PluralCount = dataAndCount[1]
|
|
||||||
}
|
|
||||||
return singleton.Localizer.MustLocalize(&conf)
|
|
||||||
},
|
|
||||||
"toValMap": func(val interface{}) map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"Value": val,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tf": func(t time.Time) string {
|
|
||||||
return t.In(singleton.Loc).Format("2006年1月2号 15:04:05")
|
|
||||||
},
|
|
||||||
"len": func(slice []interface{}) string {
|
|
||||||
return strconv.Itoa(len(slice))
|
|
||||||
},
|
|
||||||
"safe": func(s string) template.HTML {
|
|
||||||
return template.HTML(s) // #nosec
|
|
||||||
},
|
|
||||||
"tag": func(s string) template.HTML {
|
|
||||||
return template.HTML(`<` + s + `>`) // #nosec
|
|
||||||
},
|
|
||||||
"stf": func(s uint64) string {
|
|
||||||
return time.Unix(int64(s), 0).In(singleton.Loc).Format("2006年1月2号 15:04")
|
|
||||||
},
|
|
||||||
"sf": func(duration uint64) string {
|
|
||||||
return time.Duration(time.Duration(duration) * time.Second).String()
|
|
||||||
},
|
|
||||||
"sft": func(future time.Time) string {
|
|
||||||
return time.Until(future).Round(time.Second).String()
|
|
||||||
},
|
|
||||||
"bf": func(b uint64) string {
|
|
||||||
return bytefmt.ByteSize(b)
|
|
||||||
},
|
|
||||||
"ts": func(s string) string {
|
|
||||||
return strings.TrimSpace(s)
|
|
||||||
},
|
|
||||||
"float32f": func(f float32) string {
|
|
||||||
return fmt.Sprintf("%.2f", f)
|
|
||||||
},
|
|
||||||
"divU64": func(a, b uint64) float32 {
|
|
||||||
if b == 0 {
|
|
||||||
if a > 0 {
|
|
||||||
return 100
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if a == 0 {
|
|
||||||
// 这是从未在线的情况
|
|
||||||
return 0.00001 / float32(b) * 100
|
|
||||||
}
|
|
||||||
return float32(a) / float32(b) * 100
|
|
||||||
},
|
|
||||||
"div": func(a, b int) float32 {
|
|
||||||
if b == 0 {
|
|
||||||
if a > 0 {
|
|
||||||
return 100
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if a == 0 {
|
|
||||||
// 这是从未在线的情况
|
|
||||||
return 0.00001 / float32(b) * 100
|
|
||||||
}
|
|
||||||
return float32(a) / float32(b) * 100
|
|
||||||
},
|
|
||||||
"addU64": func(a, b uint64) uint64 {
|
|
||||||
return a + b
|
|
||||||
},
|
|
||||||
"add": func(a, b int) int {
|
|
||||||
return a + b
|
|
||||||
},
|
|
||||||
"dayBefore": func(i int) string {
|
|
||||||
year, month, day := time.Now().Date()
|
|
||||||
today := time.Date(year, month, day, 0, 0, 0, 0, time.Local)
|
|
||||||
return today.AddDate(0, 0, i-29).Format("1月2号")
|
|
||||||
},
|
|
||||||
"className": func(percent float32) string {
|
|
||||||
if percent == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if percent > 95 {
|
|
||||||
return "good"
|
|
||||||
}
|
|
||||||
if percent > 80 {
|
|
||||||
return "warning"
|
|
||||||
}
|
|
||||||
return "danger"
|
|
||||||
},
|
|
||||||
"statusName": func(percent float32) string {
|
|
||||||
if percent == 0 {
|
|
||||||
return "无数据"
|
|
||||||
}
|
|
||||||
if percent > 95 {
|
|
||||||
return "良好"
|
|
||||||
}
|
|
||||||
if percent > 80 {
|
|
||||||
return "低可用"
|
|
||||||
}
|
|
||||||
return "故障"
|
|
||||||
},
|
|
||||||
})
|
|
||||||
r.Static("/static", "resource/static")
|
r.Static("/static", "resource/static")
|
||||||
r.LoadHTMLGlob("resource/template/**/*.html")
|
r.LoadHTMLGlob("resource/template/**/*.html")
|
||||||
routers(r)
|
routers(r)
|
||||||
@ -176,3 +67,114 @@ func routers(r *gin.Engine) {
|
|||||||
ma.serve()
|
ma.serve()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var funcMap = template.FuncMap{
|
||||||
|
"tr": func(id string, dataAndCount ...interface{}) string {
|
||||||
|
conf := i18n.LocalizeConfig{
|
||||||
|
MessageID: id,
|
||||||
|
}
|
||||||
|
if len(dataAndCount) > 0 {
|
||||||
|
conf.TemplateData = dataAndCount[0]
|
||||||
|
}
|
||||||
|
if len(dataAndCount) > 1 {
|
||||||
|
conf.PluralCount = dataAndCount[1]
|
||||||
|
}
|
||||||
|
return singleton.Localizer.MustLocalize(&conf)
|
||||||
|
},
|
||||||
|
"toValMap": func(val interface{}) map[string]interface{} {
|
||||||
|
return map[string]interface{}{
|
||||||
|
"Value": val,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tf": func(t time.Time) string {
|
||||||
|
return t.In(singleton.Loc).Format("2006年1月2号 15:04:05")
|
||||||
|
},
|
||||||
|
"len": func(slice []interface{}) string {
|
||||||
|
return strconv.Itoa(len(slice))
|
||||||
|
},
|
||||||
|
"safe": func(s string) template.HTML {
|
||||||
|
return template.HTML(s) // #nosec
|
||||||
|
},
|
||||||
|
"tag": func(s string) template.HTML {
|
||||||
|
return template.HTML(`<` + s + `>`) // #nosec
|
||||||
|
},
|
||||||
|
"stf": func(s uint64) string {
|
||||||
|
return time.Unix(int64(s), 0).In(singleton.Loc).Format("2006年1月2号 15:04")
|
||||||
|
},
|
||||||
|
"sf": func(duration uint64) string {
|
||||||
|
return time.Duration(time.Duration(duration) * time.Second).String()
|
||||||
|
},
|
||||||
|
"sft": func(future time.Time) string {
|
||||||
|
return time.Until(future).Round(time.Second).String()
|
||||||
|
},
|
||||||
|
"bf": func(b uint64) string {
|
||||||
|
return bytefmt.ByteSize(b)
|
||||||
|
},
|
||||||
|
"ts": func(s string) string {
|
||||||
|
return strings.TrimSpace(s)
|
||||||
|
},
|
||||||
|
"float32f": func(f float32) string {
|
||||||
|
return fmt.Sprintf("%.2f", f)
|
||||||
|
},
|
||||||
|
"divU64": func(a, b uint64) float32 {
|
||||||
|
if b == 0 {
|
||||||
|
if a > 0 {
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if a == 0 {
|
||||||
|
// 这是从未在线的情况
|
||||||
|
return 0.00001 / float32(b) * 100
|
||||||
|
}
|
||||||
|
return float32(a) / float32(b) * 100
|
||||||
|
},
|
||||||
|
"div": func(a, b int) float32 {
|
||||||
|
if b == 0 {
|
||||||
|
if a > 0 {
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if a == 0 {
|
||||||
|
// 这是从未在线的情况
|
||||||
|
return 0.00001 / float32(b) * 100
|
||||||
|
}
|
||||||
|
return float32(a) / float32(b) * 100
|
||||||
|
},
|
||||||
|
"addU64": func(a, b uint64) uint64 {
|
||||||
|
return a + b
|
||||||
|
},
|
||||||
|
"add": func(a, b int) int {
|
||||||
|
return a + b
|
||||||
|
},
|
||||||
|
"dayBefore": func(i int) string {
|
||||||
|
year, month, day := time.Now().Date()
|
||||||
|
today := time.Date(year, month, day, 0, 0, 0, 0, time.Local)
|
||||||
|
return today.AddDate(0, 0, i-29).Format("1月2号")
|
||||||
|
},
|
||||||
|
"className": func(percent float32) string {
|
||||||
|
if percent == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if percent > 95 {
|
||||||
|
return "good"
|
||||||
|
}
|
||||||
|
if percent > 80 {
|
||||||
|
return "warning"
|
||||||
|
}
|
||||||
|
return "danger"
|
||||||
|
},
|
||||||
|
"statusName": func(percent float32) string {
|
||||||
|
if percent == 0 {
|
||||||
|
return "无数据"
|
||||||
|
}
|
||||||
|
if percent > 95 {
|
||||||
|
return "良好"
|
||||||
|
}
|
||||||
|
if percent > 80 {
|
||||||
|
return "低可用"
|
||||||
|
}
|
||||||
|
return "故障"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
|
|
||||||
"github.com/naiba/nezha/model"
|
"github.com/naiba/nezha/model"
|
||||||
"github.com/naiba/nezha/pkg/mygin"
|
"github.com/naiba/nezha/pkg/mygin"
|
||||||
@ -40,7 +41,7 @@ func (gp *guestPage) login(c *gin.Context) {
|
|||||||
RegistrationLink = "https://gitee.com/signup"
|
RegistrationLink = "https://gitee.com/signup"
|
||||||
}
|
}
|
||||||
c.HTML(http.StatusOK, "dashboard/login", mygin.CommonEnvironment(c, gin.H{
|
c.HTML(http.StatusOK, "dashboard/login", mygin.CommonEnvironment(c, gin.H{
|
||||||
"Title": "登录",
|
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
||||||
"LoginType": LoginType,
|
"LoginType": LoginType,
|
||||||
"RegistrationLink": RegistrationLink,
|
"RegistrationLink": RegistrationLink,
|
||||||
}))
|
}))
|
||||||
|
@ -551,6 +551,7 @@ func (ma *memberAPI) logout(c *gin.Context) {
|
|||||||
type settingForm struct {
|
type settingForm struct {
|
||||||
Title string
|
Title string
|
||||||
Admin string
|
Admin string
|
||||||
|
Language string
|
||||||
Theme string
|
Theme string
|
||||||
CustomCode string
|
CustomCode string
|
||||||
ViewPassword string
|
ViewPassword string
|
||||||
@ -572,6 +573,7 @@ func (ma *memberAPI) updateSetting(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
singleton.Conf.Language = sf.Language
|
||||||
singleton.Conf.EnableIPChangeNotification = sf.EnableIPChangeNotification == "on"
|
singleton.Conf.EnableIPChangeNotification = sf.EnableIPChangeNotification == "on"
|
||||||
singleton.Conf.EnablePlainIPInNotification = sf.EnablePlainIPInNotification == "on"
|
singleton.Conf.EnablePlainIPInNotification = sf.EnablePlainIPInNotification == "on"
|
||||||
singleton.Conf.Cover = sf.Cover
|
singleton.Conf.Cover = sf.Cover
|
||||||
@ -594,6 +596,8 @@ func (ma *memberAPI) updateSetting(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// 更新系统语言
|
||||||
|
singleton.InitLocalizer()
|
||||||
c.JSON(http.StatusOK, model.Response{
|
c.JSON(http.StatusOK, model.Response{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
})
|
})
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/naiba/nezha/model"
|
"github.com/naiba/nezha/model"
|
||||||
"github.com/naiba/nezha/pkg/mygin"
|
"github.com/naiba/nezha/pkg/mygin"
|
||||||
"github.com/naiba/nezha/service/singleton"
|
"github.com/naiba/nezha/service/singleton"
|
||||||
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
type memberPage struct {
|
type memberPage struct {
|
||||||
@ -18,8 +19,8 @@ func (mp *memberPage) serve() {
|
|||||||
mr.Use(mygin.Authorize(mygin.AuthorizeOption{
|
mr.Use(mygin.Authorize(mygin.AuthorizeOption{
|
||||||
Member: true,
|
Member: true,
|
||||||
IsPage: true,
|
IsPage: true,
|
||||||
Msg: "此页面需要登录",
|
Msg: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "YouAreNotAuthorized"}),
|
||||||
Btn: "点此登录",
|
Btn: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
||||||
Redirect: "/login",
|
Redirect: "/login",
|
||||||
}))
|
}))
|
||||||
mr.GET("/server", mp.server)
|
mr.GET("/server", mp.server)
|
||||||
@ -33,14 +34,14 @@ func (mp *memberPage) server(c *gin.Context) {
|
|||||||
singleton.SortedServerLock.RLock()
|
singleton.SortedServerLock.RLock()
|
||||||
defer singleton.SortedServerLock.RUnlock()
|
defer singleton.SortedServerLock.RUnlock()
|
||||||
c.HTML(http.StatusOK, "dashboard/server", mygin.CommonEnvironment(c, gin.H{
|
c.HTML(http.StatusOK, "dashboard/server", mygin.CommonEnvironment(c, gin.H{
|
||||||
"Title": "服务器管理",
|
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServersManagement"}),
|
||||||
"Servers": singleton.SortedServerList,
|
"Servers": singleton.SortedServerList,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *memberPage) monitor(c *gin.Context) {
|
func (mp *memberPage) monitor(c *gin.Context) {
|
||||||
c.HTML(http.StatusOK, "dashboard/monitor", mygin.CommonEnvironment(c, gin.H{
|
c.HTML(http.StatusOK, "dashboard/monitor", mygin.CommonEnvironment(c, gin.H{
|
||||||
"Title": "服务监控",
|
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesManagement"}),
|
||||||
"Monitors": singleton.ServiceSentinelShared.Monitors(),
|
"Monitors": singleton.ServiceSentinelShared.Monitors(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -49,7 +50,7 @@ func (mp *memberPage) cron(c *gin.Context) {
|
|||||||
var crons []model.Cron
|
var crons []model.Cron
|
||||||
singleton.DB.Find(&crons)
|
singleton.DB.Find(&crons)
|
||||||
c.HTML(http.StatusOK, "dashboard/cron", mygin.CommonEnvironment(c, gin.H{
|
c.HTML(http.StatusOK, "dashboard/cron", mygin.CommonEnvironment(c, gin.H{
|
||||||
"Title": "计划任务",
|
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ScheduledTasks"}),
|
||||||
"Crons": crons,
|
"Crons": crons,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -60,7 +61,7 @@ func (mp *memberPage) notification(c *gin.Context) {
|
|||||||
var ar []model.AlertRule
|
var ar []model.AlertRule
|
||||||
singleton.DB.Find(&ar)
|
singleton.DB.Find(&ar)
|
||||||
c.HTML(http.StatusOK, "dashboard/notification", mygin.CommonEnvironment(c, gin.H{
|
c.HTML(http.StatusOK, "dashboard/notification", mygin.CommonEnvironment(c, gin.H{
|
||||||
"Title": "报警通知",
|
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Notification"}),
|
||||||
"Notifications": nf,
|
"Notifications": nf,
|
||||||
"AlertRules": ar,
|
"AlertRules": ar,
|
||||||
}))
|
}))
|
||||||
@ -68,6 +69,6 @@ func (mp *memberPage) notification(c *gin.Context) {
|
|||||||
|
|
||||||
func (mp *memberPage) setting(c *gin.Context) {
|
func (mp *memberPage) setting(c *gin.Context) {
|
||||||
c.HTML(http.StatusOK, "dashboard/setting", mygin.CommonEnvironment(c, gin.H{
|
c.HTML(http.StatusOK, "dashboard/setting", mygin.CommonEnvironment(c, gin.H{
|
||||||
"Title": "系统设置",
|
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Settings"}),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ func (oa *oauth2controller) callback(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
var isAdmin bool
|
var isAdmin bool
|
||||||
for _, admin := range strings.Split(singleton.Conf.Oauth2.Admin, ",") {
|
for _, admin := range strings.Split(singleton.Conf.Oauth2.Admin, ",") {
|
||||||
if admin != "" && gu.GetLogin() == admin {
|
if admin != "" && strings.ToLower(gu.GetLogin()) == strings.ToLower(admin) {
|
||||||
isAdmin = true
|
isAdmin = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -1,51 +1,5 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/naiba/nezha/service/singleton"
|
|
||||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
)
|
|
||||||
|
|
||||||
func htmlTemplateTranslateFn(id string, data interface{}, count interface{}) string {
|
|
||||||
return singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
|
||||||
MessageID: id,
|
|
||||||
TemplateData: data,
|
|
||||||
PluralCount: count,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
singleton.InitConfigFromPath("data/config.yaml")
|
|
||||||
singleton.InitLocalizer()
|
|
||||||
fmt.Println(singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
|
||||||
MessageID: "nezhaMonitor",
|
|
||||||
}))
|
|
||||||
|
|
||||||
fmt.Println(singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{
|
|
||||||
MessageID: "nezhaMonitor",
|
|
||||||
}))
|
|
||||||
|
|
||||||
fmt.Println("tr nezhaMonitor", htmlTemplateTranslateFn("nezhaMonitor", nil, nil))
|
|
||||||
fmt.Println("tr nezhaMonitor", htmlTemplateTranslateFn("nezhaMonitor", nil, 2))
|
|
||||||
fmt.Println("tr nezhaMonitor", htmlTemplateTranslateFn("nezhaMonitor", map[string]string{
|
|
||||||
"Ext": "Plus",
|
|
||||||
}, 2))
|
|
||||||
|
|
||||||
bundle := i18n.NewBundle(language.English)
|
|
||||||
localizer := i18n.NewLocalizer(bundle, "en")
|
|
||||||
catsMessage := &i18n.Message{
|
|
||||||
ID: "Cats",
|
|
||||||
One: "I have {{.PluralCount}} cat.",
|
|
||||||
Other: "I have {{.PluralCount}} cats.",
|
|
||||||
}
|
|
||||||
fmt.Println(localizer.MustLocalize(&i18n.LocalizeConfig{
|
|
||||||
DefaultMessage: catsMessage,
|
|
||||||
PluralCount: 1,
|
|
||||||
}))
|
|
||||||
fmt.Println(localizer.MustLocalize(&i18n.LocalizeConfig{
|
|
||||||
DefaultMessage: catsMessage,
|
|
||||||
PluralCount: 2,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
|
|
||||||
"github.com/naiba/nezha/model"
|
"github.com/naiba/nezha/model"
|
||||||
"github.com/naiba/nezha/service/singleton"
|
"github.com/naiba/nezha/service/singleton"
|
||||||
@ -34,6 +35,15 @@ func CommonEnvironment(c *gin.Context, data map[string]interface{}) gin.H {
|
|||||||
if ok {
|
if ok {
|
||||||
data["Admin"] = u
|
data["Admin"] = u
|
||||||
}
|
}
|
||||||
|
data["LANG"] = map[string]string{
|
||||||
|
"Add": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Add"}),
|
||||||
|
"Edit": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Edit"}),
|
||||||
|
"AlarmRule": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "AlarmRule"}),
|
||||||
|
"Notification": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "NotificationMethod"}),
|
||||||
|
"Server": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Server"}),
|
||||||
|
"Monitor": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesManagement"}),
|
||||||
|
"Cron": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ScheduledTasks"}),
|
||||||
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,3 +68,14 @@ func IPDesensitize(ipAddr string) string {
|
|||||||
ipAddr = ipv6Desensitize(ipAddr)
|
ipAddr = ipv6Desensitize(ipAddr)
|
||||||
return ipAddr
|
return ipAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PathExists(path string) (bool, error) {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
if err == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
let LANG = {
|
||||||
|
Add: "添加",
|
||||||
|
Edit: "修改",
|
||||||
|
AlarmRule: "报警规则",
|
||||||
|
Notification: "通知方式",
|
||||||
|
Server: "服务器",
|
||||||
|
Monitor: "监控",
|
||||||
|
Cron: "计划任务",
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLang(newLang) {
|
||||||
|
if (newLang) {
|
||||||
|
LANG = newLang;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function readableBytes(bytes) {
|
function readableBytes(bytes) {
|
||||||
if (!bytes) {
|
if (!bytes) {
|
||||||
return '0B'
|
return '0B'
|
||||||
@ -105,11 +121,11 @@ function showFormModal(modelSelector, formID, URL, getData) {
|
|||||||
|
|
||||||
function addOrEditAlertRule(rule) {
|
function addOrEditAlertRule(rule) {
|
||||||
const modal = $(".rule.modal");
|
const modal = $(".rule.modal");
|
||||||
modal.children(".header").text((rule ? "修改" : "添加") + "报警规则");
|
modal.children(".header").text((rule ? LANG.Edit : LANG.Add) + ' ' + LANG.AlarmRule);
|
||||||
modal
|
modal
|
||||||
.find(".nezha-primary-btn.button")
|
.find(".nezha-primary-btn.button")
|
||||||
.html(
|
.html(
|
||||||
rule ? '修改<i class="edit icon"></i>' : '添加<i class="add icon"></i>'
|
rule ? LANG.Edit + '<i class="edit icon"></i>' : LANG.Add + '<i class="add icon"></i>'
|
||||||
);
|
);
|
||||||
modal.find("input[name=ID]").val(rule ? rule.ID : null);
|
modal.find("input[name=ID]").val(rule ? rule.ID : null);
|
||||||
modal.find("input[name=Name]").val(rule ? rule.Name : null);
|
modal.find("input[name=Name]").val(rule ? rule.Name : null);
|
||||||
@ -125,13 +141,13 @@ function addOrEditAlertRule(rule) {
|
|||||||
|
|
||||||
function addOrEditNotification(notification) {
|
function addOrEditNotification(notification) {
|
||||||
const modal = $(".notification.modal");
|
const modal = $(".notification.modal");
|
||||||
modal.children(".header").text((notification ? "修改" : "添加") + "通知方式");
|
modal.children(".header").text((notification ? LANG.Edit : LANG.Add) + ' ' + LANG.Notification);
|
||||||
modal
|
modal
|
||||||
.find(".nezha-primary-btn.button")
|
.find(".nezha-primary-btn.button")
|
||||||
.html(
|
.html(
|
||||||
notification
|
notification
|
||||||
? '修改<i class="edit icon"></i>'
|
? LANG.Edit + '<i class="edit icon"></i>'
|
||||||
: '添加<i class="add icon"></i>'
|
: LANG.Add + '<i class="add icon"></i>'
|
||||||
);
|
);
|
||||||
modal.find("input[name=ID]").val(notification ? notification.ID : null);
|
modal.find("input[name=ID]").val(notification ? notification.ID : null);
|
||||||
modal.find("input[name=Name]").val(notification ? notification.Name : null);
|
modal.find("input[name=Name]").val(notification ? notification.Name : null);
|
||||||
@ -188,11 +204,11 @@ function post(path, params, method = 'post') {
|
|||||||
|
|
||||||
function addOrEditServer(server, conf) {
|
function addOrEditServer(server, conf) {
|
||||||
const modal = $(".server.modal");
|
const modal = $(".server.modal");
|
||||||
modal.children(".header").text((server ? "修改" : "添加") + "服务器");
|
modal.children(".header").text((server ? LANG.Edit : LANG.Add) + ' ' + LANG.Server);
|
||||||
modal
|
modal
|
||||||
.find(".nezha-primary-btn.button")
|
.find(".nezha-primary-btn.button")
|
||||||
.html(
|
.html(
|
||||||
server ? '修改<i class="edit icon"></i>' : '添加<i class="add icon"></i>'
|
server ? LANG.Edit + '<i class="edit icon"></i>' : LANG.Add + '<i class="add icon"></i>'
|
||||||
);
|
);
|
||||||
modal.find("input[name=id]").val(server ? server.ID : null);
|
modal.find("input[name=id]").val(server ? server.ID : null);
|
||||||
modal.find("input[name=name]").val(server ? server.Name : null);
|
modal.find("input[name=name]").val(server ? server.Name : null);
|
||||||
@ -216,11 +232,11 @@ function addOrEditServer(server, conf) {
|
|||||||
|
|
||||||
function addOrEditMonitor(monitor) {
|
function addOrEditMonitor(monitor) {
|
||||||
const modal = $(".monitor.modal");
|
const modal = $(".monitor.modal");
|
||||||
modal.children(".header").text((monitor ? "修改" : "添加") + "监控");
|
modal.children(".header").text((monitor ? LANG.Edit : LANG.Add) + ' ' + LANG.Monitor);
|
||||||
modal
|
modal
|
||||||
.find(".nezha-primary-btn.button")
|
.find(".nezha-primary-btn.button")
|
||||||
.html(
|
.html(
|
||||||
monitor ? '修改<i class="edit icon"></i>' : '添加<i class="add icon"></i>'
|
monitor ? LANG.Edit + '<i class="edit icon"></i>' : LANG.Add + '<i class="add icon"></i>'
|
||||||
);
|
);
|
||||||
modal.find("input[name=ID]").val(monitor ? monitor.ID : null);
|
modal.find("input[name=ID]").val(monitor ? monitor.ID : null);
|
||||||
modal.find("input[name=Name]").val(monitor ? monitor.Name : null);
|
modal.find("input[name=Name]").val(monitor ? monitor.Name : null);
|
||||||
@ -257,11 +273,11 @@ function addOrEditMonitor(monitor) {
|
|||||||
|
|
||||||
function addOrEditCron(cron) {
|
function addOrEditCron(cron) {
|
||||||
const modal = $(".cron.modal");
|
const modal = $(".cron.modal");
|
||||||
modal.children(".header").text((cron ? "修改" : "添加") + "计划任务");
|
modal.children(".header").text((cron ? LANG.Edit : LANG.Add) + ' ' + LANG.Cron);
|
||||||
modal
|
modal
|
||||||
.find(".nezha-primary-btn.button")
|
.find(".nezha-primary-btn.button")
|
||||||
.html(
|
.html(
|
||||||
cron ? '修改<i class="edit icon"></i>' : '添加<i class="add icon"></i>'
|
cron ? LANG.Edit + '<i class="edit icon"></i>' : LANG.Add + '<i class="add icon"></i>'
|
||||||
);
|
);
|
||||||
modal.find("input[name=ID]").val(cron ? cron.ID : null);
|
modal.find("input[name=ID]").val(cron ? cron.ID : null);
|
||||||
modal.find("input[name=Name]").val(cron ? cron.Name : null);
|
modal.find("input[name=Name]").val(cron ? cron.Name : null);
|
||||||
|
14
resource/template/common/footer.html
vendored
14
resource/template/common/footer.html
vendored
@ -1,16 +1,22 @@
|
|||||||
{{define "common/footer"}}
|
{{define "common/footer"}}
|
||||||
<div class="ui inverted vertical footer segment">
|
<div class="ui inverted vertical footer segment">
|
||||||
<div class="ui center aligned is-size-7 container">
|
<div class="ui center aligned is-size-7 container">
|
||||||
<b>© <a style="color: white;" href="/">{{.Conf.Site.Brand}}</a></b> | <small>Powered by <a href="https://github.com/naiba/nezha"
|
<b>© <a style="color: white;" href="/">{{.Conf.Site.Brand}}</a></b> | <small>Powered by <a
|
||||||
style="color: white;" target="_blank">{{tr "nezhaMonitor"}}</a> {{.Version}}</small>
|
href="https://github.com/naiba/nezha" style="color: white;" target="_blank">{{tr "NezhaMonitoring"}}</a>
|
||||||
|
{{.Version}}</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.4.1/jquery.min.js"></script>
|
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.4.1/jquery.min.js"></script>
|
||||||
<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/semantic-ui/2.4.1/semantic.min.js"></script>
|
<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/semantic-ui/2.4.1/semantic.min.js"></script>
|
||||||
<script src="/static/semantic-ui-alerts.min.js"></script>
|
<script src="/static/semantic-ui-alerts.min.js"></script>
|
||||||
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.12/vue.min.js"></script>
|
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.12/vue.min.js"></script>
|
||||||
<script src="/static/main.js?v20220423"></script>
|
<script src="/static/main.js?v20220430"></script>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
updateLang({{.LANG }});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
{{end}}
|
{{end}}
|
4
resource/template/common/menu.html
vendored
4
resource/template/common/menu.html
vendored
@ -1,9 +1,9 @@
|
|||||||
{{define "common/menu"}}
|
{{define "common/menu"}}
|
||||||
<div class="ui large top fixed menu nb-menu">
|
<div class="ui large top fixed menu nb-menu">
|
||||||
<div class="ui container">
|
<div class="ui container">
|
||||||
<div class="item">
|
<a class="item" href="/">
|
||||||
<img src="/static/logo.svg?v20210804">
|
<img src="/static/logo.svg?v20210804">
|
||||||
</div>
|
</a>
|
||||||
{{if .IsAdminPage}}
|
{{if .IsAdminPage}}
|
||||||
<a class='item{{if eq .MatchedPath "/server"}} active{{end}}' href="/server"><i class="server icon"></i>{{tr "Server"}}</a>
|
<a class='item{{if eq .MatchedPath "/server"}} active{{end}}' href="/server"><i class="server icon"></i>{{tr "Server"}}</a>
|
||||||
<a class='item{{if eq .MatchedPath "/monitor"}} active{{end}}' href="/monitor"><i class="rss icon"></i>{{tr "Services"}}</a>
|
<a class='item{{if eq .MatchedPath "/monitor"}} active{{end}}' href="/monitor"><i class="rss icon"></i>{{tr "Services"}}</a>
|
||||||
|
2
resource/template/component/cron.html
vendored
2
resource/template/component/cron.html
vendored
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>{{tr "NotificationMethod"}}}</label>
|
<label>{{tr "NotificationMethodGroup"}}}</label>
|
||||||
<input type="text" name="NotificationTag" placeholder="default">
|
<input type="text" name="NotificationTag" placeholder="default">
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
2
resource/template/component/monitor.html
vendored
2
resource/template/component/monitor.html
vendored
@ -45,7 +45,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>{{tr "NotificationMethod"}}</label>
|
<label>{{tr "NotificationMethodGroup"}}</label>
|
||||||
<input type="text" name="NotificationTag" placeholder="default" />
|
<input type="text" name="NotificationTag" placeholder="default" />
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
2
resource/template/component/rule.html
vendored
2
resource/template/component/rule.html
vendored
@ -13,7 +13,7 @@
|
|||||||
<textarea name="RulesRaw"></textarea>
|
<textarea name="RulesRaw"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>{{tr "NotificationMethod"}}</label>
|
<label>{{tr "NotificationMethodGroup"}}</label>
|
||||||
<input type="text" name="NotificationTag" placeholder="default">
|
<input type="text" name="NotificationTag" placeholder="default">
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<th>{{tr "Name"}}</th>
|
<th>{{tr "Name"}}</th>
|
||||||
<th>{{tr "Scheduler"}}</th>
|
<th>{{tr "Scheduler"}}</th>
|
||||||
<th>{{tr "Command"}}</th>
|
<th>{{tr "Command"}}</th>
|
||||||
<th>{{tr "NotificationMethod"}}</th>
|
<th>{{tr "NotificationMethodGroup"}}</th>
|
||||||
<th>{{tr "PushSuccessfully"}}</th>
|
<th>{{tr "PushSuccessfully"}}</th>
|
||||||
<th>{{tr "Coverage"}}</th>
|
<th>{{tr "Coverage"}}</th>
|
||||||
<th>{{tr "SpecificServers"}}</th>
|
<th>{{tr "SpecificServers"}}</th>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<th>{{tr "SpecificServers"}}</th>
|
<th>{{tr "SpecificServers"}}</th>
|
||||||
<th>{{tr "Type"}}</th>
|
<th>{{tr "Type"}}</th>
|
||||||
<th>{{tr "Duration"}}</th>
|
<th>{{tr "Duration"}}</th>
|
||||||
<th>{{tr "NotificationMethod"}}</th>
|
<th>{{tr "NotificationMethodGroup"}}</th>
|
||||||
<th>{{tr "Notification"}}</th>
|
<th>{{tr "Notification"}}</th>
|
||||||
<th>{{tr "Administration"}}</th>
|
<th>{{tr "Administration"}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -36,7 +36,7 @@
|
|||||||
{{if eq $monitor.Type 1}}{{tr "SSLCertificate"}} {{else if eq $monitor.Type
|
{{if eq $monitor.Type 1}}{{tr "SSLCertificate"}} {{else if eq $monitor.Type
|
||||||
2}} ICMP Ping {{else}} {{tr "TCPPort"}} {{end}}
|
2}} ICMP Ping {{else}} {{tr "TCPPort"}} {{end}}
|
||||||
</td>
|
</td>
|
||||||
<td>{{$monitor.Duration}}{{tr "Seconds"}}</td>
|
<td>{{$monitor.Duration}} {{tr "Seconds"}}</td>
|
||||||
<td>{{$monitor.NotificationTag}}</td>
|
<td>{{$monitor.NotificationTag}}</td>
|
||||||
<td>{{$monitor.Notify}}</td>
|
<td>{{$monitor.Notify}}</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>{{tr "Name"}}</th>
|
<th>{{tr "Name"}}</th>
|
||||||
<th>{{tr "NotificationMethod"}}</th>
|
<th>{{tr "NotificationMethodGroup"}}</th>
|
||||||
<th>{{tr "Rules"}}</th>
|
<th>{{tr "Rules"}}</th>
|
||||||
<th>{{tr "Enable"}}</th>
|
<th>{{tr "Enable"}}</th>
|
||||||
<th>{{tr "Administration"}}</th>
|
<th>{{tr "Administration"}}</th>
|
||||||
|
@ -44,15 +44,11 @@
|
|||||||
data-tooltip="{{tr "ClickToCopyTheInstallationCommand"}}">
|
data-tooltip="{{tr "ClickToCopyTheInstallationCommand"}}">
|
||||||
<i class="linux icon"></i>
|
<i class="linux icon"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="ui icon mini button" data-tooltip="{{tr "NotSupportedYet"}}">
|
|
||||||
<button class="ui icon green mini button"
|
<button class="ui icon green mini button"
|
||||||
data-clipboard-text="{{if $.Conf.GRPCHost}}set-ExecutionPolicy RemoteSigned;Invoke-WebRequest https://raw.githubusercontent.com/naiba/nezha/master/script/install.ps1 -OutFile C:\install.ps1;powershell.exe C:\install.ps1 {{$.Conf.GRPCHost}}:{{if $.Conf.ProxyGRPCPort}}{{$.Conf.ProxyGRPCPort}}{{else}}{{$.Conf.GRPCPort}}{{end}} {{$server.Secret}}{{if $.Conf.TLS}} --tls{{end}}{{else}}{{tr "NoDomainAlert"}}{{end}}"
|
data-clipboard-text="{{if $.Conf.GRPCHost}}set-ExecutionPolicy RemoteSigned;Invoke-WebRequest https://raw.githubusercontent.com/naiba/nezha/master/script/install.ps1 -OutFile C:\install.ps1;powershell.exe C:\install.ps1 {{$.Conf.GRPCHost}}:{{if $.Conf.ProxyGRPCPort}}{{$.Conf.ProxyGRPCPort}}{{else}}{{$.Conf.GRPCPort}}{{end}} {{$server.Secret}}{{if $.Conf.TLS}} --tls{{end}}{{else}}{{tr "NoDomainAlert"}}{{end}}"
|
||||||
data-tooltip="{{tr "ClickToCopyTheInstallationCommand"}}">
|
data-tooltip="{{tr "ClickToCopyTheInstallationCommand"}}">
|
||||||
<i class="windows icon"></i>
|
<i class="windows icon"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="ui icon mini button" data-tooltip="{{tr "NotSupportedYet"}}">
|
|
||||||
<i class="apple icon"></i>
|
|
||||||
</button>
|
|
||||||
</td>
|
</td>
|
||||||
<td style="word-break: break-word;">{{$server.Note}}</td>
|
<td style="word-break: break-word;">{{$server.Note}}</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<form id="settingForm" class="ui large form" onsubmit="return false;">
|
<form id="settingForm" class="ui large form" onsubmit="return false;">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>{{tr "SiteTitle"}}</label>
|
<label>{{tr "SiteTitle"}}</label>
|
||||||
<input type="text" name="Title" placeholder="{{tr "nezhaMonitor"}}" value="{{.Conf.Site.Brand}}">
|
<input type="text" name="Title" placeholder="{{tr "NezhaMonitoring"}}" value="{{.Conf.Site.Brand}}">
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>{{tr "AdministratorList"}}</label>
|
<label>{{tr "AdministratorList"}}</label>
|
||||||
@ -24,12 +24,21 @@
|
|||||||
<option value="mdui" {{if eq .Conf.Site.Theme "mdui" }} selected="selected" {{end}}>Neko Mdui</option>
|
<option value="mdui" {{if eq .Conf.Site.Theme "mdui" }} selected="selected" {{end}}>Neko Mdui</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label>Language</label>
|
||||||
|
<select name="Language">
|
||||||
|
<option value="zh-CN" {{if eq .Conf.Language "zh-CN" }} selected="selected" {{end}}>
|
||||||
|
简体中文</option>
|
||||||
|
<option value="en-US" {{if eq .Conf.Language "en-US" }} selected="selected" {{end}}>
|
||||||
|
English</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>{{tr "CustomCodes"}}</label>
|
<label>{{tr "CustomCodes"}}</label>
|
||||||
<textarea name="CustomCode">{{.Conf.Site.CustomCode}}</textarea>
|
<textarea name="CustomCode">{{.Conf.Site.CustomCode}}</textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>{{tr "AccessPassword"}}}</label>
|
<label>{{tr "AccessPassword"}}</label>
|
||||||
<input type="text" name="ViewPassword" placeholder="" value="{{.Conf.Site.ViewPassword}}">
|
<input type="text" name="ViewPassword" placeholder="" value="{{.Conf.Site.ViewPassword}}">
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
@ -86,6 +95,7 @@
|
|||||||
time: '3',
|
time: '3',
|
||||||
position: 'top-center',
|
position: 'top-center',
|
||||||
});
|
});
|
||||||
|
window.location.reload()
|
||||||
} else {
|
} else {
|
||||||
$.suiAlert({
|
$.suiAlert({
|
||||||
title: '',
|
title: '',
|
||||||
|
6
resource/template/theme-daynight/home.html
vendored
6
resource/template/theme-daynight/home.html
vendored
@ -23,7 +23,7 @@
|
|||||||
<section class="nav-bar clearfix">
|
<section class="nav-bar clearfix">
|
||||||
<figure class="logo">
|
<figure class="logo">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="/static/logo.svg?v20210804" alt='{{tr "nezhaMonitor"}}' width="50" height="50">
|
<img src="/static/logo.svg?v20210804" alt='{{tr "NezhaMonitoring"}}' width="50" height="50">
|
||||||
</a>
|
</a>
|
||||||
<a href="/">{{.Conf.Site.Brand}}</a>
|
<a href="/">{{.Conf.Site.Brand}}</a>
|
||||||
</figure>
|
</figure>
|
||||||
@ -155,7 +155,7 @@
|
|||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<div class="footer-container">
|
<div class="footer-container">
|
||||||
<div><a href="https://github.com/naiba/nezha" target="_blank">Powered by {{tr "nezhaMonitor"}} · {{.Version}}</a>
|
<div><a href="https://github.com/naiba/nezha" target="_blank">Powered by {{tr "NezhaMonitoring"}} · {{.Version}}</a>
|
||||||
<p>© <span id="copyright-date">
|
<p>© <span id="copyright-date">
|
||||||
<script>document.getElementById('copyright-date').appendChild(document.createTextNode(new Date().getFullYear()))</script>
|
<script>document.getElementById('copyright-date').appendChild(document.createTextNode(new Date().getFullYear()))</script>
|
||||||
</span> · <a href="https://blog.jackiesung.com" target="_blank">Theme designed by Jackie Sung</a>
|
</span> · <a href="https://blog.jackiesung.com" target="_blank">Theme designed by Jackie Sung</a>
|
||||||
@ -239,7 +239,7 @@
|
|||||||
secondToDate(s) {
|
secondToDate(s) {
|
||||||
var d = Math.floor(s / 3600 / 24);
|
var d = Math.floor(s / 3600 / 24);
|
||||||
if (d > 0) {
|
if (d > 0) {
|
||||||
return d + "{{tr "Day"}}"
|
return d + " {{tr "Day"}}"
|
||||||
}
|
}
|
||||||
var h = Math.floor(s / 3600 % 24);
|
var h = Math.floor(s / 3600 % 24);
|
||||||
var m = Math.floor(s / 60 % 60);
|
var m = Math.floor(s / 60 % 60);
|
||||||
|
@ -118,7 +118,7 @@
|
|||||||
<footer>
|
<footer>
|
||||||
<div class="footer-container">
|
<div class="footer-container">
|
||||||
<div>
|
<div>
|
||||||
<a href="https://github.com/naiba/nezha" target="_blank">Powered by {{tr "nezhaMonitor"}} · {{.Version}}</a>
|
<a href="https://github.com/naiba/nezha" target="_blank">Powered by {{tr "NezhaMonitoring"}} · {{.Version}}</a>
|
||||||
<p>
|
<p>
|
||||||
©
|
©
|
||||||
<span id="copyright-date"
|
<span id="copyright-date"
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
<footer>
|
<footer>
|
||||||
<div class="footer-container">
|
<div class="footer-container">
|
||||||
<div>
|
<div>
|
||||||
<a href="https://github.com/naiba/nezha" target="_blank">Powered by {{tr "nezhaMonitor"}} · {{.Version}}</a>
|
<a href="https://github.com/naiba/nezha" target="_blank">Powered by {{tr "NezhaMonitoring"}} · {{.Version}}</a>
|
||||||
<p>
|
<p>
|
||||||
©<span id="copyright-date"
|
©<span id="copyright-date"
|
||||||
><script>
|
><script>
|
||||||
|
26
resource/template/theme-default/home.html
vendored
26
resource/template/theme-default/home.html
vendored
@ -20,23 +20,23 @@
|
|||||||
@#server.Name + (server.live?'':'[{{tr "Offline"}}]')#@
|
@#server.Name + (server.live?'':'[{{tr "Offline"}}]')#@
|
||||||
<i class="nezha-secondary-font info circle icon" style="height: 28px"></i>
|
<i class="nezha-secondary-font info circle icon" style="height: 28px"></i>
|
||||||
<div class="ui content popup" style="margin-bottom: 0">
|
<div class="ui content popup" style="margin-bottom: 0">
|
||||||
{{tr "Platform"}}:@#server.Host.Platform#@-@#server.Host.PlatformVersion#@
|
{{tr "Platform"}}: @#server.Host.Platform#@-@#server.Host.PlatformVersion#@
|
||||||
[<span
|
[<span
|
||||||
v-if="server.Host.Virtualization">@#server.Host.Virtualization#@:</span>@#server.Host.Arch#@]<br />
|
v-if="server.Host.Virtualization">@#server.Host.Virtualization#@:</span>@#server.Host.Arch#@]<br />
|
||||||
CPU:@#server.Host.CPU#@<br />
|
CPU: @#server.Host.CPU#@<br />
|
||||||
{{tr "DiskUsed"}}:@#formatByteSize(server.State.DiskUsed)#@/@#formatByteSize(server.Host.DiskTotal)#@<br />
|
{{tr "DiskUsed"}}: @#formatByteSize(server.State.DiskUsed)#@/@#formatByteSize(server.Host.DiskTotal)#@<br />
|
||||||
{{tr "MemUsed"}}:@#formatByteSize(server.State.MemUsed)#@/@#formatByteSize(server.Host.MemTotal)#@<br />
|
{{tr "MemUsed"}}: @#formatByteSize(server.State.MemUsed)#@/@#formatByteSize(server.Host.MemTotal)#@<br />
|
||||||
{{tr "SwapUsed"}}:@#formatByteSize(server.State.SwapUsed)#@/@#formatByteSize(server.Host.SwapTotal)#@<br />
|
{{tr "SwapUsed"}}: @#formatByteSize(server.State.SwapUsed)#@/@#formatByteSize(server.Host.SwapTotal)#@<br />
|
||||||
{{tr "NetTransfer"}}:<i
|
{{tr "NetTransfer"}}: <i
|
||||||
class="arrow alternate circle down outline icon"></i>@#formatByteSize(server.State.NetInTransfer)#@<i
|
class="arrow alternate circle down outline icon"></i>@#formatByteSize(server.State.NetInTransfer)#@<i
|
||||||
class="arrow alternate circle up outline icon"></i>@#formatByteSize(server.State.NetOutTransfer)#@<br />
|
class="arrow alternate circle up outline icon"></i>@#formatByteSize(server.State.NetOutTransfer)#@<br />
|
||||||
{{tr "Load"}}:@# toFixed2(server.State.Load1) #@/@# toFixed2(server.State.Load5) #@/@#
|
{{tr "Load"}}: @# toFixed2(server.State.Load1) #@/@# toFixed2(server.State.Load5) #@/@#
|
||||||
toFixed2(server.State.Load15) #@<br />
|
toFixed2(server.State.Load15) #@<br />
|
||||||
{{tr "ProcessCount"}}:@# server.State.ProcessCount #@<br />
|
{{tr "ProcessCount"}}: @# server.State.ProcessCount #@<br />
|
||||||
{{tr "ConnCount"}}:TCP @# server.State.TcpConnCount #@ / UDP @# server.State.UdpConnCount #@<br />
|
{{tr "ConnCount"}}: TCP @# server.State.TcpConnCount #@ / UDP @# server.State.UdpConnCount #@<br />
|
||||||
{{tr "BootTime"}}:@# formatTimestamp(server.Host.BootTime) #@<br />
|
{{tr "BootTime"}}: @# formatTimestamp(server.Host.BootTime) #@<br />
|
||||||
{{tr "LastActive"}}:@# new Date(server.LastActive).toLocaleString() #@<br />
|
{{tr "LastActive"}}: @# new Date(server.LastActive).toLocaleString() #@<br />
|
||||||
{{tr "Version"}}:@#server.Host.Version#@<br />
|
{{tr "Version"}}: @#server.Host.Version#@<br />
|
||||||
</div>
|
</div>
|
||||||
<div class="ui divider" style="margin-bottom: 5px"></div>
|
<div class="ui divider" style="margin-bottom: 5px"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -163,7 +163,7 @@
|
|||||||
secondToDate(s) {
|
secondToDate(s) {
|
||||||
var d = Math.floor(s / 3600 / 24);
|
var d = Math.floor(s / 3600 / 24);
|
||||||
if (d > 0) {
|
if (d > 0) {
|
||||||
return d + "{{tr "Day"}}"
|
return d + " {{tr "Day"}}"
|
||||||
}
|
}
|
||||||
var h = Math.floor(s / 3600 % 24);
|
var h = Math.floor(s / 3600 % 24);
|
||||||
var m = Math.floor(s / 60 % 60);
|
var m = Math.floor(s / 60 % 60);
|
||||||
|
4
resource/template/theme-hotaru/home.html
vendored
4
resource/template/theme-hotaru/home.html
vendored
@ -135,7 +135,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<p style="text-align:center;padding: 15px;">Powered by <a href="https://github.com/naiba/nezha">{{tr "nezhaMonitor"}}</a> build ·
|
<p style="text-align:center;padding: 15px;">Powered by <a href="https://github.com/naiba/nezha">{{tr "NezhaMonitoring"}}</a> build ·
|
||||||
{{.Version}}
|
{{.Version}}
|
||||||
<a href="/service">{{tr "Services"}}</a>
|
<a href="/service">{{tr "Services"}}</a>
|
||||||
<a href="/server">{{tr "AdminPanel"}}</a>
|
<a href="/server">{{tr "AdminPanel"}}</a>
|
||||||
@ -219,7 +219,7 @@
|
|||||||
secondToDate(s) {
|
secondToDate(s) {
|
||||||
var d = Math.floor(s / 3600 / 24);
|
var d = Math.floor(s / 3600 / 24);
|
||||||
if (d > 0) {
|
if (d > 0) {
|
||||||
return d + "{{tr "Day"}}"
|
return d + " {{tr "Day"}}"
|
||||||
}
|
}
|
||||||
var h = Math.floor(s / 3600 % 24);
|
var h = Math.floor(s / 3600 % 24);
|
||||||
var m = Math.floor(s / 60 % 60);
|
var m = Math.floor(s / 60 % 60);
|
||||||
|
2
resource/template/theme-mdui/footer.html
vendored
2
resource/template/theme-mdui/footer.html
vendored
@ -5,7 +5,7 @@
|
|||||||
<center>
|
<center>
|
||||||
<p>
|
<p>
|
||||||
<a href="/"><at>{{.Title}}</at></a>
|
<a href="/"><at>{{.Title}}</at></a>
|
||||||
Powered by <a href="https://github.com/naiba/nezha"><st>{{tr "nezhaMonitor"}}<{{.Version}}></st></a> | Theme designed by Mikoy Chinese
|
Powered by <a href="https://github.com/naiba/nezha"><st>{{tr "NezhaMonitoring"}}<{{.Version}}></st></a> | Theme designed by Mikoy Chinese
|
||||||
</p>
|
</p>
|
||||||
</center>
|
</center>
|
||||||
</div>
|
</div>
|
||||||
|
2
resource/template/theme-mdui/home.html
vendored
2
resource/template/theme-mdui/home.html
vendored
@ -178,7 +178,7 @@
|
|||||||
secondToDate(s) {
|
secondToDate(s) {
|
||||||
var d = Math.floor(s / 3600 / 24);
|
var d = Math.floor(s / 3600 / 24);
|
||||||
if (d > 0) {
|
if (d > 0) {
|
||||||
return d + "{{tr "Day"}}"
|
return d + " {{tr "Day"}}"
|
||||||
}
|
}
|
||||||
var h = Math.floor(s / 3600 % 24);
|
var h = Math.floor(s / 3600 % 24);
|
||||||
var m = Math.floor(s / 60 % 60);
|
var m = Math.floor(s / 60 % 60);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
debug: false
|
debug: false
|
||||||
httpport: 80
|
httpport: 80
|
||||||
|
language: nz_language
|
||||||
grpcport: nz_grpc_port
|
grpcport: nz_grpc_port
|
||||||
oauth2:
|
oauth2:
|
||||||
type: "nz_oauth2_type" #Oauth2 登录接入类型,gitee/github
|
type: "nz_oauth2_type" #Oauth2 登录接入类型,gitee/github
|
||||||
|
@ -11,7 +11,7 @@ NZ_BASE_PATH="/opt/nezha"
|
|||||||
NZ_DASHBOARD_PATH="${NZ_BASE_PATH}/dashboard"
|
NZ_DASHBOARD_PATH="${NZ_BASE_PATH}/dashboard"
|
||||||
NZ_AGENT_PATH="${NZ_BASE_PATH}/agent"
|
NZ_AGENT_PATH="${NZ_BASE_PATH}/agent"
|
||||||
NZ_AGENT_SERVICE="/etc/systemd/system/nezha-agent.service"
|
NZ_AGENT_SERVICE="/etc/systemd/system/nezha-agent.service"
|
||||||
NZ_VERSION="v0.9.0"
|
NZ_VERSION="v0.9.1"
|
||||||
|
|
||||||
red='\033[0;31m'
|
red='\033[0;31m'
|
||||||
green='\033[0;32m'
|
green='\033[0;32m'
|
||||||
|
@ -11,7 +11,7 @@ NZ_BASE_PATH="/opt/nezha"
|
|||||||
NZ_DASHBOARD_PATH="${NZ_BASE_PATH}/dashboard"
|
NZ_DASHBOARD_PATH="${NZ_BASE_PATH}/dashboard"
|
||||||
NZ_AGENT_PATH="${NZ_BASE_PATH}/agent"
|
NZ_AGENT_PATH="${NZ_BASE_PATH}/agent"
|
||||||
NZ_AGENT_SERVICE="/etc/systemd/system/nezha-agent.service"
|
NZ_AGENT_SERVICE="/etc/systemd/system/nezha-agent.service"
|
||||||
NZ_VERSION="v0.9.0"
|
NZ_VERSION="v0.9.1"
|
||||||
|
|
||||||
red='\033[0;31m'
|
red='\033[0;31m'
|
||||||
green='\033[0;32m'
|
green='\033[0;32m'
|
||||||
@ -290,10 +290,12 @@ modify_dashboard_config() {
|
|||||||
sed -i "s/nz_github_oauth_client_id/${nz_github_oauth_client_id}/" ${NZ_DASHBOARD_PATH}/data/config.yaml
|
sed -i "s/nz_github_oauth_client_id/${nz_github_oauth_client_id}/" ${NZ_DASHBOARD_PATH}/data/config.yaml
|
||||||
sed -i "s/nz_github_oauth_client_secret/${nz_github_oauth_client_secret}/" ${NZ_DASHBOARD_PATH}/data/config.yaml
|
sed -i "s/nz_github_oauth_client_secret/${nz_github_oauth_client_secret}/" ${NZ_DASHBOARD_PATH}/data/config.yaml
|
||||||
sed -i "s/nz_site_title/${nz_site_title}/" ${NZ_DASHBOARD_PATH}/data/config.yaml
|
sed -i "s/nz_site_title/${nz_site_title}/" ${NZ_DASHBOARD_PATH}/data/config.yaml
|
||||||
|
sed -i "s/nz_language/en-US/" ${NZ_DASHBOARD_PATH}/data/config.yaml
|
||||||
sed -i "s/nz_site_port/${nz_site_port}/" ${NZ_DASHBOARD_PATH}/docker-compose.yaml
|
sed -i "s/nz_site_port/${nz_site_port}/" ${NZ_DASHBOARD_PATH}/docker-compose.yaml
|
||||||
sed -i "s/nz_grpc_port/${nz_grpc_port}/g" ${NZ_DASHBOARD_PATH}/docker-compose.yaml
|
sed -i "s/nz_grpc_port/${nz_grpc_port}/g" ${NZ_DASHBOARD_PATH}/docker-compose.yaml
|
||||||
sed -i "s/nz_image_url/${Docker_IMG}/" ${NZ_DASHBOARD_PATH}/docker-compose.yaml
|
sed -i "s/nz_image_url/${Docker_IMG}/" ${NZ_DASHBOARD_PATH}/docker-compose.yaml
|
||||||
|
|
||||||
|
|
||||||
echo -e "Dashboard configuration ${green} modified successfully, please wait for Dashboard self-restart to take effect${plain}"
|
echo -e "Dashboard configuration ${green} modified successfully, please wait for Dashboard self-restart to take effect${plain}"
|
||||||
|
|
||||||
restart_and_update
|
restart_and_update
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package singleton
|
package singleton
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
|
"github.com/naiba/nezha/pkg/utils"
|
||||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
)
|
)
|
||||||
@ -11,12 +14,20 @@ var Localizer *i18n.Localizer
|
|||||||
func InitLocalizer() {
|
func InitLocalizer() {
|
||||||
bundle := i18n.NewBundle(language.Chinese)
|
bundle := i18n.NewBundle(language.Chinese)
|
||||||
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
|
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
|
||||||
_, err := bundle.LoadMessageFile("resource/l10n/" + Conf.Language + ".toml")
|
|
||||||
if err != nil {
|
userCustomLanguageFile := "resource/l10n/" + Conf.Language + ".toml"
|
||||||
panic(err)
|
|
||||||
|
if exists, err := utils.PathExists(userCustomLanguageFile); !exists {
|
||||||
|
log.Println("NEZHA>> language file not found:", userCustomLanguageFile, err)
|
||||||
|
Conf.Language = "zh-CN"
|
||||||
|
} else {
|
||||||
|
_, err := bundle.LoadMessageFile(userCustomLanguageFile)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_, err = bundle.LoadMessageFile("resource/l10n/zh-CN.toml")
|
|
||||||
if err != nil {
|
if _, err := bundle.LoadMessageFile("resource/l10n/zh-CN.toml"); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
Localizer = i18n.NewLocalizer(bundle, Conf.Language)
|
Localizer = i18n.NewLocalizer(bundle, Conf.Language)
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/naiba/nezha/pkg/utils"
|
"github.com/naiba/nezha/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Version = "v0.12.30" // !!记得修改 README 中的 badge 版本!!
|
var Version = "v0.13.1" // !!记得修改 README 中的 badge 版本!!
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Conf *model.Config
|
Conf *model.Config
|
||||||
|
Loading…
Reference in New Issue
Block a user