From ac9408c37f023b0fbe357735f1cb0915430ed596 Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 18:44:18 +0430
Subject: update sub remark for shadowsocks
---
web/service/sub.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/web/service/sub.go b/web/service/sub.go
index f39fdb1e..b9ea49bd 100644
--- a/web/service/sub.go
+++ b/web/service/sub.go
@@ -603,7 +603,8 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st
}
}
encPart := fmt.Sprintf("%s:%s:%s", method, inboundPassword, clients[clientIndex].Password)
- return fmt.Sprintf("ss://%s@%s:%d#%s", base64.StdEncoding.EncodeToString([]byte(encPart)), address, inbound.Port, clients[clientIndex].Email)
+ remark := fmt.Sprintf("%s-%s", inbound.Remark, clients[clientIndex].Email)
+ return fmt.Sprintf("ss://%s@%s:%d#%s", base64.StdEncoding.EncodeToString([]byte(encPart)), address, inbound.Port, remark)
}
func searchKey(data interface{}, key string) (interface{}, bool) {
--
cgit v1.2.3
From a48745cb3e8fa4e1fb443cf157c497081aad8130 Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 18:46:50 +0430
Subject: fix tls settings
---
web/html/xui/form/tls_settings.html | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/web/html/xui/form/tls_settings.html b/web/html/xui/form/tls_settings.html
index 91642727..35f101ca 100644
--- a/web/html/xui/form/tls_settings.html
+++ b/web/html/xui/form/tls_settings.html
@@ -10,7 +10,7 @@
Reality
- {{ i18n "pages.inbounds.realityDesc" }}
+ {{ i18n "pages.inbounds.realityDesc" }}
@@ -22,7 +22,7 @@
XTLS
- {{ i18n "pages.inbounds.xtlsDesc" }}
+ {{ i18n "pages.inbounds.xtlsDesc" }}
@@ -100,7 +100,7 @@
-
+
--
cgit v1.2.3
From 419a1938ee51e011f079777e8b6ac83d908e5366 Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 18:57:10 +0430
Subject: update settings ui
---
web/html/xui/inbounds.html | 8 ++---
web/html/xui/settings.html | 86 ++++++++++++++++++++++++++++++----------------
2 files changed, 61 insertions(+), 33 deletions(-)
diff --git a/web/html/xui/inbounds.html b/web/html/xui/inbounds.html
index 6fdf0c43..a66e84a9 100644
--- a/web/html/xui/inbounds.html
+++ b/web/html/xui/inbounds.html
@@ -105,6 +105,10 @@
+
+
{{ i18n "none" }}
@@ -112,10 +116,6 @@
{{ i18n "depleted" }}
{{ i18n "depletingSoon" }}
-
-
.ant-tabs-top-bar {
background: white;
}
+
+ .alert-msg {
+ color: rgb(194, 117, 18);
+ font-weight: bold;
+ font-size: 20px;
+ margin-top: 5px;
+ padding: 16px 6px;
+ text-align: center;
+ border-bottom: 1px solid;
+ }
+
+ .alert-msg > i {
+ color: inherit;
+ font-size: 24px;
+ }
+
+ .collapse-title {
+ color: inherit;
+ font-weight: bold;
+ font-size: 18px;
+ padding: 10px 20px;
+ border-bottom: 2px solid;
+ }
+
+ .collapse-title > i {
+ color: inherit;
+ font-size: 24px;
+ }
@@ -35,8 +63,14 @@
{{ i18n "pages.settings.save" }}
{{ i18n "pages.settings.restartPanel" }}
-
+
+
+
+
+ {{ i18n "pages.settings.infoDesc" }}
+
+
@@ -72,12 +106,6 @@
-
-
-
- {{ i18n "pages.settings.infoDesc" }}
-
-
@@ -144,8 +172,8 @@
{{ i18n "pages.settings.templates.title"}}
-
-
+
+
{{ i18n "pages.settings.infoDesc" }}
@@ -154,8 +182,8 @@
-
-
+
+
{{ i18n "pages.settings.templates.generalConfigsDesc" }}
@@ -199,8 +227,8 @@
-
-
+
+
{{ i18n "pages.settings.templates.blockConfigsDesc" }}
@@ -212,8 +240,8 @@
-
-
+
+
{{ i18n "pages.settings.templates.blockCountryConfigsDesc" }}
@@ -226,8 +254,8 @@
-
-
+
+
{{ i18n "pages.settings.templates.directCountryConfigsDesc" }}
@@ -240,8 +268,8 @@
-
-
+
+
{{ i18n "pages.settings.templates.ipv4ConfigsDesc" }}
@@ -250,8 +278,8 @@
-
-
+
+
{{ i18n "pages.settings.templates.warpConfigsDesc" }}
@@ -262,8 +290,8 @@
-
-
+
+
{{ i18n "pages.settings.templates.manualListsDesc" }}
@@ -295,6 +323,12 @@
+
+
+
+ {{ i18n "pages.settings.infoDesc" }}
+
+
@@ -303,12 +337,6 @@
-
-
-
- {{ i18n "pages.settings.infoDesc" }}
-
-
--
cgit v1.2.3
From c7e300f14d5fc8cb4d025892461a766fa8308562 Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 18:58:51 +0430
Subject: FIX redirect after restart panel
---
web/html/xui/settings.html | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/web/html/xui/settings.html b/web/html/xui/settings.html
index acff52f3..8f9e2b7b 100644
--- a/web/html/xui/settings.html
+++ b/web/html/xui/settings.html
@@ -480,7 +480,12 @@
if (msg.success) {
this.loading(true);
await PromiseUtil.sleep(5000);
- window.location.replace(this.allSetting.webBasePath + "panel/settings");
+ let protocol = "http://";
+ if (this.allSetting.webCertFile !== "") {
+ protocol = "https://";
+ }
+ const { host, pathname } = window.location;
+ window.location.replace(protocol + host + this.allSetting.webBasePath + pathname.slice(1));
}
},
async fetchUserSecret() {
--
cgit v1.2.3
From f50ccce9ec7d920919fd28a1fa2ac2b0b9b44e37 Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 19:02:37 +0430
Subject: Add manual list for ipv4 and warp and fixed it
---
web/html/xui/settings.html | 120 ++++++++++++++++++++-------------------------
1 file changed, 53 insertions(+), 67 deletions(-)
diff --git a/web/html/xui/settings.html b/web/html/xui/settings.html
index 8f9e2b7b..7dd503a6 100644
--- a/web/html/xui/settings.html
+++ b/web/html/xui/settings.html
@@ -299,6 +299,8 @@
+
+
@@ -617,30 +619,30 @@
computed: {
templateSettings: {
get: function () { return this.allSetting.xrayTemplateConfig ? JSON.parse(this.allSetting.xrayTemplateConfig) : null; },
- set: function (newValue) { this.allSetting.xrayTemplateConfig = JSON.stringify(newValue, null, 2) },
+ set: function (newValue) { this.allSetting.xrayTemplateConfig = JSON.stringify(newValue, null, 2); },
},
inboundSettings: {
get: function () { return this.templateSettings ? JSON.stringify(this.templateSettings.inbounds, null, 2) : null; },
set: function (newValue) {
newTemplateSettings = this.templateSettings;
- newTemplateSettings.inbounds = JSON.parse(newValue)
- this.templateSettings = newTemplateSettings
+ newTemplateSettings.inbounds = JSON.parse(newValue);
+ this.templateSettings = newTemplateSettings;
},
},
outboundSettings: {
get: function () { return this.templateSettings ? JSON.stringify(this.templateSettings.outbounds, null, 2) : null; },
set: function (newValue) {
newTemplateSettings = this.templateSettings;
- newTemplateSettings.outbounds = JSON.parse(newValue)
- this.templateSettings = newTemplateSettings
+ newTemplateSettings.outbounds = JSON.parse(newValue);
+ this.templateSettings = newTemplateSettings;
},
},
routingRuleSettings: {
get: function () { return this.templateSettings ? JSON.stringify(this.templateSettings.routing.rules, null, 2) : null; },
set: function (newValue) {
newTemplateSettings = this.templateSettings;
- newTemplateSettings.routing.rules = JSON.parse(newValue)
- this.templateSettings = newTemplateSettings
+ newTemplateSettings.routing.rules = JSON.parse(newValue);
+ this.templateSettings = newTemplateSettings;
},
},
freedomStrategy: {
@@ -715,6 +717,24 @@
this.syncRulesWithOutbound("direct", this.directSettings);
}
},
+ ipv4Domains: {
+ get: function () {
+ return this.templateRuleGetter({ outboundTag: "IPv4", property: "domain" });
+ },
+ set: function (newValue) {
+ this.templateRuleSetter({ outboundTag: "IPv4", property: "domain", data: newValue });
+ this.syncRulesWithOutbound("IPv4", this.ipv4Settings);
+ }
+ },
+ warpDomains: {
+ get: function () {
+ return this.templateRuleGetter({ outboundTag: "WARP", property: "domain" });
+ },
+ set: function (newValue) {
+ this.templateRuleSetter({ outboundTag: "WARP", property: "domain", data: newValue });
+ this.syncRulesWithOutbound("WARP", this.warpSettings);
+ }
+ },
manualBlockedIPs: {
get: function () { return JSON.stringify(this.blockedIPs, null, 2); },
set: debounce(function (value) { this.blockedIPs = JSON.parse(value); }, 1000)
@@ -731,6 +751,14 @@
get: function () { return JSON.stringify(this.directDomains, null, 2); },
set: debounce(function (value) { this.directDomains = JSON.parse(value); }, 1000)
},
+ manualIPv4Domains: {
+ get: function () { return JSON.stringify(this.ipv4Domains, null, 2); },
+ set: debounce(function (value) { this.ipv4Domains = JSON.parse(value); }, 1000)
+ },
+ manualWARPDomains: {
+ get: function () { return JSON.stringify(this.warpDomains, null, 2); },
+ set: debounce(function (value) { this.warpDomains = JSON.parse(value); }, 1000)
+ },
torrentSettings: {
get: function () {
return doAllItemsExist(this.settingsData.protocols.bittorrent, this.blockedProtocols);
@@ -796,40 +824,26 @@
},
GoogleIPv4Settings: {
get: function () {
- return doAllItemsExist(this.settingsData.domains.google, this.templateRuleGetter({ outboundTag: "IPv4", property: "domain" }));
+ return doAllItemsExist(this.settingsData.domains.google, this.ipv4Domains);
},
set: function (newValue) {
- oldData = this.templateRuleGetter({ outboundTag: "IPv4", property: "domain" });
if (newValue) {
- oldData = [...oldData, ...this.settingsData.domains.google];
+ this.ipv4Domains = [...this.ipv4Domains, ...this.settingsData.domains.google];
} else {
- oldData = oldData.filter(data => !this.settingsData.domains.google.includes(data))
+ this.ipv4Domains = this.ipv4Domains.filter(data => !this.settingsData.domains.google.includes(data));
}
- this.templateRuleSetter({
- outboundTag: "IPv4",
- property: "domain",
- data: oldData
- });
- this.syncRulesWithOutbound("IPv4", this.ipv4Settings);
},
},
NetflixIPv4Settings: {
get: function () {
- return doAllItemsExist(this.settingsData.domains.netflix, this.templateRuleGetter({ outboundTag: "IPv4", property: "domain" }));
+ return doAllItemsExist(this.settingsData.domains.netflix, this.ipv4Domains);
},
set: function (newValue) {
- oldData = this.templateRuleGetter({ outboundTag: "IPv4", property: "domain" });
if (newValue) {
- oldData = [...oldData, ...this.settingsData.domains.netflix];
+ this.ipv4Domains = [...this.ipv4Domains, ...this.settingsData.domains.netflix];
} else {
- oldData = oldData.filter(data => !this.settingsData.domains.netflix.includes(data))
+ this.ipv4Domains = this.ipv4Domains.filter(data => !this.settingsData.domains.netflix.includes(data));
}
- this.templateRuleSetter({
- outboundTag: "IPv4",
- property: "domain",
- data: oldData
- });
- this.syncRulesWithOutbound("IPv4", this.ipv4Settings);
},
},
IRIpSettings: {
@@ -978,78 +992,50 @@
},
GoogleWARPSettings: {
get: function () {
- return doAllItemsExist(this.settingsData.domains.google, this.templateRuleGetter({ outboundTag: "WARP", property: "domain" }));
+ return doAllItemsExist(this.settingsData.domains.google, this.warpDomains);
},
set: function (newValue) {
- oldData = this.templateRuleGetter({ outboundTag: "WARP", property: "domain" });
if (newValue) {
- oldData = [...oldData, ...this.settingsData.domains.google];
+ this.warpDomains = [...this.warpDomains, ...this.settingsData.domains.google];
} else {
- oldData = oldData.filter(data => !this.settingsData.domains.google.includes(data))
+ this.warpDomains = this.warpDomains.filter(data => !this.settingsData.domains.google.includes(data));
}
- this.templateRuleSetter({
- outboundTag: "WARP",
- property: "domain",
- data: oldData
- });
- this.syncRulesWithOutbound("WARP", this.warpSettings);
},
},
OpenAIWARPSettings: {
get: function () {
- return doAllItemsExist(this.settingsData.domains.openai, this.templateRuleGetter({ outboundTag: "WARP", property: "domain" }));
+ return doAllItemsExist(this.settingsData.domains.openai, this.warpDomains);
},
set: function (newValue) {
- oldData = this.templateRuleGetter({ outboundTag: "WARP", property: "domain" });
if (newValue) {
- oldData = [...oldData, ...this.settingsData.domains.openai];
+ this.warpDomains = [...this.warpDomains, ...this.settingsData.domains.openai];
} else {
- oldData = oldData.filter(data => !this.settingsData.domains.openai.includes(data))
+ this.warpDomains = this.warpDomains.filter(data => !this.settingsData.domains.openai.includes(data));
}
- this.templateRuleSetter({
- outboundTag: "WARP",
- property: "domain",
- data: oldData
- });
- this.syncRulesWithOutbound("WARP", this.warpSettings);
},
},
NetflixWARPSettings: {
get: function () {
- return doAllItemsExist(this.settingsData.domains.netflix, this.templateRuleGetter({ outboundTag: "WARP", property: "domain" }));
+ return doAllItemsExist(this.settingsData.domains.netflix, this.warpDomains);
},
set: function (newValue) {
- oldData = this.templateRuleGetter({ outboundTag: "WARP", property: "domain" });
if (newValue) {
- oldData = [...oldData, ...this.settingsData.domains.netflix];
+ this.warpDomains = [...this.warpDomains, ...this.settingsData.domains.netflix];
} else {
- oldData = oldData.filter(data => !this.settingsData.domains.netflix.includes(data))
+ this.warpDomains = this.warpDomains.filter(data => !this.settingsData.domains.netflix.includes(data));
}
- this.templateRuleSetter({
- outboundTag: "WARP",
- property: "domain",
- data: oldData
- });
- this.syncRulesWithOutbound("WARP", this.warpSettings);
},
},
SpotifyWARPSettings: {
get: function () {
- return doAllItemsExist(this.settingsData.domains.spotify, this.templateRuleGetter({ outboundTag: "WARP", property: "domain" }));
+ return doAllItemsExist(this.settingsData.domains.spotify, this.warpDomains);
},
set: function (newValue) {
- oldData = this.templateRuleGetter({ outboundTag: "WARP", property: "domain" });
if (newValue) {
- oldData = [...oldData, ...this.settingsData.domains.spotify];
+ this.warpDomains = [...this.warpDomains, ...this.settingsData.domains.spotify];
} else {
- oldData = oldData.filter(data => !this.settingsData.domains.spotify.includes(data))
+ this.warpDomains = this.warpDomains.filter(data => !this.settingsData.domains.spotify.includes(data));
}
- this.templateRuleSetter({
- outboundTag: "WARP",
- property: "domain",
- data: oldData
- });
- this.syncRulesWithOutbound("WARP", this.warpSettings);
},
},
},
--
cgit v1.2.3
From 3166d497f99df530e3a909ab1ba134fe53ef39ff Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 19:03:31 +0430
Subject: Update .gitignore
---
.gitignore | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/.gitignore b/.gitignore
index 6277cfc9..158f4ee1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,15 @@
.idea
.vscode
+.cache
+.sync*
+*.tar.gz
+access.log
+error.log
tmp
+main
backup/
bin/
dist/
-x-ui-*.tar.gz
-/x-ui
-/release.sh
-.sync*
-main
release/
-access.log
-error.log
-.cache
+/release.sh
+/x-ui
--
cgit v1.2.3
From 4831c2f1b2c73c1e40f23a61e728530b7cf4afe9 Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 19:15:20 +0430
Subject: Add tgLang option
---
web/assets/js/model/models.js | 1 +
web/entity/entity.go | 1 +
web/network/auto_https_conn.go | 67 ++++++++++++++++++++++++++++++++++++++++++
web/network/autp_https_conn.go | 67 ------------------------------------------
web/service/setting.go | 5 ++++
5 files changed, 74 insertions(+), 67 deletions(-)
create mode 100644 web/network/auto_https_conn.go
delete mode 100644 web/network/autp_https_conn.go
diff --git a/web/assets/js/model/models.js b/web/assets/js/model/models.js
index a3fd2633..e1fb5d02 100644
--- a/web/assets/js/model/models.js
+++ b/web/assets/js/model/models.js
@@ -181,6 +181,7 @@ class AllSetting {
this.tgRunTime = "@daily";
this.tgBotBackup = false;
this.tgCpu = "";
+ this.tgLang = "";
this.xrayTemplateConfig = "";
this.secretEnable = false;
diff --git a/web/entity/entity.go b/web/entity/entity.go
index b370b7ba..52f26769 100644
--- a/web/entity/entity.go
+++ b/web/entity/entity.go
@@ -41,6 +41,7 @@ type AllSetting struct {
TgRunTime string `json:"tgRunTime" form:"tgRunTime"`
TgBotBackup bool `json:"tgBotBackup" form:"tgBotBackup"`
TgCpu int `json:"tgCpu" form:"tgCpu"`
+ TgLang string `json:"tgLang" form:"tgLang"`
XrayTemplateConfig string `json:"xrayTemplateConfig" form:"xrayTemplateConfig"`
TimeLocation string `json:"timeLocation" form:"timeLocation"`
SecretEnable bool `json:"secretEnable" form:"secretEnable"`
diff --git a/web/network/auto_https_conn.go b/web/network/auto_https_conn.go
new file mode 100644
index 00000000..d1a9d521
--- /dev/null
+++ b/web/network/auto_https_conn.go
@@ -0,0 +1,67 @@
+package network
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "net"
+ "net/http"
+ "sync"
+)
+
+type AutoHttpsConn struct {
+ net.Conn
+
+ firstBuf []byte
+ bufStart int
+
+ readRequestOnce sync.Once
+}
+
+func NewAutoHttpsConn(conn net.Conn) net.Conn {
+ return &AutoHttpsConn{
+ Conn: conn,
+ }
+}
+
+func (c *AutoHttpsConn) readRequest() bool {
+ c.firstBuf = make([]byte, 2048)
+ n, err := c.Conn.Read(c.firstBuf)
+ c.firstBuf = c.firstBuf[:n]
+ if err != nil {
+ return false
+ }
+ reader := bytes.NewReader(c.firstBuf)
+ bufReader := bufio.NewReader(reader)
+ request, err := http.ReadRequest(bufReader)
+ if err != nil {
+ return false
+ }
+ resp := http.Response{
+ Header: http.Header{},
+ }
+ resp.StatusCode = http.StatusTemporaryRedirect
+ location := fmt.Sprintf("https://%v%v", request.Host, request.RequestURI)
+ resp.Header.Set("Location", location)
+ resp.Write(c.Conn)
+ c.Close()
+ c.firstBuf = nil
+ return true
+}
+
+func (c *AutoHttpsConn) Read(buf []byte) (int, error) {
+ c.readRequestOnce.Do(func() {
+ c.readRequest()
+ })
+
+ if c.firstBuf != nil {
+ n := copy(buf, c.firstBuf[c.bufStart:])
+ c.bufStart += n
+ if c.bufStart >= len(c.firstBuf) {
+ c.firstBuf = nil
+ }
+ return n, nil
+ }
+
+ return c.Conn.Read(buf)
+}
diff --git a/web/network/autp_https_conn.go b/web/network/autp_https_conn.go
deleted file mode 100644
index d1a9d521..00000000
--- a/web/network/autp_https_conn.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package network
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "net"
- "net/http"
- "sync"
-)
-
-type AutoHttpsConn struct {
- net.Conn
-
- firstBuf []byte
- bufStart int
-
- readRequestOnce sync.Once
-}
-
-func NewAutoHttpsConn(conn net.Conn) net.Conn {
- return &AutoHttpsConn{
- Conn: conn,
- }
-}
-
-func (c *AutoHttpsConn) readRequest() bool {
- c.firstBuf = make([]byte, 2048)
- n, err := c.Conn.Read(c.firstBuf)
- c.firstBuf = c.firstBuf[:n]
- if err != nil {
- return false
- }
- reader := bytes.NewReader(c.firstBuf)
- bufReader := bufio.NewReader(reader)
- request, err := http.ReadRequest(bufReader)
- if err != nil {
- return false
- }
- resp := http.Response{
- Header: http.Header{},
- }
- resp.StatusCode = http.StatusTemporaryRedirect
- location := fmt.Sprintf("https://%v%v", request.Host, request.RequestURI)
- resp.Header.Set("Location", location)
- resp.Write(c.Conn)
- c.Close()
- c.firstBuf = nil
- return true
-}
-
-func (c *AutoHttpsConn) Read(buf []byte) (int, error) {
- c.readRequestOnce.Do(func() {
- c.readRequest()
- })
-
- if c.firstBuf != nil {
- n := copy(buf, c.firstBuf[c.bufStart:])
- c.bufStart += n
- if c.bufStart >= len(c.firstBuf) {
- c.firstBuf = nil
- }
- return n, nil
- }
-
- return c.Conn.Read(buf)
-}
diff --git a/web/service/setting.go b/web/service/setting.go
index d3072252..fec324af 100644
--- a/web/service/setting.go
+++ b/web/service/setting.go
@@ -39,6 +39,7 @@ var defaultValueMap = map[string]string{
"tgRunTime": "@daily",
"tgBotBackup": "false",
"tgCpu": "0",
+ "tgLang": "en-US",
"secretEnable": "false",
}
@@ -256,6 +257,10 @@ func (s *SettingService) GetTgCpu() (int, error) {
return s.getInt("tgCpu")
}
+func (s *SettingService) GetTgLang() (string, error) {
+ return s.getString("tgLang")
+}
+
func (s *SettingService) GetPort() (int, error) {
return s.getInt("webPort")
}
--
cgit v1.2.3
From 91360a3f49895d80d34183a0421f2dcc5d64b18e Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 19:20:54 +0430
Subject: add tgLang to settings
---
web/html/xui/settings.html | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/web/html/xui/settings.html b/web/html/xui/settings.html
index 7dd503a6..f5ea4994 100644
--- a/web/html/xui/settings.html
+++ b/web/html/xui/settings.html
@@ -338,6 +338,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--
cgit v1.2.3
From 795835c54fbbaf35755c13855fb2b64e4e85e49c Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 19:21:10 +0430
Subject: Update translations
---
web/translation/translate.en_US.toml | 4 +++-
web/translation/translate.fa_IR.toml | 2 ++
web/translation/translate.ru_RU.toml | 2 ++
web/translation/translate.zh_Hans.toml | 2 ++
4 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml
index 075bf6e9..4855bf5e 100644
--- a/web/translation/translate.en_US.toml
+++ b/web/translation/translate.en_US.toml
@@ -209,7 +209,7 @@
[pages.settings]
"title" = "Settings"
"save" = "Save"
-"infoDesc" = "Every change made here needs to be saved. Please restart the panel for the changes to take effect."
+"infoDesc" = "Every change made here needs to be saved. Please restart the panel to apply changes."
"restartPanel" = "Restart Panel "
"restartPanelDesc" = "Are you sure you want to restart the panel? Click OK to restart after 3 seconds. If you cannot access the panel after restarting, please view the panel log information on the server."
"actions" = "Actions"
@@ -336,6 +336,8 @@
"manualBlockedDomains" = "List of Blocked Domains"
"manualDirectIPs" = "List of Direct IPs"
"manualDirectDomains" = "List of Direct Domains"
+"manualIPv4Domains" = "List of IPv4 Domains"
+"manualWARPDomains" = "List of WARP Domains"
[pages.settings.security]
"admin" = "Admin"
diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml
index 9e31f4ef..7bcca58a 100644
--- a/web/translation/translate.fa_IR.toml
+++ b/web/translation/translate.fa_IR.toml
@@ -336,6 +336,8 @@
"manualBlockedDomains" = "لیست دامنه های مسدود شده"
"manualDirectIPs" = "لیست آیپی های مستقیم"
"manualDirectDomains" = "لیست دامنه های مستقیم"
+"manualIPv4Domains" = "لیست دامنههای IPv4"
+"manualWARPDomains" = "لیست دامنه های WARP"
[pages.settings.security]
"admin" = "مدیر"
diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml
index 15e45b84..7b5175ea 100644
--- a/web/translation/translate.ru_RU.toml
+++ b/web/translation/translate.ru_RU.toml
@@ -336,6 +336,8 @@
"manualBlockedDomains" = "Список заблокированных доменов"
"manualDirectIPs" = "Список прямых IP адресов"
"manualDirectDomains" = "Список прямых доменов"
+"manualIPv4Domains" = "Список доменов IPv4"
+"manualWARPDomains" = "Список доменов WARP"
[pages.settings.security]
"admin" = "Админ"
diff --git a/web/translation/translate.zh_Hans.toml b/web/translation/translate.zh_Hans.toml
index a1205447..ecdfb540 100644
--- a/web/translation/translate.zh_Hans.toml
+++ b/web/translation/translate.zh_Hans.toml
@@ -336,6 +336,8 @@
"manualBlockedDomains" = "被阻止的域列表"
"manualDirectIPs" = "直接 IP 列表"
"manualDirectDomains" = "直接域列表"
+"manualIPv4Domains" = "IPv4 域名列表"
+"manualWARPDomains" = "WARP域名列表"
[pages.settings.security]
"admin" = "行政"
--
cgit v1.2.3
From 678962d4ca3045bd869930efef0a196a0f8a29ba Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 19:39:01 +0430
Subject: some fix and prune for tgbot
---
web/controller/index.go | 5 ++-
web/service/tgbot.go | 104 ++++++++++++++++++++++++++++--------------------
web/web.go | 2 +-
3 files changed, 64 insertions(+), 47 deletions(-)
diff --git a/web/controller/index.go b/web/controller/index.go
index ac2ceca1..7a7a0cce 100644
--- a/web/controller/index.go
+++ b/web/controller/index.go
@@ -60,15 +60,16 @@ func (a *IndexController) login(c *gin.Context) {
pureJsonMsg(c, false, I18n(c, "pages.login.toasts.emptyPassword"))
return
}
+
user := a.userService.CheckUser(form.Username, form.Password, form.LoginSecret)
timeStr := time.Now().Format("2006-01-02 15:04:05")
if user == nil {
- a.tgbot.UserLoginNotify(form.Username, getRemoteIp(c), timeStr, 0)
logger.Infof("wrong username or password: \"%s\" \"%s\"", form.Username, form.Password)
+ a.tgbot.UserLoginNotify(form.Username, getRemoteIp(c), timeStr, 0)
pureJsonMsg(c, false, I18n(c, "pages.login.toasts.wrongUsernameOrPassword"))
return
} else {
- logger.Infof("%s login success,Ip Address:%s\n", form.Username, getRemoteIp(c))
+ logger.Infof("%s login success, Ip Address: %s\n", form.Username, getRemoteIp(c))
a.tgbot.UserLoginNotify(form.Username, getRemoteIp(c), timeStr, 1)
}
diff --git a/web/service/tgbot.go b/web/service/tgbot.go
index 0b301e29..72f8ae1a 100644
--- a/web/service/tgbot.go
+++ b/web/service/tgbot.go
@@ -81,7 +81,7 @@ func (t *Tgbot) Start() error {
return nil
}
-func (t *Tgbot) IsRunnging() bool {
+func (t *Tgbot) IsRunning() bool {
return isRunning
}
@@ -102,19 +102,19 @@ func (t *Tgbot) OnReceive() {
botHandler, _ = th.NewBotHandler(bot, updates)
- botHandler.HandleMessage(func(bot *telego.Bot, message telego.Message) {
+ botHandler.HandleMessage(func(_ *telego.Bot, message telego.Message) {
t.SendMsgToTgbot(message.Chat.ID, "Custom Keyboard Closed!", tu.ReplyKeyboardRemove())
}, th.TextEqual("❌ Close Keyboard"))
- botHandler.HandleMessage(func(bot *telego.Bot, message telego.Message) {
+ botHandler.HandleMessage(func(_ *telego.Bot, message telego.Message) {
t.answerCommand(&message, message.Chat.ID, checkAdmin(message.From.ID))
}, th.AnyCommand())
- botHandler.HandleCallbackQuery(func(bot *telego.Bot, query telego.CallbackQuery) {
+ botHandler.HandleCallbackQuery(func(_ *telego.Bot, query telego.CallbackQuery) {
t.asnwerCallback(&query, checkAdmin(query.From.ID))
}, th.AnyCallbackQueryWithMessage())
- botHandler.HandleMessage(func(bot *telego.Bot, message telego.Message) {
+ botHandler.HandleMessage(func(_ *telego.Bot, message telego.Message) {
if message.UserShared != nil {
if checkAdmin(message.From.ID) {
err := t.inboundService.SetClientTelegramUserID(message.UserShared.RequestID, strconv.FormatInt(message.UserShared.UserID, 10))
@@ -424,32 +424,32 @@ func (t *Tgbot) SendAnswer(chatId int64, msg string, isAdmin bool) {
tu.InlineKeyboardButton("Commands").WithCallbackData("client_commands"),
),
)
- params := telego.SendMessageParams{
- ChatID: tu.ID(chatId),
- Text: msg,
- ParseMode: "HTML",
- }
+ var ReplyMarkup telego.ReplyMarkup
if isAdmin {
- params.ReplyMarkup = numericKeyboard
+ ReplyMarkup = numericKeyboard
} else {
- params.ReplyMarkup = numericKeyboardClient
- }
- _, err := bot.SendMessage(¶ms)
- if err != nil {
- logger.Warning("Error sending telegram message :", err)
+ ReplyMarkup = numericKeyboardClient
}
+ t.SendMsgToTgbot(chatId, msg, ReplyMarkup)
}
func (t *Tgbot) SendMsgToTgbot(chatId int64, msg string, replyMarkup ...telego.ReplyMarkup) {
if !isRunning {
return
}
+ if msg == "" {
+ logger.Info("[tgbot] message is empty!")
+ return
+ }
+
var allMessages []string
limit := 2000
+
// paging message if it is big
if len(msg) > limit {
messages := strings.Split(msg, "\r\n \r\n")
lastIndex := -1
+
for _, message := range messages {
if (len(allMessages) == 0) || (len(allMessages[lastIndex])+len(message) > limit) {
allMessages = append(allMessages, message)
@@ -510,12 +510,12 @@ func (t *Tgbot) SendBackUP(c *gin.Context) {
func (t *Tgbot) getServerUsage() string {
var info string
//get hostname
- name, err := os.Hostname()
+ hostname, err := os.Hostname()
if err != nil {
logger.Error("get hostname error:", err)
- name = ""
+ hostname = ""
}
- info = fmt.Sprintf("💻 Hostname: %s\r\n", name)
+ info = fmt.Sprintf("💻 Hostname: %s\r\n", hostname)
info += fmt.Sprintf("🚀X-UI Version: %s\r\n", config.GetVersion())
//get ip address
var ip string
@@ -557,25 +557,32 @@ func (t *Tgbot) getServerUsage() string {
}
func (t *Tgbot) UserLoginNotify(username string, ip string, time string, status LoginStatus) {
+ if !t.IsRunning() {
+ return
+ }
+
if username == "" || ip == "" || time == "" {
- logger.Warning("UserLoginNotify failed,invalid info")
+ logger.Warning("UserLoginNotify failed, invalid info!")
return
}
- var msg string
+
// Get hostname
- name, err := os.Hostname()
+ hostname, err := os.Hostname()
if err != nil {
logger.Warning("get hostname error:", err)
return
}
+
+ msg := ""
if status == LoginSuccess {
- msg = fmt.Sprintf("✅ Successfully logged-in to the panel\r\nHostname:%s\r\n", name)
+ msg = fmt.Sprintf("✅ Successfully logged-in to the panel\r\nHostname:%s\r\n", hostname)
} else if status == LoginFail {
- msg = fmt.Sprintf("❗ Login to the panel was unsuccessful\r\nHostname:%s\r\n", name)
+ msg = fmt.Sprintf("❗ Login to the panel was unsuccessful\r\nHostname:%s\r\n", hostname)
}
msg += fmt.Sprintf("⏰ Time:%s\r\n", time)
msg += fmt.Sprintf("🆔 Username:%s\r\n", username)
msg += fmt.Sprintf("🌐 IP:%s\r\n", ip)
+
t.SendMsgToTgbotAdmins(msg)
}
@@ -686,11 +693,12 @@ func (t *Tgbot) clientTelegramUserInfo(chatId int64, email string, messageID ...
t.SendMsgToTgbot(chatId, msg)
return
}
- tdId := "None"
+ tgId := "None"
if len(client.TgID) > 0 {
- tdId = client.TgID
+ tgId = client.TgID
}
- output := fmt.Sprintf("📧 Email: %s\r\n👤 Telegram User: %s\r\n", email, tdId)
+
+ output := fmt.Sprintf("📧 Email: %s\r\n👤 Telegram User: %s\r\n", email, tgId)
inlineKeyboard := tu.InlineKeyboard(
tu.InlineKeyboardRow(
tu.InlineKeyboardButton("🔄 Refresh").WithCallbackData("tgid_refresh "+email),
@@ -699,6 +707,7 @@ func (t *Tgbot) clientTelegramUserInfo(chatId int64, email string, messageID ...
tu.InlineKeyboardButton("❌ Remove Telegram User").WithCallbackData("tgid_remove "+email),
),
)
+
if len(messageID) > 0 {
t.editMessageTgBot(chatId, messageID[0], output, inlineKeyboard)
} else {
@@ -732,6 +741,7 @@ func (t *Tgbot) searchClient(chatId int64, email string, messageID ...int) {
t.SendMsgToTgbot(chatId, msg)
return
}
+
expiryTime := ""
if traffic.ExpiryTime == 0 {
expiryTime = "♾Unlimited"
@@ -740,15 +750,18 @@ func (t *Tgbot) searchClient(chatId int64, email string, messageID ...int) {
} else {
expiryTime = time.Unix((traffic.ExpiryTime / 1000), 0).Format("2006-01-02 15:04:05")
}
+
total := ""
if traffic.Total == 0 {
total = "♾Unlimited"
} else {
total = common.FormatTraffic((traffic.Total))
}
+
output := fmt.Sprintf("💡 Active: %t\r\n📧 Email: %s\r\n🔼 Upload↑: %s\r\n🔽 Download↓: %s\r\n🔄 Total: %s / %s\r\n📅 Expire in: %s\r\n",
traffic.Enable, traffic.Email, common.FormatTraffic(traffic.Up), common.FormatTraffic(traffic.Down), common.FormatTraffic((traffic.Up + traffic.Down)),
total, expiryTime)
+
inlineKeyboard := tu.InlineKeyboard(
tu.InlineKeyboardRow(
tu.InlineKeyboardButton("🔄 Refresh").WithCallbackData("client_refresh "+email),
@@ -770,6 +783,7 @@ func (t *Tgbot) searchClient(chatId int64, email string, messageID ...int) {
tu.InlineKeyboardButton("🔘 Enable / Disable").WithCallbackData("toggle_enable "+email),
),
)
+
if len(messageID) > 0 {
t.editMessageTgBot(chatId, messageID[0], output, inlineKeyboard)
} else {
@@ -785,6 +799,12 @@ func (t *Tgbot) searchInbound(chatId int64, remark string) {
t.SendMsgToTgbot(chatId, msg)
return
}
+ if len(inbouds) == 0 {
+ msg := "❌ No inbounds found!"
+ t.SendMsgToTgbot(chatId, msg)
+ return
+ }
+
for _, inbound := range inbouds {
info := ""
info += fmt.Sprintf("📍Inbound:%s\r\nPort:%d\r\n", inbound.Remark, inbound.Port)
@@ -795,6 +815,7 @@ func (t *Tgbot) searchInbound(chatId int64, remark string) {
info += fmt.Sprintf("Expire date:%s\r\n \r\n", time.Unix((inbound.ExpiryTime/1000), 0).Format("2006-01-02 15:04:05"))
}
t.SendMsgToTgbot(chatId, info)
+
for _, traffic := range inbound.ClientStats {
expiryTime := ""
if traffic.ExpiryTime == 0 {
@@ -804,6 +825,7 @@ func (t *Tgbot) searchInbound(chatId int64, remark string) {
} else {
expiryTime = time.Unix((traffic.ExpiryTime / 1000), 0).Format("2006-01-02 15:04:05")
}
+
total := ""
if traffic.Total == 0 {
total = "♾Unlimited"
@@ -831,6 +853,7 @@ func (t *Tgbot) searchForClient(chatId int64, query string) {
t.SendMsgToTgbot(chatId, msg)
return
}
+
expiryTime := ""
if traffic.ExpiryTime == 0 {
expiryTime = "♾Unlimited"
@@ -839,12 +862,14 @@ func (t *Tgbot) searchForClient(chatId int64, query string) {
} else {
expiryTime = time.Unix((traffic.ExpiryTime / 1000), 0).Format("2006-01-02 15:04:05")
}
+
total := ""
if traffic.Total == 0 {
total = "♾Unlimited"
} else {
total = common.FormatTraffic((traffic.Total))
}
+
output := fmt.Sprintf("💡 Active: %t\r\n📧 Email: %s\r\n🔼 Upload↑: %s\r\n🔽 Download↓: %s\r\n🔄 Total: %s / %s\r\n📅 Expire in: %s\r\n",
traffic.Enable, traffic.Email, common.FormatTraffic(traffic.Up), common.FormatTraffic(traffic.Down), common.FormatTraffic((traffic.Up + traffic.Down)),
total, expiryTime)
@@ -859,6 +884,7 @@ func (t *Tgbot) getExhausted() string {
var exhaustedClients []xray.ClientTraffic
var disabledInbounds []model.Inbound
var disabledClients []xray.ClientTraffic
+
output := ""
TrafficThreshold, err := t.settingService.GetTrafficDiff()
if err == nil && TrafficThreshold > 0 {
@@ -872,6 +898,7 @@ func (t *Tgbot) getExhausted() string {
if err != nil {
logger.Warning("Unable to load Inbounds", err)
}
+
for _, inbound := range inbounds {
if inbound.Enable {
if (inbound.ExpiryTime > 0 && (inbound.ExpiryTime-now < exDiff)) ||
@@ -894,6 +921,7 @@ func (t *Tgbot) getExhausted() string {
disabledInbounds = append(disabledInbounds, *inbound)
}
}
+
output += fmt.Sprintf("Exhausted Inbounds count:\r\n🛑 Disabled: %d\r\n🔜 Deplete soon: %d\r\n \r\n", len(disabledInbounds), len(exhaustedInbounds))
if len(exhaustedInbounds) > 0 {
output += "Exhausted Inbounds:\r\n"
@@ -906,6 +934,7 @@ func (t *Tgbot) getExhausted() string {
}
}
}
+
output += fmt.Sprintf("Exhausted Clients count:\r\n🛑 Exhausted: %d\r\n🔜 Deplete soon: %d\r\n \r\n", len(disabledClients), len(exhaustedClients))
if len(exhaustedClients) > 0 {
output += "Exhausted Clients:\r\n"
@@ -934,6 +963,10 @@ func (t *Tgbot) getExhausted() string {
}
func (t *Tgbot) sendBackup(chatId int64) {
+ if !t.IsRunning() {
+ return
+ }
+
sendingTime := time.Now().Format("2006-01-02 15:04:05")
t.SendMsgToTgbot(chatId, "Backup time: "+sendingTime)
file, err := os.Open(config.GetDBPath())
@@ -997,20 +1030,3 @@ func (t *Tgbot) editMessageTgBot(chatId int64, messageID int, text string, inlin
logger.Warning(err)
}
}
-
-func fromChat(u *telego.Update) *telego.Chat {
- switch {
- case u.Message != nil:
- return &u.Message.Chat
- case u.EditedMessage != nil:
- return &u.EditedMessage.Chat
- case u.ChannelPost != nil:
- return &u.ChannelPost.Chat
- case u.EditedChannelPost != nil:
- return &u.EditedChannelPost.Chat
- case u.CallbackQuery != nil:
- return &u.CallbackQuery.Message.Chat
- default:
- return nil
- }
-}
diff --git a/web/web.go b/web/web.go
index 1795e1d4..bd1c4721 100644
--- a/web/web.go
+++ b/web/web.go
@@ -453,7 +453,7 @@ func (s *Server) Stop() error {
if s.cron != nil {
s.cron.Stop()
}
- if s.tgbotService.IsRunnging() {
+ if s.tgbotService.IsRunning() {
s.tgbotService.Stop()
}
var err1 error
--
cgit v1.2.3
From 0b7aa8a9e03647a622b0de064c61e9634c20a958 Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 19:41:08 +0430
Subject: Refactor i18n localizer
---
web/locale/locale.go | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 110 insertions(+)
create mode 100644 web/locale/locale.go
diff --git a/web/locale/locale.go b/web/locale/locale.go
new file mode 100644
index 00000000..ba7a30e5
--- /dev/null
+++ b/web/locale/locale.go
@@ -0,0 +1,110 @@
+package locale
+
+import (
+ "embed"
+ "io/fs"
+ "strings"
+ "x-ui/logger"
+
+ "github.com/nicksnyder/go-i18n/v2/i18n"
+ "github.com/pelletier/go-toml/v2"
+ "golang.org/x/text/language"
+)
+
+var i18nBundle *i18n.Bundle
+var LocalizerWeb *i18n.Localizer
+var LocalizerBot *i18n.Localizer
+
+type I18nType string
+
+const (
+ Bot I18nType = "bot"
+ Web I18nType = "web"
+)
+
+type SettingService interface {
+ GetTgLang() (string, error)
+}
+
+func InitLocalizer(i18nFS embed.FS, settingService SettingService) error {
+ // set default bundle to english
+ i18nBundle = i18n.NewBundle(language.English)
+ i18nBundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
+
+ // parse files
+ if err := parseTranslationFiles(i18nFS, i18nBundle); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func createTemplateData(params []string, seperator ...string) map[string]interface{} {
+ var sep string = "=="
+ if len(seperator) > 0 {
+ sep = seperator[0]
+ }
+
+ templateData := make(map[string]interface{})
+ for _, param := range params {
+ parts := strings.SplitN(param, sep, 2)
+ templateData[parts[0]] = parts[1]
+ }
+
+ return templateData
+}
+
+func I18n(i18nType I18nType, key string, params ...string) string {
+ var localizer *i18n.Localizer
+
+ switch i18nType {
+ case "bot":
+ localizer = LocalizerBot
+ case "web":
+ localizer = LocalizerWeb
+ default:
+ logger.Errorf("Invalid type for I18n: %s", i18nType)
+ return ""
+ }
+
+ templateData := createTemplateData(params)
+
+ msg, err := localizer.Localize(&i18n.LocalizeConfig{
+ MessageID: key,
+ TemplateData: templateData,
+ })
+
+ if err != nil {
+ logger.Errorf("Failed to localize message: %v", err)
+ return ""
+ }
+
+ return msg
+}
+
+func parseTranslationFiles(i18nFS embed.FS, i18nBundle *i18n.Bundle) error {
+ err := fs.WalkDir(i18nFS, "translation",
+ func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+
+ if d.IsDir() {
+ return nil
+ }
+
+ data, err := i18nFS.ReadFile(path)
+ if err != nil {
+ return err
+ }
+
+ _, err = i18nBundle.ParseMessageFileBytes(data, path)
+ return err
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
--
cgit v1.2.3
From 92eaff9608f924f7a78a7837daecec6cfb252b50 Mon Sep 17 00:00:00 2001
From: Hamidreza Ghavami <70919649+hamid-gh98@users.noreply.github.com>
Date: Sat, 20 May 2023 19:43:59 +0430
Subject: replace new localizer to web.go
---
web/web.go | 101 ++++++-------------------------------------------------------
1 file changed, 10 insertions(+), 91 deletions(-)
diff --git a/web/web.go b/web/web.go
index bd1c4721..afac077f 100644
--- a/web/web.go
+++ b/web/web.go
@@ -18,16 +18,14 @@ import (
"x-ui/util/common"
"x-ui/web/controller"
"x-ui/web/job"
+ "x-ui/web/locale"
"x-ui/web/network"
"x-ui/web/service"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
- "github.com/nicksnyder/go-i18n/v2/i18n"
- "github.com/pelletier/go-toml/v2"
"github.com/robfig/cron/v3"
- "golang.org/x/text/language"
)
//go:embed assets/*
@@ -202,13 +200,16 @@ func (s *Server) initRouter() (*gin.Engine, error) {
c.Header("Cache-Control", "max-age=31536000")
}
})
- err = s.initI18n(engine)
+
+ // init i18n
+ err = locale.InitLocalizer(i18nFS, &s.settingService)
if err != nil {
return nil, err
}
+ // set static files and template
if config.IsDebug() {
- // for develop
+ // for development
files, err := s.getHtmlFiles()
if err != nil {
return nil, err
@@ -216,12 +217,12 @@ func (s *Server) initRouter() (*gin.Engine, error) {
engine.LoadHTMLFiles(files...)
engine.StaticFS(basePath+"assets", http.FS(os.DirFS("web/assets")))
} else {
- // for prod
- t, err := s.getHtmlTemplate(engine.FuncMap)
+ // for production
+ template, err := s.getHtmlTemplate(engine.FuncMap)
if err != nil {
return nil, err
}
- engine.SetHTMLTemplate(t)
+ engine.SetHTMLTemplate(template)
engine.StaticFS(basePath+"assets", http.FS(&wrapAssetsFS{FS: assetsFS}))
}
@@ -239,87 +240,6 @@ func (s *Server) initRouter() (*gin.Engine, error) {
return engine, nil
}
-func (s *Server) initI18n(engine *gin.Engine) error {
- bundle := i18n.NewBundle(language.SimplifiedChinese)
- bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
- err := fs.WalkDir(i18nFS, "translation", func(path string, d fs.DirEntry, err error) error {
- if err != nil {
- return err
- }
- if d.IsDir() {
- return nil
- }
- data, err := i18nFS.ReadFile(path)
- if err != nil {
- return err
- }
- _, err = bundle.ParseMessageFileBytes(data, path)
- return err
- })
- if err != nil {
- return err
- }
-
- findI18nParamNames := func(key string) []string {
- names := make([]string, 0)
- keyLen := len(key)
- for i := 0; i < keyLen-1; i++ {
- if key[i:i+2] == "{{" { // 判断开头 "{{"
- j := i + 2
- isFind := false
- for ; j < keyLen-1; j++ {
- if key[j:j+2] == "}}" { // 结尾 "}}"
- isFind = true
- break
- }
- }
- if isFind {
- names = append(names, key[i+3:j])
- }
- }
- }
- return names
- }
-
- var localizer *i18n.Localizer
-
- I18n := func(key string, params ...string) (string, error) {
- names := findI18nParamNames(key)
- if len(names) != len(params) {
- return "", common.NewError("find names:", names, "---------- params:", params, "---------- num not equal")
- }
- templateData := map[string]interface{}{}
- for i := range names {
- templateData[names[i]] = params[i]
- }
- return localizer.Localize(&i18n.LocalizeConfig{
- MessageID: key,
- TemplateData: templateData,
- })
- }
-
- engine.FuncMap["i18n"] = I18n
-
- engine.Use(func(c *gin.Context) {
- //accept := c.GetHeader("Accept-Language")
-
- var lang string
-
- if cookie, err := c.Request.Cookie("lang"); err == nil {
- lang = cookie.Value
- } else {
- lang = c.GetHeader("Accept-Language")
- }
-
- localizer = i18n.NewLocalizer(bundle, lang)
- c.Set("localizer", localizer)
- c.Set("I18n", I18n)
- c.Next()
- })
-
- return nil
-}
-
func (s *Server) startTask() {
err := s.xrayService.RestartXray(true)
if err != nil {
@@ -346,7 +266,7 @@ func (s *Server) startTask() {
if (err == nil) && (isTgbotenabled) {
runtime, err := s.settingService.GetTgbotRuntime()
if err != nil || runtime == "" {
- logger.Errorf("Add NewStatsNotifyJob error[%s],Runtime[%s] invalid,wil run default", err, runtime)
+ logger.Errorf("Add NewStatsNotifyJob error[%s], Runtime[%s] invalid, will run default", err, runtime)
runtime = "@daily"
}
logger.Infof("Tg notify enabled,run at %s", runtime)
@@ -361,7 +281,6 @@ func (s *Server) startTask() {
if (err == nil) && (cpuThreshold > 0) {
s.cron.AddJob("@every 10s", job.NewCheckCpuJob())
}
-
} else {
s.cron.Remove(entry)
}
--
cgit v1.2.3
From 4865754b3d3d2d6a3296c8b07bb69a7f0bb0c489 Mon Sep 17 00:00:00 2001
Fro