From ca997cc994e9177193abd43efd887c33b870f176 Mon Sep 17 00:00:00 2001 From: uubulb Date: Fri, 1 Nov 2024 14:07:05 +0800 Subject: [PATCH] add zh_TW locale, rename ssl to tls --- .gitignore | 1 + cmd/dashboard/controller/member_api.go | 4 +- cmd/dashboard/controller/notification.go | 8 +- model/notification.go | 4 +- model/notification_api.go | 2 +- pkg/i18n/template.pot | 8 +- .../translations/en_US/LC_MESSAGES/nezha.mo | Bin 4074 -> 4110 bytes .../translations/en_US/LC_MESSAGES/nezha.po | 17 +- .../translations/zh_CN/LC_MESSAGES/nezha.mo | Bin 3944 -> 4002 bytes .../translations/zh_CN/LC_MESSAGES/nezha.po | 28 +-- .../translations/zh_TW/LC_MESSAGES/nezha.mo | Bin 0 -> 4011 bytes .../translations/zh_TW/LC_MESSAGES/nezha.po | 222 ++++++++++++++++++ pkg/utils/http.go | 8 +- pkg/utils/utils.go | 4 - script/i18n.sh | 175 ++++++++++++++ service/singleton/notification.go | 4 +- service/singleton/servicesentinel.go | 32 +-- 17 files changed, 455 insertions(+), 62 deletions(-) create mode 100644 pkg/i18n/translations/zh_TW/LC_MESSAGES/nezha.mo create mode 100644 pkg/i18n/translations/zh_TW/LC_MESSAGES/nezha.po create mode 100755 script/i18n.sh diff --git a/.gitignore b/.gitignore index 89b21d4..782cf4b 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ *.test # Output of the go coverage tool, specifically when used with LiteIDE +*~ *.out *.pprof .idea diff --git a/cmd/dashboard/controller/member_api.go b/cmd/dashboard/controller/member_api.go index 158fa7e..13a7aba 100644 --- a/cmd/dashboard/controller/member_api.go +++ b/cmd/dashboard/controller/member_api.go @@ -299,8 +299,8 @@ func (ma *memberAPI) addOrEditNotification(c *gin.Context) { n.RequestHeader = nf.RequestHeader n.RequestBody = nf.RequestBody n.URL = nf.URL - verifySSL := nf.VerifySSL == "on" - n.VerifySSL = &verifySSL + //verifySSL := nf.VerifySSL == "on" + //n.VerifySSL = &verifySSL n.ID = nf.ID ns := model.NotificationServerBundle{ Notification: &n, diff --git a/cmd/dashboard/controller/notification.go b/cmd/dashboard/controller/notification.go index 3360021..5ba950c 100644 --- a/cmd/dashboard/controller/notification.go +++ b/cmd/dashboard/controller/notification.go @@ -54,8 +54,8 @@ func createNotification(c *gin.Context) (uint64, error) { n.RequestHeader = nf.RequestHeader n.RequestBody = nf.RequestBody n.URL = nf.URL - verifySSL := nf.VerifySSL - n.VerifySSL = &verifySSL + verifyTLS := nf.VerifyTLS + n.VerifyTLS = &verifyTLS ns := model.NotificationServerBundle{ Notification: &n, @@ -112,8 +112,8 @@ func updateNotification(c *gin.Context) (any, error) { n.RequestHeader = nf.RequestHeader n.RequestBody = nf.RequestBody n.URL = nf.URL - verifySSL := nf.VerifySSL - n.VerifySSL = &verifySSL + verifyTLS := nf.VerifyTLS + n.VerifyTLS = &verifyTLS ns := model.NotificationServerBundle{ Notification: &n, diff --git a/model/notification.go b/model/notification.go index 992c85f..02c683b 100644 --- a/model/notification.go +++ b/model/notification.go @@ -38,7 +38,7 @@ type Notification struct { RequestType int `json:"request_type,omitempty"` RequestHeader string `json:"request_header,omitempty" gorm:"type:longtext"` RequestBody string `json:"request_body,omitempty" gorm:"type:longtext"` - VerifySSL *bool `json:"verify_ssl,omitempty"` + VerifyTLS *bool `json:"verify_tls,omitempty"` } func (ns *NotificationServerBundle) reqURL(message string) string { @@ -111,7 +111,7 @@ func (n *Notification) setRequestHeader(req *http.Request) error { func (ns *NotificationServerBundle) Send(message string) error { var client *http.Client n := ns.Notification - if n.VerifySSL != nil && *n.VerifySSL { + if n.VerifyTLS != nil && *n.VerifyTLS { client = utils.HttpClient } else { client = utils.HttpClientSkipTlsVerify diff --git a/model/notification_api.go b/model/notification_api.go index d5fde9e..8f36189 100644 --- a/model/notification_api.go +++ b/model/notification_api.go @@ -7,6 +7,6 @@ type NotificationForm struct { RequestType int `json:"request_type,omitempty"` RequestHeader string `json:"request_header,omitempty"` RequestBody string `json:"request_body,omitempty"` - VerifySSL bool `json:"verify_ssl,omitempty"` + VerifyTLS bool `json:"verify_tls,omitempty"` SkipCheck bool `json:"skip_check,omitempty"` } diff --git a/pkg/i18n/template.pot b/pkg/i18n/template.pot index f3d6764..46b419a 100644 --- a/pkg/i18n/template.pot +++ b/pkg/i18n/template.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-11-01 05:06+0800\n" +"POT-Creation-Date: 2024-11-01 13:32+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -188,18 +188,18 @@ msgstr "" #: service/singleton/servicesentinel.go:515 #, c-format -msgid "[SSL] Fetch cert info failed, %s %s" +msgid "[TLS] Fetch cert info failed, Reporter: %s, Error: %s" msgstr "" #: service/singleton/servicesentinel.go:555 #, c-format -msgid "The SSL certificate will expire within seven days. Expiration time: %s" +msgid "The TLS certificate will expire within seven days. Expiration time: %s" msgstr "" #: service/singleton/servicesentinel.go:568 #, c-format msgid "" -"SSL certificate changed, old: issuer %s, expires at %s; new: issuer %s, " +"TLS certificate changed, old: issuer %s, expires at %s; new: issuer %s, " "expires at %s" msgstr "" diff --git a/pkg/i18n/translations/en_US/LC_MESSAGES/nezha.mo b/pkg/i18n/translations/en_US/LC_MESSAGES/nezha.mo index 109907810e07778455979d642a46540680e298d5..6a3e9703800918d0cbfc2b80afbf9167edfcda07 100644 GIT binary patch delta 845 zcma*k&r8#B9LMqZ{BG(tXBt{*nagQS{DCG55+aCD79E7CV2a>Tg>f2`4 z88mCeJ{-U|%h{G(iee>X_5{CT8Y_#<%5fNLaRRk)4(sp(Uc+5f-#%)CQ>?;RiNCG^ zZ}I#H)&ByMn8iDoFR`56rPwYs{=hb#t<>x$v||N6LoFCa{oyp$U>>`06Pxh}8}Mq_ z-zbG;JdfgaoWwJnMMAKtNX{>2B4&JSo-h8xmQfq$k(q3*@cRbpq}!-O_E1q;)E{^d zdw6_>^|*!V`(E%5D)9tUDe<8kMVew273Co+@?WTh6)`{Z6e_|Ds&4`{$Xit8E2wqr zsDyS={Rf!Db5w#&ELP&ZsJ`)+6m1lXsK~caC;x_8aENLwz2ZmSgo^wzHsfnlcetJK I&;MO@0fh@<-v9sr delta 839 zcma*lJ4jn$7{>88IVZKT_7bRfZETNMqE(TAbu3j(5jq4xq0l;sb&#NgPG@XfigG9@ zxG18alL&&~q9BFR4sj3%M<)r+1qb_oJQ+InBj^0yFZr$y`POuuT>4l!YG%Ez*$e!N z&A7FkOZgtfO3dsn9$^OW@CjxfnAPDJYQiiw;tE#b0czZD)WVne9B)zco|Tz3U{#ha1>|=lBXO9&Y4e1>F&> z#&P_EIV1%8QtpSvOt~2!o8!eA=A$;wBWJPI()a7AD0fgdwnt$yNz{Sg;ShetByN{} z|537tN<6`-lz7^w$WY9qqC7!GS3pHxL`9x>97foU8aISGz$hy6In=yGR6?7m$d9od zFHi|an5@J-)VQhl6kQaPs2hAo-Fy!<;RH4C3KeyWhYJ7|<@D0kk&nOoxU^b>F zC-xQLD)M@i^@p(({kRsx$ttKy2xjetUvVS3N>Qo+DsdS$ploPCIq)*(VHj(08q3ha zBFsunTvUf?sE>}6+)R9w(~o-_|@+n>0bd;?X=C2vRRWW zYmVX^+Ndgc|9mR-D~DhAId>-QYtpsOCjHiFI+}?WoKND8xbm|Pbe!!9oa+eqOmBCE zxhoLp3izg8xRRW%sv2MQCOwxrW0?A)yG*Bes^hyR+{d)flOK-{dG_Qk&W63+i?jXT zhHqPu$o$-BtS7>l{^H5Y-e!8MPcRn?jYo$>29L2r5>Z;UjMBpICO!_ zr$#g+t?6xq|9|%CPe#_A8PStwMh}`7^@`bTWQe!Tw+&04usfEke)hOc&%jV}U`Vfe z-|JalyfORBcTd-RC-r52xDk*0Q^BMa%h}e}i-pZfW&Pt~eX5eQ^s+zVwk`eBZ+F^O sz4&Tlu2?V4ZWI?KTiuou`vYN*O=Rhbz(eE5^iuU}VANGT*Y?2m4-C_J %2f, Reporter: %s" -msgstr "[延迟告警] %s %2f > %2f, 报告服务: %s" +msgstr "[延迟告警] %s %2f > %2f,报告服务: %s" #: service/singleton/servicesentinel.go:446 #, c-format msgid "[Latency] %s %2f < %2f, Reporter: %s" -msgstr "[延迟告警] %s %2f < %2f, 报告服务: %s" +msgstr "[延迟告警] %s %2f < %2f,报告服务: %s" #: service/singleton/servicesentinel.go:472 #, c-format msgid "[%s] %s Reporter: %s, Error: %s" -msgstr "[%s] %s 报告服务: %s, 错误信息: %s" +msgstr "[%s] %s 报告服务:%s,错误信息:%s" #: service/singleton/servicesentinel.go:515 #, c-format -msgid "[SSL] Fetch cert info failed, %s %s" -msgstr "[SSL] 获取证书信息失败, %s %s" +msgid "[TLS] Fetch cert info failed, Reporter: %s, Error: %s" +msgstr "[TLS] 获取证书信息失败,报告服务:%s,错误信息:%s" #: service/singleton/servicesentinel.go:555 #, c-format -msgid "The SSL certificate will expire within seven days. Expiration time: %s" -msgstr "SSL 证书将在 7 天内过期。过期时间为:%s" +msgid "The TLS certificate will expire within seven days. Expiration time: %s" +msgstr "TLS 证书将在 7 天内过期。过期时间为:%s" #: service/singleton/servicesentinel.go:568 #, c-format msgid "" -"SSL certificate changed, old: issuer %s, expires at %s; new: issuer %s, " +"TLS certificate changed, old: issuer %s, expires at %s; new: issuer %s, " "expires at %s" msgstr "" -"SSL 证书发生更改,旧值:颁发者 %s,过期日 %s;新值:颁发者 %s,过期日 %s" +"TLS 证书发生更改,旧值:颁发者 %s,过期日 %s;新值:颁发者 %s,过期日 %s" #: service/singleton/servicesentinel.go:604 msgid "No Data" diff --git a/pkg/i18n/translations/zh_TW/LC_MESSAGES/nezha.mo b/pkg/i18n/translations/zh_TW/LC_MESSAGES/nezha.mo new file mode 100644 index 0000000000000000000000000000000000000000..3789727725d434ef73be55296c87c14e7451d650 GIT binary patch literal 4011 zcmai#du$v>9ml7o4=|L{@GQ@v)NR`Mj4y85;1Z;^i7Queu@V;$QK;6tb9dXGcdz?6 z#}!D1^OR>p9b&4 z-$1hC@8Flf2Vf+vdjuqZcYq}Sb8s{G2KZfY z1bhr!21)KiFb0xyWPdeCe!m2g{63K6eg!@Zj)1k`HSh^A03QK2eMaip27V6xUw~f) zUkCpK9tL45`z3-*JPcxp^+f%Fs6QI_ za{h;iAA$AgKMA8q?hTOo)8HoXHb`;0`vDohhe6W!6!>MZ5quC-L5i~tQrx@2FM?Ab ztzU}ze~#vTkm7bPk`?9!B)J_R#kCnE`?Da~aWWb|1CrctBmM<^2K|45q<0I9A^Tne zX&)7&ICg@Rzkcv8a5Ea^g=z;S9o7uM9!G-+`yO@hk!|!nhDPa8;U7#m%%<$93Cwg~coFDlQIWbW7M=anOC18=~#wry1E}^F(L|cT8@Hq;5OH zs^j}ub4u`yTHEw=I?}+~bSI@7+!k43a7}5qtKk`RD~@g&+|gS_9V}q`D((Fs-y<@n z6>d#d?y@WsT4;VZ+%eSlP^fZig8z`?x2i<`PN5%_6N0t-dA)GdR2V9*8woRVu5`Z= z{b5dI2*`#ycw}Y6U?QyCOeE5}A-G~_TvZIibl`uOKkgtv4g$#bbHvJ)9UE~$jMmF# zEHfjlbbB?g*ALLDR#+CUROF!aw=+BD8w_0W$Q*V3}0oIB`wp_eR@Eot4x)mD@=%=KbrMO-+&UTEW9uA#V2%Cz)1u`vl7N-M5A z#dthSlxWT1ifyvY*AS0bgBJUVKRRl1H)+S3O$;~vIJQS*brOo< zUdFAowPx#6v3NXI6X)^Ty7&*a)NHS*so0G(6Kl2T}~J=k}jN&H4CM6UB8aM znR>PPrxlG2jk}8a^}KDfQy8+7-09m}_uM+&Fk##GSJiGz>v z!od^%*tq}Bxv)Fx56%ByF&0cOc}IJsDfy8j(mrgB_XjVYRPW7qd1KT38Sb5(@j9oZ znh!e;Mf!#h6^4GDKeUKdmBshQJAK)EtH&SfgTLVn8Q41)oIi`W1k*i{w6}DBtWo~(qd>fud zmlsAS@;62>imdxr2W5I$p<_6=I2x^;?~-$}a->96aN&5NeaKnv z)+MCbJ95RFJ%u2%+(L&x@vgscF_@W@<}(>C-msJIwA?};B$1$vZ&J{8)ti3{iP`WH z`KRXmvGci=qo|IOM+l?A^sIMjgvrwN7B9$*6(6DEp0zBPI^(~0lKl6F56Kdh;uOg& z%m3y`bQcyaEOd}JJa7RL%>9l_*5sShUQS7u}&g2{gGSQmm@ zx>HFYyt$+KiRHrJ4R3MMyVY4Z-R+&7@`sl3vJ^V|@;5KtVc7c933G$PH-m`_GR(mg zoxf5WOSBO;5CaR#-*J1 h+%OxLl4B>j{fj-g^CA)NWM6*zvWy, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-11-01 13:14+0800\n" +"PO-Revision-Date: 2024-11-01 13:19+0800\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_TW\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.5\n" + +#: cmd/dashboard/controller/alertrule.go:100 +#, c-format +msgid "alert id %d does not exist" +msgstr "告警 ID %d 不存在" + +#: cmd/dashboard/controller/alertrule.go:155 +msgid "duration need to be at least 3" +msgstr "duration 至少為 3" + +#: cmd/dashboard/controller/alertrule.go:159 +msgid "cycle_interval need to be at least 1" +msgstr "cycle_interval 至少為 1" + +#: cmd/dashboard/controller/alertrule.go:162 +msgid "cycle_start is not set" +msgstr "cycle_start 未設定" + +#: cmd/dashboard/controller/alertrule.go:165 +msgid "cycle_start is a future value" +msgstr "cycle_start 是未來值" + +#: cmd/dashboard/controller/alertrule.go:170 +msgid "need to configure at least a single rule" +msgstr "需要至少定義一條規則" + +#: cmd/dashboard/controller/controller.go:188 +msgid "database error" +msgstr "資料庫錯誤" + +#: cmd/dashboard/controller/cron.go:63 cmd/dashboard/controller/cron.go:122 +msgid "scheduled tasks cannot be triggered by alarms" +msgstr "排程任務不能被告警觸發" + +#: cmd/dashboard/controller/cron.go:161 +#, c-format +msgid "task id %d does not exist" +msgstr "任務 id %d 不存在" + +#: cmd/dashboard/controller/ddns.go:56 cmd/dashboard/controller/ddns.go:120 +msgid "the retry count must be an integer between 1 and 10" +msgstr "重試次數必須為大於 1 且不超過 10 的整數" + +#: cmd/dashboard/controller/ddns.go:79 cmd/dashboard/controller/ddns.go:148 +msgid "error parsing %s: %v" +msgstr "解析 %s 時發生錯誤:%v" + +#: cmd/dashboard/controller/ddns.go:125 cmd/dashboard/controller/nat.go:95 +#, c-format +msgid "profile id %d does not exist" +msgstr "配置 id %d 不存在" + +#: cmd/dashboard/controller/fm.go:45 cmd/dashboard/controller/terminal.go:43 +msgid "server not found or not connected" +msgstr "伺服器未找到或仍未連線" + +#: cmd/dashboard/controller/notification.go:67 +#: cmd/dashboard/controller/notification.go:125 +msgid "a test message" +msgstr "一條測試資訊" + +#: cmd/dashboard/controller/notification.go:106 +#, c-format +msgid "notification id %d does not exist" +msgstr "通知方式 id %d 不存在" + +#: cmd/dashboard/controller/notification_group.go:80 +#: cmd/dashboard/controller/notification_group.go:142 +msgid "have invalid notification id" +msgstr "通知方式 id 無效" + +#: cmd/dashboard/controller/notification_group.go:131 +#: cmd/dashboard/controller/server_group.go:130 +#, c-format +msgid "group id %d does not exist" +msgstr "組 id %d 不存在" + +#: cmd/dashboard/controller/server.go:59 +#, c-format +msgid "server id %d does not exist" +msgstr "伺服器 id %d 不存在" + +#: cmd/dashboard/controller/server_group.go:78 +#: cmd/dashboard/controller/server_group.go:139 +msgid "have invalid server id" +msgstr "伺服器 id 無效" + +#: cmd/dashboard/controller/service.go:79 +#: cmd/dashboard/controller/service.go:155 +msgid "server not found" +msgstr "未找到伺服器" + +#: cmd/dashboard/controller/service.go:86 +msgid "unauthorized" +msgstr "未授權" + +#: cmd/dashboard/controller/service.go:247 +#, c-format +msgid "service id %d does not exist" +msgstr "服務 id %d 不存在" + +#: cmd/dashboard/controller/user.go:45 +msgid "password length must be greater than 6" +msgstr "密碼長度必須大於 6" + +#: cmd/dashboard/controller/user.go:48 +msgid "username can't be empty" +msgstr "使用者名稱不能為空" + +#: service/rpc/io_stream.go:122 +msgid "timeout: no connection established" +msgstr "超時:無連線建立" + +#: service/rpc/io_stream.go:125 +msgid "timeout: user connection not established" +msgstr "超時:使用者連線未建立" + +#: service/rpc/io_stream.go:128 +msgid "timeout: agent connection not established" +msgstr "超時:agent 連線未建立" + +#: service/rpc/nezha.go:57 +msgid "Scheduled Task Executed Successfully" +msgstr "排程任務執行成功" + +#: service/rpc/nezha.go:61 +msgid "Scheduled Task Executed Failed" +msgstr "排程任務執行失敗" + +#: service/rpc/nezha.go:156 +msgid "IP Changed" +msgstr "IP 變更" + +#: service/singleton/alertsentinel.go:159 +msgid "Incident" +msgstr "事件" + +#: service/singleton/alertsentinel.go:169 +msgid "Resolved" +msgstr "恢復" + +#: service/singleton/crontask.go:52 +msgid "Tasks failed to register: [" +msgstr "註冊失敗的任務:[" + +#: service/singleton/crontask.go:59 +msgid "" +"] These tasks will not execute properly. Fix them in the admin dashboard." +msgstr "這些任務將無法正常執行,請進入後台重新修改儲存。" + +#: service/singleton/crontask.go:150 service/singleton/crontask.go:175 +#, c-format +msgid "[Task failed] %s: server %s is offline and cannot execute the task" +msgstr "[任務失敗] %s,伺服器 %s 離線,無法執行" + +#: service/singleton/servicesentinel.go:439 +#, c-format +msgid "[Latency] %s %2f > %2f, Reporter: %s" +msgstr "[延遲告警] %s %2f > %2f,報告服務: %s" + +#: service/singleton/servicesentinel.go:446 +#, c-format +msgid "[Latency] %s %2f < %2f, Reporter: %s" +msgstr "[延遲告警] %s %2f < %2f,報告服務: %s" + +#: service/singleton/servicesentinel.go:472 +#, c-format +msgid "[%s] %s Reporter: %s, Error: %s" +msgstr "[%s] %s 報告服務:%s,錯誤資訊:%s" + +#: service/singleton/servicesentinel.go:515 +#, c-format +msgid "[TLS] Fetch cert info failed, Reporter: %s, Error: %s" +msgstr "[TLS] 獲取證書資訊失敗,報告服務:%s,錯誤資訊:%s" + +#: service/singleton/servicesentinel.go:555 +#, c-format +msgid "The TLS certificate will expire within seven days. Expiration time: %s" +msgstr "TLS 證書將在 7 天內過期。過期時間為:%s" + +#: service/singleton/servicesentinel.go:568 +#, c-format +msgid "" +"TLS certificate changed, old: issuer %s, expires at %s; new: issuer %s, " +"expires at %s" +msgstr "" +"TLS 證書發生更改,舊值:頒發者 %s,過期日 %s;新值:頒發者 %s,過期日 %s" + +#: service/singleton/servicesentinel.go:604 +msgid "No Data" +msgstr "無資料" + +#: service/singleton/servicesentinel.go:606 +msgid "Good" +msgstr "正常" + +#: service/singleton/servicesentinel.go:608 +msgid "Low Availability" +msgstr "低可用" + +#: service/singleton/servicesentinel.go:610 +msgid "Down" +msgstr "故障" diff --git a/pkg/utils/http.go b/pkg/utils/http.go index a792bf9..19227c4 100644 --- a/pkg/utils/http.go +++ b/pkg/utils/http.go @@ -14,12 +14,12 @@ var ( func init() { HttpClientSkipTlsVerify = httpClient(_httpClient{ Transport: httpTransport(_httpTransport{ - SkipVerifySSL: true, + SkipVerifyTLS: true, }), }) HttpClient = httpClient(_httpClient{ Transport: httpTransport(_httpTransport{ - SkipVerifySSL: false, + SkipVerifyTLS: false, }), }) @@ -27,12 +27,12 @@ func init() { } type _httpTransport struct { - SkipVerifySSL bool + SkipVerifyTLS bool } func httpTransport(conf _httpTransport) *http.Transport { return &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: conf.SkipVerifySSL}, + TLSClientConfig: &tls.Config{InsecureSkipVerify: conf.SkipVerifyTLS}, Proxy: http.ProxyFromEnvironment, } } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index b2d2ffa..08f2766 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -19,10 +19,6 @@ var ( DNSServers = []string{"1.1.1.1:53", "223.5.5.5:53"} ) -func IsWindows() bool { - return os.PathSeparator == '\\' && os.PathListSeparator == ';' -} - var ipv4Re = regexp.MustCompile(`(\d*\.).*(\.\d*)`) func ipv4Desensitize(ipv4Addr string) string { diff --git a/script/i18n.sh b/script/i18n.sh new file mode 100755 index 0000000..e25ea81 --- /dev/null +++ b/script/i18n.sh @@ -0,0 +1,175 @@ +#!/bin/bash + +LANG=() +while IFS='' read -r line; do LANG+=("$line"); done < <(ls pkg/i18n/translations) +TEMPLATE="pkg/i18n/template.pot" +PODIR="pkg/i18n/translations/%s/LC_MESSAGES" +GIT_ROOT=$(git rev-parse --show-toplevel) + +red='\033[0;31m' +green='\033[0;32m' +yellow='\033[0;33m' +plain='\033[0m' + +err() { + printf "${red}%s${plain}\n" "$*" >&2 +} + +success() { + printf "${green}%s${plain}\n" "$*" +} + +info() { + printf "${yellow}%s${plain}\n" "$*" +} + +generate() { + case $1 in + "template") + generate_template + ;; + "en") + generate_en + ;; + *) + err "invalid argument" + ;; + esac +} + +generate_template() { + read -ra src < <(find . -name "*.go" | sort) + xgettext -C --add-comments=TRANSLATORS: -kErrorT -kT -kTf -kN:1,2 --from-code=UTF-8 -o $TEMPLATE "${src[@]}" +} + +generate_en() { + local po_file + po_file=$(printf "$PODIR/nezha.po" "en_US") + local mo_file + mo_file=$(printf "$PODIR/nezha.mo" "en_US") + msginit --input=$TEMPLATE --locale=en_US.UTF-8 --output-file="$po_file" --no-translator + msgfmt "$po_file" -o "$mo_file" +} + +compile() { + if [[ $# != 0 ]]; then + compile_single "$1" + else + compile_all + fi +} + +compile_single() { + local param="$1" + local found=0 + + for lang in "${LANG[@]}"; do + if [[ "$lang" == "$param" ]]; then + found=1 + break + fi + done + + if [[ $found == 0 ]]; then + err "the language does not exist." + return + fi + + local po_file + po_file=$(printf "$PODIR/nezha.po" "$param") + local mo_file + mo_file=$(printf "$PODIR/nezha.mo" "$param") + + msgfmt "$po_file" -o "$mo_file" +} + +compile_all() { + local po_file + local mo_file + for lang in "${LANG[@]}"; do + po_file=$(printf "$PODIR/nezha.po" "$lang") + mo_file=$(printf "$PODIR/nezha.mo" "$lang") + + msgfmt "$po_file" -o "$mo_file" + done +} + +update() { + if [[ $# != 0 ]]; then + update_single "$1" + else + update_all + fi +} + +update_single() { + local param="$1" + local found=0 + + for lang in "${LANG[@]}"; do + if [[ "$lang" == "$param" ]]; then + found=1 + break + fi + done + + if [[ $found == 0 ]]; then + err "the language does not exist." + return + fi + + local po_file + po_file=$(printf "$PODIR/nezha.po" "$param") + msgmerge -U "$po_file" $TEMPLATE +} + +update_all() { + for lang in "${LANG[@]}"; do + local po_file + po_file=$(printf "$PODIR/nezha.po" "$lang") + msgmerge -U "$po_file" $TEMPLATE + done +} + +show_help() { + echo "Usage: $0 [command] args" + echo "" + echo "Available commands:" + echo " update Update .po from .pot" + echo " compile Compile .mo from .po" + echo " generate Generate template or en_US locale" + echo "" + echo "Examples:" + echo " $0 update # Update all locales" + echo " $0 update zh_CN # Update zh_CN locale" + echo " $0 compile # Compile all locales" + echo " $0 compile zh_CN # Compile zh_CN locale" + echo " $0 generate template # Generate template" + echo " $0 generate en # Generate en_US locale" +} + +main() { + if [[ $PWD != "$GIT_ROOT" ]]; then + err "Must execute in the project root" + exit 1 + fi + + case "$1" in + "update") + update "$2" + ;; + "compile") + compile "$2" + ;; + "generate") + generate "$2" + ;; + *) + echo "Error: Unknown command '$1'" + show_help + exit 1 + ;; + esac +} + +main "$@" diff --git a/service/singleton/notification.go b/service/singleton/notification.go index 5d28ceb..d2b26d8 100644 --- a/service/singleton/notification.go +++ b/service/singleton/notification.go @@ -322,7 +322,7 @@ func (_NotificationMuteLabel) ServiceStateChanged(serviceId uint64) *string { return &label } -func (_NotificationMuteLabel) ServiceSSL(serviceId uint64, extraInfo string) *string { - label := fmt.Sprintf("bf::sssl-%d-%s", serviceId, extraInfo) +func (_NotificationMuteLabel) ServiceTLS(serviceId uint64, extraInfo string) *string { + label := fmt.Sprintf("bf::stls-%d-%s", serviceId, extraInfo) return &label } diff --git a/service/singleton/servicesentinel.go b/service/singleton/servicesentinel.go index bb467f2..a7fc0b7 100644 --- a/service/singleton/servicesentinel.go +++ b/service/singleton/servicesentinel.go @@ -43,7 +43,7 @@ func NewServiceSentinel(serviceSentinelDispatchBus chan<- model.Service) { serviceResponseDataStoreCurrentAvgDelay: make(map[uint64]float32), serviceResponsePing: make(map[uint64]map[uint64]*pingStore), Services: make(map[uint64]*model.Service), - sslCertCache: make(map[uint64]string), + tlsCertCache: make(map[uint64]string), // 30天数据缓存 monthlyStatus: make(map[uint64]*model.ServiceResponseItem), dispatchBus: serviceSentinelDispatchBus, @@ -102,7 +102,7 @@ type ServiceSentinel struct { serviceResponseDataStoreCurrentAvgDelay map[uint64]float32 // [service_id] -> 当前服务离线计数 serviceResponsePing map[uint64]map[uint64]*pingStore // [service_id] -> ClientID -> delay lastStatus map[uint64]int - sslCertCache map[uint64]string + tlsCertCache map[uint64]string ServicesLock sync.RWMutex Services map[uint64]*model.Service @@ -279,7 +279,7 @@ func (ss *ServiceSentinel) OnServiceDelete(ids []uint64) { delete(ss.serviceResponseDataStoreCurrentUp, id) delete(ss.serviceResponseDataStoreCurrentDown, id) delete(ss.serviceResponseDataStoreCurrentAvgDelay, id) - delete(ss.sslCertCache, id) + delete(ss.tlsCertCache, id) delete(ss.serviceStatusToday, id) // 停掉定时任务 @@ -501,7 +501,7 @@ func (ss *ServiceSentinel) worker() { } ss.serviceResponseDataStoreLock.Unlock() - // SSL 证书报警 + // TLS 证书报警 var errMsg string if strings.HasPrefix(mh.Data, "SSL证书错误:") { // i/o timeout、connection timeout、EOF 错误 @@ -511,15 +511,15 @@ func (ss *ServiceSentinel) worker() { errMsg = mh.Data ss.ServicesLock.RLock() if ss.Services[mh.GetId()].Notify { - muteLabel := NotificationMuteLabel.ServiceSSL(mh.GetId(), "network") - go SendNotification(ss.Services[mh.GetId()].NotificationGroupID, Localizer.Tf("[SSL] Fetch cert info failed, %s %s", ss.Services[mh.GetId()].Name, errMsg), muteLabel) + muteLabel := NotificationMuteLabel.ServiceTLS(mh.GetId(), "network") + go SendNotification(ss.Services[mh.GetId()].NotificationGroupID, Localizer.Tf("[TLS] Fetch cert info failed, Reporter: %s, Error: %s", ss.Services[mh.GetId()].Name, errMsg), muteLabel) } ss.ServicesLock.RUnlock() } } else { // 清除网络错误静音缓存 - UnMuteNotification(ss.Services[mh.GetId()].NotificationGroupID, NotificationMuteLabel.ServiceSSL(mh.GetId(), "network")) + UnMuteNotification(ss.Services[mh.GetId()].NotificationGroupID, NotificationMuteLabel.ServiceTLS(mh.GetId(), "network")) var newCert = strings.Split(mh.Data, "|") if len(newCert) > 1 { @@ -527,11 +527,11 @@ func (ss *ServiceSentinel) worker() { enableNotify := ss.Services[mh.GetId()].Notify // 首次获取证书信息时,缓存证书信息 - if ss.sslCertCache[mh.GetId()] == "" { - ss.sslCertCache[mh.GetId()] = mh.Data + if ss.tlsCertCache[mh.GetId()] == "" { + ss.tlsCertCache[mh.GetId()] = mh.Data } - oldCert := strings.Split(ss.sslCertCache[mh.GetId()], "|") + oldCert := strings.Split(ss.tlsCertCache[mh.GetId()], "|") isCertChanged := false expiresOld, _ := time.Parse("2006-01-02 15:04:05 -0700 MST", oldCert[1]) expiresNew, _ := time.Parse("2006-01-02 15:04:05 -0700 MST", newCert[1]) @@ -539,7 +539,7 @@ func (ss *ServiceSentinel) worker() { // 证书变更时,更新缓存 if oldCert[0] != newCert[0] && !expiresNew.Equal(expiresOld) { isCertChanged = true - ss.sslCertCache[mh.GetId()] = mh.Data + ss.tlsCertCache[mh.GetId()] = mh.Data } notificationGroupID := ss.Services[mh.GetId()].NotificationGroupID @@ -552,24 +552,24 @@ func (ss *ServiceSentinel) worker() { if expiresNew.Before(time.Now().AddDate(0, 0, 7)) { expiresTimeStr := expiresNew.Format("2006-01-02 15:04:05") errMsg = Localizer.Tf( - "The SSL certificate will expire within seven days. Expiration time: %s", + "The TLS certificate will expire within seven days. Expiration time: %s", expiresTimeStr, ) // 静音规则: 服务id+证书过期时间 // 用于避免多个监测点对相同证书同时报警 - muteLabel := NotificationMuteLabel.ServiceSSL(mh.GetId(), fmt.Sprintf("expire_%s", expiresTimeStr)) - go SendNotification(notificationGroupID, fmt.Sprintf("[SSL] %s %s", serviceName, errMsg), muteLabel) + muteLabel := NotificationMuteLabel.ServiceTLS(mh.GetId(), fmt.Sprintf("expire_%s", expiresTimeStr)) + go SendNotification(notificationGroupID, fmt.Sprintf("[TLS] %s %s", serviceName, errMsg), muteLabel) } // 证书变更提醒 if isCertChanged { errMsg = Localizer.Tf( - "SSL certificate changed, old: issuer %s, expires at %s; new: issuer %s, expires at %s", + "TLS certificate changed, old: issuer %s, expires at %s; new: issuer %s, expires at %s", oldCert[0], expiresOld.Format("2006-01-02 15:04:05"), newCert[0], expiresNew.Format("2006-01-02 15:04:05")) // 证书变更后会自动更新缓存,所以不需要静音 - go SendNotification(notificationGroupID, fmt.Sprintf("[SSL] %s %s", serviceName, errMsg), nil) + go SendNotification(notificationGroupID, fmt.Sprintf("[TLS] %s %s", serviceName, errMsg), nil) } } }