diff --git a/control.go b/control.go index c079a67..726d8dc 100644 --- a/control.go +++ b/control.go @@ -3,6 +3,7 @@ package main import ( "errors" "fmt" + "github.com/chai2010/gettext-go" "github.com/spf13/viper" "github.com/tidwall/gjson" tb "gopkg.in/tucnak/telebot.v2" @@ -22,7 +23,7 @@ func BindUser(m *tb.Message, cid, cse string) error { tmp := strings.Split(m.Text, " ") if len(tmp) != 2 { logger.Printf("%d Bind error:Wrong Bind Format\n", m.Chat.ID) - return errors.New("绑定格式错误") + return errors.New(gettext.Gettext("bindFormatError")) } logger.Println("alias: " + tmp[1]) alias := tmp[1] @@ -35,7 +36,7 @@ func BindUser(m *tb.Message, cid, cse string) error { } //token has gotten - bot.Send(m.Chat, "Token获取成功!") + bot.Send(m.Chat, gettext.Gettext("getToken")) info, err := MSGetUserInfo(access) //fmt.Printf("TGID:%d Refresh Token: %s\n", m.Chat.ID, refresh) if err != nil { @@ -57,7 +58,7 @@ func BindUser(m *tb.Message, cid, cse string) error { //MS User Is Exist if MSAppIsExist(u.tgId, u.clientId) { logger.Printf("%d Bind error:MSUserHasExisted\n", m.Chat.ID) - return errors.New("该应用已经绑定过了,无需重复绑定") + return errors.New(gettext.Gettext("alreadyBind")) } //MS information has gotten bot.Send(m.Chat, "MS_ID(MD5): "+u.msId+"\nuserPrincipalName: "+gjson.Get(info, "userPrincipalName").String()+"\ndisplayName: "+gjson.Get(info, "displayName").String()+"\n") @@ -103,7 +104,7 @@ func SignTask() { fmt.Println("Start Sign") //签到任务 for _, u := range data { - pre := "您的账户: " + u.alias + "\n在任务执行时出现了错误!\n错误:" + pre := fmt.Sprintf(gettext.Gettext("taskError"), u.alias) chat, err := bot.ChatByID(strconv.FormatInt(u.tgId, 10)) if err != nil { logger.Println(err) @@ -111,7 +112,7 @@ func SignTask() { } //生成解绑按钮 var inlineKeys [][]tb.InlineButton - UnBindBtn := tb.InlineButton{Unique: "un" + u.msId, Text: "点击解绑该账户", Data: u.msId} + UnBindBtn := tb.InlineButton{Unique: "un" + u.msId, Text: gettext.Gettext("clickToUnBind"), Data: u.msId} bot.Handle(&UnBindBtn, bUnBindInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{UnBindBtn}) tmpBtn := &tb.ReplyMarkup{InlineKeyboard: inlineKeys} @@ -163,7 +164,7 @@ func SignTask() { logger.Println(err) } else { UnbindUser = append(UnbindUser, u.msId+" ( @"+chat.Username+" )") - _, err = bot.Send(chat, "您的账户因达到错误上限而被自动解绑\n后会有期!\n\n别名: "+u.alias+"\nclient_id: "+u.clientId+"\nclient_secret: "+u.clientSecret) + _, err = bot.Send(chat, gettext.Gettext("unBindByMaxLimit")+u.alias+"\nclient_id: "+u.clientId+"\nclient_secret: "+u.clientSecret) if err != nil { logger.Println(err) } @@ -172,7 +173,7 @@ func SignTask() { } if !isSend[u.tgId] { //静默发送,过多消息很烦 - _, err = bot.Send(chat, "任务反馈\n时间: "+time.Now().Format("2006-01-02 15:04:05")+"\n结果: "+strconv.Itoa(SignOk[u.tgId])+"/"+strconv.Itoa(GetBindNum(u.tgId)), &tb.SendOptions{DisableNotification: true}) + _, err = bot.Send(chat, gettext.Gettext("taskFeedback")+time.Now().Format("2006-01-02 15:04:05")+gettext.Gettext("result")+strconv.Itoa(SignOk[u.tgId])+"/"+strconv.Itoa(GetBindNum(u.tgId)), &tb.SendOptions{DisableNotification: true}) if err != nil { logger.Println(err) } @@ -190,7 +191,7 @@ func SignTask() { } for _, a := range admin { chat, _ := bot.ChatByID(strconv.FormatInt(a, 10)) - bot.Send(chat, "任务反馈(管理员)\n完成时间: "+time.Now().Format("2006-01-02 15:04:05")+"\n结果: "+strconv.Itoa(signOk)+"/"+strconv.Itoa(num)+"\n错误账户:\n"+ErrUserStr+"\n清退账户:\n"+UnbindUserStr) + bot.Send(chat, gettext.Gettext("taskFeedbackAdmin")+time.Now().Format("2006-01-02 15:04:05")+gettext.Gettext("result")+strconv.Itoa(signOk)+"/"+strconv.Itoa(num)+gettext.Gettext("wrongAccount")+ErrUserStr+gettext.Gettext("clearingAccount")+UnbindUserStr) } fmt.Println("----Task End----") } diff --git a/go.mod b/go.mod index badc22a..0db7f09 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,13 @@ module main go 1.13 require ( + github.com/chai2010/gettext-go v1.0.2 github.com/fsnotify/fsnotify v1.4.7 + github.com/mattn/go-sqlite3 v1.14.5 github.com/robfig/cron/v3 v3.0.0 github.com/spf13/viper v1.6.2 github.com/tidwall/gjson v1.6.0 github.com/tidwall/pretty v1.0.1 // indirect golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e gopkg.in/tucnak/telebot.v2 v2.0.0-20200328014118-dd123e949ee1 - github.com/mattn/go-sqlite3 v1.14.5 ) diff --git a/go.sum b/go.sum index 75745f7..51f6c5e 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= +github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -24,8 +26,6 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= diff --git a/handle.go b/handle.go index 2f59db0..727216f 100644 --- a/handle.go +++ b/handle.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "github.com/chai2010/gettext-go" "github.com/fsnotify/fsnotify" "github.com/spf13/viper" tb "gopkg.in/tucnak/telebot.v2" @@ -14,31 +15,20 @@ import ( ) const ( - bLogBasePath string = "./log/" - bStartContent string = "欢迎使用E5SubBot!" - bHelpContent string = ` - 命令: - /my 查看已绑定账户信息 - /bind 绑定新账户 - /unbind 解绑账户 - /export 导出账户信息(JSON格式) - /help 帮助 - /task 手动执行一次任务(管理员) - /log 获取最近日志文件(管理员) - 源代码:https://github.com/rainerosion/E5SubBot - 原作者:https://github.com/iyear/E5SubBot -` + bLogBasePath string = "./log/" ) var ( - UserStatus map[int64]int - UserCid map[int64]string - UserCSecret map[int64]string - ErrorTimes map[string]int //错误次数 - BindMaxNum int - ErrMaxTimes int - notice string - admin []int64 + UserStatus map[int64]int + UserCid map[int64]string + UserCSecret map[int64]string + ErrorTimes map[string]int //错误次数 + BindMaxNum int + ErrMaxTimes int + notice string + admin []int64 + bStartContent string + bHelpContent string ) const ( @@ -56,6 +46,16 @@ func init() { viper.SetDefault("errlimit", 5) viper.SetDefault("bindmax", 5) + viper.SetDefault("bindmax", 5) + viper.SetDefault("lang", "zh_CN") + + //set language + gettext.BindLocale(gettext.New("resources", "???", jsonData)) + lang := strings.Trim(viper.GetString("lang"), "") + gettext.SetLanguage(lang) + + bStartContent = gettext.Gettext("welcome") + bHelpContent = gettext.Gettext("helpContent") BindMaxNum = viper.GetInt("bindmax") ErrMaxTimes = viper.GetInt("errlimit") @@ -94,21 +94,21 @@ func bMy(m *tb.Message) { bot.Handle(&inlineBtn, bMyInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) } - bot.Send(m.Chat, "选择一个账户查看具体信息\n\n绑定数: "+strconv.Itoa(GetBindNum(m.Chat.ID))+"/"+strconv.Itoa(BindMaxNum), &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) + bot.Send(m.Chat, gettext.Gettext("chooseAnAccount")+strconv.Itoa(GetBindNum(m.Chat.ID))+"/"+strconv.Itoa(BindMaxNum), &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) } func bMyInlineBtn(c *tb.Callback) { logger.Println(strconv.FormatInt(c.Message.Chat.ID, 10) + " Get User Info") r := QueryDataByMS(c.Data) u := r[0] - bot.Send(c.Message.Chat, "信息\n别名:"+u.alias+"\nMS_ID(MD5): "+u.msId+"\nclient_id: "+u.clientId+"\nclient_secret: "+u.clientSecret+"\n最近更新时间: "+time.Unix(u.uptime, 0).Format("2006-01-02 15:04:05")) + bot.Send(c.Message.Chat, gettext.Gettext("accountInformation")+u.alias+"\nMS_ID(MD5): "+u.msId+"\nclient_id: "+u.clientId+"\nclient_secret: "+u.clientSecret+gettext.Gettext("updateTime")+time.Unix(u.uptime, 0).Format("2006-01-02 15:04:05")) bot.Respond(c) } func bBind1(m *tb.Message) { logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Bind") logger.Println("ReApp: " + strconv.FormatInt(m.Chat.ID, 10)) - bot.Send(m.Chat, "应用注册: [点击直达]("+MSGetReAppUrl()+")", tb.ModeMarkdown) - _, err := bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true}) + bot.Send(m.Chat, gettext.Gettext("register")+"("+MSGetReAppUrl()+")", tb.ModeMarkdown) + _, err := bot.Send(m.Chat, gettext.Gettext("bind1Reply"), &tb.ReplyMarkup{ForceReply: true}) if err != nil { logger.Println(err) return @@ -122,14 +122,14 @@ func bBind2(m *tb.Message) { tmp := strings.Split(m.Text, " ") if len(tmp) != 2 { logger.Printf("%d Bind error:Wrong Bind Format\n", m.Chat.ID) - bot.Send(m.Chat, "错误的格式") + bot.Send(m.Chat, gettext.Gettext("formatError")) return } logger.Println("client_id: " + tmp[0] + " client_secret: " + tmp[1]) cid := tmp[0] cse := tmp[1] - bot.Send(m.Chat, "授权账户: [点击直达]("+MSGetAuthUrl(cid)+")", tb.ModeMarkdown) - _, err := bot.Send(m.Chat, "请回复http://localhost/…… + 空格 + 别名(用于管理)", &tb.ReplyMarkup{ForceReply: true}) + bot.Send(m.Chat, gettext.Gettext("signIn")+"("+MSGetAuthUrl(cid)+")", tb.ModeMarkdown) + _, err := bot.Send(m.Chat, gettext.Gettext("bind2Reply"), &tb.ReplyMarkup{ForceReply: true}) if err != nil { logger.Println(err) return @@ -152,7 +152,7 @@ func bUnBind(m *tb.Message) { bot.Handle(&inlineBtn, bUnBindInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) } - bot.Send(m.Chat, "选择一个账户将其解绑\n\n当前绑定数: "+strconv.Itoa(GetBindNum(m.Chat.ID))+"/"+strconv.Itoa(BindMaxNum), &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) + bot.Send(m.Chat, gettext.Gettext("unBind")+strconv.Itoa(GetBindNum(m.Chat.ID))+"/"+strconv.Itoa(BindMaxNum), &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) } func bUnBindInlineBtn(c *tb.Callback) { logger.Println(strconv.FormatInt(c.Message.Chat.ID, 10) + " Unbind: " + c.Data) @@ -160,11 +160,11 @@ func bUnBindInlineBtn(c *tb.Callback) { u := r[0] if ok, _ := DelData(u.msId); !ok { logger.Println(u.msId + " UnBind ERROR") - bot.Send(c.Message.Chat, "解绑失败!") + bot.Send(c.Message.Chat, gettext.Gettext("unBindError")) return } logger.Println(u.msId + " UnBind Success") - bot.Send(c.Message.Chat, "解绑成功!") + bot.Send(c.Message.Chat, gettext.Gettext("unBindSuccess")) bot.Respond(c) } func bExport(m *tb.Message) { @@ -179,7 +179,7 @@ func bExport(m *tb.Message) { var MsMini []MsMiniData data := QueryDataByTG(m.Chat.ID) if len(data) == 0 { - bot.Send(m.Chat, "你还没有绑定过账户嗷~") + bot.Send(m.Chat, gettext.Gettext("unbound")) return } for _, u := range data { @@ -195,14 +195,14 @@ func bExport(m *tb.Message) { export, err := json.MarshalIndent(MsMini, "", "\t") if err != nil { logger.Println(err) - bot.Send(m.Chat, "获取JSON失败~\n"+err.Error()) + bot.Send(m.Chat, gettext.Gettext("json")+err.Error()) return } //fmt.Println(string(export)) fileName := "./" + strconv.FormatInt(m.Chat.ID, 10) + "_export_tmp.json" if err = ioutil.WriteFile(fileName, export, 0644); err != nil { logger.Println(err) - bot.Send(m.Chat, "写入临时文件失败~\n"+err.Error()) + bot.Send(m.Chat, gettext.Gettext("temporary")+err.Error()) return } exportFile := &tb.Document{File: tb.FromDisk(fileName), FileName: strconv.FormatInt(m.Chat.ID, 10) + ".json", MIME: "text/plain"} @@ -225,13 +225,13 @@ func bOnText(m *tb.Message) { switch UserStatus[m.Chat.ID] { case USNone: { - bot.Send(m.Chat, "发送/help获取帮助嗷") + bot.Send(m.Chat, gettext.Gettext("getHelp")) return } case USBind1: { if !m.IsReply() { - bot.Send(m.Chat, "请通过回复方式绑定") + bot.Send(m.Chat, gettext.Gettext("replyBind")) return } bBind2(m) @@ -239,19 +239,19 @@ func bOnText(m *tb.Message) { case USBind2: { if !m.IsReply() { - bot.Send(m.Chat, "请通过回复方式绑定") + bot.Send(m.Chat, gettext.Gettext("replyBind")) return } if GetBindNum(m.Chat.ID) == BindMaxNum { - bot.Send(m.Chat, "已经达到最大可绑定数") + bot.Send(m.Chat, gettext.Gettext("maximum")) return } - bot.Send(m.Chat, "正在绑定中……") + bot.Send(m.Chat, gettext.Gettext("binding")) err := BindUser(m, UserCid[m.Chat.ID], UserCSecret[m.Chat.ID]) if err != nil { bot.Send(m.Chat, err.Error()) } else { - bot.Send(m.Chat, "绑定成功!") + bot.Send(m.Chat, gettext.Gettext("bindSuccess")) } UserStatus[m.Chat.ID] = USNone } @@ -265,7 +265,7 @@ func bTask(m *tb.Message) { return } } - bot.Send(m.Chat, "您没有权限执行此操作~") + bot.Send(m.Chat, gettext.Gettext("noPermission")) } func bLog(m *tb.Message) { logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Get Logs") @@ -276,7 +276,7 @@ func bLog(m *tb.Message) { } } if flag == 0 { - bot.Send(m.Chat, "您没有权限执行此操作~") + bot.Send(m.Chat, gettext.Gettext("noPermission")) return } logs := GetRecentLogs(bLogBasePath, 5) @@ -290,7 +290,7 @@ func bLog(m *tb.Message) { bot.Handle(&inlineBtn, bLogsInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) } - _, err := bot.Send(m.Chat, "选择一个日志", &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) + _, err := bot.Send(m.Chat, gettext.Gettext("logs"), &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) if err != nil { logger.Println(err) } diff --git a/language.go b/language.go new file mode 100644 index 0000000..a2f6030 --- /dev/null +++ b/language.go @@ -0,0 +1,220 @@ +package main + +const jsonData = `{ + "zh_CN": { + "LC_MESSAGES": { + "resources.json": [{ + "msgid" : "helpContent", + "msgstr" : ["命令:\n/my 查看已绑定账户信息\n/bind 绑定新账户\n/unbind 解绑账户\n/export 导出账户信息(JSON格式)\n/help 帮助\n/task 手动执行一次任务(管理员)\n/log 获取最近日志文件(管理员)\n源代码:https://github.com/rainerosion/E5SubBot\n原作者:https://github.com/iyear/E5SubBot"] + },{ + "msgid" : "welcome", + "msgstr" : ["欢迎使用E5SubBot!"] + },{ + "msgid" : "chooseAnAccount", + "msgstr" : ["选择一个账户查看具体信息\n\n绑定数: "] + },{ + "msgid" : "accountInformation", + "msgstr" : ["信息\n别名"] + },{ + "msgid" : "updateTime", + "msgstr" : ["\n最近更新时间: "] + },{ + "msgid" : "register", + "msgstr" : ["应用注册: [点击直达]"] + },{ + "msgid" : "bind1Reply", + "msgstr" : ["请回复client_id+空格+client_secret"] + },{ + "msgid" : "formatError", + "msgstr" : ["错误的格式"] + },{ + "msgid" : "signIn", + "msgstr" : ["授权账户: [点击直达]"] + },{ + "msgid" : "bind2Reply", + "msgstr" : ["请回复http://localhost/…… + 空格 + 别名(用于管理)"] + },{ + "msgid" : "unBind", + "msgstr" : ["选择一个账户将其解绑\n\n当前绑定数: "] + },{ + "msgid" : "unBindError", + "msgstr" : ["解绑失败!"] + },{ + "msgid" : "unBindSuccess", + "msgstr" : ["解绑成功!"] + },{ + "msgid" : "unbound", + "msgstr" : ["你还没有绑定过账户嗷~"] + },{ + "msgid" : "json", + "msgstr" : ["获取JSON失败\n"] + },{ + "msgid" : "temporary", + "msgstr" : ["写入临时文件失败~\n"] + },{ + "msgid" : "getHelp", + "msgstr" : ["发送/help获取帮助嗷"] + },{ + "msgid" : "replyBind", + "msgstr" : ["请通过回复方式绑定"] + },{ + "msgid" : "maximum", + "msgstr" : ["已经达到最大可绑定数"] + },{ + "msgid" : "binding", + "msgstr" : ["正在绑定中……"] + },{ + "msgid" : "bindSuccess", + "msgstr" : ["绑定成功!"] + },{ + "msgid" : "logs", + "msgstr" : ["选择一个日志"] + },{ + "msgid" : "noPermission", + "msgstr" : ["您没有权限执行此操作~"] + },{ + "msgid" : "bindFormatError", + "msgstr" : ["绑定格式错误"] + },{ + "msgid" : "getToken", + "msgstr" : ["Token获取成功!"] + },{ + "msgid" : "alreadyBind", + "msgstr" : ["该应用已经绑定过了,无需重复绑定!"] + },{ + "msgid" : "taskError", + "msgstr" : ["您的账户: %s 在任务执行时出现了错误!\n错误:"] + },{ + "msgid" : "clickToUnBind", + "msgstr" : ["点击解绑该账户"] + },{ + "msgid" : "unBindByMaxLimit", + "msgstr" : ["您的账户因达到错误上限而被自动解绑\n后会有期!\n\n别名: "] + },{ + "msgid" : "taskFeedback", + "msgstr" : ["任务反馈\n时间: "] + },{ + "msgid" : "result", + "msgstr" : ["\n结果: "] + },{ + "msgid" : "taskFeedbackAdmin", + "msgstr" : ["任务反馈(管理员)\n完成时间: "] + },{ + "msgid" : "wrongAccount", + "msgstr" : ["\n错误账户:\n"] + },{ + "msgid" : "clearingAccount", + "msgstr" : ["\n清退账户:\n"] + } + ] + } + }, + "en_US": { + "LC_MESSAGES": { + "resources.json": [{ + "msgid" : "helpContent", + "msgstr" : ["/my View bound account information\n/bind Bind new account\n/unbind Unbind account\n/export Export account information (JSON format)\n/help help\n/task Manually execute a task (Bot Administrator)\n/log Get the most recent log file (Bot Administrator)\nSource Code:https://github.com/rainerosion/E5SubBot\nOriginal Author:https://github.com/iyear/E5SubBot"] + },{ + "msgid" : "welcome", + "msgstr" : ["Welcome to E5SubBot!"] + },{ + "msgid" : "chooseAnAccount", + "msgstr" : ["Select an account to view information.\n\nNumber of bindings: "] + },{ + "msgid" : "accountInformation", + "msgstr" : ["Account information\nAlias: "] + },{ + "msgid" : "updateTime", + "msgstr" : ["\nUpdate Time: "] + },{ + "msgid" : "register", + "msgstr" : ["Application registration: [Click here]"] + },{ + "msgid" : "bind1Reply", + "msgstr" : ["Please reply client_id+Space+client_secret"] + },{ + "msgid" : "formatError", + "msgstr" : ["Format error"] + },{ + "msgid" : "signIn", + "msgstr" : ["Login account [Click here]"] + },{ + "msgid" : "bind2Reply", + "msgstr" : ["Please reply http://localhost/…… + Space + Alias(for management)"] + },{ + "msgid" : "unBind", + "msgstr" : ["Select the account to be unbound.\n\nNumber of bindings: "] + },{ + "msgid" : "unBindError", + "msgstr" : ["Unbind failed!"] + },{ + "msgid" : "unBindSuccess", + "msgstr" : ["Successfully unbound!"] + },{ + "msgid" : "unbound", + "msgstr" : ["You haven't tied an account yet."] + },{ + "msgid" : "json", + "msgstr" : ["Failed to get json\n"] + },{ + "msgid" : "temporary", + "msgstr" : ["Write to temporary file failed.\n"] + },{ + "msgid" : "getHelp", + "msgstr" : ["Send /help for help"] + },{ + "msgid" : "replyBind", + "msgstr" : ["Please bind by reply."] + },{ + "msgid" : "maximum", + "msgstr" : ["The maximum number of bindings has been reached."] + },{ + "msgid" : "binding", + "msgstr" : ["Binding……"] + },{ + "msgid" : "bindSuccess", + "msgstr" : ["绑定成功!"] + },{ + "msgid" : "logs", + "msgstr" : ["Select a log."] + },{ + "msgid" : "noPermission", + "msgstr" : ["You do not have permission."] + },{ + "msgid" : "bindFormatError", + "msgstr" : ["Format error"] + },{ + "msgid" : "getToken", + "msgstr" : ["Token obtained successfully!"] + },{ + "msgid" : "alreadyBind", + "msgstr" : ["Account already exists!"] + },{ + "msgid" : "taskError", + "msgstr" : ["The account %s an error.\nError details:"] + },{ + "msgid" : "clickToUnBind", + "msgstr" : ["Click to unbundle this account"] + },{ + "msgid" : "unBindByMaxLimit", + "msgstr" : ["Your account has been automatically unbundled due to an error limit being reached\nAccount alias: "] + },{ + "msgid" : "taskFeedback", + "msgstr" : ["Task feedback\nTime: "] + },{ + "msgid" : "result", + "msgstr" : ["\nResult: "] + },{ + "msgid" : "taskFeedbackAdmin", + "msgstr" : ["Task feedback(administrator)\nExecution time: "] + },{ + "msgid" : "wrongAccount", + "msgstr" : ["\nWrong account:\n"] + },{ + "msgid" : "clearingAccount", + "msgstr" : ["\nClearing account:\n"] + } + ] + } + } + }`