From 5c670544a3fb69e681c4881bf2858730176dd088 Mon Sep 17 00:00:00 2001 From: iyear Date: Thu, 11 Mar 2021 12:57:30 +0800 Subject: [PATCH 01/29] Rewrite --- .gitignore | 3 +- bots/bots.go | 132 +++++++++++++++++++++++++ control.go => bots/control.go | 160 ++++++++++++++++--------------- handle.go => bots/handle.go | 56 ++++++----- mysql.go => db/mysql.go | 30 +++--- go.mod | 2 + go.sum | 16 ++++ logger/logger.go | 41 ++++++++ main.go | 132 +------------------------ outlook.go => outlook/outlook.go | 3 +- util.go => util/util.go | 2 +- 11 files changed, 325 insertions(+), 252 deletions(-) create mode 100644 bots/bots.go rename control.go => bots/control.go (52%) rename handle.go => bots/handle.go (86%) rename mysql.go => db/mysql.go (86%) create mode 100644 logger/logger.go rename outlook.go => outlook/outlook.go (99%) rename util.go => util/util.go (99%) diff --git a/.gitignore b/.gitignore index 93e5a6e..4cfd383 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,5 @@ config.yml #Goreleaser /dist #Logs -/log \ No newline at end of file +/log +/.idea \ No newline at end of file diff --git a/bots/bots.go b/bots/bots.go new file mode 100644 index 0000000..d9b9b39 --- /dev/null +++ b/bots/bots.go @@ -0,0 +1,132 @@ +package bots + +import ( + "database/sql" + "fmt" + "github.com/robfig/cron/v3" + "github.com/spf13/viper" + "golang.org/x/net/proxy" + tb "gopkg.in/tucnak/telebot.v2" + "main/logger" + "net/http" + "strconv" + "strings" + "time" +) + +var ( + BotToken string + Socks5 string + bot *tb.Bot + //logger *log.Logger +) + +const ( + dbDriverName = "mysql" + logo = ` + ______ _____ _____ _ ____ _ + | ____| ____/ ____| | | | _ \ | | + | |__ | |__| (___ _ _| |__ | |_) | ___ | |_ + | __| |___ \\___ \| | | | '_ \| _ < / _ \| __| + | |____ ___) |___) | |_| | |_) | |_) | (_) | |_ + |______|____/_____/ \__,_|_.__/|____/ \___/ \__| +` +) + +var dbPath string + +func BotStart() { + MakeHandle() + TaskLaunch() + logger.Println("Bot Start") + fmt.Println("------------") + bot.Start() +} +func MakeHandle() { + logger.Println("Make Handle……") + //所有用户 + bot.Handle("/start", bStart) + bot.Handle("/my", bMy) + bot.Handle("/bind", bBind1) + bot.Handle("/unbind", bUnBind) + bot.Handle("/export", bExport) + bot.Handle("/help", bHelp) + bot.Handle(tb.OnText, bOnText) + //管理员 + bot.Handle("/task", bTask) + bot.Handle("/log", bLog) +} +func TaskLaunch() { + task := cron.New() + //每三小时执行一次 + task.AddFunc(viper.GetString("cron"), SignTask) + //log分为每天 + //task.AddFunc(" 0 0 * * *", InitLogger) + // */1 * * * * 1 */3 * * * + logger.Println("Cron Task Start……") + task.Start() +} +func init() { + fmt.Println(logo) + + //read config + logger.Println("Read Config……") + viper.SetConfigName("config") + viper.AddConfigPath(".") + err := viper.ReadInConfig() + if err != nil { + logger.Println(err) + } + host := viper.GetString("mysql.host") + user := viper.GetString("mysql.user") + port := viper.GetString("mysql.port") + pwd := viper.GetString("mysql.password") + database := viper.GetString("mysql.database") + dbPath = strings.Join([]string{user, ":", pwd, "@tcp(", host, ":", port, ")/", database, "?charset=utf8"}, "") + //fmt.Println(path) + db, err := sql.Open(dbDriverName, dbPath) + if err != nil { + logger.Println(err) + } + logger.Println("Connect MySQL Success!") + if ok, err := CreateTB(); !ok { + logger.Println(err) + } + defer db.Close() + BotToken = viper.GetString("bot_token") + Socks5 = viper.GetString("socks5") + //set bot + logger.Println("Bot Settings……") + Poller := &tb.LongPoller{Timeout: 15 * time.Second} + spamProtected := tb.NewMiddlewarePoller(Poller, func(upd *tb.Update) bool { + if upd.Message == nil { + return true + } + if !upd.Message.Private() { + return false + } + return true + }) + botsettings := tb.Settings{ + Token: BotToken, + Poller: spamProtected, + } + //set socks5 + if Socks5 != "" { + logger.Println("Proxy:" + Socks5) + dialer, err := proxy.SOCKS5("tcp", Socks5, nil, proxy.Direct) + if err != nil { + logger.Println(err) + } + httpTransport := &http.Transport{} + httpClient := &http.Client{Transport: httpTransport} + httpTransport.Dial = dialer.Dial + botsettings.Client = httpClient + } + //create bot + bot, err = tb.NewBot(botsettings) + if err != nil { + logger.Println(err) + } + logger.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username) +} diff --git a/control.go b/bots/control.go similarity index 52% rename from control.go rename to bots/control.go index 2187998..b93e2f5 100644 --- a/control.go +++ b/bots/control.go @@ -1,4 +1,4 @@ -package main +package bots import ( "errors" @@ -6,9 +6,10 @@ import ( "github.com/spf13/viper" "github.com/tidwall/gjson" tb "gopkg.in/tucnak/telebot.v2" - "io" - "log" - "os" + "main/db" + "main/logger" + "main/outlook" + "main/util" "strconv" "strings" "time" @@ -18,69 +19,69 @@ var SignOk map[int64]int //If Successfully return "",else return error information func BindUser(m *tb.Message, cid, cse string) error { - logger.Printf("%d Begin Bind\n", m.Chat.ID) + logger.Println("%d Begin Bind\n", m.Chat.ID) tmp := strings.Split(m.Text, " ") if len(tmp) != 2 { - logger.Printf("%d Bind error:Wrong Bind Format\n", m.Chat.ID) + logger.Println("%d Bind error:Wrong Bind Format\n", m.Chat.ID) return errors.New("绑定格式错误") } - logger.Println("alias: " + tmp[1]) - alias := tmp[1] - code := GetURLValue(tmp[0], "code") + logger.Println("Alias: " + tmp[1]) + Alias := tmp[1] + code := util.GetURLValue(tmp[0], "code") //fmt.Println(code) - access, refresh, err := MSFirGetToken(code, cid, cse) + access, refresh, err := outlook.MSFirGetToken(code, cid, cse) if err != nil { - logger.Printf("%d Bind error:GetRefreshToken %s \n", m.Chat.ID, err.Error()) + logger.Println("%d Bind error:GetRefreshToken %s \n", m.Chat.ID, err.Error()) return err } //token has gotten bot.Send(m.Chat, "Token获取成功!") - info, err := MSGetUserInfo(access) - //fmt.Printf("TGID:%d Refresh Token: %s\n", m.Chat.ID, refresh) + info, err := outlook.MSGetUserInfo(access) + //fmt.Println("TgId:%d Refresh Token: %s\n", m.Chat.ID, refresh) if err != nil { - logger.Printf("%d Bind error:Getinfo %s \n", m.Chat.ID, err.Error()) + logger.Println("%d Bind error:Getinfo %s \n", m.Chat.ID, err.Error()) return err } - var u MSData - u.tgId = m.Chat.ID - u.refreshToken = refresh - //TG的Data传递最高64bytes,一些msid超过了报错BUTTON_DATA_INVALID (0),采取md5 - u.msId = Get16MD5Encode(gjson.Get(info, "id").String()) - u.uptime = time.Now().Unix() - logger.Println(u.uptime) - u.alias = alias - u.clientId = cid - u.clientSecret = cse - u.other = "" + var u db.MSData + u.TgId = m.Chat.ID + u.RefreshToken = refresh + //TG的Data传递最高64bytes,一些MsId超过了报错BUTTON_DATA_INVALID (0),采取md5 + u.MsId = util.Get16MD5Encode(gjson.Get(info, "id").String()) + u.Uptime = time.Now().Unix() + logger.Println(u.Uptime) + u.Alias = Alias + u.ClientId = cid + u.ClientSecret = cse + u.Other = "" //MS User Is Exist - if MSAppIsExist(u.tgId, u.clientId) { - logger.Printf("%d Bind error:MSUserHasExisted\n", m.Chat.ID) + if MSAppIsExist(u.TgId, u.ClientId) { + logger.Println("%d Bind error:MSUserHasExisted\n", m.Chat.ID) return errors.New("该应用已经绑定过了,无需重复绑定") } //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") - if ok, err := AddData(u); !ok { - logger.Printf("%d Bind error: %s\n", m.Chat.ID, err) + bot.Send(m.Chat, "MS_ID(MD5): "+u.MsId+"\nuserPrincipalName: "+gjson.Get(info, "userPrincipalName").String()+"\ndisplayName: "+gjson.Get(info, "displayName").String()+"\n") + if ok, err := db.AddData(u); !ok { + logger.Println("%d Bind error: %s\n", m.Chat.ID, err) return err } - logger.Printf("%d Bind Successfully!\n", m.Chat.ID) + logger.Println("%d Bind Successfully!\n", m.Chat.ID) return nil } //get bind num -func GetBindNum(tgId int64) int { - data := QueryDataByTG(tgId) +func GetBindNum(TgId int64) int { + data := db.QueryDataByTG(TgId) return len(data) } //return true => exist -func MSAppIsExist(tgId int64, clientId string) bool { - data := QueryDataByTG(tgId) - var res MSData +func MSAppIsExist(TgId int64, ClientId string) bool { + data := db.QueryDataByTG(TgId) + var res db.MSData for _, res = range data { - if res.clientId == clientId { + if res.ClientId == ClientId { return true } } @@ -98,52 +99,52 @@ func SignTask() { SignOk = make(map[int64]int) fmt.Println("----Task Begin----") fmt.Println("Time:" + time.Now().Format("2006-01-02 15:04:05")) - data := QueryDataAll() + data := db.QueryDataAll() num = len(data) fmt.Println("Start Sign") //签到任务 for _, u := range data { - pre := "您的账户: " + u.alias + "\n在任务执行时出现了错误!\n错误:" - chat, err := bot.ChatByID(strconv.FormatInt(u.tgId, 10)) + pre := "您的账户: " + u.Alias + "\n在任务执行时出现了错误!\n错误:" + chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10)) if err != nil { logger.Println(err) continue } //生成解绑按钮 var inlineKeys [][]tb.InlineButton - UnBindBtn := tb.InlineButton{Unique: "un" + u.msId, Text: "点击解绑该账户", Data: u.msId} + UnBindBtn := tb.InlineButton{Unique: "un" + u.MsId, Text: "点击解绑该账户", Data: u.MsId} bot.Handle(&UnBindBtn, bUnBindInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{UnBindBtn}) tmpBtn := &tb.ReplyMarkup{InlineKeyboard: inlineKeys} - se := u.msId + " ( @" + chat.Username + " )" - access, newRefreshToken, err := MSGetToken(u.refreshToken, u.clientId, u.clientSecret) + se := u.MsId + " ( @" + chat.Username + " )" + access, newRefreshToken, err := outlook.MSGetToken(u.RefreshToken, u.ClientId, u.ClientSecret) if err != nil { - logger.Println(u.msId+" ", err) + logger.Println(u.MsId+" ", err) bot.Send(chat, pre+gjson.Get(err.Error(), "error").String(), tmpBtn) SignErr = append(SignErr, se) - ErrorTimes[u.msId]++ + ErrorTimes[u.MsId]++ continue } - if ok, err := OutLookGetMails(access); !ok { - logger.Println(u.msId+" ", err) + if ok, err := outlook.OutLookGetMails(access); !ok { + logger.Println(u.MsId+" ", err) bot.Send(chat, pre+gjson.Get(err.Error(), "error").String(), tmpBtn) - ErrorTimes[u.msId]++ + ErrorTimes[u.MsId]++ SignErr = append(SignErr, se) continue } - u.uptime = time.Now().Unix() - u.refreshToken = newRefreshToken - if ok, err := UpdateData(u); !ok { - logger.Println(u.msId+" ", err) + u.Uptime = time.Now().Unix() + u.RefreshToken = newRefreshToken + if ok, err := db.UpdateData(u); !ok { + logger.Println(u.MsId+" ", err) bot.Send(chat, pre+err.Error(), tmpBtn) SignErr = append(SignErr, se) - ErrorTimes[u.msId]++ + ErrorTimes[u.MsId]++ continue } - fmt.Println(u.msId + " Sign OK!") - SignOk[u.tgId]++ + fmt.Println(u.MsId + " Sign OK!") + SignOk[u.TgId]++ signOk++ } fmt.Println("Sign End,Start Send") @@ -151,32 +152,32 @@ func SignTask() { isSend = make(map[int64]bool) //用户任务反馈 for _, u := range data { - chat, err := bot.ChatByID(strconv.FormatInt(u.tgId, 10)) + chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10)) if err != nil { logger.Println("Send Result ERROR: ", err) continue } //错误上限账户清退 - if ErrorTimes[u.msId] == ErrMaxTimes { - logger.Println(u.msId + " Error Limit") - if ok, err := DelData(u.msId); !ok { + if ErrorTimes[u.MsId] == ErrMaxTimes { + logger.Println(u.MsId + " Error Limit") + if ok, err := db.DelData(u.MsId); !ok { 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) + UnbindUser = append(UnbindUser, u.MsId+" ( @"+chat.Username+" )") + _, err = bot.Send(chat, "您的账户因达到错误上限而被自动解绑\n后会有期!\n\n别名: "+u.Alias+"\nclient_id: "+u.ClientId+"\nclient_secret: "+u.ClientSecret) if err != nil { logger.Println(err) } } } - if !isSend[u.tgId] { + 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, "任务反馈\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}) if err != nil { logger.Println(err) } - isSend[u.tgId] = true + isSend[u.TgId] = true } } //管理员任务反馈 @@ -207,19 +208,20 @@ func GetAdmin() []int64 { } return result } -func InitLogger() { - if !PathExists(bLogBasePath) { - os.Mkdir(bLogBasePath, 0773) - } - path := bLogBasePath + time.Now().Format("2006-01-02") + ".log" - f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0773) - if err != nil { - logger.Println(err) - } - writers := []io.Writer{ - f, - os.Stdout} - faoWriter := io.MultiWriter(writers...) - logger = log.New(faoWriter, "【E5Sub】", log.Ldate|log.Ltime|log.Lshortfile) -} +//func InitLogger() { +// if !util.PathExists(bLogBasePath) { +// os.Mkdir(bLogBasePath, 0773) +// } +// +// path := bLogBasePath + time.Now().Format("2006-01-02") + ".log" +// f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0773) +// if err != nil { +// logger.Println(err) +// } +// writers := []io.Writer{ +// f, +// os.Stdout} +// faoWriter := io.MultiWriter(writers...) +// //logger = log.New(faoWriter, "【E5Sub】", log.Ldate|log.Ltime|log.Lshortfile) +//} diff --git a/handle.go b/bots/handle.go similarity index 86% rename from handle.go rename to bots/handle.go index f8b111b..ba7c696 100644 --- a/handle.go +++ b/bots/handle.go @@ -1,4 +1,4 @@ -package main +package bots import ( "encoding/json" @@ -6,6 +6,10 @@ import ( "github.com/spf13/viper" tb "gopkg.in/tucnak/telebot.v2" "io/ioutil" + "main/db" + "main/logger" + "main/outlook" + "main/util" "os" "path/filepath" "strconv" @@ -51,7 +55,7 @@ func init() { viper.SetConfigName("config") viper.AddConfigPath(".") err := viper.ReadInConfig() - CheckErr(err) + util.CheckErr(err) viper.SetDefault("errlimit", 5) viper.SetDefault("bindmax", 5) @@ -82,13 +86,13 @@ func bStart(m *tb.Message) { func bMy(m *tb.Message) { logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Manager Users") - data := QueryDataByTG(m.Chat.ID) + data := db.QueryDataByTG(m.Chat.ID) var inlineKeys [][]tb.InlineButton for _, u := range data { inlineBtn := tb.InlineButton{ - Unique: "my" + u.msId, - Text: u.alias, - Data: u.msId, + Unique: "my" + u.MsId, + Text: u.Alias, + Data: u.MsId, } bot.Handle(&inlineBtn, bMyInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) @@ -97,16 +101,16 @@ func bMy(m *tb.Message) { } func bMyInlineBtn(c *tb.Callback) { logger.Println(strconv.FormatInt(c.Message.Chat.ID, 10) + " Get User Info") - r := QueryDataByMS(c.Data) + r := db.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, "信息\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.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) + bot.Send(m.Chat, "应用注册: [点击直达]("+outlook.MSGetReAppUrl()+")", tb.ModeMarkdown) _, err := bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true}) if err != nil { logger.Println(err) @@ -120,14 +124,14 @@ func bBind2(m *tb.Message) { logger.Println("Auth: " + strconv.FormatInt(m.Chat.ID, 10)) tmp := strings.Split(m.Text, " ") if len(tmp) != 2 { - logger.Printf("%d Bind error:Wrong Bind Format\n", m.Chat.ID) + logger.Println("%d Bind error:Wrong Bind Format\n", m.Chat.ID) bot.Send(m.Chat, "错误的格式") 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) + bot.Send(m.Chat, "授权账户: [点击直达]("+outlook.MSGetAuthUrl(cid)+")", tb.ModeMarkdown) _, err := bot.Send(m.Chat, "请回复http://localhost/…… + 空格 + 别名(用于管理)", &tb.ReplyMarkup{ForceReply: true}) if err != nil { logger.Println(err) @@ -140,13 +144,13 @@ func bBind2(m *tb.Message) { func bUnBind(m *tb.Message) { logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Unbind") - data := QueryDataByTG(m.Chat.ID) + data := db.QueryDataByTG(m.Chat.ID) var inlineKeys [][]tb.InlineButton for _, u := range data { inlineBtn := tb.InlineButton{ - Unique: "unbind" + u.msId, - Text: u.alias, - Data: u.msId, + Unique: "unbind" + u.MsId, + Text: u.Alias, + Data: u.MsId, } bot.Handle(&inlineBtn, bUnBindInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) @@ -155,14 +159,14 @@ func bUnBind(m *tb.Message) { } func bUnBindInlineBtn(c *tb.Callback) { logger.Println(strconv.FormatInt(c.Message.Chat.ID, 10) + " Unbind: " + c.Data) - r := QueryDataByMS(c.Data) + r := db.QueryDataByMS(c.Data) u := r[0] - if ok, _ := DelData(u.msId); !ok { - logger.Println(u.msId + " UnBind ERROR") + if ok, _ := db.DelData(u.MsId); !ok { + logger.Println(u.MsId + " UnBind ERROR") bot.Send(c.Message.Chat, "解绑失败!") return } - logger.Println(u.msId + " UnBind Success") + logger.Println(u.MsId + " UnBind Success") bot.Send(c.Message.Chat, "解绑成功!") bot.Respond(c) } @@ -176,18 +180,18 @@ func bExport(m *tb.Message) { Other string } var MsMini []MsMiniData - data := QueryDataByTG(m.Chat.ID) + data := db.QueryDataByTG(m.Chat.ID) if len(data) == 0 { bot.Send(m.Chat, "你还没有绑定过账户嗷~") return } for _, u := range data { var ms MsMiniData - ms.RefreshToken = u.refreshToken - ms.Alias = u.alias - ms.ClientId = u.clientId - ms.ClientSecret = u.clientSecret - ms.Other = u.other + ms.RefreshToken = u.RefreshToken + ms.Alias = u.Alias + ms.ClientId = u.ClientId + ms.ClientSecret = u.ClientSecret + ms.Other = u.Other MsMini = append(MsMini, ms) } //MarshalIndent是为json+美化,/t表缩进 @@ -278,7 +282,7 @@ func bLog(m *tb.Message) { bot.Send(m.Chat, "您没有权限执行此操作~") return } - logs := GetRecentLogs(bLogBasePath, 5) + logs := util.GetRecentLogs(bLogBasePath, 5) var inlineKeys [][]tb.InlineButton for _, log := range logs { inlineBtn := tb.InlineButton{ diff --git a/mysql.go b/db/mysql.go similarity index 86% rename from mysql.go rename to db/mysql.go index af0f152..b2c5cef 100644 --- a/mysql.go +++ b/db/mysql.go @@ -1,19 +1,21 @@ -package main +package db import ( "database/sql" _ "github.com/go-sql-driver/mysql" + "main/logger" + "main/util" ) type MSData struct { - tgId int64 - refreshToken string - msId string - uptime int64 - alias string - clientId string - clientSecret string - other string + TgId int64 + RefreshToken string + MsId string + Uptime int64 + Alias string + ClientId string + ClientSecret string + Other string } //update data by msId @@ -28,7 +30,7 @@ func UpdateData(u MSData) (bool, error) { if err != nil { return false, err } - _, err = stmt.Exec(u.tgId, u.refreshToken, u.uptime, u.alias, u.clientId, u.clientSecret, u.other, u.msId) + _, err = stmt.Exec(u.TgId, u.RefreshToken, u.Uptime, u.Alias, u.ClientId, u.ClientSecret, u.Other, u.MsId) if err != nil { return false, err } @@ -49,7 +51,7 @@ func AddData(u MSData) (bool, error) { if err != nil { return false, err } - _, err = stmt.Exec(u.tgId, u.refreshToken, u.msId, u.uptime, u.alias, u.clientId, u.clientSecret, u.other) + _, err = stmt.Exec(u.TgId, u.RefreshToken, u.MsId, u.Uptime, u.Alias, u.ClientId, u.ClientSecret, u.Other) if err != nil { return false, err } @@ -100,7 +102,7 @@ func QueryDataByMS(msId string) []MSData { } defer db.Close() rows, err := db.Query("select * from users where ms_id = ?", msId) - CheckErr(err) + util.CheckErr(err) return QueryData(rows) } @@ -111,7 +113,7 @@ func QueryDataAll() []MSData { } defer db.Close() rows, err := db.Query("select * from users ") - CheckErr(err) + util.CheckErr(err) return QueryData(rows) } @@ -123,7 +125,7 @@ func QueryDataByTG(tgId int64) []MSData { } defer db.Close() rows, err := db.Query("select * from users where tg_id = ?", tgId) - CheckErr(err) + util.CheckErr(err) return QueryData(rows) } func CreateTB() (bool, error) { diff --git a/go.mod b/go.mod index 772d1bd..b9d45ad 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,8 @@ require ( github.com/spf13/viper v1.6.2 github.com/tidwall/gjson v1.6.0 github.com/tidwall/pretty v1.0.1 // indirect + go.uber.org/zap v1.10.0 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e + gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/tucnak/telebot.v2 v2.0.0-20200328014118-dd123e949ee1 ) diff --git a/go.sum b/go.sum index c334d46..ff6aebd 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,7 @@ github.com/Azure/azure-sdk-for-go v30.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0= github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= github.com/Azure/go-autorest v12.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo= @@ -63,6 +64,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -119,6 +121,7 @@ github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs167 github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/goreleaser/goreleaser v0.129.0 h1:hJHsgxxNck3oe/MU4K+yznH2qgAVGNcxARTRP8ODSRk= github.com/goreleaser/goreleaser v0.129.0/go.mod h1:tzHV+xcU9AJMYNby0QS0lHm1DRrTCBkJXW9ic2reepY= @@ -148,6 +151,7 @@ github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqx github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kamilsk/retry/v4 v4.7.2 h1:8C33aqTQtTSvPf7MpLZ4xSY4JZK2YCvY+hTlsbiHNq8= @@ -156,8 +160,10 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= @@ -197,6 +203,7 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= @@ -216,9 +223,11 @@ github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -236,6 +245,7 @@ github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfD github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -270,8 +280,11 @@ go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= gocloud.dev v0.19.0 h1:EDRyaRAnMGSq/QBto486gWFxMLczAfIYUmusV7XLNBM= gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI= @@ -393,11 +406,14 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tucnak/telebot.v2 v2.0.0-20200301001213-9852df39ae6c h1:+7l/yyky9hchNME0hDMl+cA+wVlHQGte/5EwKHeSqoc= diff --git a/logger/logger.go b/logger/logger.go new file mode 100644 index 0000000..dfe5543 --- /dev/null +++ b/logger/logger.go @@ -0,0 +1,41 @@ +package logger + +import ( + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "gopkg.in/natefinch/lumberjack.v2" + "os" +) + +func Println(a ...interface{}) { + return +} + +// 日志切割设置 +func getLogWriter() zapcore.WriteSyncer { + lumberJackLogger := &lumberjack.Logger{ + Filename: "./log/latest.log", // 日志文件位置 + MaxSize: 1, // 日志文件最大大小(MB) + MaxBackups: 5, // 保留旧文件最大数量 + MaxAge: 30, // 保留旧文件最长天数 + Compress: true, // 是否压缩旧文件 + } + return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(lumberJackLogger)) +} + +// 编码器 +func getEncoder() zapcore.Encoder { + // 使用默认的JSON编码 + encoderConfig := zap.NewDevelopmentEncoderConfig() + encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder + return zapcore.NewJSONEncoder(encoderConfig) +} + +// InitLogger 初始化Logger +func InitLogger() { + writeSyncer := getLogWriter() + encoder := getEncoder() + core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel) + zap.ReplaceGlobals(zap.New(core, zap.AddCaller())) +} diff --git a/main.go b/main.go index f8da15c..82e01da 100644 --- a/main.go +++ b/main.go @@ -1,135 +1,7 @@ package main -import ( - "database/sql" - "fmt" - "github.com/robfig/cron/v3" - "github.com/spf13/viper" - "golang.org/x/net/proxy" - tb "gopkg.in/tucnak/telebot.v2" - "log" - "net/http" - "strconv" - "strings" - "time" -) - -var ( - BotToken string - Socks5 string - bot *tb.Bot - logger *log.Logger -) - -const ( - dbDriverName = "mysql" - logo = ` - ______ _____ _____ _ ____ _ - | ____| ____/ ____| | | | _ \ | | - | |__ | |__| (___ _ _| |__ | |_) | ___ | |_ - | __| |___ \\___ \| | | | '_ \| _ < / _ \| __| - | |____ ___) |___) | |_| | |_) | |_) | (_) | |_ - |______|____/_____/ \__,_|_.__/|____/ \___/ \__| -` -) - -var dbPath string +import "main/bots" func main() { - BotStart() -} -func BotStart() { - MakeHandle() - TaskLaunch() - logger.Println("Bot Start") - fmt.Println("------------") - bot.Start() -} -func MakeHandle() { - logger.Println("Make Handle……") - //所有用户 - bot.Handle("/start", bStart) - bot.Handle("/my", bMy) - bot.Handle("/bind", bBind1) - bot.Handle("/unbind", bUnBind) - bot.Handle("/export", bExport) - bot.Handle("/help", bHelp) - bot.Handle(tb.OnText, bOnText) - //管理员 - bot.Handle("/task", bTask) - bot.Handle("/log", bLog) -} -func TaskLaunch() { - task := cron.New() - //每三小时执行一次 - task.AddFunc(viper.GetString("cron"), SignTask) - //log分为每天 - task.AddFunc(" 0 0 * * *", InitLogger) - // */1 * * * * 1 */3 * * * - logger.Println("Cron Task Start……") - task.Start() -} -func init() { - fmt.Println(logo) - InitLogger() - //read config - logger.Println("Read Config……") - viper.SetConfigName("config") - viper.AddConfigPath(".") - err := viper.ReadInConfig() - if err != nil { - logger.Fatal(err) - } - host := viper.GetString("mysql.host") - user := viper.GetString("mysql.user") - port := viper.GetString("mysql.port") - pwd := viper.GetString("mysql.password") - database := viper.GetString("mysql.database") - dbPath = strings.Join([]string{user, ":", pwd, "@tcp(", host, ":", port, ")/", database, "?charset=utf8"}, "") - //fmt.Println(path) - db, err := sql.Open(dbDriverName, dbPath) - if err != nil { - logger.Fatal(err) - } - logger.Println("Connect MySQL Success!") - if ok, err := CreateTB(); !ok { - logger.Fatal(err) - } - defer db.Close() - BotToken = viper.GetString("bot_token") - Socks5 = viper.GetString("socks5") - //set bot - logger.Println("Bot Settings……") - Poller := &tb.LongPoller{Timeout: 15 * time.Second} - spamProtected := tb.NewMiddlewarePoller(Poller, func(upd *tb.Update) bool { - if upd.Message == nil { - return true - } - if !upd.Message.Private() { - return false - } - return true - }) - botsettings := tb.Settings{ - Token: BotToken, - Poller: spamProtected, - } - //set socks5 - if Socks5 != "" { - logger.Println("Proxy:" + Socks5) - dialer, err := proxy.SOCKS5("tcp", Socks5, nil, proxy.Direct) - if err != nil { - logger.Println(err) - } - httpTransport := &http.Transport{} - httpClient := &http.Client{Transport: httpTransport} - httpTransport.Dial = dialer.Dial - botsettings.Client = httpClient - } - //create bot - bot, err = tb.NewBot(botsettings) - if err != nil { - logger.Fatal(err) - } - logger.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username) + bots.BotStart() } diff --git a/outlook.go b/outlook/outlook.go similarity index 99% rename from outlook.go rename to outlook/outlook.go index 02e8703..521e7ea 100644 --- a/outlook.go +++ b/outlook/outlook.go @@ -1,9 +1,10 @@ -package main +package outlook import ( "errors" "github.com/tidwall/gjson" "io/ioutil" + "main/logger" "net/http" "net/url" "strings" diff --git a/util.go b/util/util.go similarity index 99% rename from util.go rename to util/util.go index 52b0e2e..be3aa34 100644 --- a/util.go +++ b/util/util.go @@ -1,4 +1,4 @@ -package main +package util import ( "crypto/md5" From 90248dc9468e65f5fa747557e2bfe82035569443 Mon Sep 17 00:00:00 2001 From: iyear Date: Fri, 12 Mar 2021 12:54:32 +0800 Subject: [PATCH 02/29] Refactor --- bots/control.go | 26 ++--- bots/handle.go | 18 +-- core/client.go | 12 ++ {db => core}/mysql.go | 57 +++++---- go.mod | 1 + go.sum | 262 +----------------------------------------- outlook/outlook.go | 51 ++++---- 7 files changed, 104 insertions(+), 323 deletions(-) create mode 100644 core/client.go rename {db => core}/mysql.go (69%) diff --git a/bots/control.go b/bots/control.go index b93e2f5..578bb2d 100644 --- a/bots/control.go +++ b/bots/control.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/viper" "github.com/tidwall/gjson" tb "gopkg.in/tucnak/telebot.v2" - "main/db" + "main/core" "main/logger" "main/outlook" "main/util" @@ -29,7 +29,7 @@ func BindUser(m *tb.Message, cid, cse string) error { Alias := tmp[1] code := util.GetURLValue(tmp[0], "code") //fmt.Println(code) - access, refresh, err := outlook.MSFirGetToken(code, cid, cse) + access, refresh, err := MSFirGetToken(code, cid, cse) if err != nil { logger.Println("%d Bind error:GetRefreshToken %s \n", m.Chat.ID, err.Error()) return err @@ -37,14 +37,14 @@ func BindUser(m *tb.Message, cid, cse string) error { //token has gotten bot.Send(m.Chat, "Token获取成功!") - info, err := outlook.MSGetUserInfo(access) + info, err := outlook.GetUserInfo(access) //fmt.Println("TgId:%d Refresh Token: %s\n", m.Chat.ID, refresh) if err != nil { logger.Println("%d Bind error:Getinfo %s \n", m.Chat.ID, err.Error()) return err } - var u db.MSData + var u core.Client u.TgId = m.Chat.ID u.RefreshToken = refresh //TG的Data传递最高64bytes,一些MsId超过了报错BUTTON_DATA_INVALID (0),采取md5 @@ -62,7 +62,7 @@ func BindUser(m *tb.Message, cid, cse string) error { } //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") - if ok, err := db.AddData(u); !ok { + if ok, err := core.AddData(u); !ok { logger.Println("%d Bind error: %s\n", m.Chat.ID, err) return err } @@ -72,14 +72,14 @@ func BindUser(m *tb.Message, cid, cse string) error { //get bind num func GetBindNum(TgId int64) int { - data := db.QueryDataByTG(TgId) + data := core.QueryDataByTG(TgId) return len(data) } //return true => exist func MSAppIsExist(TgId int64, ClientId string) bool { - data := db.QueryDataByTG(TgId) - var res db.MSData + data := core.QueryDataByTG(TgId) + var res core.Client for _, res = range data { if res.ClientId == ClientId { return true @@ -99,7 +99,7 @@ func SignTask() { SignOk = make(map[int64]int) fmt.Println("----Task Begin----") fmt.Println("Time:" + time.Now().Format("2006-01-02 15:04:05")) - data := db.QueryDataAll() + data := core.QueryDataAll() num = len(data) fmt.Println("Start Sign") //签到任务 @@ -118,7 +118,7 @@ func SignTask() { tmpBtn := &tb.ReplyMarkup{InlineKeyboard: inlineKeys} se := u.MsId + " ( @" + chat.Username + " )" - access, newRefreshToken, err := outlook.MSGetToken(u.RefreshToken, u.ClientId, u.ClientSecret) + access, newRefreshToken, err := outlook.GetToken(u.RefreshToken, u.ClientId, u.ClientSecret) if err != nil { logger.Println(u.MsId+" ", err) @@ -127,7 +127,7 @@ func SignTask() { ErrorTimes[u.MsId]++ continue } - if ok, err := outlook.OutLookGetMails(access); !ok { + if ok, err := outlook.GetOutLookMails(access); !ok { logger.Println(u.MsId+" ", err) bot.Send(chat, pre+gjson.Get(err.Error(), "error").String(), tmpBtn) ErrorTimes[u.MsId]++ @@ -136,7 +136,7 @@ func SignTask() { } u.Uptime = time.Now().Unix() u.RefreshToken = newRefreshToken - if ok, err := db.UpdateData(u); !ok { + if ok, err := core.UpdateData(u); !ok { logger.Println(u.MsId+" ", err) bot.Send(chat, pre+err.Error(), tmpBtn) SignErr = append(SignErr, se) @@ -160,7 +160,7 @@ func SignTask() { //错误上限账户清退 if ErrorTimes[u.MsId] == ErrMaxTimes { logger.Println(u.MsId + " Error Limit") - if ok, err := db.DelData(u.MsId); !ok { + if ok, err := core.DelData(u.MsId); !ok { logger.Println(err) } else { UnbindUser = append(UnbindUser, u.MsId+" ( @"+chat.Username+" )") diff --git a/bots/handle.go b/bots/handle.go index ba7c696..1dab746 100644 --- a/bots/handle.go +++ b/bots/handle.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/viper" tb "gopkg.in/tucnak/telebot.v2" "io/ioutil" - "main/db" + "main/core" "main/logger" "main/outlook" "main/util" @@ -86,7 +86,7 @@ func bStart(m *tb.Message) { func bMy(m *tb.Message) { logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Manager Users") - data := db.QueryDataByTG(m.Chat.ID) + data := core.QueryDataByTG(m.Chat.ID) var inlineKeys [][]tb.InlineButton for _, u := range data { inlineBtn := tb.InlineButton{ @@ -101,7 +101,7 @@ func bMy(m *tb.Message) { } func bMyInlineBtn(c *tb.Callback) { logger.Println(strconv.FormatInt(c.Message.Chat.ID, 10) + " Get User Info") - r := db.QueryDataByMS(c.Data) + r := core.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.Respond(c) @@ -110,7 +110,7 @@ func bMyInlineBtn(c *tb.Callback) { 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, "应用注册: [点击直达]("+outlook.MSGetReAppUrl()+")", tb.ModeMarkdown) + bot.Send(m.Chat, "应用注册: [点击直达]("+outlook.GetMSRegisterAppUrl()+")", tb.ModeMarkdown) _, err := bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true}) if err != nil { logger.Println(err) @@ -131,7 +131,7 @@ func bBind2(m *tb.Message) { logger.Println("client_id: " + tmp[0] + " client_secret: " + tmp[1]) cid := tmp[0] cse := tmp[1] - bot.Send(m.Chat, "授权账户: [点击直达]("+outlook.MSGetAuthUrl(cid)+")", tb.ModeMarkdown) + bot.Send(m.Chat, "授权账户: [点击直达]("+outlook.GetMSAuthUrl(cid)+")", tb.ModeMarkdown) _, err := bot.Send(m.Chat, "请回复http://localhost/…… + 空格 + 别名(用于管理)", &tb.ReplyMarkup{ForceReply: true}) if err != nil { logger.Println(err) @@ -144,7 +144,7 @@ func bBind2(m *tb.Message) { func bUnBind(m *tb.Message) { logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Unbind") - data := db.QueryDataByTG(m.Chat.ID) + data := core.QueryDataByTG(m.Chat.ID) var inlineKeys [][]tb.InlineButton for _, u := range data { inlineBtn := tb.InlineButton{ @@ -159,9 +159,9 @@ func bUnBind(m *tb.Message) { } func bUnBindInlineBtn(c *tb.Callback) { logger.Println(strconv.FormatInt(c.Message.Chat.ID, 10) + " Unbind: " + c.Data) - r := db.QueryDataByMS(c.Data) + r := core.QueryDataByMS(c.Data) u := r[0] - if ok, _ := db.DelData(u.MsId); !ok { + if ok, _ := core.DelData(u.MsId); !ok { logger.Println(u.MsId + " UnBind ERROR") bot.Send(c.Message.Chat, "解绑失败!") return @@ -180,7 +180,7 @@ func bExport(m *tb.Message) { Other string } var MsMini []MsMiniData - data := db.QueryDataByTG(m.Chat.ID) + data := core.QueryDataByTG(m.Chat.ID) if len(data) == 0 { bot.Send(m.Chat, "你还没有绑定过账户嗷~") return diff --git a/core/client.go b/core/client.go new file mode 100644 index 0000000..ce30af8 --- /dev/null +++ b/core/client.go @@ -0,0 +1,12 @@ +package core + +type Client struct { + TgId int64 `gorm:"column:tg_id"` + RefreshToken string `gorm:"column:refresh_token"` + MsId string `gorm:"column:ms_id"` + Uptime int64 `gorm:"column:uptime"` + Alias string `gorm:"column:alias"` + ClientId string `gorm:"column:client_id"` + ClientSecret string `gorm:"column:client_secret"` + Other string `gorm:"column:other"` +} diff --git a/db/mysql.go b/core/mysql.go similarity index 69% rename from db/mysql.go rename to core/mysql.go index b2c5cef..bf637ee 100644 --- a/db/mysql.go +++ b/core/mysql.go @@ -1,31 +1,38 @@ -package db +package core import ( "database/sql" _ "github.com/go-sql-driver/mysql" + "gorm.io/gorm" "main/logger" + "main/outlook" "main/util" + "time" ) -type MSData struct { - TgId int64 - RefreshToken string - MsId string - Uptime int64 - Alias string - ClientId string - ClientSecret string - Other string +var db *gorm.DB + +func InitDB() error { + var err error + db, err = gorm.Open("11", &gorm.Config{ + NowFunc: func() time.Time { + return time.Now().UTC() + }, + }) + if err != nil { + return err + } + return nil } //update data by msId -func UpdateData(u MSData) (bool, error) { +func UpdateData(u Client) (bool, error) { db, err := sql.Open(dbDriverName, dbPath) if err != nil { logger.Println(err) } defer db.Close() - sqlString := `UPDATE users set tg_id=?,refresh_token=?,uptime=?,alias=?,client_id=?,client_secret=?,other=? where ms_id=?` + sqlString := `UPDATE Clients set tg_id=?,refresh_token=?,uptime=?,alias=?,client_id=?,client_secret=?,other=? where ms_id=?` stmt, err := db.Prepare(sqlString) if err != nil { return false, err @@ -38,14 +45,14 @@ func UpdateData(u MSData) (bool, error) { } //add data -func AddData(u MSData) (bool, error) { +func AddData(u Client) (bool, error) { db, err := sql.Open(dbDriverName, dbPath) if err != nil { logger.Println(err) } defer db.Close() sqlString := ` - INSERT INTO users (tg_id, refresh_token,ms_id, uptime,alias,client_id,client_secret,other) + INSERT INTO Clients (tg_id, refresh_token,ms_id, uptime,alias,client_id,client_secret,other) VALUES (?,?,?,?,?,?,?,?)` stmt, err := db.Prepare(sqlString) if err != nil { @@ -65,7 +72,7 @@ func DelData(msId string) (bool, error) { logger.Println(err) } defer db.Close() - sqlString := `delete from users where ms_id=?` + sqlString := `delete from Clients where ms_id=?` stmt, err := db.Prepare(sqlString) if err != nil { return false, err @@ -80,9 +87,9 @@ func DelData(msId string) (bool, error) { } return true, nil } -func QueryData(rows *sql.Rows) []MSData { +func QueryData(rows *sql.Rows) []Client { - var result = make([]MSData, 0) + var result = make([]Client, 0) defer rows.Close() for rows.Next() { var ( @@ -91,40 +98,40 @@ func QueryData(rows *sql.Rows) []MSData { ) rows.Scan(&tgIdt, &refresht, &msidt, &uptimet, &aliast, &clientIdt, &clientSet, &othert) //fmt.Println(string(tgNamet) + "=>" + uptimet.Format("2006-01-02 15:04:05")) - result = append(result, MSData{tgIdt, refresht, msidt, uptimet, aliast, clientIdt, clientSet, othert}) + result = append(result, Client{tgIdt, refresht, msidt, uptimet, aliast, clientIdt, clientSet, othert}) } return result } -func QueryDataByMS(msId string) []MSData { +func QueryDataByMS(msId string) []Client { db, err := sql.Open(dbDriverName, dbPath) if err != nil { logger.Println(err) } defer db.Close() - rows, err := db.Query("select * from users where ms_id = ?", msId) + rows, err := db.Query("select * from Clients where ms_id = ?", msId) util.CheckErr(err) return QueryData(rows) } -func QueryDataAll() []MSData { +func QueryDataAll() []Client { db, err := sql.Open(dbDriverName, dbPath) if err != nil { logger.Println(err) } defer db.Close() - rows, err := db.Query("select * from users ") + rows, err := db.Query("select * from Clients ") util.CheckErr(err) return QueryData(rows) } //query data by tg_id -func QueryDataByTG(tgId int64) []MSData { +func QueryDataByTG(tgId int64) []Client { db, err := sql.Open(dbDriverName, dbPath) if err != nil { logger.Println(err) } defer db.Close() - rows, err := db.Query("select * from users where tg_id = ?", tgId) + rows, err := db.Query("select * from Clients where tg_id = ?", tgId) util.CheckErr(err) return QueryData(rows) } @@ -135,7 +142,7 @@ func CreateTB() (bool, error) { } defer db.Close() sqltable := ` - create table if not exists users + create table if not exists Clients ( tg_id INTEGER, refresh_token TEXT, diff --git a/go.mod b/go.mod index b9d45ad..3e87cd1 100644 --- a/go.mod +++ b/go.mod @@ -13,4 +13,5 @@ require ( golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/tucnak/telebot.v2 v2.0.0-20200328014118-dd123e949ee1 + gorm.io/gorm v1.21.3 ) diff --git a/go.sum b/go.sum index ff6aebd..6ddb00c 100644 --- a/go.sum +++ b/go.sum @@ -1,61 +1,12 @@ -bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -code.gitea.io/sdk/gitea v0.0.0-20200128061546-ea2b5af37297 h1:2jEu+HD5Hk87b8HiztAoTo+bSkerjFik3mU5z8sJycg= -code.gitea.io/sdk/gitea v0.0.0-20200128061546-ea2b5af37297/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY= -contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= -contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0= -contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw= -contrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= -contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA= -github.com/Azure/azure-amqp-common-go/v2 v2.1.0/go.mod h1:R8rea+gJRuJR6QxTir/XuEd+YuKoUiazDC/N96FiDEU= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-sdk-for-go v29.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v30.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0= -github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= -github.com/Azure/go-autorest v12.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo= -github.com/Masterminds/semver/v3 v3.0.3 h1:znjIyLfpXEDQjOIEWh+ehwpTU14UzUPub3c3sm36u14= -github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/apex/log v1.1.1 h1:BwhRZ0qbjYtTob0I+2M+smavV0kOC8XgcnGZcyL9liA= -github.com/apex/log v1.1.1/go.mod h1:Ls949n1HFtXfbDcjiTTFQqkVUrte0puoIBfO3SVgwOA= -github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= -github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.19.45/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.25.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= 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/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= -github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= -github.com/caarlos0/ctrlc v1.0.0 h1:2DtF8GSIcajgffDFJzyG15vO+1PuBWOMUdFut7NnXhw= -github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw= -github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e h1:V9a67dfYqPLAvzk5hMQOXYJlZ4SLIXgyKIE+ZiHzgGQ= -github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo= -github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e h1:hHg27A0RSSp2Om9lubZpiMgVbvn39bsUmW9U5h0twqc= -github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= -github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -63,26 +14,16 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= 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.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 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= @@ -90,72 +31,27 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo= -github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= -github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0 h1:BW6OvS3kpT5UEPbCZ+KyX/OB4Ks9/MNMhWjqPPkZxsE= -github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg= -github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs16741s= -github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/goreleaser/goreleaser v0.129.0 h1:hJHsgxxNck3oe/MU4K+yznH2qgAVGNcxARTRP8ODSRk= -github.com/goreleaser/goreleaser v0.129.0/go.mod h1:tzHV+xcU9AJMYNby0QS0lHm1DRrTCBkJXW9ic2reepY= -github.com/goreleaser/nfpm v1.2.1 h1:AEnu9XVmupRDTR930Z2rAs31Mj6sLIPxFcR9ESYvgDA= -github.com/goreleaser/nfpm v1.2.1/go.mod h1:TtWrABZozuLOttX2uDlYyECfQX7x5XYkVxhjYcR6G9w= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.2/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8= -github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= -github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/jarcoal/httpmock v1.0.4/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E= +github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kamilsk/retry/v4 v4.7.2 h1:8C33aqTQtTSvPf7MpLZ4xSY4JZK2YCvY+hTlsbiHNq8= -github.com/kamilsk/retry/v4 v4.7.2/go.mod h1:pIQtBtycHTXScrJmpu3N2SSBT07s07Uruq2Au1aRLks= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -165,44 +61,18 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= -github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-zglob v0.0.1 h1:xsEx/XUoVlI6yXjqBK062zYhRTZltCNmYPx6v+8DNaY= -github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI= -github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4= -github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -214,22 +84,14 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= -github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E= github.com/robfig/cron/v3 v3.0.0/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= @@ -242,18 +104,11 @@ github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/techoner/gophp v0.2.0 h1:vVFoS2XC/NZariagUOhAGqC8p/Ws8R8ARYpj/9lTIAo= -github.com/techoner/gophp v0.2.0/go.mod h1:NOxB/qoTl4+G82CkQp60T18Az5rOTufCqm83x9i/u7M= github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc= github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= @@ -262,173 +117,68 @@ github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8= github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= -github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0= -github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao= -github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8= -github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= -github.com/xanzy/go-gitlab v0.28.0 h1:nsyjDVvBrP4KRXEN4b1m1ewiqmTNL4BOWW041nKGV7k= -github.com/xanzy/go-gitlab v0.28.0/go.mod h1:t4Bmvnxj7k37S4Y17lfLx+nLqkf/oQwT2HagfWKv5Og= -github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -gocloud.dev v0.19.0 h1:EDRyaRAnMGSq/QBto486gWFxMLczAfIYUmusV7XLNBM= -gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc h1:c0o/qxkaO2LF5t6fQrT4b5hzyggAkLLlCUjqfRxd8Q4= -golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190620070143-6f217b454f45/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.6.0/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/tucnak/telebot.v2 v2.0.0-20200301001213-9852df39ae6c h1:+7l/yyky9hchNME0hDMl+cA+wVlHQGte/5EwKHeSqoc= -gopkg.in/tucnak/telebot.v2 v2.0.0-20200301001213-9852df39ae6c/go.mod h1:+//wyPtHTeW2kfyEBwB05Hqnxev7AGrsLIyylSH++KU= gopkg.in/tucnak/telebot.v2 v2.0.0-20200328014118-dd123e949ee1 h1:L9z5n/aaxpAjeEMHu4PfZ7GgQa0lRirKW5G+LHuNQDU= gopkg.in/tucnak/telebot.v2 v2.0.0-20200328014118-dd123e949ee1/go.mod h1:+//wyPtHTeW2kfyEBwB05Hqnxev7AGrsLIyylSH++KU= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gorm.io/gorm v1.21.3 h1:qDFi55ZOsjZTwk5eN+uhAmHi8GysJ/qCTichM/yO7ME= +gorm.io/gorm v1.21.3/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -pack.ag/amqp v0.11.2/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/outlook/outlook.go b/outlook/outlook.go index 521e7ea..0fdbcd0 100644 --- a/outlook/outlook.go +++ b/outlook/outlook.go @@ -11,35 +11,46 @@ import ( ) const ( - MsApiUrl string = "https://login.microsoftonline.com" - MsGraUrl string = "https://graph.microsoft.com" + msApiUrl string = "https://login.microsoftonline.com" + msGraUrl string = "https://graph.microsoft.com" redirectUri string = "http://localhost/e5sub" scope string = "openid offline_access mail.read user.read" ) -func MSGetAuthUrl(cid string) string { - return "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + cid + "&response_type=code&redirect_uri=" + url.QueryEscape(redirectUri) + "&response_mode=query&scope=" + url.QueryEscape(scope) +type msClient struct { + clientId string + clientSecret string } -func MSGetReAppUrl() string { + +func NewMSClient(clientId string, clientSecret string) *msClient { + return &msClient{ + clientId: clientId, + clientSecret: clientSecret, + } +} +func GetMSAuthUrl(clientId string) string { + return "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + clientId + "&response_type=code&redirect_uri=" + url.QueryEscape(redirectUri) + "&response_mode=query&scope=" + url.QueryEscape(scope) +} +func GetMSRegisterAppUrl() string { ru := "https://developer.microsoft.com/en-us/graph/quick-start?appID=_appId_&appName=_appName_&redirectUrl=http://localhost:8000&platform=option-windowsuniversal" deeplink := "/quickstart/graphIO?publicClientSupport=false&appName=e5sub&redirectUrl=http://localhost/e5sub&allowImplicitFlow=false&ru=" + url.QueryEscape(ru) - app_url := "https://apps.dev.microsoft.com/?deepLink=" + url.QueryEscape(deeplink) - return app_url + appUrl := "https://apps.dev.microsoft.com/?deepLink=" + url.QueryEscape(deeplink) + return appUrl } //return access_token and refresh_token -func MSFirGetToken(code, cid, cse string) (access string, refresh string, Error error) { +func (c *msClient) GetTokenWithCode(code string) (access string, refresh string, Error error) { var r http.Request client := &http.Client{} r.ParseForm() - r.Form.Add("client_id", cid) - r.Form.Add("client_secret", cse) + r.Form.Add("client_id", c.clientId) + r.Form.Add("client_secret", c.clientSecret) r.Form.Add("grant_type", "authorization_code") r.Form.Add("scope", scope) r.Form.Add("code", code) r.Form.Add("redirect_uri", redirectUri) body := strings.NewReader(r.Form.Encode()) - req, err := http.NewRequest("POST", MsApiUrl+"/common/oauth2/v2.0/token", body) + req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body) if err != nil { logger.Println(err) return "", "", err @@ -62,19 +73,19 @@ func MSFirGetToken(code, cid, cse string) (access string, refresh string, Error } //return access_token and new refresh token -func MSGetToken(refreshtoken, cid, cse string) (access string, newRefreshToken string, Error error) { +func (c *msClient) GetToken(refreshToken string) (access string, newRefreshToken string, Error error) { var r http.Request client := &http.Client{} r.ParseForm() - r.Form.Add("client_id", cid) - r.Form.Add("client_secret", cse) + r.Form.Add("client_id", c.clientId) + r.Form.Add("client_secret", c.clientSecret) r.Form.Add("grant_type", "refresh_token") r.Form.Add("scope", scope) - r.Form.Add("refresh_token", refreshtoken) + r.Form.Add("refresh_token", refreshToken) r.Form.Add("redirect_uri", redirectUri) body := strings.NewReader(r.Form.Encode()) //fmt.Println(body) - req, err := http.NewRequest("POST", MsApiUrl+"/common/oauth2/v2.0/token", body) + req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body) if err != nil { logger.Println(err) return "", "", err @@ -99,9 +110,9 @@ func MSGetToken(refreshtoken, cid, cse string) (access string, newRefreshToken s } //Get User's Information -func MSGetUserInfo(accesstoken string) (json string, Error error) { +func GetUserInfo(accesstoken string) (json string, Error error) { client := http.Client{} - req, err := http.NewRequest("GET", MsGraUrl+"/v1.0/me", nil) + req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me", nil) if err != nil { logger.Println(err) return "", err @@ -125,9 +136,9 @@ func MSGetUserInfo(accesstoken string) (json string, Error error) { return "", errors.New(string(content)) } -func OutLookGetMails(accesstoken string) (bool, error) { +func GetOutLookMails(accesstoken string) (bool, error) { client := http.Client{} - req, err := http.NewRequest("GET", MsGraUrl+"/v1.0/me/messages", nil) + req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me/messages", nil) if err != nil { logger.Println(err) return false, err From 3dacd6c5ccf01963dbd078b561549c9049b600e9 Mon Sep 17 00:00:00 2001 From: iyear Date: Sat, 13 Mar 2021 13:15:31 +0800 Subject: [PATCH 03/29] Refactor --- bots/control.go | 28 ++------ bots/handle.go | 12 ++-- core/client.go | 148 ++++++++++++++++++++++++++++++++++++++++ outlook/outlook.go | 164 --------------------------------------------- 4 files changed, 158 insertions(+), 194 deletions(-) delete mode 100644 outlook/outlook.go diff --git a/bots/control.go b/bots/control.go index 578bb2d..726b02b 100644 --- a/bots/control.go +++ b/bots/control.go @@ -8,7 +8,6 @@ import ( tb "gopkg.in/tucnak/telebot.v2" "main/core" "main/logger" - "main/outlook" "main/util" "strconv" "strings" @@ -27,43 +26,36 @@ func BindUser(m *tb.Message, cid, cse string) error { } logger.Println("Alias: " + tmp[1]) Alias := tmp[1] + client := core.NewClient(cid, cse) code := util.GetURLValue(tmp[0], "code") //fmt.Println(code) - access, refresh, err := MSFirGetToken(code, cid, cse) + err := client.GetTokenWithCode(code) if err != nil { - logger.Println("%d Bind error:GetRefreshToken %s \n", m.Chat.ID, err.Error()) return err } - - //token has gotten bot.Send(m.Chat, "Token获取成功!") - info, err := outlook.GetUserInfo(access) + info, err := client.GetUserInfo() //fmt.Println("TgId:%d Refresh Token: %s\n", m.Chat.ID, refresh) if err != nil { - logger.Println("%d Bind error:Getinfo %s \n", m.Chat.ID, err.Error()) return err } - var u core.Client u.TgId = m.Chat.ID - u.RefreshToken = refresh + u.RefreshToken = client.RefreshToken //TG的Data传递最高64bytes,一些MsId超过了报错BUTTON_DATA_INVALID (0),采取md5 u.MsId = util.Get16MD5Encode(gjson.Get(info, "id").String()) u.Uptime = time.Now().Unix() - logger.Println(u.Uptime) u.Alias = Alias u.ClientId = cid u.ClientSecret = cse u.Other = "" //MS User Is Exist if MSAppIsExist(u.TgId, u.ClientId) { - logger.Println("%d Bind error:MSUserHasExisted\n", m.Chat.ID) return errors.New("该应用已经绑定过了,无需重复绑定") } //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") if ok, err := core.AddData(u); !ok { - logger.Println("%d Bind error: %s\n", m.Chat.ID, err) return err } logger.Println("%d Bind Successfully!\n", m.Chat.ID) @@ -118,16 +110,8 @@ func SignTask() { tmpBtn := &tb.ReplyMarkup{InlineKeyboard: inlineKeys} se := u.MsId + " ( @" + chat.Username + " )" - access, newRefreshToken, err := outlook.GetToken(u.RefreshToken, u.ClientId, u.ClientSecret) - - if err != nil { - logger.Println(u.MsId+" ", err) - bot.Send(chat, pre+gjson.Get(err.Error(), "error").String(), tmpBtn) - SignErr = append(SignErr, se) - ErrorTimes[u.MsId]++ - continue - } - if ok, err := outlook.GetOutLookMails(access); !ok { + client := core.NewClient(u.ClientId, u.ClientSecret) + if err := client.GetOutlookMails(); err != nil { logger.Println(u.MsId+" ", err) bot.Send(chat, pre+gjson.Get(err.Error(), "error").String(), tmpBtn) ErrorTimes[u.MsId]++ diff --git a/bots/handle.go b/bots/handle.go index 1dab746..36ccd81 100644 --- a/bots/handle.go +++ b/bots/handle.go @@ -8,7 +8,6 @@ import ( "io/ioutil" "main/core" "main/logger" - "main/outlook" "main/util" "os" "path/filepath" @@ -25,10 +24,8 @@ const ( /my 查看已绑定账户信息 /bind 绑定新账户 /unbind 解绑账户 - /export 导出账户信息(JSON格式) + /export 导出账户信息(JSON) /help 帮助 - /task 手动执行一次任务(管理员) - /log 获取最近日志文件(管理员) 源码及使用方法:https://github.com/iyear/E5SubBot ` ) @@ -110,7 +107,7 @@ func bMyInlineBtn(c *tb.Callback) { 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, "应用注册: [点击直达]("+outlook.GetMSRegisterAppUrl()+")", tb.ModeMarkdown) + bot.Send(m.Chat, "应用注册: [点击直达]("+core.GetMSRegisterAppUrl()+")", tb.ModeMarkdown) _, err := bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true}) if err != nil { logger.Println(err) @@ -131,7 +128,7 @@ func bBind2(m *tb.Message) { logger.Println("client_id: " + tmp[0] + " client_secret: " + tmp[1]) cid := tmp[0] cse := tmp[1] - bot.Send(m.Chat, "授权账户: [点击直达]("+outlook.GetMSAuthUrl(cid)+")", tb.ModeMarkdown) + bot.Send(m.Chat, "授权账户: [点击直达]("+core.GetMSAuthUrl(cid)+")", tb.ModeMarkdown) _, err := bot.Send(m.Chat, "请回复http://localhost/…… + 空格 + 别名(用于管理)", &tb.ReplyMarkup{ForceReply: true}) if err != nil { logger.Println(err) @@ -194,7 +191,7 @@ func bExport(m *tb.Message) { ms.Other = u.Other MsMini = append(MsMini, ms) } - //MarshalIndent是为json+美化,/t表缩进 + //MarshalIndent json美化,/t缩进 export, err := json.MarshalIndent(MsMini, "", "\t") if err != nil { logger.Println(err) @@ -305,7 +302,6 @@ func bLogsInlineBtn(c *tb.Callback) { logfile := &tb.Document{File: tb.FromDisk(bLogBasePath + c.Data), FileName: c.Data, MIME: "text/plain"} _, err := bot.Send(c.Message.Chat, logfile) if err != nil { - logger.Println(err) return } bot.Respond(c) diff --git a/core/client.go b/core/client.go index ce30af8..a8b2df2 100644 --- a/core/client.go +++ b/core/client.go @@ -1,5 +1,14 @@ package core +import ( + "github.com/pkg/errors" + "github.com/tidwall/gjson" + "io/ioutil" + "net/http" + "net/url" + "strings" +) + type Client struct { TgId int64 `gorm:"column:tg_id"` RefreshToken string `gorm:"column:refresh_token"` @@ -10,3 +19,142 @@ type Client struct { ClientSecret string `gorm:"column:client_secret"` Other string `gorm:"column:other"` } + +const ( + msApiUrl string = "https://login.microsoftonline.com" + msGraUrl string = "https://graph.microsoft.com" + redirectUri string = "http://localhost/e5sub" + scope string = "openid offline_access mail.read user.read" +) + +func NewClient(clientId string, clientSecret string) *Client { + return &Client{ + ClientId: clientId, + ClientSecret: clientSecret, + } +} +func GetMSAuthUrl(clientId string) string { + return "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + clientId + "&response_type=code&redirect_uri=" + url.QueryEscape(redirectUri) + "&response_mode=query&scope=" + url.QueryEscape(scope) +} +func GetMSRegisterAppUrl() string { + ru := "https://developer.microsoft.com/en-us/graph/quick-start?appID=_appId_&appName=_appName_&redirectUrl=http://localhost:8000&platform=option-windowsuniversal" + deeplink := "/quickstart/graphIO?publicClientSupport=false&appName=e5sub&redirectUrl=http://localhost/e5sub&allowImplicitFlow=false&ru=" + url.QueryEscape(ru) + appUrl := "https://apps.dev.microsoft.com/?deepLink=" + url.QueryEscape(deeplink) + return appUrl +} + +//return access_token and refresh_token +func (c *Client) GetTokenWithCode(code string) (error error) { + var r http.Request + client := &http.Client{} + r.ParseForm() + r.Form.Add("client_id", c.ClientId) + r.Form.Add("client_secret", c.ClientSecret) + r.Form.Add("grant_type", "authorization_code") + r.Form.Add("scope", scope) + r.Form.Add("code", code) + r.Form.Add("redirect_uri", redirectUri) + body := strings.NewReader(r.Form.Encode()) + req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body) + if err != nil { + return err + } + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + if gjson.Get(string(content), "token_type").String() == "Bearer" { + c.RefreshToken = gjson.Get(string(content), "refresh_token").String() + return nil + } + return errors.New(string(content)) +} + +//return access_token and new refresh token +func (c *Client) getToken() (access string) { + var r http.Request + client := &http.Client{} + r.ParseForm() + r.Form.Add("client_id", c.ClientId) + r.Form.Add("client_secret", c.ClientSecret) + r.Form.Add("grant_type", "refresh_token") + r.Form.Add("scope", scope) + r.Form.Add("refresh_token", c.RefreshToken) + r.Form.Add("redirect_uri", redirectUri) + body := strings.NewReader(r.Form.Encode()) + //fmt.Println(body) + req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body) + if err != nil { + return "" + } + resp, err := client.Do(req) + if err != nil { + return "" + } + defer resp.Body.Close() + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "" + } + //fmt.Println(string(content)) + //fmt.Println(gjson.Get(string(content), "access_token").String()) + if gjson.Get(string(content), "token_type").String() == "Bearer" { + c.RefreshToken = gjson.Get(string(content), "refresh_token").String() + return gjson.Get(string(content), "access_token").String() + } + return "" +} + +//Get User's Information +func (c *Client) GetUserInfo() (json string, error error) { + client := http.Client{} + req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me", nil) + if err != nil { + return "", err + } + req.Header.Set("Authorization", c.getToken()) + resp, err := client.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + if gjson.Get(string(content), "id").String() != "" { + //fmt.Println("UserName: " + gjson.Get(string(content), "displayName").String()) + return string(content), nil + } + return "", errors.New(string(content)) +} + +func (c *Client) GetOutlookMails() error { + client := http.Client{} + req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me/messages", nil) + + if err != nil { + return err + } + req.Header.Set("Authorization", c.getToken()) + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + //fmt.Println(string(content)) + //这里的.需要转义,否则会按路径的方式解析 + if gjson.Get(string(content), "@odata\\.context").String() != "" { + return nil + } + return errors.New(string(content)) +} diff --git a/outlook/outlook.go b/outlook/outlook.go deleted file mode 100644 index 0fdbcd0..0000000 --- a/outlook/outlook.go +++ /dev/null @@ -1,164 +0,0 @@ -package outlook - -import ( - "errors" - "github.com/tidwall/gjson" - "io/ioutil" - "main/logger" - "net/http" - "net/url" - "strings" -) - -const ( - msApiUrl string = "https://login.microsoftonline.com" - msGraUrl string = "https://graph.microsoft.com" - redirectUri string = "http://localhost/e5sub" - scope string = "openid offline_access mail.read user.read" -) - -type msClient struct { - clientId string - clientSecret string -} - -func NewMSClient(clientId string, clientSecret string) *msClient { - return &msClient{ - clientId: clientId, - clientSecret: clientSecret, - } -} -func GetMSAuthUrl(clientId string) string { - return "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + clientId + "&response_type=code&redirect_uri=" + url.QueryEscape(redirectUri) + "&response_mode=query&scope=" + url.QueryEscape(scope) -} -func GetMSRegisterAppUrl() string { - ru := "https://developer.microsoft.com/en-us/graph/quick-start?appID=_appId_&appName=_appName_&redirectUrl=http://localhost:8000&platform=option-windowsuniversal" - deeplink := "/quickstart/graphIO?publicClientSupport=false&appName=e5sub&redirectUrl=http://localhost/e5sub&allowImplicitFlow=false&ru=" + url.QueryEscape(ru) - appUrl := "https://apps.dev.microsoft.com/?deepLink=" + url.QueryEscape(deeplink) - return appUrl -} - -//return access_token and refresh_token -func (c *msClient) GetTokenWithCode(code string) (access string, refresh string, Error error) { - var r http.Request - client := &http.Client{} - r.ParseForm() - r.Form.Add("client_id", c.clientId) - r.Form.Add("client_secret", c.clientSecret) - r.Form.Add("grant_type", "authorization_code") - r.Form.Add("scope", scope) - r.Form.Add("code", code) - r.Form.Add("redirect_uri", redirectUri) - body := strings.NewReader(r.Form.Encode()) - req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body) - if err != nil { - logger.Println(err) - return "", "", err - } - resp, err := client.Do(req) - if err != nil { - logger.Println(err) - return "", "", err - } - defer resp.Body.Close() - content, err := ioutil.ReadAll(resp.Body) - if err != nil { - logger.Println(err) - return "", "", err - } - if gjson.Get(string(content), "token_type").String() == "Bearer" { - return gjson.Get(string(content), "access_token").String(), gjson.Get(string(content), "refresh_token").String(), nil - } - return "", "", errors.New(string(content)) -} - -//return access_token and new refresh token -func (c *msClient) GetToken(refreshToken string) (access string, newRefreshToken string, Error error) { - var r http.Request - client := &http.Client{} - r.ParseForm() - r.Form.Add("client_id", c.clientId) - r.Form.Add("client_secret", c.clientSecret) - r.Form.Add("grant_type", "refresh_token") - r.Form.Add("scope", scope) - r.Form.Add("refresh_token", refreshToken) - r.Form.Add("redirect_uri", redirectUri) - body := strings.NewReader(r.Form.Encode()) - //fmt.Println(body) - req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body) - if err != nil { - logger.Println(err) - return "", "", err - } - resp, err := client.Do(req) - if err != nil { - logger.Println(err) - return "", "", err - } - defer resp.Body.Close() - content, err := ioutil.ReadAll(resp.Body) - if err != nil { - logger.Println(err) - return "", "", err - } - //fmt.Println(string(content)) - //fmt.Println(gjson.Get(string(content), "access_token").String()) - if gjson.Get(string(content), "token_type").String() == "Bearer" { - return gjson.Get(string(content), "access_token").String(), gjson.Get(string(content), "refresh_token").String(), nil - } - return "", "", errors.New(string(content)) -} - -//Get User's Information -func GetUserInfo(accesstoken string) (json string, Error error) { - client := http.Client{} - req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me", nil) - if err != nil { - logger.Println(err) - return "", err - } - req.Header.Set("Authorization", accesstoken) - resp, err := client.Do(req) - if err != nil { - logger.Println(err) - return "", err - } - defer resp.Body.Close() - content, err := ioutil.ReadAll(resp.Body) - if err != nil { - logger.Println(err) - return "", err - } - if gjson.Get(string(content), "id").String() != "" { - //fmt.Println("UserName: " + gjson.Get(string(content), "displayName").String()) - return string(content), nil - } - return "", errors.New(string(content)) -} - -func GetOutLookMails(accesstoken string) (bool, error) { - client := http.Client{} - req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me/messages", nil) - if err != nil { - logger.Println(err) - return false, err - } - req.Header.Set("Authorization", accesstoken) - resp, err := client.Do(req) - if err != nil { - logger.Println(err) - return false, err - } - defer resp.Body.Close() - content, err := ioutil.ReadAll(resp.Body) - if err != nil { - logger.Println(err) - return false, err - } - //fmt.Println(string(content)) - //这里的.需要转义,否则会按路径的方式解析 - if gjson.Get(string(content), "@odata\\.context").String() != "" { - return true, nil - } - return false, errors.New(string(content)) -} From 088d0f2708e87e6dc112c669f69ac28b04b2d49d Mon Sep 17 00:00:00 2001 From: iyear Date: Mon, 14 Jun 2021 13:07:08 +0800 Subject: [PATCH 04/29] change logger to zap --- bots/bots.go | 28 ++++++++++++-------------- bots/control.go | 45 ++++++++++++++++------------------------- bots/handle.go | 53 +++++++++++-------------------------------------- core/client.go | 2 +- go.mod | 2 +- main.go | 2 +- 6 files changed, 45 insertions(+), 87 deletions(-) diff --git a/bots/bots.go b/bots/bots.go index d9b9b39..0ae152c 100644 --- a/bots/bots.go +++ b/bots/bots.go @@ -5,9 +5,9 @@ import ( "fmt" "github.com/robfig/cron/v3" "github.com/spf13/viper" + "go.uber.org/zap" "golang.org/x/net/proxy" tb "gopkg.in/tucnak/telebot.v2" - "main/logger" "net/http" "strconv" "strings" @@ -38,12 +38,12 @@ var dbPath string func BotStart() { MakeHandle() TaskLaunch() - logger.Println("Bot Start") + fmt.Println("Bot Start") fmt.Println("------------") bot.Start() } func MakeHandle() { - logger.Println("Make Handle……") + fmt.Println("Make Handlers……") //所有用户 bot.Handle("/start", bStart) bot.Handle("/my", bMy) @@ -63,19 +63,19 @@ func TaskLaunch() { //log分为每天 //task.AddFunc(" 0 0 * * *", InitLogger) // */1 * * * * 1 */3 * * * - logger.Println("Cron Task Start……") + fmt.Println("Cron Task Start……") task.Start() } func init() { fmt.Println(logo) //read config - logger.Println("Read Config……") + fmt.Println("Read Config……") viper.SetConfigName("config") viper.AddConfigPath(".") err := viper.ReadInConfig() if err != nil { - logger.Println(err) + zap.S().Errorw("failed to read config","error",err) } host := viper.GetString("mysql.host") user := viper.GetString("mysql.user") @@ -86,17 +86,15 @@ func init() { //fmt.Println(path) db, err := sql.Open(dbDriverName, dbPath) if err != nil { - logger.Println(err) + zap.S().Errorw("failed to connect db","error",err,"path",dbPath) } - logger.Println("Connect MySQL Success!") + fmt.Println("Connect MySQL Success!") if ok, err := CreateTB(); !ok { - logger.Println(err) + zap.S().Errorw("failed to create table","error",err,"path",dbPath) } defer db.Close() BotToken = viper.GetString("bot_token") Socks5 = viper.GetString("socks5") - //set bot - logger.Println("Bot Settings……") Poller := &tb.LongPoller{Timeout: 15 * time.Second} spamProtected := tb.NewMiddlewarePoller(Poller, func(upd *tb.Update) bool { if upd.Message == nil { @@ -113,10 +111,10 @@ func init() { } //set socks5 if Socks5 != "" { - logger.Println("Proxy:" + Socks5) + fmt.Println("Proxy:" + Socks5) dialer, err := proxy.SOCKS5("tcp", Socks5, nil, proxy.Direct) if err != nil { - logger.Println(err) + zap.S().Errorw("failed to make dialer","error",err,"socks5",Socks5) } httpTransport := &http.Transport{} httpClient := &http.Client{Transport: httpTransport} @@ -126,7 +124,7 @@ func init() { //create bot bot, err = tb.NewBot(botsettings) if err != nil { - logger.Println(err) + zap.S().Errorw("failed to create bot","error",err) } - logger.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username) + fmt.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username) } diff --git a/bots/control.go b/bots/control.go index 726b02b..d1ca191 100644 --- a/bots/control.go +++ b/bots/control.go @@ -3,12 +3,12 @@ package bots import ( "errors" "fmt" + "github.com/iyear/E5SubBot/core" + "github.com/iyear/E5SubBot/util" "github.com/spf13/viper" "github.com/tidwall/gjson" + "go.uber.org/zap" tb "gopkg.in/tucnak/telebot.v2" - "main/core" - "main/logger" - "main/util" "strconv" "strings" "time" @@ -16,15 +16,12 @@ import ( var SignOk map[int64]int -//If Successfully return "",else return error information +// BindUser If Successfully return "",else return error information func BindUser(m *tb.Message, cid, cse string) error { - logger.Println("%d Begin Bind\n", m.Chat.ID) tmp := strings.Split(m.Text, " ") if len(tmp) != 2 { - logger.Println("%d Bind error:Wrong Bind Format\n", m.Chat.ID) - return errors.New("绑定格式错误") + return errors.New("wrong format") } - logger.Println("Alias: " + tmp[1]) Alias := tmp[1] client := core.NewClient(cid, cse) code := util.GetURLValue(tmp[0], "code") @@ -58,17 +55,16 @@ func BindUser(m *tb.Message, cid, cse string) error { if ok, err := core.AddData(u); !ok { return err } - logger.Println("%d Bind Successfully!\n", m.Chat.ID) return nil } -//get bind num +// GetBindNum get bind num func GetBindNum(TgId int64) int { data := core.QueryDataByTG(TgId) return len(data) } -//return true => exist +// MSAppIsExist return true => exist func MSAppIsExist(TgId int64, ClientId string) bool { data := core.QueryDataByTG(TgId) var res core.Client @@ -80,7 +76,6 @@ func MSAppIsExist(TgId int64, ClientId string) bool { return false } -//SignTask func SignTask() { var ( SignOk map[int64]int @@ -99,7 +94,7 @@ func SignTask() { pre := "您的账户: " + u.Alias + "\n在任务执行时出现了错误!\n错误:" chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10)) if err != nil { - logger.Println(err) + zap.S().Errorw("wrong chat id","error",err,"tg_id",u.TgId) continue } //生成解绑按钮 @@ -112,8 +107,8 @@ func SignTask() { se := u.MsId + " ( @" + chat.Username + " )" client := core.NewClient(u.ClientId, u.ClientSecret) if err := client.GetOutlookMails(); err != nil { - logger.Println(u.MsId+" ", err) - bot.Send(chat, pre+gjson.Get(err.Error(), "error").String(), tmpBtn) + zap.S().Errorw("failed to get outlook mails","error",err,"ms_id",u.MsId) + bot.Send(chat, pre+err.Error(), tmpBtn) ErrorTimes[u.MsId]++ SignErr = append(SignErr, se) continue @@ -121,7 +116,7 @@ func SignTask() { u.Uptime = time.Now().Unix() u.RefreshToken = newRefreshToken if ok, err := core.UpdateData(u); !ok { - logger.Println(u.MsId+" ", err) + zap.S().Errorw("failed to update db data","error",err,"ms_id",u.MsId) bot.Send(chat, pre+err.Error(), tmpBtn) SignErr = append(SignErr, se) ErrorTimes[u.MsId]++ @@ -138,29 +133,23 @@ func SignTask() { for _, u := range data { chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10)) if err != nil { - logger.Println("Send Result ERROR: ", err) + zap.S().Errorw("failed to get chat","error",err,"tg_id",u.TgId) continue } //错误上限账户清退 if ErrorTimes[u.MsId] == ErrMaxTimes { - logger.Println(u.MsId + " Error Limit") + zap.S().Errorw("binding max num limit","ms_id",u.MsId) if ok, err := core.DelData(u.MsId); !ok { - logger.Println(err) + zap.S().Errorw("failed to delete db data","error",err,"ms_id",u.MsId) } 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) - if err != nil { - logger.Println(err) - } + bot.Send(chat, "您的账户因达到错误上限而被自动解绑\n后会有期!\n\n别名: "+u.Alias+"\nclient_id: "+u.ClientId+"\nclient_secret: "+u.ClientSecret) } } 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}) - if err != nil { - logger.Println(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}) isSend[u.TgId] = true } } @@ -176,7 +165,7 @@ func SignTask() { for _, a := range admin { chat, err := bot.ChatByID(strconv.FormatInt(a, 10)) if err != nil { - logger.Println(err) + zap.S().Errorw("failed to get chat","error",err,"tg_id",a) continue } 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) diff --git a/bots/handle.go b/bots/handle.go index 36ccd81..37af50a 100644 --- a/bots/handle.go +++ b/bots/handle.go @@ -3,12 +3,12 @@ package bots import ( "encoding/json" "github.com/fsnotify/fsnotify" + "github.com/iyear/E5SubBot/core" + "github.com/iyear/E5SubBot/util" "github.com/spf13/viper" + "go.uber.org/zap" tb "gopkg.in/tucnak/telebot.v2" "io/ioutil" - "main/core" - "main/logger" - "main/util" "os" "path/filepath" "strconv" @@ -82,7 +82,6 @@ func bStart(m *tb.Message) { } func bMy(m *tb.Message) { - logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Manager Users") data := core.QueryDataByTG(m.Chat.ID) var inlineKeys [][]tb.InlineButton for _, u := range data { @@ -97,7 +96,6 @@ func bMy(m *tb.Message) { bot.Send(m.Chat, "选择一个账户查看具体信息\n\n绑定数: "+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 := core.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")) @@ -105,33 +103,22 @@ func bMyInlineBtn(c *tb.Callback) { } 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, "应用注册: [点击直达]("+core.GetMSRegisterAppUrl()+")", tb.ModeMarkdown) - _, err := bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true}) - if err != nil { - logger.Println(err) - return - } + bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true}) UserStatus[m.Chat.ID] = USBind1 UserCid[m.Chat.ID] = m.Text } func bBind2(m *tb.Message) { - logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Bind2") - logger.Println("Auth: " + strconv.FormatInt(m.Chat.ID, 10)) tmp := strings.Split(m.Text, " ") if len(tmp) != 2 { - logger.Println("%d Bind error:Wrong Bind Format\n", m.Chat.ID) bot.Send(m.Chat, "错误的格式") return } - logger.Println("client_id: " + tmp[0] + " client_secret: " + tmp[1]) cid := tmp[0] cse := tmp[1] bot.Send(m.Chat, "授权账户: [点击直达]("+core.GetMSAuthUrl(cid)+")", tb.ModeMarkdown) _, err := bot.Send(m.Chat, "请回复http://localhost/…… + 空格 + 别名(用于管理)", &tb.ReplyMarkup{ForceReply: true}) if err != nil { - logger.Println(err) return } UserStatus[m.Chat.ID] = USBind2 @@ -140,7 +127,6 @@ func bBind2(m *tb.Message) { } func bUnBind(m *tb.Message) { - logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Unbind") data := core.QueryDataByTG(m.Chat.ID) var inlineKeys [][]tb.InlineButton for _, u := range data { @@ -155,20 +141,17 @@ func bUnBind(m *tb.Message) { bot.Send(m.Chat, "选择一个账户将其解绑\n\n当前绑定数: "+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) r := core.QueryDataByMS(c.Data) u := r[0] - if ok, _ := core.DelData(u.MsId); !ok { - logger.Println(u.MsId + " UnBind ERROR") + if ok, err := core.DelData(u.MsId); !ok { + zap.S().Errorw("failed to delete db data","error",err,"ms_id",u.MsId) bot.Send(c.Message.Chat, "解绑失败!") return } - logger.Println(u.MsId + " UnBind Success") bot.Send(c.Message.Chat, "解绑成功!") bot.Respond(c) } func bExport(m *tb.Message) { - logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Export") type MsMiniData struct { Alias string ClientId string @@ -194,28 +177,22 @@ func bExport(m *tb.Message) { //MarshalIndent json美化,/t缩进 export, err := json.MarshalIndent(MsMini, "", "\t") if err != nil { - logger.Println(err) + zap.S().Errorw("failed to marshal json","error",err) bot.Send(m.Chat, "获取JSON失败~\n"+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) + zap.S().Errorw("failed to write file","error",err) bot.Send(m.Chat, "写入临时文件失败~\n"+err.Error()) return } exportFile := &tb.Document{File: tb.FromDisk(fileName), FileName: strconv.FormatInt(m.Chat.ID, 10) + ".json", MIME: "text/plain"} - _, err = bot.Send(m.Chat, exportFile) - if err != nil { - logger.Println(err) - return - } + bot.Send(m.Chat, exportFile) //不遗留本地文件 - if exportFile.InCloud() == true && os.Remove(fileName) == nil { - logger.Println(fileName + " Has Removed") - } else { - logger.Println(fileName + " Removed ERROR") + if exportFile.InCloud() != true || os.Remove(fileName) != nil { + zap.S().Errorw("failed to export files") } } func bHelp(m *tb.Message) { @@ -258,7 +235,6 @@ func bOnText(m *tb.Message) { } } func bTask(m *tb.Message) { - logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start SignTask") for _, a := range admin { if a == m.Chat.ID { SignTask() @@ -268,7 +244,6 @@ func bTask(m *tb.Message) { bot.Send(m.Chat, "您没有权限执行此操作~") } func bLog(m *tb.Message) { - logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Get Logs") flag := 0 for _, a := range admin { if a == m.Chat.ID { @@ -290,13 +265,9 @@ func bLog(m *tb.Message) { bot.Handle(&inlineBtn, bLogsInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) } - _, err := bot.Send(m.Chat, "选择一个日志", &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) - if err != nil { - logger.Println(err) - } + bot.Send(m.Chat, "选择一个日志", &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) } func bLogsInlineBtn(c *tb.Callback) { - logger.Println(strconv.FormatInt(c.Message.Chat.ID, 10) + " Get Logs: " + c.Data) //fmt.Println(c.Data) //logger.Println(bLogBasePath + c.Data + ".log") logfile := &tb.Document{File: tb.FromDisk(bLogBasePath + c.Data), FileName: c.Data, MIME: "text/plain"} diff --git a/core/client.go b/core/client.go index a8b2df2..ea55f53 100644 --- a/core/client.go +++ b/core/client.go @@ -156,5 +156,5 @@ func (c *Client) GetOutlookMails() error { if gjson.Get(string(content), "@odata\\.context").String() != "" { return nil } - return errors.New(string(content)) + return errors.New(gjson.Get(string(content), "error").String()) } diff --git a/go.mod b/go.mod index 3e87cd1..75ac59c 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module main +module github.com/iyear/E5SubBot go 1.13 diff --git a/main.go b/main.go index 82e01da..43a131a 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,6 @@ package main -import "main/bots" +import "github.com/iyear/E5SubBot/bots" func main() { bots.BotStart() From 3e5ed2b26c4c526f3b468c2ec4da6b917b1edd27 Mon Sep 17 00:00:00 2001 From: iyear Date: Mon, 14 Jun 2021 21:37:58 +0800 Subject: [PATCH 05/29] change db to sqlite --- core/mysql.go | 161 -------------------------------------- {core => model}/client.go | 18 ++--- model/sqlite.go | 23 ++++++ 3 files changed, 32 insertions(+), 170 deletions(-) delete mode 100644 core/mysql.go rename {core => model}/client.go (92%) create mode 100644 model/sqlite.go diff --git a/core/mysql.go b/core/mysql.go deleted file mode 100644 index bf637ee..0000000 --- a/core/mysql.go +++ /dev/null @@ -1,161 +0,0 @@ -package core - -import ( - "database/sql" - _ "github.com/go-sql-driver/mysql" - "gorm.io/gorm" - "main/logger" - "main/outlook" - "main/util" - "time" -) - -var db *gorm.DB - -func InitDB() error { - var err error - db, err = gorm.Open("11", &gorm.Config{ - NowFunc: func() time.Time { - return time.Now().UTC() - }, - }) - if err != nil { - return err - } - return nil -} - -//update data by msId -func UpdateData(u Client) (bool, error) { - db, err := sql.Open(dbDriverName, dbPath) - if err != nil { - logger.Println(err) - } - defer db.Close() - sqlString := `UPDATE Clients set tg_id=?,refresh_token=?,uptime=?,alias=?,client_id=?,client_secret=?,other=? where ms_id=?` - stmt, err := db.Prepare(sqlString) - if err != nil { - return false, err - } - _, err = stmt.Exec(u.TgId, u.RefreshToken, u.Uptime, u.Alias, u.ClientId, u.ClientSecret, u.Other, u.MsId) - if err != nil { - return false, err - } - return true, nil -} - -//add data -func AddData(u Client) (bool, error) { - db, err := sql.Open(dbDriverName, dbPath) - if err != nil { - logger.Println(err) - } - defer db.Close() - sqlString := ` - INSERT INTO Clients (tg_id, refresh_token,ms_id, uptime,alias,client_id,client_secret,other) - VALUES (?,?,?,?,?,?,?,?)` - stmt, err := db.Prepare(sqlString) - if err != nil { - return false, err - } - _, err = stmt.Exec(u.TgId, u.RefreshToken, u.MsId, u.Uptime, u.Alias, u.ClientId, u.ClientSecret, u.Other) - if err != nil { - return false, err - } - return true, nil -} - -//del data by ms_id -func DelData(msId string) (bool, error) { - db, err := sql.Open(dbDriverName, dbPath) - if err != nil { - logger.Println(err) - } - defer db.Close() - sqlString := `delete from Clients where ms_id=?` - stmt, err := db.Prepare(sqlString) - if err != nil { - return false, err - } - res, err := stmt.Exec(msId) - if err != nil { - return false, err - } - _, err = res.RowsAffected() - if err != nil { - return false, err - } - return true, nil -} -func QueryData(rows *sql.Rows) []Client { - - var result = make([]Client, 0) - defer rows.Close() - for rows.Next() { - var ( - tgIdt, uptimet int64 - refresht, othert, msidt, aliast, clientIdt, clientSet string - ) - rows.Scan(&tgIdt, &refresht, &msidt, &uptimet, &aliast, &clientIdt, &clientSet, &othert) - //fmt.Println(string(tgNamet) + "=>" + uptimet.Format("2006-01-02 15:04:05")) - result = append(result, Client{tgIdt, refresht, msidt, uptimet, aliast, clientIdt, clientSet, othert}) - } - return result -} -func QueryDataByMS(msId string) []Client { - db, err := sql.Open(dbDriverName, dbPath) - if err != nil { - logger.Println(err) - } - defer db.Close() - rows, err := db.Query("select * from Clients where ms_id = ?", msId) - util.CheckErr(err) - return QueryData(rows) -} - -func QueryDataAll() []Client { - db, err := sql.Open(dbDriverName, dbPath) - if err != nil { - logger.Println(err) - } - defer db.Close() - rows, err := db.Query("select * from Clients ") - util.CheckErr(err) - return QueryData(rows) -} - -//query data by tg_id -func QueryDataByTG(tgId int64) []Client { - db, err := sql.Open(dbDriverName, dbPath) - if err != nil { - logger.Println(err) - } - defer db.Close() - rows, err := db.Query("select * from Clients where tg_id = ?", tgId) - util.CheckErr(err) - return QueryData(rows) -} -func CreateTB() (bool, error) { - db, err := sql.Open(dbDriverName, dbPath) - if err != nil { - logger.Println(err) - } - defer db.Close() - sqltable := ` - create table if not exists Clients - ( - tg_id INTEGER, - refresh_token TEXT, - ms_id VARCHAR(255), - uptime INTEGER, - alias VARCHAR(255), - client_id VARCHAR(255), - client_secret VARCHAR(255), - other TEXT - );` - _, err = db.Exec(sqltable) - if err != nil { - return false, err - } - return true, nil -} diff --git a/core/client.go b/model/client.go similarity index 92% rename from core/client.go rename to model/client.go index ea55f53..6db5a02 100644 --- a/core/client.go +++ b/model/client.go @@ -1,4 +1,4 @@ -package core +package model import ( "github.com/pkg/errors" @@ -10,14 +10,14 @@ import ( ) type Client struct { - TgId int64 `gorm:"column:tg_id"` - RefreshToken string `gorm:"column:refresh_token"` - MsId string `gorm:"column:ms_id"` - Uptime int64 `gorm:"column:uptime"` - Alias string `gorm:"column:alias"` - ClientId string `gorm:"column:client_id"` - ClientSecret string `gorm:"column:client_secret"` - Other string `gorm:"column:other"` + TgId int64 `gorm:"unique;not null"` + RefreshToken string `gorm:"not null"` + MsId string `gorm:"unique;primaryKey;not null"` + Uptime int64 `gorm:"autoUpdateTime;not null"` + Alias string `gorm:"not null"` + ClientId string `gorm:"not null"` + ClientSecret string `gorm:"not null"` + Other string } const ( diff --git a/model/sqlite.go b/model/sqlite.go new file mode 100644 index 0000000..f7699fb --- /dev/null +++ b/model/sqlite.go @@ -0,0 +1,23 @@ +package model + +import ( + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "time" +) + +var DB *gorm.DB + +func InitDB() error { + var err error + DB, err = gorm.Open(sqlite.Open("data.db"), &gorm.Config{ + NowFunc: func() time.Time { + return time.Now().UTC() + }, + }) + if err != nil { + return err + } + DB.AutoMigrate(&Client{}) + return nil +} From d82ace223bced768449913c21816911a31cb09b0 Mon Sep 17 00:00:00 2001 From: iyear Date: Mon, 14 Jun 2021 21:40:03 +0800 Subject: [PATCH 06/29] change to gorm --- bots/control.go | 276 +++++++++++++++++++++++------------------------- 1 file changed, 131 insertions(+), 145 deletions(-) diff --git a/bots/control.go b/bots/control.go index d1ca191..44ed7a2 100644 --- a/bots/control.go +++ b/bots/control.go @@ -3,7 +3,7 @@ package bots import ( "errors" "fmt" - "github.com/iyear/E5SubBot/core" + "github.com/iyear/E5SubBot/model" "github.com/iyear/E5SubBot/util" "github.com/spf13/viper" "github.com/tidwall/gjson" @@ -17,162 +17,165 @@ import ( var SignOk map[int64]int // BindUser If Successfully return "",else return error information -func BindUser(m *tb.Message, cid, cse string) error { +func BindUser(m *tb.Message, ClientId, ClientSecret string) error { tmp := strings.Split(m.Text, " ") if len(tmp) != 2 { return errors.New("wrong format") } - Alias := tmp[1] - client := core.NewClient(cid, cse) code := util.GetURLValue(tmp[0], "code") - //fmt.Println(code) - err := client.GetTokenWithCode(code) - if err != nil { + Alias := tmp[1] + cli := model.NewClient(ClientId, ClientSecret) + if err := cli.GetTokenWithCode(code); err != nil { return err } bot.Send(m.Chat, "Token获取成功!") - info, err := client.GetUserInfo() - //fmt.Println("TgId:%d Refresh Token: %s\n", m.Chat.ID, refresh) + + info, err := cli.GetUserInfo() if err != nil { return err } - var u core.Client - u.TgId = m.Chat.ID - u.RefreshToken = client.RefreshToken - //TG的Data传递最高64bytes,一些MsId超过了报错BUTTON_DATA_INVALID (0),采取md5 - u.MsId = util.Get16MD5Encode(gjson.Get(info, "id").String()) - u.Uptime = time.Now().Unix() - u.Alias = Alias - u.ClientId = cid - u.ClientSecret = cse - u.Other = "" + var u = &model.Client{ + TgId: m.Chat.ID, + //TG的Data传递最高64bytes,一些MsId超过了报错BUTTON_DATA_INVALID (0),采取md5 + RefreshToken: cli.RefreshToken, + MsId: util.Get16MD5Encode(gjson.Get(info, "id").String()), + Alias: Alias, + ClientId: ClientId, + ClientSecret: ClientSecret, + Other: "", + } + //MS User Is Exist if MSAppIsExist(u.TgId, u.ClientId) { return errors.New("该应用已经绑定过了,无需重复绑定") } //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") - if ok, err := core.AddData(u); !ok { - return err + bot.Send(m.Chat, + fmt.Sprintf("MS_ID(MD5): %s\nuserPrincipalName: %s\ndisplayName: %s\n", + u.MsId, + gjson.Get(info, "userPrincipalName").String(), + gjson.Get(info, "displayName").String()), + ) + + if result := model.DB.Create(&u); result.Error != nil { + return result.Error } return nil } // GetBindNum get bind num func GetBindNum(TgId int64) int { - data := core.QueryDataByTG(TgId) - return len(data) + var bindings []*model.Client + result := model.DB.Where("tg_id = ?", TgId).Find(&bindings) + return int(result.RowsAffected) } // MSAppIsExist return true => exist func MSAppIsExist(TgId int64, ClientId string) bool { - data := core.QueryDataByTG(TgId) - var res core.Client - for _, res = range data { - if res.ClientId == ClientId { - return true - } - } - return false + result := model.DB. + Where("tg_id = ? AND client_id = ?", TgId, ClientId). + First(&model.Client{}) + return util.IF(result.RowsAffected == 0, false, true).(bool) } -func SignTask() { - var ( - SignOk map[int64]int - SignErr []string - UnbindUser []string - num, signOk int - ) - SignOk = make(map[int64]int) - fmt.Println("----Task Begin----") - fmt.Println("Time:" + time.Now().Format("2006-01-02 15:04:05")) - data := core.QueryDataAll() - num = len(data) - fmt.Println("Start Sign") - //签到任务 - for _, u := range data { - pre := "您的账户: " + u.Alias + "\n在任务执行时出现了错误!\n错误:" - chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10)) - if err != nil { - zap.S().Errorw("wrong chat id","error",err,"tg_id",u.TgId) - continue - } - //生成解绑按钮 - var inlineKeys [][]tb.InlineButton - UnBindBtn := tb.InlineButton{Unique: "un" + u.MsId, Text: "点击解绑该账户", Data: u.MsId} - bot.Handle(&UnBindBtn, bUnBindInlineBtn) - inlineKeys = append(inlineKeys, []tb.InlineButton{UnBindBtn}) - tmpBtn := &tb.ReplyMarkup{InlineKeyboard: inlineKeys} +// func SignTask() { +// var ( +// SignOk map[int64]int +// SignErr []string +// UnbindUser []string +// num, signOk int +// ) +// SignOk = make(map[int64]int) +// fmt.Println("----Task Begin----") +// fmt.Println("Time:" + time.Now().Format("2006-01-02 15:04:05")) +// data := model.QueryDataAll() +// num = len(data) +// fmt.Println("Start Sign") +// //签到任务 +// for _, u := range data { +// pre := "您的账户: " + u.Alias + "\n在任务执行时出现了错误!\n错误:" +// chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10)) +// if err != nil { +// zap.S().Errorw("wrong chat id", "error", err, "tg_id", u.TgId) +// continue +// } +// //生成解绑按钮 +// var inlineKeys [][]tb.InlineButton +// UnBindBtn := tb.InlineButton{Unique: "un" + u.MsId, Text: "点击解绑该账户", Data: u.MsId} +// bot.Handle(&UnBindBtn, bUnBindInlineBtn) +// inlineKeys = append(inlineKeys, []tb.InlineButton{UnBindBtn}) +// tmpBtn := &tb.ReplyMarkup{InlineKeyboard: inlineKeys} +// +// se := u.MsId + " ( @" + chat.Username + " )" +// client := model.NewClient(u.ClientId, u.ClientSecret) +// if err := client.GetOutlookMails(); err != nil { +// zap.S().Errorw("failed to get outlook mails", "error", err, "ms_id", u.MsId) +// bot.Send(chat, pre+err.Error(), tmpBtn) +// ErrorTimes[u.MsId]++ +// SignErr = append(SignErr, se) +// continue +// } +// u.Uptime = time.Now().Unix() +// u.RefreshToken = newRefreshToken +// if ok, err := model.UpdateData(u); !ok { +// zap.S().Errorw("failed to update db data", "error", err, "ms_id", u.MsId) +// bot.Send(chat, pre+err.Error(), tmpBtn) +// SignErr = append(SignErr, se) +// ErrorTimes[u.MsId]++ +// continue +// } +// fmt.Println(u.MsId + " Sign OK!") +// SignOk[u.TgId]++ +// signOk++ +// } +// fmt.Println("Sign End,Start Send") +// var isSend map[int64]bool +// isSend = make(map[int64]bool) +// //用户任务反馈 +// for _, u := range data { +// chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10)) +// if err != nil { +// zap.S().Errorw("failed to get chat", "error", err, "tg_id", u.TgId) +// continue +// } +// //错误上限账户清退 +// if ErrorTimes[u.MsId] == ErrMaxTimes { +// zap.S().Errorw("binding max num limit", "ms_id", u.MsId) +// if ok, err := model.DelData(u.MsId); !ok { +// zap.S().Errorw("failed to delete db data", "error", err, "ms_id", u.MsId) +// } else { +// UnbindUser = append(UnbindUser, u.MsId+" ( @"+chat.Username+" )") +// bot.Send(chat, "您的账户因达到错误上限而被自动解绑\n后会有期!\n\n别名: "+u.Alias+"\nclient_id: "+u.ClientId+"\nclient_secret: "+u.ClientSecret) +// } +// +// } +// if !isSend[u.TgId] { +// //静默发送,过多消息很烦 +// 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}) +// isSend[u.TgId] = true +// } +// } +// //管理员任务反馈 +// var ErrUserStr string +// var UnbindUserStr string +// for _, eu := range SignErr { +// ErrUserStr = ErrUserStr + eu + "\n" +// } +// for _, ubu := range UnbindUser { +// UnbindUserStr = UnbindUserStr + ubu + "\n" +// } +// for _, a := range admin { +// chat, err := bot.ChatByID(strconv.FormatInt(a, 10)) +// if err != nil { +// zap.S().Errorw("failed to get chat", "error", err, "tg_id", a) +// continue +// } +// 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) +// } +// fmt.Println("----Task End----") +//} - se := u.MsId + " ( @" + chat.Username + " )" - client := core.NewClient(u.ClientId, u.ClientSecret) - if err := client.GetOutlookMails(); err != nil { - zap.S().Errorw("failed to get outlook mails","error",err,"ms_id",u.MsId) - bot.Send(chat, pre+err.Error(), tmpBtn) - ErrorTimes[u.MsId]++ - SignErr = append(SignErr, se) - continue - } - u.Uptime = time.Now().Unix() - u.RefreshToken = newRefreshToken - if ok, err := core.UpdateData(u); !ok { - zap.S().Errorw("failed to update db data","error",err,"ms_id",u.MsId) - bot.Send(chat, pre+err.Error(), tmpBtn) - SignErr = append(SignErr, se) - ErrorTimes[u.MsId]++ - continue - } - fmt.Println(u.MsId + " Sign OK!") - SignOk[u.TgId]++ - signOk++ - } - fmt.Println("Sign End,Start Send") - var isSend map[int64]bool - isSend = make(map[int64]bool) - //用户任务反馈 - for _, u := range data { - chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10)) - if err != nil { - zap.S().Errorw("failed to get chat","error",err,"tg_id",u.TgId) - continue - } - //错误上限账户清退 - if ErrorTimes[u.MsId] == ErrMaxTimes { - zap.S().Errorw("binding max num limit","ms_id",u.MsId) - if ok, err := core.DelData(u.MsId); !ok { - zap.S().Errorw("failed to delete db data","error",err,"ms_id",u.MsId) - } else { - UnbindUser = append(UnbindUser, u.MsId+" ( @"+chat.Username+" )") - bot.Send(chat, "您的账户因达到错误上限而被自动解绑\n后会有期!\n\n别名: "+u.Alias+"\nclient_id: "+u.ClientId+"\nclient_secret: "+u.ClientSecret) - } - - } - if !isSend[u.TgId] { - //静默发送,过多消息很烦 - 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}) - isSend[u.TgId] = true - } - } - //管理员任务反馈 - var ErrUserStr string - var UnbindUserStr string - for _, eu := range SignErr { - ErrUserStr = ErrUserStr + eu + "\n" - } - for _, ubu := range UnbindUser { - UnbindUserStr = UnbindUserStr + ubu + "\n" - } - for _, a := range admin { - chat, err := bot.ChatByID(strconv.FormatInt(a, 10)) - if err != nil { - zap.S().Errorw("failed to get chat","error",err,"tg_id",a) - continue - } - 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) - } - fmt.Println("----Task End----") -} -func GetAdmin() []int64 { +func GetAdmins() []int64 { var result []int64 admins := strings.Split(viper.GetString("admin"), ",") for _, v := range admins { @@ -181,20 +184,3 @@ func GetAdmin() []int64 { } return result } - -//func InitLogger() { -// if !util.PathExists(bLogBasePath) { -// os.Mkdir(bLogBasePath, 0773) -// } -// -// path := bLogBasePath + time.Now().Format("2006-01-02") + ".log" -// f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0773) -// if err != nil { -// logger.Println(err) -// } -// writers := []io.Writer{ -// f, -// os.Stdout} -// faoWriter := io.MultiWriter(writers...) -// //logger = log.New(faoWriter, "【E5Sub】", log.Ldate|log.Ltime|log.Lshortfile) -//} From dd5f3fa3ba1beddc69b1cc4586c533685fd264ea Mon Sep 17 00:00:00 2001 From: iyear Date: Mon, 14 Jun 2021 22:12:18 +0800 Subject: [PATCH 07/29] add function comments --- util/util.go | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/util/util.go b/util/util.go index be3aa34..88b3468 100644 --- a/util/util.go +++ b/util/util.go @@ -8,11 +8,10 @@ import ( "log" "net/url" "os" - "strings" "time" ) -//true=>no error +// Min true=>no error func Min(x, y int) int { if x < y { return x @@ -38,21 +37,6 @@ func PathExists(path string) bool { } return false } -func GetBetweenStr(str, start, end string) string { - n := strings.Index(str, start) - if n == -1 { - n = 0 - } else { - n = n + len(start) - } - str = string([]byte(str)[n:]) - m := strings.Index(str, end) - if m == -1 { - m = len(str) - } - str = string([]byte(str)[:m]) - return str -} func GetURLValue(Url, key string) string { u, _ := url.Parse(Url) query := u.Query() @@ -60,19 +44,17 @@ func GetURLValue(Url, key string) string { return query.Get(key) } -//返回一个32位md5加密后的字符串 func GetMD5Encode(data string) string { h := md5.New() h.Write([]byte(data)) return hex.EncodeToString(h.Sum(nil)) } -//返回一个16位md5加密后的字符串 func Get16MD5Encode(data string) string { return GetMD5Encode(data)[8:24] } -//只返回文件名 +// GetPathFiles only return file name func GetPathFiles(path string) []string { files, _ := ioutil.ReadDir(path) var t []string @@ -86,7 +68,7 @@ func GetPathFiles(path string) []string { return t } -//输入文件夹路径,返回最近n个log的路径,不到n个返回所有 +// GetRecentLogs 输入文件夹路径,返回最近n个log的路径,不到n个返回所有 func GetRecentLogs(path string, n int) []string { var paths []string if !PathExists(path) { @@ -110,3 +92,9 @@ func GetRecentLogs(path string, n int) []string { } return paths } +func IF(f bool, a interface{}, b interface{}) interface{} { + if f { + return a + } + return b +} From b8490fe1506d18f5289295b757a7b866a1e85eb5 Mon Sep 17 00:00:00 2001 From: iyear Date: Mon, 14 Jun 2021 23:02:01 +0800 Subject: [PATCH 08/29] remove CheckErr() --- util/util.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/util/util.go b/util/util.go index 88b3468..5ac5572 100644 --- a/util/util.go +++ b/util/util.go @@ -3,9 +3,7 @@ package util import ( "crypto/md5" "encoding/hex" - "fmt" "io/ioutil" - "log" "net/url" "os" "time" @@ -18,15 +16,6 @@ func Min(x, y int) int { } return y } -func CheckErr(err error) bool { - if err != nil { - log.Println(err) - fmt.Println("ERROR") - panic(err) - return false - } - return true -} func PathExists(path string) bool { _, err := os.Stat(path) if err == nil { From e50ce27d246e95c70b6904bea2e1aa865c32f82f Mon Sep 17 00:00:00 2001 From: iyear Date: Mon, 14 Jun 2021 23:02:42 +0800 Subject: [PATCH 09/29] remove mysql connection --- bots/bots.go | 51 +++++++++++++-------------------------------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/bots/bots.go b/bots/bots.go index 0ae152c..29a3681 100644 --- a/bots/bots.go +++ b/bots/bots.go @@ -1,8 +1,8 @@ package bots import ( - "database/sql" "fmt" + "github.com/iyear/E5SubBot/task" "github.com/robfig/cron/v3" "github.com/spf13/viper" "go.uber.org/zap" @@ -10,7 +10,6 @@ import ( tb "gopkg.in/tucnak/telebot.v2" "net/http" "strconv" - "strings" "time" ) @@ -18,12 +17,10 @@ var ( BotToken string Socks5 string bot *tb.Bot - //logger *log.Logger ) const ( - dbDriverName = "mysql" - logo = ` + logo = ` ______ _____ _____ _ ____ _ | ____| ____/ ____| | | | _ \ | | | |__ | |__| (___ _ _| |__ | |_) | ___ | |_ @@ -33,8 +30,6 @@ const ( ` ) -var dbPath string - func BotStart() { MakeHandle() TaskLaunch() @@ -57,14 +52,10 @@ func MakeHandle() { bot.Handle("/log", bLog) } func TaskLaunch() { - task := cron.New() - //每三小时执行一次 - task.AddFunc(viper.GetString("cron"), SignTask) - //log分为每天 - //task.AddFunc(" 0 0 * * *", InitLogger) - // */1 * * * * 1 */3 * * * + c := cron.New() + c.AddFunc(viper.GetString("cron"), task.SignTask) fmt.Println("Cron Task Start……") - task.Start() + c.Start() } func init() { fmt.Println(logo) @@ -75,28 +66,12 @@ func init() { viper.AddConfigPath(".") err := viper.ReadInConfig() if err != nil { - zap.S().Errorw("failed to read config","error",err) + zap.S().Errorw("failed to read config", "error", err) } - host := viper.GetString("mysql.host") - user := viper.GetString("mysql.user") - port := viper.GetString("mysql.port") - pwd := viper.GetString("mysql.password") - database := viper.GetString("mysql.database") - dbPath = strings.Join([]string{user, ":", pwd, "@tcp(", host, ":", port, ")/", database, "?charset=utf8"}, "") - //fmt.Println(path) - db, err := sql.Open(dbDriverName, dbPath) - if err != nil { - zap.S().Errorw("failed to connect db","error",err,"path",dbPath) - } - fmt.Println("Connect MySQL Success!") - if ok, err := CreateTB(); !ok { - zap.S().Errorw("failed to create table","error",err,"path",dbPath) - } - defer db.Close() BotToken = viper.GetString("bot_token") Socks5 = viper.GetString("socks5") Poller := &tb.LongPoller{Timeout: 15 * time.Second} - spamProtected := tb.NewMiddlewarePoller(Poller, func(upd *tb.Update) bool { + spamPoller := tb.NewMiddlewarePoller(Poller, func(upd *tb.Update) bool { if upd.Message == nil { return true } @@ -105,26 +80,26 @@ func init() { } return true }) - botsettings := tb.Settings{ + botSetting := tb.Settings{ Token: BotToken, - Poller: spamProtected, + Poller: spamPoller, } //set socks5 if Socks5 != "" { fmt.Println("Proxy:" + Socks5) dialer, err := proxy.SOCKS5("tcp", Socks5, nil, proxy.Direct) if err != nil { - zap.S().Errorw("failed to make dialer","error",err,"socks5",Socks5) + zap.S().Errorw("failed to make dialer", "error", err, "socks5", Socks5) } httpTransport := &http.Transport{} httpClient := &http.Client{Transport: httpTransport} httpTransport.Dial = dialer.Dial - botsettings.Client = httpClient + botSetting.Client = httpClient } //create bot - bot, err = tb.NewBot(botsettings) + bot, err = tb.NewBot(botSetting) if err != nil { - zap.S().Errorw("failed to create bot","error",err) + zap.S().Errorw("failed to create bot", "error", err) } fmt.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username) } From b026671553f9fe45d8c62eaaa1481c2edb7bdb2a Mon Sep 17 00:00:00 2001 From: iyear Date: Mon, 14 Jun 2021 23:03:16 +0800 Subject: [PATCH 10/29] remove SignTask() --- bots/control.go | 102 ------------------------------------------------ 1 file changed, 102 deletions(-) diff --git a/bots/control.go b/bots/control.go index 44ed7a2..65b14aa 100644 --- a/bots/control.go +++ b/bots/control.go @@ -7,15 +7,11 @@ import ( "github.com/iyear/E5SubBot/util" "github.com/spf13/viper" "github.com/tidwall/gjson" - "go.uber.org/zap" tb "gopkg.in/tucnak/telebot.v2" "strconv" "strings" - "time" ) -var SignOk map[int64]int - // BindUser If Successfully return "",else return error information func BindUser(m *tb.Message, ClientId, ClientSecret string) error { tmp := strings.Split(m.Text, " ") @@ -77,104 +73,6 @@ func MSAppIsExist(TgId int64, ClientId string) bool { First(&model.Client{}) return util.IF(result.RowsAffected == 0, false, true).(bool) } - -// func SignTask() { -// var ( -// SignOk map[int64]int -// SignErr []string -// UnbindUser []string -// num, signOk int -// ) -// SignOk = make(map[int64]int) -// fmt.Println("----Task Begin----") -// fmt.Println("Time:" + time.Now().Format("2006-01-02 15:04:05")) -// data := model.QueryDataAll() -// num = len(data) -// fmt.Println("Start Sign") -// //签到任务 -// for _, u := range data { -// pre := "您的账户: " + u.Alias + "\n在任务执行时出现了错误!\n错误:" -// chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10)) -// if err != nil { -// zap.S().Errorw("wrong chat id", "error", err, "tg_id", u.TgId) -// continue -// } -// //生成解绑按钮 -// var inlineKeys [][]tb.InlineButton -// UnBindBtn := tb.InlineButton{Unique: "un" + u.MsId, Text: "点击解绑该账户", Data: u.MsId} -// bot.Handle(&UnBindBtn, bUnBindInlineBtn) -// inlineKeys = append(inlineKeys, []tb.InlineButton{UnBindBtn}) -// tmpBtn := &tb.ReplyMarkup{InlineKeyboard: inlineKeys} -// -// se := u.MsId + " ( @" + chat.Username + " )" -// client := model.NewClient(u.ClientId, u.ClientSecret) -// if err := client.GetOutlookMails(); err != nil { -// zap.S().Errorw("failed to get outlook mails", "error", err, "ms_id", u.MsId) -// bot.Send(chat, pre+err.Error(), tmpBtn) -// ErrorTimes[u.MsId]++ -// SignErr = append(SignErr, se) -// continue -// } -// u.Uptime = time.Now().Unix() -// u.RefreshToken = newRefreshToken -// if ok, err := model.UpdateData(u); !ok { -// zap.S().Errorw("failed to update db data", "error", err, "ms_id", u.MsId) -// bot.Send(chat, pre+err.Error(), tmpBtn) -// SignErr = append(SignErr, se) -// ErrorTimes[u.MsId]++ -// continue -// } -// fmt.Println(u.MsId + " Sign OK!") -// SignOk[u.TgId]++ -// signOk++ -// } -// fmt.Println("Sign End,Start Send") -// var isSend map[int64]bool -// isSend = make(map[int64]bool) -// //用户任务反馈 -// for _, u := range data { -// chat, err := bot.ChatByID(strconv.FormatInt(u.TgId, 10)) -// if err != nil { -// zap.S().Errorw("failed to get chat", "error", err, "tg_id", u.TgId) -// continue -// } -// //错误上限账户清退 -// if ErrorTimes[u.MsId] == ErrMaxTimes { -// zap.S().Errorw("binding max num limit", "ms_id", u.MsId) -// if ok, err := model.DelData(u.MsId); !ok { -// zap.S().Errorw("failed to delete db data", "error", err, "ms_id", u.MsId) -// } else { -// UnbindUser = append(UnbindUser, u.MsId+" ( @"+chat.Username+" )") -// bot.Send(chat, "您的账户因达到错误上限而被自动解绑\n后会有期!\n\n别名: "+u.Alias+"\nclient_id: "+u.ClientId+"\nclient_secret: "+u.ClientSecret) -// } -// -// } -// if !isSend[u.TgId] { -// //静默发送,过多消息很烦 -// 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}) -// isSend[u.TgId] = true -// } -// } -// //管理员任务反馈 -// var ErrUserStr string -// var UnbindUserStr string -// for _, eu := range SignErr { -// ErrUserStr = ErrUserStr + eu + "\n" -// } -// for _, ubu := range UnbindUser { -// UnbindUserStr = UnbindUserStr + ubu + "\n" -// } -// for _, a := range admin { -// chat, err := bot.ChatByID(strconv.FormatInt(a, 10)) -// if err != nil { -// zap.S().Errorw("failed to get chat", "error", err, "tg_id", a) -// continue -// } -// 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) -// } -// fmt.Println("----Task End----") -//} - func GetAdmins() []int64 { var result []int64 admins := strings.Split(viper.GetString("admin"), ",") From 9d6db79a33a48435a0eac369ba76764545615d17 Mon Sep 17 00:00:00 2001 From: iyear Date: Mon, 14 Jun 2021 23:17:11 +0800 Subject: [PATCH 11/29] Beautify and independently config --- bots/control.go | 11 --- bots/handle.go | 204 ++++++++++++++++++++++------------------------- config/config.go | 63 +++++++++++++++ 3 files changed, 159 insertions(+), 119 deletions(-) create mode 100644 config/config.go diff --git a/bots/control.go b/bots/control.go index 65b14aa..566f458 100644 --- a/bots/control.go +++ b/bots/control.go @@ -5,10 +5,8 @@ import ( "fmt" "github.com/iyear/E5SubBot/model" "github.com/iyear/E5SubBot/util" - "github.com/spf13/viper" "github.com/tidwall/gjson" tb "gopkg.in/tucnak/telebot.v2" - "strconv" "strings" ) @@ -73,12 +71,3 @@ func MSAppIsExist(TgId int64, ClientId string) bool { First(&model.Client{}) return util.IF(result.RowsAffected == 0, false, true).(bool) } -func GetAdmins() []int64 { - var result []int64 - admins := strings.Split(viper.GetString("admin"), ",") - for _, v := range admins { - id, _ := strconv.ParseInt(v, 10, 64) - result = append(result, id) - } - return result -} diff --git a/bots/handle.go b/bots/handle.go index 37af50a..92216a2 100644 --- a/bots/handle.go +++ b/bots/handle.go @@ -2,10 +2,11 @@ package bots import ( "encoding/json" - "github.com/fsnotify/fsnotify" - "github.com/iyear/E5SubBot/core" + "fmt" + "github.com/iyear/E5SubBot/config" + "github.com/iyear/E5SubBot/model" + "github.com/iyear/E5SubBot/task" "github.com/iyear/E5SubBot/util" - "github.com/spf13/viper" "go.uber.org/zap" tb "gopkg.in/tucnak/telebot.v2" "io/ioutil" @@ -16,29 +17,10 @@ import ( "time" ) -const ( - bLogBasePath string = "./log/" - bStartContent string = "欢迎使用E5SubBot!" - bHelpContent string = ` - 命令: - /my 查看已绑定账户信息 - /bind 绑定新账户 - /unbind 解绑账户 - /export 导出账户信息(JSON) - /help 帮助 - 源码及使用方法:https://github.com/iyear/E5SubBot -` -) - 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 + UserClientId map[int64]string + UserClientSecret map[int64]string ) const ( @@ -48,41 +30,19 @@ const ( ) func init() { - //read config - viper.SetConfigName("config") - viper.AddConfigPath(".") - err := viper.ReadInConfig() - util.CheckErr(err) - - viper.SetDefault("errlimit", 5) - viper.SetDefault("bindmax", 5) - - BindMaxNum = viper.GetInt("bindmax") - ErrMaxTimes = viper.GetInt("errlimit") - notice = viper.GetString("notice") - admin = GetAdmin() - - viper.WatchConfig() - viper.OnConfigChange(func(e fsnotify.Event) { - BindMaxNum = viper.GetInt("bindmax") - ErrMaxTimes = viper.GetInt("errlimit") - notice = viper.GetString("notice") - admin = GetAdmin() - }) - UserStatus = make(map[int64]int) - UserCid = make(map[int64]string) - UserCSecret = make(map[int64]string) - ErrorTimes = make(map[string]int) + UserClientId = make(map[int64]string) + UserClientSecret = make(map[int64]string) } func bStart(m *tb.Message) { - bot.Send(m.Sender, bStartContent) + bot.Send(m.Sender, config.WelcomeContent) bHelp(m) } func bMy(m *tb.Message) { - data := core.QueryDataByTG(m.Chat.ID) + var data []*model.Client + model.DB.Where("tg_id = ?", m.Chat.ID).Find(&data) var inlineKeys [][]tb.InlineButton for _, u := range data { inlineBtn := tb.InlineButton{ @@ -93,20 +53,34 @@ 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, + fmt.Sprintf("选择一个账户查看具体信息\n\n绑定数: %d/%d", GetBindNum(m.Chat.ID), config.BindMaxNum), + &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) } func bMyInlineBtn(c *tb.Callback) { - r := core.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")) + var u *model.Client + model.DB.Where("ms_id = ?", c.Data).First(&u) + bot.Send(c.Message.Chat, + fmt.Sprintf("信息\n别名:%s\nMS_ID(MD5): %s\nclient_id: %s\nclient_secret: %s\n最近更新时间: %s", + u.Alias, + u.MsId, + u.ClientId, + u.ClientSecret, + time.Unix(u.Uptime, 0).Format("2006-01-02 15:04:05")), + ) bot.Respond(c) } func bBind1(m *tb.Message) { - bot.Send(m.Chat, "应用注册: [点击直达]("+core.GetMSRegisterAppUrl()+")", tb.ModeMarkdown) - bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true}) + bot.Send(m.Chat, + fmt.Sprintf("应用注册: [点击直达](%s)", model.GetMSRegisterAppUrl()), + tb.ModeMarkdown) + bot.Send(m.Chat, + "请回复client_id(空格)client_secret", + &tb.ReplyMarkup{ForceReply: true}) UserStatus[m.Chat.ID] = USBind1 - UserCid[m.Chat.ID] = m.Text + UserClientId[m.Chat.ID] = m.Text } func bBind2(m *tb.Message) { tmp := strings.Split(m.Text, " ") @@ -114,21 +88,22 @@ func bBind2(m *tb.Message) { bot.Send(m.Chat, "错误的格式") return } - cid := tmp[0] - cse := tmp[1] - bot.Send(m.Chat, "授权账户: [点击直达]("+core.GetMSAuthUrl(cid)+")", tb.ModeMarkdown) - _, err := bot.Send(m.Chat, "请回复http://localhost/…… + 空格 + 别名(用于管理)", &tb.ReplyMarkup{ForceReply: true}) - if err != nil { - return - } + ClientId := tmp[0] + ClientSecret := tmp[1] + bot.Send(m.Chat, "授权账户: [点击直达]("+model.GetMSAuthUrl(ClientId)+")", tb.ModeMarkdown) + bot.Send(m.Chat, + "请回复http://localhost/…… + 空格 + 别名(用于管理)", + &tb.ReplyMarkup{ForceReply: true}) UserStatus[m.Chat.ID] = USBind2 - UserCid[m.Chat.ID] = cid - UserCSecret[m.Chat.ID] = cse + UserClientId[m.Chat.ID] = ClientId + UserClientSecret[m.Chat.ID] = ClientSecret } func bUnBind(m *tb.Message) { - data := core.QueryDataByTG(m.Chat.ID) + var data []*model.Client + model.DB.Where("tg_id = ?", m.Chat.ID).Find(&data) var inlineKeys [][]tb.InlineButton + for _, u := range data { inlineBtn := tb.InlineButton{ Unique: "unbind" + u.MsId, @@ -138,13 +113,18 @@ 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, + fmt.Sprintf("选择一个账户将其解绑\n\n当前绑定数: %d/%d", GetBindNum(m.Chat.ID), config.BindMaxNum), + &tb.ReplyMarkup{InlineKeyboard: inlineKeys}, + ) } func bUnBindInlineBtn(c *tb.Callback) { - r := core.QueryDataByMS(c.Data) - u := r[0] - if ok, err := core.DelData(u.MsId); !ok { - zap.S().Errorw("failed to delete db data","error",err,"ms_id",u.MsId) + if result := model.DB.Where("ms_id = ?", c.Data).Delete(&model.Client{}); result.Error != nil { + zap.S().Errorw("failed to delete db data", + "error", result.Error, + "ms_id", c.Data, + ) bot.Send(c.Message.Chat, "解绑失败!") return } @@ -152,43 +132,49 @@ func bUnBindInlineBtn(c *tb.Callback) { bot.Respond(c) } func bExport(m *tb.Message) { - type MsMiniData struct { + type ClientExport struct { Alias string ClientId string ClientSecret string RefreshToken string Other string } - var MsMini []MsMiniData - data := core.QueryDataByTG(m.Chat.ID) + var exports []ClientExport + var data []*model.Client + model.DB.Where("tg_id = ?", m.Chat.ID).Find(&data) if len(data) == 0 { bot.Send(m.Chat, "你还没有绑定过账户嗷~") return } for _, u := range data { - var ms MsMiniData - ms.RefreshToken = u.RefreshToken - ms.Alias = u.Alias - ms.ClientId = u.ClientId - ms.ClientSecret = u.ClientSecret - ms.Other = u.Other - MsMini = append(MsMini, ms) + var cExport = ClientExport{ + Alias: u.Alias, + ClientId: u.ClientId, + ClientSecret: u.ClientSecret, + RefreshToken: u.RefreshToken, + Other: u.Other, + } + exports = append(exports, cExport) } - //MarshalIndent json美化,/t缩进 - export, err := json.MarshalIndent(MsMini, "", "\t") + export, err := json.MarshalIndent(exports, "", "\t") if err != nil { - zap.S().Errorw("failed to marshal json","error",err) - bot.Send(m.Chat, "获取JSON失败~\n"+err.Error()) + zap.S().Errorw("failed to marshal json", + "error", err) + bot.Send(m.Chat, fmt.Sprintf("获取JSON失败!\n\nERROR: %s", err.Error())) return } - //fmt.Println(string(export)) - fileName := "./" + strconv.FormatInt(m.Chat.ID, 10) + "_export_tmp.json" + fileName := fmt.Sprintf("./%d_export_tmp.json", m.Chat.ID) if err = ioutil.WriteFile(fileName, export, 0644); err != nil { - zap.S().Errorw("failed to write file","error",err) + zap.S().Errorw("failed to write file", + "error", err) bot.Send(m.Chat, "写入临时文件失败~\n"+err.Error()) return } - exportFile := &tb.Document{File: tb.FromDisk(fileName), FileName: strconv.FormatInt(m.Chat.ID, 10) + ".json", MIME: "text/plain"} + exportFile := &tb.Document{ + File: tb.FromDisk(fileName), + FileName: strconv.FormatInt(m.Chat.ID, 10) + ".json", + MIME: "text/plain", + } bot.Send(m.Chat, exportFile) //不遗留本地文件 if exportFile.InCloud() != true || os.Remove(fileName) != nil { @@ -196,7 +182,10 @@ func bExport(m *tb.Message) { } } func bHelp(m *tb.Message) { - bot.Send(m.Sender, bHelpContent+"\n"+notice, &tb.SendOptions{DisableWebPagePreview: false}) + bot.Send( + m.Sender, + config.HelpContent+"\n"+config.Notice, + &tb.SendOptions{DisableWebPagePreview: false}) } func bOnText(m *tb.Message) { switch UserStatus[m.Chat.ID] { @@ -219,12 +208,12 @@ func bOnText(m *tb.Message) { bot.Send(m.Chat, "请通过回复方式绑定") return } - if GetBindNum(m.Chat.ID) == BindMaxNum { + if GetBindNum(m.Chat.ID) == config.BindMaxNum { bot.Send(m.Chat, "已经达到最大可绑定数") return } bot.Send(m.Chat, "正在绑定中……") - err := BindUser(m, UserCid[m.Chat.ID], UserCSecret[m.Chat.ID]) + err := BindUser(m, UserClientId[m.Chat.ID], UserClientSecret[m.Chat.ID]) if err != nil { bot.Send(m.Chat, err.Error()) } else { @@ -235,26 +224,26 @@ func bOnText(m *tb.Message) { } } func bTask(m *tb.Message) { - for _, a := range admin { + for _, a := range config.Admins { if a == m.Chat.ID { - SignTask() + task.SignTask() return } } - bot.Send(m.Chat, "您没有权限执行此操作~") + bot.Send(m.Chat, "只有Bot管理员才有权限执行此操作") } func bLog(m *tb.Message) { flag := 0 - for _, a := range admin { + for _, a := range config.Admins { if a == m.Chat.ID { flag = 1 } } if flag == 0 { - bot.Send(m.Chat, "您没有权限执行此操作~") + bot.Send(m.Chat, "只有Bot管理员才有权限执行此操作") return } - logs := util.GetRecentLogs(bLogBasePath, 5) + logs := util.GetRecentLogs(config.LogBasePath, 5) var inlineKeys [][]tb.InlineButton for _, log := range logs { inlineBtn := tb.InlineButton{ @@ -265,15 +254,14 @@ func bLog(m *tb.Message) { bot.Handle(&inlineBtn, bLogsInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) } - bot.Send(m.Chat, "选择一个日志", &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) + bot.Send(m.Chat, "请选择日志", &tb.ReplyMarkup{InlineKeyboard: inlineKeys}) } func bLogsInlineBtn(c *tb.Callback) { - //fmt.Println(c.Data) - //logger.Println(bLogBasePath + c.Data + ".log") - logfile := &tb.Document{File: tb.FromDisk(bLogBasePath + c.Data), FileName: c.Data, MIME: "text/plain"} - _, err := bot.Send(c.Message.Chat, logfile) - if err != nil { - return + logfile := &tb.Document{ + File: tb.FromDisk(config.LogBasePath + c.Data), + FileName: c.Data, + MIME: "text/plain", } + bot.Send(c.Message.Chat, logfile) bot.Respond(c) } diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..5e8ea2b --- /dev/null +++ b/config/config.go @@ -0,0 +1,63 @@ +package config + +import ( + "github.com/fsnotify/fsnotify" + "github.com/spf13/viper" + "strconv" + "strings" +) + +const ( + LogBasePath string = "./log/" + WelcomeContent string = "欢迎使用E5SubBot!" + HelpContent string = ` + 命令: + /my 查看已绑定账户信息 + /bind 绑定新账户 + /unbind 解绑账户 + /export 导出账户信息(JSON) + /help 帮助 + 源码及使用方法:https://github.com/iyear/E5SubBot +` +) + +var ( + ErrorTimes map[string]int //错误次数 + BindMaxNum int + ErrMaxTimes int + Notice string + Admins []int64 +) + +func InitConfig() { + viper.SetConfigName("config") + viper.AddConfigPath(".") + err := viper.ReadInConfig() + if err != nil { + + } + viper.SetDefault("errlimit", 5) + viper.SetDefault("bindmax", 5) + + BindMaxNum = viper.GetInt("bindmax") + ErrMaxTimes = viper.GetInt("errlimit") + Notice = viper.GetString("notice") + Admins = getAdmins() + + viper.WatchConfig() + viper.OnConfigChange(func(e fsnotify.Event) { + BindMaxNum = viper.GetInt("bindmax") + ErrMaxTimes = viper.GetInt("errlimit") + Notice = viper.GetString("notice") + Admins = getAdmins() + }) +} +func getAdmins() []int64 { + var result []int64 + admins := strings.Split(viper.GetString("admin"), ",") + for _, v := range admins { + id, _ := strconv.ParseInt(v, 10, 64) + result = append(result, id) + } + return result +} From 6d142803ccc50a384868fd2a768c7559fc050992 Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 15 Jun 2021 09:02:17 +0800 Subject: [PATCH 12/29] remove error return --- model/sqlite.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/model/sqlite.go b/model/sqlite.go index f7699fb..f14e0d5 100644 --- a/model/sqlite.go +++ b/model/sqlite.go @@ -1,6 +1,7 @@ package model import ( + "go.uber.org/zap" "gorm.io/driver/sqlite" "gorm.io/gorm" "time" @@ -8,16 +9,15 @@ import ( var DB *gorm.DB -func InitDB() error { +func InitDB() { var err error DB, err = gorm.Open(sqlite.Open("data.db"), &gorm.Config{ NowFunc: func() time.Time { - return time.Now().UTC() + return time.Now() }, }) if err != nil { - return err + zap.S().Errorw("failed to open db", "error", err) } DB.AutoMigrate(&Client{}) - return nil } From a1e68cdc5c424b054182d01ec0c24184564769f4 Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 15 Jun 2021 09:59:22 +0800 Subject: [PATCH 13/29] fix client EOF error --- model/client.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/model/client.go b/model/client.go index 6db5a02..006c8ee 100644 --- a/model/client.go +++ b/model/client.go @@ -1,6 +1,7 @@ package model import ( + "fmt" "github.com/pkg/errors" "github.com/tidwall/gjson" "io/ioutil" @@ -10,7 +11,7 @@ import ( ) type Client struct { - TgId int64 `gorm:"unique;not null"` + TgId int64 `gorm:"not null"` RefreshToken string `gorm:"not null"` MsId string `gorm:"unique;primaryKey;not null"` Uptime int64 `gorm:"autoUpdateTime;not null"` @@ -43,7 +44,7 @@ func GetMSRegisterAppUrl() string { return appUrl } -//return access_token and refresh_token +// GetTokenWithCode return access_token and refresh_token func (c *Client) GetTokenWithCode(code string) (error error) { var r http.Request client := &http.Client{} @@ -59,6 +60,11 @@ func (c *Client) GetTokenWithCode(code string) (error error) { if err != nil { return err } + + //prevents the connection from being re-used + ////https://stackoverflow.com/questions/17714494/golang-http-request-results-in-eof-errors-when-making-multiple-requests-successi + req.Close = true + resp, err := client.Do(req) if err != nil { return err @@ -92,6 +98,7 @@ func (c *Client) getToken() (access string) { if err != nil { return "" } + req.Close = true resp, err := client.Do(req) if err != nil { return "" @@ -101,8 +108,6 @@ func (c *Client) getToken() (access string) { if err != nil { return "" } - //fmt.Println(string(content)) - //fmt.Println(gjson.Get(string(content), "access_token").String()) if gjson.Get(string(content), "token_type").String() == "Bearer" { c.RefreshToken = gjson.Get(string(content), "refresh_token").String() return gjson.Get(string(content), "access_token").String() @@ -110,13 +115,16 @@ func (c *Client) getToken() (access string) { return "" } -//Get User's Information +// GetUserInfo Get User's Information func (c *Client) GetUserInfo() (json string, error error) { client := http.Client{} req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me", nil) if err != nil { return "", err } + + req.Close = true + req.Header.Set("Authorization", c.getToken()) resp, err := client.Do(req) if err != nil { @@ -124,6 +132,7 @@ func (c *Client) GetUserInfo() (json string, error error) { } defer resp.Body.Close() content, err := ioutil.ReadAll(resp.Body) + fmt.Println(string(content)) if err != nil { return "", err } @@ -137,10 +146,10 @@ func (c *Client) GetUserInfo() (json string, error error) { func (c *Client) GetOutlookMails() error { client := http.Client{} req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me/messages", nil) - if err != nil { return err } + req.Close = true req.Header.Set("Authorization", c.getToken()) resp, err := client.Do(req) if err != nil { From 15e9d93abdc9586c002d2773c5715fdc8bc1b655 Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 15 Jun 2021 10:00:51 +0800 Subject: [PATCH 14/29] independent config --- bots/bots.go | 95 +++++++++++++++++++++++------------------------- config/config.go | 9 ++++- 2 files changed, 53 insertions(+), 51 deletions(-) diff --git a/bots/bots.go b/bots/bots.go index 29a3681..1d55473 100644 --- a/bots/bots.go +++ b/bots/bots.go @@ -2,6 +2,9 @@ package bots import ( "fmt" + "github.com/iyear/E5SubBot/config" + "github.com/iyear/E5SubBot/logger" + "github.com/iyear/E5SubBot/model" "github.com/iyear/E5SubBot/task" "github.com/robfig/cron/v3" "github.com/spf13/viper" @@ -14,9 +17,7 @@ import ( ) var ( - BotToken string - Socks5 string - bot *tb.Bot + bot *tb.Bot ) const ( @@ -31,6 +32,48 @@ const ( ) func BotStart() { + var err error + fmt.Println(logo) + //read config + config.InitConfig() + //Init Logger + logger.InitLogger() + //InitDB + model.InitDB() + Poller := &tb.LongPoller{Timeout: 15 * time.Second} + spamPoller := tb.NewMiddlewarePoller(Poller, func(upd *tb.Update) bool { + if upd.Message == nil { + return true + } + if !upd.Message.Private() { + return false + } + return true + }) + botSetting := tb.Settings{ + Token: config.BotToken, + Poller: spamPoller, + } + //set socks5 + if config.Socks5 != "" { + fmt.Println("Proxy:" + config.Socks5) + dialer, err := proxy.SOCKS5("tcp", config.Socks5, nil, proxy.Direct) + if err != nil { + zap.S().Errorw("failed to make dialer", "error", err, "socks5", config.Socks5) + } + httpTransport := &http.Transport{} + httpClient := &http.Client{Transport: httpTransport} + httpTransport.Dial = dialer.Dial + botSetting.Client = httpClient + } + //create bot + bot, err = tb.NewBot(botSetting) + if err != nil { + zap.S().Errorw("failed to create bot", "error", err) + return + } + fmt.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username) + MakeHandle() TaskLaunch() fmt.Println("Bot Start") @@ -57,49 +100,3 @@ func TaskLaunch() { fmt.Println("Cron Task Start……") c.Start() } -func init() { - fmt.Println(logo) - - //read config - fmt.Println("Read Config……") - viper.SetConfigName("config") - viper.AddConfigPath(".") - err := viper.ReadInConfig() - if err != nil { - zap.S().Errorw("failed to read config", "error", err) - } - BotToken = viper.GetString("bot_token") - Socks5 = viper.GetString("socks5") - Poller := &tb.LongPoller{Timeout: 15 * time.Second} - spamPoller := tb.NewMiddlewarePoller(Poller, func(upd *tb.Update) bool { - if upd.Message == nil { - return true - } - if !upd.Message.Private() { - return false - } - return true - }) - botSetting := tb.Settings{ - Token: BotToken, - Poller: spamPoller, - } - //set socks5 - if Socks5 != "" { - fmt.Println("Proxy:" + Socks5) - dialer, err := proxy.SOCKS5("tcp", Socks5, nil, proxy.Direct) - if err != nil { - zap.S().Errorw("failed to make dialer", "error", err, "socks5", Socks5) - } - httpTransport := &http.Transport{} - httpClient := &http.Client{Transport: httpTransport} - httpTransport.Dial = dialer.Dial - botSetting.Client = httpClient - } - //create bot - bot, err = tb.NewBot(botSetting) - if err != nil { - zap.S().Errorw("failed to create bot", "error", err) - } - fmt.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username) -} diff --git a/config/config.go b/config/config.go index 5e8ea2b..a934042 100644 --- a/config/config.go +++ b/config/config.go @@ -3,6 +3,7 @@ package config import ( "github.com/fsnotify/fsnotify" "github.com/spf13/viper" + "go.uber.org/zap" "strconv" "strings" ) @@ -22,7 +23,8 @@ const ( ) var ( - ErrorTimes map[string]int //错误次数 + BotToken string + Socks5 string BindMaxNum int ErrMaxTimes int Notice string @@ -34,8 +36,11 @@ func InitConfig() { viper.AddConfigPath(".") err := viper.ReadInConfig() if err != nil { - + zap.S().Errorw("failed to read config", "error", err) } + BotToken = viper.GetString("bot_token") + Socks5 = viper.GetString("socks5") + viper.SetDefault("errlimit", 5) viper.SetDefault("bindmax", 5) From 956942419b11246067df658446c48b40f7b5e2ea Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 15 Jun 2021 18:27:28 +0800 Subject: [PATCH 15/29] independent sign task --- bots/bots.go | 13 +++---------- bots/handle.go | 3 +-- config/config.go | 21 +++++++++++++-------- model/client.go | 32 ++++++++++++++++++-------------- 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/bots/bots.go b/bots/bots.go index 1d55473..cc5f428 100644 --- a/bots/bots.go +++ b/bots/bots.go @@ -5,9 +5,6 @@ import ( "github.com/iyear/E5SubBot/config" "github.com/iyear/E5SubBot/logger" "github.com/iyear/E5SubBot/model" - "github.com/iyear/E5SubBot/task" - "github.com/robfig/cron/v3" - "github.com/spf13/viper" "go.uber.org/zap" "golang.org/x/net/proxy" tb "gopkg.in/tucnak/telebot.v2" @@ -40,6 +37,9 @@ func BotStart() { logger.InitLogger() //InitDB model.InitDB() + //Init Task + InitTask() + Poller := &tb.LongPoller{Timeout: 15 * time.Second} spamPoller := tb.NewMiddlewarePoller(Poller, func(upd *tb.Update) bool { if upd.Message == nil { @@ -75,7 +75,6 @@ func BotStart() { fmt.Println("Bot: " + strconv.Itoa(bot.Me.ID) + " " + bot.Me.Username) MakeHandle() - TaskLaunch() fmt.Println("Bot Start") fmt.Println("------------") bot.Start() @@ -94,9 +93,3 @@ func MakeHandle() { bot.Handle("/task", bTask) bot.Handle("/log", bLog) } -func TaskLaunch() { - c := cron.New() - c.AddFunc(viper.GetString("cron"), task.SignTask) - fmt.Println("Cron Task Start……") - c.Start() -} diff --git a/bots/handle.go b/bots/handle.go index 92216a2..78581ef 100644 --- a/bots/handle.go +++ b/bots/handle.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/iyear/E5SubBot/config" "github.com/iyear/E5SubBot/model" - "github.com/iyear/E5SubBot/task" "github.com/iyear/E5SubBot/util" "go.uber.org/zap" tb "gopkg.in/tucnak/telebot.v2" @@ -226,7 +225,7 @@ func bOnText(m *tb.Message) { func bTask(m *tb.Message) { for _, a := range config.Admins { if a == m.Chat.ID { - task.SignTask() + SignTask() return } } diff --git a/config/config.go b/config/config.go index a934042..25e7c99 100644 --- a/config/config.go +++ b/config/config.go @@ -23,12 +23,14 @@ const ( ) var ( - BotToken string - Socks5 string - BindMaxNum int - ErrMaxTimes int - Notice string - Admins []int64 + BotToken string + Socks5 string + BindMaxNum int + MaxGoroutines int + MaxErrTimes int + Cron string + Notice string + Admins []int64 ) func InitConfig() { @@ -45,14 +47,17 @@ func InitConfig() { viper.SetDefault("bindmax", 5) BindMaxNum = viper.GetInt("bindmax") - ErrMaxTimes = viper.GetInt("errlimit") + MaxErrTimes = viper.GetInt("errlimit") Notice = viper.GetString("notice") + Cron = viper.GetString("cron") + MaxGoroutines = viper.GetInt("goroutine") Admins = getAdmins() viper.WatchConfig() viper.OnConfigChange(func(e fsnotify.Event) { + MaxGoroutines = viper.GetInt("goroutine") BindMaxNum = viper.GetInt("bindmax") - ErrMaxTimes = viper.GetInt("errlimit") + MaxErrTimes = viper.GetInt("errlimit") Notice = viper.GetString("notice") Admins = getAdmins() }) diff --git a/model/client.go b/model/client.go index 006c8ee..40c5bdc 100644 --- a/model/client.go +++ b/model/client.go @@ -1,25 +1,29 @@ package model import ( - "fmt" "github.com/pkg/errors" "github.com/tidwall/gjson" "io/ioutil" "net/http" "net/url" "strings" + "time" ) type Client struct { TgId int64 `gorm:"not null"` RefreshToken string `gorm:"not null"` - MsId string `gorm:"unique;primaryKey;not null"` + MsId string `gorm:"not null"` Uptime int64 `gorm:"autoUpdateTime;not null"` Alias string `gorm:"not null"` ClientId string `gorm:"not null"` ClientSecret string `gorm:"not null"` Other string } +type ErrClient struct { + *Client + Err error +} const ( msApiUrl string = "https://login.microsoftonline.com" @@ -28,6 +32,15 @@ const ( scope string = "openid offline_access mail.read user.read" ) +var client = &http.Client{} + +func init() { + client.Timeout = 10 * time.Second + tp := http.DefaultTransport.(*http.Transport).Clone() + tp.MaxIdleConns = 100 + tp.MaxIdleConnsPerHost = 100 + client.Transport = tp +} func NewClient(clientId string, clientSecret string) *Client { return &Client{ ClientId: clientId, @@ -47,7 +60,6 @@ func GetMSRegisterAppUrl() string { // GetTokenWithCode return access_token and refresh_token func (c *Client) GetTokenWithCode(code string) (error error) { var r http.Request - client := &http.Client{} r.ParseForm() r.Form.Add("client_id", c.ClientId) r.Form.Add("client_secret", c.ClientSecret) @@ -60,17 +72,15 @@ func (c *Client) GetTokenWithCode(code string) (error error) { if err != nil { return err } - //prevents the connection from being re-used ////https://stackoverflow.com/questions/17714494/golang-http-request-results-in-eof-errors-when-making-multiple-requests-successi - req.Close = true - resp, err := client.Do(req) if err != nil { return err } defer resp.Body.Close() content, err := ioutil.ReadAll(resp.Body) + if err != nil { return err } @@ -84,7 +94,6 @@ func (c *Client) GetTokenWithCode(code string) (error error) { //return access_token and new refresh token func (c *Client) getToken() (access string) { var r http.Request - client := &http.Client{} r.ParseForm() r.Form.Add("client_id", c.ClientId) r.Form.Add("client_secret", c.ClientSecret) @@ -98,7 +107,6 @@ func (c *Client) getToken() (access string) { if err != nil { return "" } - req.Close = true resp, err := client.Do(req) if err != nil { return "" @@ -117,14 +125,11 @@ func (c *Client) getToken() (access string) { // GetUserInfo Get User's Information func (c *Client) GetUserInfo() (json string, error error) { - client := http.Client{} req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me", nil) if err != nil { return "", err } - req.Close = true - req.Header.Set("Authorization", c.getToken()) resp, err := client.Do(req) if err != nil { @@ -132,7 +137,7 @@ func (c *Client) GetUserInfo() (json string, error error) { } defer resp.Body.Close() content, err := ioutil.ReadAll(resp.Body) - fmt.Println(string(content)) + if err != nil { return "", err } @@ -144,12 +149,10 @@ func (c *Client) GetUserInfo() (json string, error error) { } func (c *Client) GetOutlookMails() error { - client := http.Client{} req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me/messages", nil) if err != nil { return err } - req.Close = true req.Header.Set("Authorization", c.getToken()) resp, err := client.Do(req) if err != nil { @@ -157,6 +160,7 @@ func (c *Client) GetOutlookMails() error { } defer resp.Body.Close() content, err := ioutil.ReadAll(resp.Body) + if err != nil { return err } From f572bdb1e0f2ee01321f75faabc8929002328bff Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 15 Jun 2021 18:44:51 +0800 Subject: [PATCH 16/29] add primaryKey ID field --- bots/control.go | 3 +-- bots/handle.go | 14 +++++++------- model/client.go | 1 + 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bots/control.go b/bots/control.go index 566f458..23b612a 100644 --- a/bots/control.go +++ b/bots/control.go @@ -29,8 +29,7 @@ func BindUser(m *tb.Message, ClientId, ClientSecret string) error { return err } var u = &model.Client{ - TgId: m.Chat.ID, - //TG的Data传递最高64bytes,一些MsId超过了报错BUTTON_DATA_INVALID (0),采取md5 + TgId: m.Chat.ID, RefreshToken: cli.RefreshToken, MsId: util.Get16MD5Encode(gjson.Get(info, "id").String()), Alias: Alias, diff --git a/bots/handle.go b/bots/handle.go index 78581ef..199fcfb 100644 --- a/bots/handle.go +++ b/bots/handle.go @@ -45,9 +45,9 @@ func bMy(m *tb.Message) { var inlineKeys [][]tb.InlineButton for _, u := range data { inlineBtn := tb.InlineButton{ - Unique: "my" + u.MsId, + Unique: "my" + strconv.Itoa(u.ID), Text: u.Alias, - Data: u.MsId, + Data: strconv.Itoa(u.ID), } bot.Handle(&inlineBtn, bMyInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) @@ -59,7 +59,7 @@ func bMy(m *tb.Message) { } func bMyInlineBtn(c *tb.Callback) { var u *model.Client - model.DB.Where("ms_id = ?", c.Data).First(&u) + model.DB.Where("id = ?", c.Data).First(&u) bot.Send(c.Message.Chat, fmt.Sprintf("信息\n别名:%s\nMS_ID(MD5): %s\nclient_id: %s\nclient_secret: %s\n最近更新时间: %s", u.Alias, @@ -105,9 +105,9 @@ func bUnBind(m *tb.Message) { for _, u := range data { inlineBtn := tb.InlineButton{ - Unique: "unbind" + u.MsId, + Unique: "unbind" + strconv.Itoa(u.ID), Text: u.Alias, - Data: u.MsId, + Data: strconv.Itoa(u.ID), } bot.Handle(&inlineBtn, bUnBindInlineBtn) inlineKeys = append(inlineKeys, []tb.InlineButton{inlineBtn}) @@ -119,10 +119,10 @@ func bUnBind(m *tb.Message) { ) } func bUnBindInlineBtn(c *tb.Callback) { - if result := model.DB.Where("ms_id = ?", c.Data).Delete(&model.Client{}); result.Error != nil { + if result := model.DB.Where("id = ?", c.Data).Delete(&model.Client{}); result.Error != nil { zap.S().Errorw("failed to delete db data", "error", result.Error, - "ms_id", c.Data, + "id", c.Data, ) bot.Send(c.Message.Chat, "解绑失败!") return diff --git a/model/client.go b/model/client.go index 40c5bdc..8385972 100644 --- a/model/client.go +++ b/model/client.go @@ -11,6 +11,7 @@ import ( ) type Client struct { + ID int `gorm:"unique;primaryKey;not null"` TgId int64 `gorm:"not null"` RefreshToken string `gorm:"not null"` MsId string `gorm:"not null"` From 0c2cc1ee066c0ff6b0d9be6305bc8327208c9c3c Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 15 Jun 2021 19:04:26 +0800 Subject: [PATCH 17/29] improve messages --- bots/control.go | 5 +++-- bots/handle.go | 33 ++++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/bots/control.go b/bots/control.go index 23b612a..5178fc6 100644 --- a/bots/control.go +++ b/bots/control.go @@ -44,10 +44,11 @@ func BindUser(m *tb.Message, ClientId, ClientSecret string) error { } //MS information has gotten bot.Send(m.Chat, - fmt.Sprintf("MS_ID(MD5): %s\nuserPrincipalName: %s\ndisplayName: %s\n", + fmt.Sprintf("ms_id(MD5):%s\nuserPrincipalName:%s\ndisplayName:%s", u.MsId, gjson.Get(info, "userPrincipalName").String(), - gjson.Get(info, "displayName").String()), + gjson.Get(info, "displayName").String(), + ), ) if result := model.DB.Create(&u); result.Error != nil { diff --git a/bots/handle.go b/bots/handle.go index 199fcfb..9182547 100644 --- a/bots/handle.go +++ b/bots/handle.go @@ -60,13 +60,15 @@ func bMy(m *tb.Message) { func bMyInlineBtn(c *tb.Callback) { var u *model.Client model.DB.Where("id = ?", c.Data).First(&u) + fmt.Println(u.ID) bot.Send(c.Message.Chat, - fmt.Sprintf("信息\n别名:%s\nMS_ID(MD5): %s\nclient_id: %s\nclient_secret: %s\n最近更新时间: %s", + fmt.Sprintf("信息\n别名:%s\nms_id: %s\nclient_id: %s\nclient_secret: %s\n最近更新时间: %s", u.Alias, u.MsId, u.ClientId, u.ClientSecret, - time.Unix(u.Uptime, 0).Format("2006-01-02 15:04:05")), + time.Unix(u.Uptime, 0).Format("2006-01-02 15:04:05"), + ), ) bot.Respond(c) } @@ -74,10 +76,15 @@ func bMyInlineBtn(c *tb.Callback) { func bBind1(m *tb.Message) { bot.Send(m.Chat, fmt.Sprintf("应用注册: [点击直达](%s)", model.GetMSRegisterAppUrl()), - tb.ModeMarkdown) + tb.ModeMarkdown, + ) + bot.Send(m.Chat, - "请回复client_id(空格)client_secret", - &tb.ReplyMarkup{ForceReply: true}) + "请回复 `client_id(空格)client_secret`", + &tb.SendOptions{ParseMode: tb.ModeMarkdown, + ReplyMarkup: &tb.ReplyMarkup{ForceReply: true}}, + ) + UserStatus[m.Chat.ID] = USBind1 UserClientId[m.Chat.ID] = m.Text } @@ -89,10 +96,18 @@ func bBind2(m *tb.Message) { } ClientId := tmp[0] ClientSecret := tmp[1] - bot.Send(m.Chat, "授权账户: [点击直达]("+model.GetMSAuthUrl(ClientId)+")", tb.ModeMarkdown) bot.Send(m.Chat, - "请回复http://localhost/…… + 空格 + 别名(用于管理)", - &tb.ReplyMarkup{ForceReply: true}) + "授权账户: [点击直达]("+model.GetMSAuthUrl(ClientId)+")", + tb.ModeMarkdown, + ) + + bot.Send(m.Chat, + "请回复`http://localhost/……(空格)别名`(用于管理)", + &tb.SendOptions{ParseMode: tb.ModeMarkdown, + ReplyMarkup: &tb.ReplyMarkup{ForceReply: true}, + }, + ) + UserStatus[m.Chat.ID] = USBind2 UserClientId[m.Chat.ID] = ClientId UserClientSecret[m.Chat.ID] = ClientSecret @@ -190,7 +205,7 @@ func bOnText(m *tb.Message) { switch UserStatus[m.Chat.ID] { case USNone: { - bot.Send(m.Chat, "发送/help获取帮助嗷") + bot.Send(m.Chat, "发送 /help 获取帮助嗷") return } case USBind1: From 2390200f55b94a02e92ed2959bf8bf48a77ce79d Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 15 Jun 2021 19:41:19 +0800 Subject: [PATCH 18/29] fix Get EOF and Client.Timeout exceeded while awaiting headers --- model/client.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/model/client.go b/model/client.go index 8385972..2260a30 100644 --- a/model/client.go +++ b/model/client.go @@ -38,8 +38,16 @@ var client = &http.Client{} func init() { client.Timeout = 10 * time.Second tp := http.DefaultTransport.(*http.Transport).Clone() - tp.MaxIdleConns = 100 - tp.MaxIdleConnsPerHost = 100 + //TODO + //https://gocn.vip/topics/11970 + //DefaultMaxIdleConnsPerHost 设置的太小就会导致一个问题, + //在大量请求的情况下去访问特定的 host 的时候,长连接会退化成短链接. + tp.MaxIdleConns = 0 + tp.MaxIdleConnsPerHost = 50 + //to avoid "context deadline exceeded (Client.Timeout exceeded while awaiting headers)" + //https://cloud.tencent.com/developer/article/1529840 + tp.IdleConnTimeout = 5 * time.Second + client.Transport = tp } func NewClient(clientId string, clientSecret string) *Client { @@ -73,8 +81,6 @@ func (c *Client) GetTokenWithCode(code string) (error error) { if err != nil { return err } - //prevents the connection from being re-used - ////https://stackoverflow.com/questions/17714494/golang-http-request-results-in-eof-errors-when-making-multiple-requests-successi resp, err := client.Do(req) if err != nil { return err From cc0440055a9f6651a41775d5180c9b9294a0e918 Mon Sep 17 00:00:00 2001 From: iyear Date: Thu, 17 Jun 2021 20:20:09 +0800 Subject: [PATCH 19/29] Remove useless code --- bots/bots.go | 1 - bots/handle.go | 1 - logger/logger.go | 4 ---- model/client.go | 33 ++++++++++++++++++++++----------- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/bots/bots.go b/bots/bots.go index cc5f428..611a38f 100644 --- a/bots/bots.go +++ b/bots/bots.go @@ -80,7 +80,6 @@ func BotStart() { bot.Start() } func MakeHandle() { - fmt.Println("Make Handlers……") //所有用户 bot.Handle("/start", bStart) bot.Handle("/my", bMy) diff --git a/bots/handle.go b/bots/handle.go index 9182547..ff976d7 100644 --- a/bots/handle.go +++ b/bots/handle.go @@ -60,7 +60,6 @@ func bMy(m *tb.Message) { func bMyInlineBtn(c *tb.Callback) { var u *model.Client model.DB.Where("id = ?", c.Data).First(&u) - fmt.Println(u.ID) bot.Send(c.Message.Chat, fmt.Sprintf("信息\n别名:%s\nms_id: %s\nclient_id: %s\nclient_secret: %s\n最近更新时间: %s", u.Alias, diff --git a/logger/logger.go b/logger/logger.go index dfe5543..66aabdc 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -7,10 +7,6 @@ import ( "os" ) -func Println(a ...interface{}) { - return -} - // 日志切割设置 func getLogWriter() zapcore.WriteSyncer { lumberJackLogger := &lumberjack.Logger{ diff --git a/model/client.go b/model/client.go index 2260a30..eb9c239 100644 --- a/model/client.go +++ b/model/client.go @@ -38,15 +38,17 @@ var client = &http.Client{} func init() { client.Timeout = 10 * time.Second tp := http.DefaultTransport.(*http.Transport).Clone() - //TODO //https://gocn.vip/topics/11970 //DefaultMaxIdleConnsPerHost 设置的太小就会导致一个问题, //在大量请求的情况下去访问特定的 host 的时候,长连接会退化成短链接. tp.MaxIdleConns = 0 + tp.TLSHandshakeTimeout = 20 * time.Second tp.MaxIdleConnsPerHost = 50 + tp.ResponseHeaderTimeout = 20 * time.Second //to avoid "context deadline exceeded (Client.Timeout exceeded while awaiting headers)" //https://cloud.tencent.com/developer/article/1529840 - tp.IdleConnTimeout = 5 * time.Second + tp.IdleConnTimeout = 20 * time.Second + tp.ExpectContinueTimeout = 20 * time.Second client.Transport = tp } @@ -99,7 +101,7 @@ func (c *Client) GetTokenWithCode(code string) (error error) { } //return access_token and new refresh token -func (c *Client) getToken() (access string) { +func (c *Client) getToken() (accessToken string, error error) { var r http.Request r.ParseForm() r.Form.Add("client_id", c.ClientId) @@ -112,32 +114,36 @@ func (c *Client) getToken() (access string) { //fmt.Println(body) req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body) if err != nil { - return "" + return "", err } resp, err := client.Do(req) if err != nil { - return "" + return "", err } defer resp.Body.Close() content, err := ioutil.ReadAll(resp.Body) if err != nil { - return "" + return "", err } if gjson.Get(string(content), "token_type").String() == "Bearer" { c.RefreshToken = gjson.Get(string(content), "refresh_token").String() - return gjson.Get(string(content), "access_token").String() + return gjson.Get(string(content), "access_token").String(), nil } - return "" + return "", errors.New(gjson.Get(string(content), "error").String()) } // GetUserInfo Get User's Information func (c *Client) GetUserInfo() (json string, error error) { + var accessToken string req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me", nil) if err != nil { return "", err } - - req.Header.Set("Authorization", c.getToken()) + accessToken, err = c.getToken() + if err != nil { + return "", err + } + req.Header.Set("Authorization", accessToken) resp, err := client.Do(req) if err != nil { return "", err @@ -156,11 +162,16 @@ func (c *Client) GetUserInfo() (json string, error error) { } func (c *Client) GetOutlookMails() error { + var accessToken string req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me/messages", nil) if err != nil { return err } - req.Header.Set("Authorization", c.getToken()) + accessToken, err = c.getToken() + if err != nil { + return err + } + req.Header.Set("Authorization", accessToken) resp, err := client.Do(req) if err != nil { return err From b9171867f62935c1005192ba4f34785eef46ce85 Mon Sep 17 00:00:00 2001 From: iyear Date: Fri, 18 Jun 2021 19:36:13 +0800 Subject: [PATCH 20/29] Remove useless comments --- bots/bots.go | 2 +- bots/handle.go | 2 +- model/client.go | 2 +- util/util.go | 4 +--- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/bots/bots.go b/bots/bots.go index 611a38f..f74c1e6 100644 --- a/bots/bots.go +++ b/bots/bots.go @@ -30,7 +30,7 @@ const ( func BotStart() { var err error - fmt.Println(logo) + fmt.Printf("%s\n", logo) //read config config.InitConfig() //Init Logger diff --git a/bots/handle.go b/bots/handle.go index ff976d7..c068981 100644 --- a/bots/handle.go +++ b/bots/handle.go @@ -189,7 +189,7 @@ func bExport(m *tb.Message) { MIME: "text/plain", } bot.Send(m.Chat, exportFile) - //不遗留本地文件 + if exportFile.InCloud() != true || os.Remove(fileName) != nil { zap.S().Errorw("failed to export files") } diff --git a/model/client.go b/model/client.go index eb9c239..b2ef1d9 100644 --- a/model/client.go +++ b/model/client.go @@ -182,7 +182,7 @@ func (c *Client) GetOutlookMails() error { if err != nil { return err } - //fmt.Println(string(content)) + //这里的.需要转义,否则会按路径的方式解析 if gjson.Get(string(content), "@odata\\.context").String() != "" { return nil diff --git a/util/util.go b/util/util.go index 5ac5572..1960b82 100644 --- a/util/util.go +++ b/util/util.go @@ -57,13 +57,12 @@ func GetPathFiles(path string) []string { return t } -// GetRecentLogs 输入文件夹路径,返回最近n个log的路径,不到n个返回所有 func GetRecentLogs(path string, n int) []string { var paths []string if !PathExists(path) { return paths } - //path末尾检查/ + if path[len(path)-1:] != "/" { path += "/" } @@ -71,7 +70,6 @@ func GetRecentLogs(path string, n int) []string { d, _ := time.ParseDuration("-24h") //不到n个返回所有 nt := Min(n, len(GetPathFiles(path))) - //fmt.Println(nt) for i := 1; i <= nt; { if PathExists(path + data.Format("2006-01-02") + ".log") { paths = append(paths, data.Format("2006-01-02")+".log") From 89946ffd6267fedb7d7a9398b384d8a2166782cf Mon Sep 17 00:00:00 2001 From: iyear Date: Sat, 19 Jun 2021 13:02:49 +0800 Subject: [PATCH 21/29] Use goroutine to speed up the sign speed --- bots/sender.go | 86 ++++++++++++++++++++++++++++ bots/task.go | 148 +++++++++++++++++++++++++++++++++++++++++++++++++ task/sign.go | 59 ++++++++++++++++++++ 3 files changed, 293 insertions(+) create mode 100644 bots/sender.go create mode 100644 bots/task.go create mode 100644 task/sign.go diff --git a/bots/sender.go b/bots/sender.go new file mode 100644 index 0000000..8dcc8ed --- /dev/null +++ b/bots/sender.go @@ -0,0 +1,86 @@ +package bots + +import ( + "fmt" + "go.uber.org/zap" + "gopkg.in/tucnak/telebot.v2" + "strconv" + "sync" +) + +type Sender struct { + done chan struct{} + in chan *Msg + wg sync.WaitGroup +} +type Msg struct { + To telebot.Recipient + What interface{} + Options []interface{} +} + +//牺牲错误处理和解耦,加快发送速度 + +func NewSender() *Sender { + return &Sender{} +} +func (s *Sender) Init(goroutine int) { + + s.done = make(chan struct{}) + s.in = make(chan *Msg) + + for i := 0; i < goroutine; i++ { + go func() { + s.sender() + }() + } +} + +//Stop until all messages were sent +func (s *Sender) Stop() { + s.wg.Wait() + close(s.done) + fmt.Println("task finished") +} +func (s *Sender) SendMessageByID(ID int64, what interface{}, options ...interface{}) { + s.wg.Add(1) + go func() { + chat, err := bot.ChatByID(strconv.FormatInt(ID, 10)) + if err != nil { + zap.S().Errorw("failed to get chat", + "error", err, + "id", ID, + ) + s.wg.Done() + return + } + s.SendMessage(chat, what, options...) + }() +} +func (s *Sender) SendMessage(to telebot.Recipient, what interface{}, options ...interface{}) { + s.in <- &Msg{ + To: to, + What: what, + Options: options, + } +} +func (s *Sender) sender() { + for { + select { + case msg, f := <-s.in: + if !f { + continue + } + fmt.Println("send to " + msg.To.Recipient()) + if _, err := bot.Send(msg.To, msg.What, msg.Options...); err != nil { + zap.S().Errorw("failed to send msg", + "error", err, + "id", msg.To.Recipient(), + ) + } + s.wg.Done() + case <-s.done: + return + } + } +} diff --git a/bots/task.go b/bots/task.go new file mode 100644 index 0000000..fb655bc --- /dev/null +++ b/bots/task.go @@ -0,0 +1,148 @@ +package bots + +import ( + "fmt" + "github.com/iyear/E5SubBot/config" + "github.com/iyear/E5SubBot/model" + "github.com/iyear/E5SubBot/task" + "github.com/robfig/cron/v3" + "go.uber.org/zap" + tb "gopkg.in/tucnak/telebot.v2" + "strconv" + "time" +) + +var errorTimes map[int]int +var signErr map[int64]int +var unbindUsers []int64 +var msgSender *Sender + +func InitTask() { + errorTimes = make(map[int]int) + msgSender = NewSender() + + c := cron.New() + c.AddFunc(config.Cron, SignTask) + c.Start() +} +func SignTask() { + msgSender.Init(config.MaxGoroutines) + + signErr = make(map[int64]int) + unbindUsers = nil + + var clients []*model.Client + if result := model.DB.Find(&clients); result.Error != nil { + zap.S().Errorw("failed to get all clients", + "error", result.Error) + return + } + + fmt.Printf("clients: %d goroutines:%d\n", + len(clients), + config.MaxGoroutines, + ) + + start := time.Now() + + errClients := task.Sign(clients) + + for _, errClient := range errClients { + if errClient.Err != nil { + opErrorSign(errClient) + continue + } + //请求一次成功清零errorTimes,避免接口的偶然错误积累导致账号被清退 + errorTimes[errClient.ID] = 0 + model.DB.Save(&errClient.Client) + } + + //fmt.Println(signErr) + //fmt.Println(errorTimes) + timeSpending := time.Since(start).Seconds() + summarySignTaskForUsers(errClients) + summarySignTaskForAdmins(errClients, timeSpending) + + msgSender.Stop() +} + +func summarySignTaskForAdmins(errClients []*model.ErrClient, timeSpending float64) { + var Count = len(errClients) + var ErrCount int + var ErrUserStr string + var UnbindUserStr string + for err, count := range signErr { + ErrCount += count + ErrUserStr += fmt.Sprintf("[%d](tg://user?id=%d)\n", err, err) + } + for _, unbindUser := range unbindUsers { + UnbindUserStr += fmt.Sprintf("[%d](tg://user?id=%d)\n", unbindUser, unbindUser) + } + for _, admin := range config.Admins { + a := admin + msgSender.SendMessageByID(a, fmt.Sprintf("任务反馈(管理员)\n完成时间: %s\n用时: %.2fs\n结果: %d/%d\n错误账户: \n%s\n清退账户: \n%s", + time.Now().Format("2006-01-02 15:04:05"), + timeSpending, + Count-ErrCount, Count, + ErrUserStr, UnbindUserStr, + ), + tb.ModeMarkdown, + ) + } +} +func summarySignTaskForUsers(errClients []*model.ErrClient) { + + var isSent map[int64]bool + isSent = make(map[int64]bool) + + for _, errClient := range errClients { + errClient := errClient + //pending SignErrNum + if errorTimes[errClient.ID] > config.MaxErrTimes { + if result := model.DB.Delete(&errClient.Client); result.Error != nil { + zap.S().Errorw("failed to delete data", + "error", result.Error, + "id", errClient.ID, + ) + continue + } + + unbindUsers = append(unbindUsers, errClient.TgId) + + msgSender.SendMessageByID(errClient.TgId, fmt.Sprintf("您的账户因达到错误上限而被自动解绑\n后会有期!\n\n别名: %s\nclient_id: %s\nclient_secret: %s", + errClient.Alias, + errClient.ClientId, + errClient.ClientSecret, + )) + continue + + } + if isSent[errClient.TgId] { + continue + } + signOK := GetBindNum(errClient.TgId) - signErr[errClient.TgId] + + msgSender.SendMessageByID(errClient.TgId, + fmt.Sprintf("任务反馈\n时间: %s\n结果:%d/%d", + time.Now().Format("2006-01-02 15:04:05"), + signOK, + signErr[errClient.TgId]+signOK, + ), + ) + isSent[errClient.TgId] = true + time.Sleep(time.Millisecond * 100) + } +} +func opErrorSign(errClient *model.ErrClient) { + errorTimes[errClient.ID]++ + signErr[errClient.TgId]++ + + UnBindBtn := tb.InlineButton{Unique: "un" + errClient.MsId, Text: "点击解绑", Data: strconv.Itoa(errClient.ID)} + bot.Handle(&UnBindBtn, bUnBindInlineBtn) + + msgSender.SendMessageByID(errClient.TgId, + fmt.Sprintf("您的帐户 %s 在执行时出现了错误\n您可以选择解绑该用户\n错误: %s", + errClient.Alias, errClient.Err), + &tb.ReplyMarkup{InlineKeyboard: [][]tb.InlineButton{{UnBindBtn}}}, + ) +} diff --git a/task/sign.go b/task/sign.go new file mode 100644 index 0000000..535db56 --- /dev/null +++ b/task/sign.go @@ -0,0 +1,59 @@ +package task + +import ( + "fmt" + "github.com/iyear/E5SubBot/config" + "github.com/iyear/E5SubBot/model" + "go.uber.org/zap" +) + +func Sign(clients []*model.Client) []*model.ErrClient { + var errClients []*model.ErrClient + + done := make(chan struct{}) + in := make(chan *model.ErrClient, 5) + out := make(chan *model.ErrClient, 5) + + go func() { + for _, client := range clients { + in <- &model.ErrClient{ + Client: client, + Err: nil, + } + } + close(in) + }() + for i := 0; i < config.MaxGoroutines; i++ { + go func() { + for { + select { + case errCli, f := <-in: + if !f { + continue + } + + err := errCli.GetOutlookMails() + errCli.Err = err + out <- errCli + case <-done: + return + } + } + }() + } + for i := 0; i < len(clients); i++ { + errClient := <-out + if errClient.Err == nil { + fmt.Printf("%s OK\n", errClient.MsId) + } else { + zap.S().Errorw("failed to sign", + "error", errClient.Err, + "id", errClient.ID, + ) + //fmt.Printf("%s %s\n",errClient.MsId,errClient.Err) + } + errClients = append(errClients, errClient) + } + close(done) + return errClients +} From 9a919c53998f6cdaabab2d6623becfc1df0fb200 Mon Sep 17 00:00:00 2001 From: iyear Date: Sat, 19 Jun 2021 13:03:38 +0800 Subject: [PATCH 22/29] refactor socks5 proxy and cron config --- bots/bots.go | 8 +++++--- config/config.go | 6 +++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/bots/bots.go b/bots/bots.go index f74c1e6..ecb6682 100644 --- a/bots/bots.go +++ b/bots/bots.go @@ -56,14 +56,16 @@ func BotStart() { } //set socks5 if config.Socks5 != "" { - fmt.Println("Proxy:" + config.Socks5) + fmt.Println("Proxy: " + config.Socks5) dialer, err := proxy.SOCKS5("tcp", config.Socks5, nil, proxy.Direct) if err != nil { - zap.S().Errorw("failed to make dialer", "error", err, "socks5", config.Socks5) + zap.S().Errorw("failed to get dialer", + "error", err, "proxy", config.Socks5) } httpTransport := &http.Transport{} - httpClient := &http.Client{Transport: httpTransport} httpTransport.Dial = dialer.Dial + httpClient := &http.Client{Transport: httpTransport} + botSetting.Client = httpClient } //create bot diff --git a/config/config.go b/config/config.go index 25e7c99..97e23e8 100644 --- a/config/config.go +++ b/config/config.go @@ -41,7 +41,11 @@ func InitConfig() { zap.S().Errorw("failed to read config", "error", err) } BotToken = viper.GetString("bot_token") + Cron = viper.GetString("cron") Socks5 = viper.GetString("socks5") + //if Socks5[:5] != "socks5" { + // Socks5 = "socks5://" + Socks5 + //} viper.SetDefault("errlimit", 5) viper.SetDefault("bindmax", 5) @@ -49,7 +53,7 @@ func InitConfig() { BindMaxNum = viper.GetInt("bindmax") MaxErrTimes = viper.GetInt("errlimit") Notice = viper.GetString("notice") - Cron = viper.GetString("cron") + MaxGoroutines = viper.GetInt("goroutine") Admins = getAdmins() From f260c54314258e42ddb2113f33ab79f4abdd7931 Mon Sep 17 00:00:00 2001 From: iyear Date: Sat, 19 Jun 2021 13:21:11 +0800 Subject: [PATCH 23/29] Use gout instead of client --- go.mod | 5 +- go.sum | 73 ++++++++++++++++--- model/client.go | 184 ++++++++++++++++++------------------------------ 3 files changed, 137 insertions(+), 125 deletions(-) diff --git a/go.mod b/go.mod index 75ac59c..e8fc8a3 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,17 @@ go 1.13 require ( github.com/fsnotify/fsnotify v1.4.7 - github.com/go-sql-driver/mysql v1.5.0 + github.com/guonaihong/gout v0.1.12 + github.com/pkg/errors v0.9.1 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 + go.uber.org/automaxprocs v1.4.0 go.uber.org/zap v1.10.0 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/tucnak/telebot.v2 v2.0.0-20200328014118-dd123e949ee1 + gorm.io/driver/sqlite v1.1.4 gorm.io/gorm v1.21.3 ) diff --git a/go.sum b/go.sum index 6ddb00c..18e9135 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,7 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -21,11 +22,21 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.0 h1:Lb3veSYoGaNck69fV2+Vf2juLSsHpMTf3Vk5+X+EDJg= +github.com/gin-gonic/gin v1.6.0/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= 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-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= 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= @@ -34,14 +45,24 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/guonaihong/gout v0.1.12 h1:PE2nJofrLpxpoHOTJ4NWcyPBU6gbjWjp5Du3DMsAv2Y= +github.com/guonaihong/gout v0.1.12/go.mod h1:JkjNv1G2oRWvFgP/r4DUbYhoeIBB0zMP2j1ID+5CYpU= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -49,6 +70,8 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -61,18 +84,29 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ= +github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -104,26 +138,34 @@ github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc= github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8= github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/automaxprocs v1.4.0 h1:CpDZl6aOlLhReez+8S3eEotD7Jx0Os++lemPlMULQP0= +go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= @@ -136,8 +178,8 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -148,22 +190,28 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= @@ -177,8 +225,13 @@ gopkg.in/tucnak/telebot.v2 v2.0.0-20200328014118-dd123e949ee1 h1:L9z5n/aaxpAjeEM gopkg.in/tucnak/telebot.v2 v2.0.0-20200328014118-dd123e949ee1/go.mod h1:+//wyPtHTeW2kfyEBwB05Hqnxev7AGrsLIyylSH++KU= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= +gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= +gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.21.3 h1:qDFi55ZOsjZTwk5eN+uhAmHi8GysJ/qCTichM/yO7ME= gorm.io/gorm v1.21.3/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/model/client.go b/model/client.go index b2ef1d9..7f37716 100644 --- a/model/client.go +++ b/model/client.go @@ -1,13 +1,10 @@ package model import ( + "github.com/guonaihong/gout" "github.com/pkg/errors" "github.com/tidwall/gjson" - "io/ioutil" - "net/http" "net/url" - "strings" - "time" ) type Client struct { @@ -33,25 +30,6 @@ const ( scope string = "openid offline_access mail.read user.read" ) -var client = &http.Client{} - -func init() { - client.Timeout = 10 * time.Second - tp := http.DefaultTransport.(*http.Transport).Clone() - //https://gocn.vip/topics/11970 - //DefaultMaxIdleConnsPerHost 设置的太小就会导致一个问题, - //在大量请求的情况下去访问特定的 host 的时候,长连接会退化成短链接. - tp.MaxIdleConns = 0 - tp.TLSHandshakeTimeout = 20 * time.Second - tp.MaxIdleConnsPerHost = 50 - tp.ResponseHeaderTimeout = 20 * time.Second - //to avoid "context deadline exceeded (Client.Timeout exceeded while awaiting headers)" - //https://cloud.tencent.com/developer/article/1529840 - tp.IdleConnTimeout = 20 * time.Second - tp.ExpectContinueTimeout = 20 * time.Second - - client.Transport = tp -} func NewClient(clientId string, clientSecret string) *Client { return &Client{ ClientId: clientId, @@ -68,124 +46,102 @@ func GetMSRegisterAppUrl() string { return appUrl } -// GetTokenWithCode return access_token and refresh_token -func (c *Client) GetTokenWithCode(code string) (error error) { - var r http.Request - r.ParseForm() - r.Form.Add("client_id", c.ClientId) - r.Form.Add("client_secret", c.ClientSecret) - r.Form.Add("grant_type", "authorization_code") - r.Form.Add("scope", scope) - r.Form.Add("code", code) - r.Form.Add("redirect_uri", redirectUri) - body := strings.NewReader(r.Form.Encode()) - req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body) - if err != nil { - return err - } - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - content, err := ioutil.ReadAll(resp.Body) +func (c *Client) GetTokenWithCode(code string) error { + var content string + err := gout.POST(msApiUrl + "/common/oauth2/v2.0/token"). + SetWWWForm(gout.H{ + "client_id": c.ClientId, + "client_secret": c.ClientSecret, + "grant_type": "authorization_code", + "scope": scope, + "code": code, + "redirect_uri": redirectUri, + }). + BindBody(&content).Do() if err != nil { return err } - if gjson.Get(string(content), "token_type").String() == "Bearer" { - c.RefreshToken = gjson.Get(string(content), "refresh_token").String() + + if gjson.Get(content, "token_type").String() == "Bearer" { + c.RefreshToken = gjson.Get(content, "refresh_token").String() return nil } - return errors.New(string(content)) + return errors.New(content) } -//return access_token and new refresh token -func (c *Client) getToken() (accessToken string, error error) { - var r http.Request - r.ParseForm() - r.Form.Add("client_id", c.ClientId) - r.Form.Add("client_secret", c.ClientSecret) - r.Form.Add("grant_type", "refresh_token") - r.Form.Add("scope", scope) - r.Form.Add("refresh_token", c.RefreshToken) - r.Form.Add("redirect_uri", redirectUri) - body := strings.NewReader(r.Form.Encode()) - //fmt.Println(body) - req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body) +//getToken return accessToken and error +func (c *Client) getToken() (string, error) { + + var content string + err := gout.POST(msApiUrl + "/common/oauth2/v2.0/token"). + SetWWWForm(gout.H{ + "client_id": c.ClientId, + "client_secret": c.ClientSecret, + "grant_type": "refresh_token", + "scope": scope, + "refresh_token": c.RefreshToken, + "redirect_uri": redirectUri, + }). + BindBody(&content). + Do() if err != nil { return "", err } - resp, err := client.Do(req) - if err != nil { - return "", err + + if gjson.Get(content, "token_type").String() == "Bearer" { + c.RefreshToken = gjson.Get(content, "refresh_token").String() + return gjson.Get(content, "access_token").String(), nil } - defer resp.Body.Close() - content, err := ioutil.ReadAll(resp.Body) - if err != nil { - return "", err - } - if gjson.Get(string(content), "token_type").String() == "Bearer" { - c.RefreshToken = gjson.Get(string(content), "refresh_token").String() - return gjson.Get(string(content), "access_token").String(), nil - } - return "", errors.New(gjson.Get(string(content), "error").String()) + return "", errors.New(gjson.Get(content, "error").String()) } -// GetUserInfo Get User's Information -func (c *Client) GetUserInfo() (json string, error error) { - var accessToken string - req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me", nil) +// GetUserInfo return infoJSON and error +func (c *Client) GetUserInfo() (string, error) { + var ( + content string + err error + accessToken string + ) + if accessToken, err = c.getToken(); err != nil { + return "", err + } + err = gout.GET(msGraUrl + "/v1.0/me/messages"). + SetHeader(gout.H{ + "Authorization": accessToken, + }). + BindBody(&content). + Do() if err != nil { return "", err } - accessToken, err = c.getToken() - if err != nil { - return "", err - } - req.Header.Set("Authorization", accessToken) - resp, err := client.Do(req) - if err != nil { - return "", err - } - defer resp.Body.Close() - content, err := ioutil.ReadAll(resp.Body) - if err != nil { - return "", err + if gjson.Get(content, "id").String() != "" { + return content, nil } - if gjson.Get(string(content), "id").String() != "" { - //fmt.Println("UserName: " + gjson.Get(string(content), "displayName").String()) - return string(content), nil - } - return "", errors.New(string(content)) + return "", errors.New(content) } func (c *Client) GetOutlookMails() error { + + var content string + var err error var accessToken string - req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me/messages", nil) + if accessToken, err = c.getToken(); err != nil { + return err + } + err = gout.GET(msGraUrl + "/v1.0/me/messages"). + SetHeader(gout.H{ + "Authorization": accessToken, + }). + BindBody(&content). + Do() if err != nil { return err } - accessToken, err = c.getToken() - if err != nil { - return err - } - req.Header.Set("Authorization", accessToken) - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - content, err := ioutil.ReadAll(resp.Body) - - if err != nil { - return err - } - //这里的.需要转义,否则会按路径的方式解析 - if gjson.Get(string(content), "@odata\\.context").String() != "" { + if gjson.Get(content, "@odata\\.context").String() != "" { return nil } - return errors.New(gjson.Get(string(content), "error").String()) + return errors.New(gjson.Get(content, "error").String()) } From 37176b753f5e650c34bd12a4b200cd33153b7d5f Mon Sep 17 00:00:00 2001 From: iyear Date: Sat, 19 Jun 2021 15:06:07 +0800 Subject: [PATCH 24/29] fix getUserInfo wrong url --- config/config.go | 5 ++--- model/client.go | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/config/config.go b/config/config.go index 97e23e8..26b8ff7 100644 --- a/config/config.go +++ b/config/config.go @@ -43,12 +43,11 @@ func InitConfig() { BotToken = viper.GetString("bot_token") Cron = viper.GetString("cron") Socks5 = viper.GetString("socks5") - //if Socks5[:5] != "socks5" { - // Socks5 = "socks5://" + Socks5 - //} viper.SetDefault("errlimit", 5) viper.SetDefault("bindmax", 5) + viper.SetDefault("goroutine", 10) + viper.SetDefault("bindmax", 5) BindMaxNum = viper.GetInt("bindmax") MaxErrTimes = viper.GetInt("errlimit") diff --git a/model/client.go b/model/client.go index 7f37716..2c39db5 100644 --- a/model/client.go +++ b/model/client.go @@ -106,7 +106,7 @@ func (c *Client) GetUserInfo() (string, error) { if accessToken, err = c.getToken(); err != nil { return "", err } - err = gout.GET(msGraUrl + "/v1.0/me/messages"). + err = gout.GET(msGraUrl + "/v1.0/me"). SetHeader(gout.H{ "Authorization": accessToken, }). From 0ce6822978f166b43b312fa7c60ea20c6a11f2ba Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 6 Jul 2021 20:35:22 +0800 Subject: [PATCH 25/29] Use mysql as the database --- config/config.go | 16 ++++++++++++++++ model/db.go | 32 ++++++++++++++++++++++++++++++++ model/sqlite.go | 23 ----------------------- 3 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 model/db.go delete mode 100644 model/sqlite.go diff --git a/config/config.go b/config/config.go index 26b8ff7..93bb476 100644 --- a/config/config.go +++ b/config/config.go @@ -31,8 +31,17 @@ var ( Cron string Notice string Admins []int64 + Mysql MysqlConfig ) +type MysqlConfig struct { + Host string + Port int + User string + Password string + DB string +} + func InitConfig() { viper.SetConfigName("config") viper.AddConfigPath(".") @@ -56,6 +65,13 @@ func InitConfig() { MaxGoroutines = viper.GetInt("goroutine") Admins = getAdmins() + Mysql = MysqlConfig{ + Host: viper.GetString("mysql.host"), + Port: viper.GetInt("mysql.port"), + User: viper.GetString("mysql.user"), + Password: viper.GetString("mysql.password"), + DB: viper.GetString("mysql.database"), + } viper.WatchConfig() viper.OnConfigChange(func(e fsnotify.Event) { MaxGoroutines = viper.GetInt("goroutine") diff --git a/model/db.go b/model/db.go new file mode 100644 index 0000000..672c8ec --- /dev/null +++ b/model/db.go @@ -0,0 +1,32 @@ +package model + +import ( + "fmt" + "github.com/iyear/E5SubBot/config" + "go.uber.org/zap" + "gorm.io/driver/mysql" + "gorm.io/gorm" + "time" +) + +var DB *gorm.DB + +func InitDB() { + var err error + dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", + config.Mysql.User, + config.Mysql.Password, + config.Mysql.Host, + config.Mysql.Port, + config.Mysql.DB, + ) + DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{ + NowFunc: func() time.Time { + return time.Now() + }, + }) + if err != nil { + zap.S().Errorw("failed to open db", "error", err) + } + DB.AutoMigrate(&Client{}) +} diff --git a/model/sqlite.go b/model/sqlite.go deleted file mode 100644 index f14e0d5..0000000 --- a/model/sqlite.go +++ /dev/null @@ -1,23 +0,0 @@ -package model - -import ( - "go.uber.org/zap" - "gorm.io/driver/sqlite" - "gorm.io/gorm" - "time" -) - -var DB *gorm.DB - -func InitDB() { - var err error - DB, err = gorm.Open(sqlite.Open("data.db"), &gorm.Config{ - NowFunc: func() time.Time { - return time.Now() - }, - }) - if err != nil { - zap.S().Errorw("failed to open db", "error", err) - } - DB.AutoMigrate(&Client{}) -} From f85de1bf74f93be7f5377194cab848e81ca26c42 Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 6 Jul 2021 21:03:40 +0800 Subject: [PATCH 26/29] Custom table name --- config/config.go | 2 ++ model/client.go | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/config/config.go b/config/config.go index 93bb476..5c49c23 100644 --- a/config/config.go +++ b/config/config.go @@ -40,6 +40,7 @@ type MysqlConfig struct { User string Password string DB string + Table string } func InitConfig() { @@ -71,6 +72,7 @@ func InitConfig() { User: viper.GetString("mysql.user"), Password: viper.GetString("mysql.password"), DB: viper.GetString("mysql.database"), + Table: viper.GetString("mysql.table"), } viper.WatchConfig() viper.OnConfigChange(func(e fsnotify.Event) { diff --git a/model/client.go b/model/client.go index 2c39db5..6797c1c 100644 --- a/model/client.go +++ b/model/client.go @@ -2,6 +2,7 @@ package model import ( "github.com/guonaihong/gout" + "github.com/iyear/E5SubBot/config" "github.com/pkg/errors" "github.com/tidwall/gjson" "net/url" @@ -30,6 +31,9 @@ const ( scope string = "openid offline_access mail.read user.read" ) +func (c *Client) TableName() string { + return config.Mysql.Table +} func NewClient(clientId string, clientSecret string) *Client { return &Client{ ClientId: clientId, From e25dab3ec02b83b668bc20684c90677021fb7a17 Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 6 Jul 2021 21:21:49 +0800 Subject: [PATCH 27/29] Modify documents --- README.md | 64 ++++++++++++++------------------- README_zhCN.md | 89 ++++++++++++++-------------------------------- config.yml.example | 4 ++- config/config.go | 1 - go.mod | 5 ++- go.sum | 27 +++++++++++--- 6 files changed, 79 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index b81acd7..45707a4 100644 --- a/README.md +++ b/README.md @@ -4,20 +4,13 @@ ![](https://img.shields.io/badge/license-GPL-lightgrey.svg?style=flat-square) ![](https://img.shields.io/github/v/release/iyear/E5SubBot?color=green&style=flat-square) -English | [简体中文](https://github.com/iyear/E5SubBot/blob/master/README_zhCN.md) +English | [简体中文](https://github.com/iyear/E5SubBot/blob/master/README_zhCN.md) | [交流群组](https://t.me/e5subbot) A Simple Telebot for E5 Renewal `Golang` + `MySQL` -DEMO: https://t.me/E5Sub_bot (all new functions will be tested in DEMO) - -Communication: [Telegram Group](https://t.me/e5subbot) - -## Preview -
- -
+DEMO: https://t.me/E5Sub_bot ## Feature @@ -25,7 +18,7 @@ Communication: [Telegram Group](https://t.me/e5subbot) - Manageable Simple Account System - Available Task Execution Feedback - Convenient Authorization - +- Use concurrency to speed up ## Principle @@ -60,15 +53,16 @@ docker-compose up -d ``` ### Binary Deployment -Download the binary files of the corresponding system on the [Releases](https://github.com/iyear/E5SubBot/releases) page and upload it to the server +Download the binary files of the corresponding system on the [Releases](https://github.com/iyear/E5SubBot/releases) page +and upload it to the server -Windows: Start `E5SubBot.exe` in `cmd` +Windows: Start `E5SubBot.exe` -Linux: +Linux: ```bash screen -S e5sub -chmod 773 E5SubBot +chmod +x E5SubBot ./E5SubBot (Ctrl A+D) ``` @@ -77,7 +71,7 @@ chmod 773 E5SubBot Download the source code and install the GO environment ```shell -go build +git clone https://github.com/iyear/E5SubBot.git && cd E5SubBot && go build ``` ## Configuration @@ -91,6 +85,7 @@ bot_token: YOUR_BOT_TOKEN socks5: 127.0.0.1:1080 notice: "first line \n second line" admin: 66666,77777,88888 +goroutine: 10 errlimit: 5 cron: "1 */3 * * *" bindmax: 3 @@ -100,21 +95,25 @@ mysql: user: e5sub password: e5sub database: e5sub + table: users ``` -`bindmax`, `notice`, `admin`, `errlimit` can be hot updated, just update `config.yml` to save. -| Configuration | Explanation| -| ---- | ---- | -| bot_token | Change to your own `BotToken` | -| socks5 | `Socks5` proxy,if you do not need ,you should delete it. For example: `127.0.0.1:1080` | -|notice|Announcement. Merged into `/help`| -|admin|The administrator's `tgid`, go to https://t.me/userinfobot to get it, separated by `,`; Administrator permissions: manually call the task, get the total feedback of the task| -|errlimit|The maximum number of errors for a single account, automatically unbind the single account and send a notification when it is full, without limiting the number of errors, change the value to a negative number `(-1)`; all errors will be cleared after the bot restarts| -|cron|API call frequency, using `cron` expression| -|bindmax|Maximum number of bindable| -|mysql|Mysql configuration, please create database in advance| +`bindmax`, `notice`, `admin`,`goroutine`, `errlimit` can be hot updated, just update `config.yml` to save. + +| Configuration | Explanation|Default| +| ---- | ---- |----| +| bot_token | Change to your own `BotToken` |-| +| socks5 | `Socks5` proxy,if you do not need ,you should delete it. For example: `127.0.0.1:1080` |-| +|notice|Announcement. Merged into `/help`|-| +|admin|The administrator's `tgid`, go to https://t.me/userinfobot to get it, separated by `,`; Administrator permissions: manually call the task, get the total feedback of the task|-| +|goroutine|Concurrent number, don’t be too big|10| +|errlimit|The maximum number of errors for a single account, automatically unbind the single account and send a notification when it is full, without limiting the number of errors, change the value to a negative number `(-1)`; all errors will be cleared after the bot restarts|5| +|cron|API call frequency, using `cron` expression|-| +|bindmax|Maximum number of bindable|5| +|mysql|Mysql configuration, please create database in advance(If you upgrade the old version, please set table to users, otherwise the data table cannot be read)|-| ### Command + ``` /my View bound account information /bind Bind new account @@ -141,25 +140,14 @@ Suspected memory leak. Not yet resolved, please run the daemon or restart Bot re https://t.me/e5subbot/5201 -## Third-Party -- [Telebot](https://gopkg.in/tucnak/telebot) -- [Mysql_driver](https://github.com/go-sql-driver/mysql) -- [Gjson](https://github.com/tidwall/gjson) -- [Cron](https://github.com/robfig/cron/) -- [Viper](https://github.com/spf13/viper) -- [Goreleaser](https://https://github.com/goreleaser/goreleaser) - ## Contributing - Provide documentation in other languages - Provide help for code operation - Suggests user interaction - …… ## More Functions -If you still want to support new features, please use FeatHub to vote. We will consider the voting results and other factors to determine the development priority. -[![Feature Requests](https://cloud.githubusercontent.com/assets/390379/10127973/045b3a96-6560-11e5-9b20-31a2032956b2.png)](http://feathub.com/NervJS/taro) - -[![Feature Requests](https://feathub.com/iyear/E5SubBot?format=svg)](https://feathub.com/iyear/E5SubBot) +If you still want to support new features, please initiate an issue. ## License diff --git a/README_zhCN.md b/README_zhCN.md index 019784e..b382260 100644 --- a/README_zhCN.md +++ b/README_zhCN.md @@ -4,20 +4,14 @@ ![](https://img.shields.io/badge/license-GPL-lightgrey.svg?style=flat-square) ![](https://img.shields.io/github/v/release/iyear/E5SubBot?color=green&style=flat-square) -[English](https://github.com/iyear/E5SubBot) | 简体中文 +[English](https://github.com/iyear/E5SubBot) | 简体中文 | [交流群组](https://t.me/e5subbot) A Simple Telebot for E5 Renewal `Golang` + `MySQL` -DEMO: https://t.me/E5Sub_bot (长期运行,所有新功能会在DEMO测试) +DEMO: https://t.me/E5Sub_bot -[交流群组](https://t.me/e5subbot) - -## 预览 -
- -
## 特性 @@ -25,6 +19,7 @@ DEMO: https://t.me/E5Sub_bot (长期运行,所有新功能会在DEMO测试) - 可管理的简易账户系统 - 完善的任务执行反馈 - 极为方便的授权方式 +- 使用并发加快运行速度 ## 原理 @@ -61,13 +56,13 @@ docker-compose up -d 在[Releases](https://github.com/iyear/E5SubBot/releases)页面下载对应系统的二进制文件,上传至服务器 -Windows: 在`cmd`中启动 `E5SubBot.exe` +Windows: 启动 `E5SubBot.exe` -Linux: +Linux: ```bash screen -S e5sub -chmod 773 E5SubBot +chmod +x E5SubBot ./E5SubBot (Ctrl A+D) ``` @@ -76,7 +71,7 @@ chmod 773 E5SubBot 下载源码,安装GO环境 ```shell -go build +git clone https://github.com/iyear/E5SubBot.git && cd E5SubBot && go build ``` ## 部署配置 @@ -90,6 +85,7 @@ bot_token: YOUR_BOT_TOKEN socks5: 127.0.0.1:1080 notice: "第一行\n第二行" admin: 66666,77777,88888 +goroutine: 10 errlimit: 5 cron: "1 */3 * * *" bindmax: 3 @@ -99,21 +95,25 @@ mysql: user: e5sub password: e5sub database: e5sub + table: users ``` -`bindmax`,`notice`,`admin`,`errlimit`可热更新,直接更新`config.yml`保存即可 -| 配置项 | 说明 | -| ---- | ---- | -| bot_token | 更换为自己的`BotToken` | -| socks5 | `Socks5`代理,不需要删去即可.例如:`127.0.0.1:1080` | -|notice|公告.合并至`/help`| -|admin|管理员`tgid`,前往 https://t.me/userinfobot 获取,用`,`隔开;管理员权限: 手动调用任务,获得任务总反馈| -|errlimit|单账户最大出错次数,满后自动解绑单账户并发送通知,不限制错误次数将值改为负数`(-1)`即可;bot重启后会清零所有错误次数| -|cron|API调用频率,使用cron表达式| -|bindmax|最大可绑定数| -|mysql|mysql配置,请提前创建数据库| +`bindmax`,`notice`,`admin`,`goroutine`,`errlimit`可热更新,直接更新`config.yml`保存即可 + +| 配置项 | 说明 |默认值| +| ---- | ---- | ---- | +| bot_token | 更换为自己的`BotToken` | -| +| socks5 | `Socks5`代理,不需要删去即可.例如:`127.0.0.1:1080` |-| +|notice|公告.合并至`/help`|-| +|admin|管理员`tgid`,前往 https://t.me/userinfobot 获取,用`,`隔开;管理员权限: 手动调用任务,获得任务总反馈|-| +|goroutine|并发数,不要过大|10| +|errlimit|单账户最大出错次数,满后自动解绑单账户并发送通知,不限制错误次数将值改为负数`(-1)`即可;bot重启后会清零所有错误次数|5| +|cron|API调用频率,使用cron表达式|-| +|bindmax|最大可绑定数|5| +|mysql|mysql配置,请提前创建数据库(旧版本升级请设置table为users,否则读不到数据表)|-| ### 命令 + ``` /my 查看已绑定账户信息 /bind 绑定新账户 @@ -143,54 +143,17 @@ mysql: > 无法通过Bot创建应用程序 https://t.me/e5subbot/5201 + ## 更多功能 -如果你还想支持新的特性,请使用 FeatHub 进行投票,我们将综合考虑投票结果等因素来确定开发的优先级。 -[![Feature Requests](https://cloud.githubusercontent.com/assets/390379/10127973/045b3a96-6560-11e5-9b20-31a2032956b2.png)](http://feathub.com/NervJS/taro) +如果你还想支持新的特性,请发起issue. -[![Feature Requests](https://feathub.com/iyear/E5SubBot?format=svg)](https://feathub.com/iyear/E5SubBot) ## 做出贡献 + - 提供其他语言的文档 - 为代码运行提供帮助 - 对用户交互提出建议 - …… -## 小总结 -#### 得到了什么? -- git的基本操作:add,commit,pull,push.但是对代码合并与冲突解决没有得到足够的实践和深入 -- github版本库方面的使用(issue,pull request...),还有一些没玩过 -- 体验了Docker Hub 的自动构建 -- sql的CRUD,但都只是浮于表面,有时间再去琢磨 -- telegram bot的golang基本框架和一些有意思的玩法 -- 一些著名第三方库(viper,gjson)的基本用法 -- docker以及docker-compose的基本用法 -- 一些工具:gox;goreleaser的基本用法 -- …… -#### 还缺点什么? - -- 对`CGO`知难而退,编译各种出错。下个项目如果用到`sqlite`一定解决`CGO`交叉编译 -- `DockerFile` 还不会写 -- 对项目的概念和意识不太行,目录太乱,随缘写全局变量 -- 看`telebot`的文档还好,看`stackflow` 只能看看代码。搜索还是习惯性带中文导致`stackflow`很难出现,降低了解决问题的效率 - -#### 最后 - -从2020.3.28开发至2020.4.12,一共经历14天,利用课余时间最终完成。 - -就要开学了,因为马上步入高三,学习紧迫,遂不再进行功能开发。 - -项目差不多就停更了,最多也就是每个星期看看issue、tg群组,修一修bug - -**DEMO依旧能保持服务水平,不会因为个人问题在这段时间停止运行** - -如果一年后还有人在用,一定会继续 - -## Third-Party -- [telebot](https://gopkg.in/tucnak/telebot) -- [mysql_driver](https://github.com/go-sql-driver/mysql) -- [gjson](https://github.com/tidwall/gjson) -- [cron](https://github.com/robfig/cron/) -- [viper](https://github.com/spf13/viper) -- [goreleaser](https://https://github.com/goreleaser/goreleaser) ## License diff --git a/config.yml.example b/config.yml.example index c9fdae3..167d375 100644 --- a/config.yml.example +++ b/config.yml.example @@ -2,6 +2,7 @@ bot_token: xxx #socks5: 127.0.0.1:1080 bindmax: 3 admin: 555,666,777 +goroutine: 10 errlimit: 5 notice: "aaa\nbbb" cron: "1 */3 * * *" @@ -11,4 +12,5 @@ mysql: port: 3306 user: root password: root - database: e5sub \ No newline at end of file + database: e5sub + table: users \ No newline at end of file diff --git a/config/config.go b/config/config.go index 5c49c23..b0a4e9b 100644 --- a/config/config.go +++ b/config/config.go @@ -57,7 +57,6 @@ func InitConfig() { viper.SetDefault("errlimit", 5) viper.SetDefault("bindmax", 5) viper.SetDefault("goroutine", 10) - viper.SetDefault("bindmax", 5) BindMaxNum = viper.GetInt("bindmax") MaxErrTimes = viper.GetInt("errlimit") diff --git a/go.mod b/go.mod index e8fc8a3..52b4f31 100644 --- a/go.mod +++ b/go.mod @@ -10,11 +10,10 @@ require ( github.com/spf13/viper v1.6.2 github.com/tidwall/gjson v1.6.0 github.com/tidwall/pretty v1.0.1 // indirect - go.uber.org/automaxprocs v1.4.0 go.uber.org/zap v1.10.0 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/tucnak/telebot.v2 v2.0.0-20200328014118-dd123e949ee1 - gorm.io/driver/sqlite v1.1.4 - gorm.io/gorm v1.21.3 + gorm.io/driver/mysql v1.1.1 + gorm.io/gorm v1.21.9 ) diff --git a/go.sum b/go.sum index 18e9135..e511291 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -29,6 +31,8 @@ github.com/gin-gonic/gin v1.6.0/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwv 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-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= @@ -37,6 +41,8 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.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= @@ -57,7 +63,10 @@ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -67,8 +76,9 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= +github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -95,6 +105,8 @@ github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGw github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mkevac/debugcharts v0.0.0-20191222103121-ae1c48aa8615 h1:/mD+ABZyXD39BzJI2XyRJlqdZG11gXFo0SSynL+OFeU= +github.com/mkevac/debugcharts v0.0.0-20191222103121-ae1c48aa8615/go.mod h1:Ad7oeElCZqA1Ufj0U9/liOF4BtVepxRcTvr2ey7zTvM= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= @@ -121,6 +133,10 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E= github.com/robfig/cron/v3 v3.0.0/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/shirou/gopsutil v2.19.11+incompatible h1:lJHR0foqAjI4exXqWsU3DbH7bX1xvdhGdnXTIARA9W4= +github.com/shirou/gopsutil v2.19.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U= +github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -164,8 +180,6 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/automaxprocs v1.4.0 h1:CpDZl6aOlLhReez+8S3eEotD7Jx0Os++lemPlMULQP0= -go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= @@ -191,6 +205,7 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191220220014-0732a990476f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -229,9 +244,11 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gorm.io/driver/mysql v1.1.1 h1:yr1bpyqiwuSPJ4aGGUX9nu46RHXlF8RASQVb1QQNcvo= +gorm.io/driver/mysql v1.1.1/go.mod h1:KdrTanmfLPPyAOeYGyG+UpDys7/7eeWT1zCq+oekYnU= gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.21.3 h1:qDFi55ZOsjZTwk5eN+uhAmHi8GysJ/qCTichM/yO7ME= -gorm.io/gorm v1.21.3/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.21.9 h1:INieZtn4P2Pw6xPJ8MzT0G4WUOsHq3RhfuDF1M6GW0E= +gorm.io/gorm v1.21.9/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 58cf0e5320fee12626d9cf5b4c58d1f07db743e2 Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 6 Jul 2021 21:50:11 +0800 Subject: [PATCH 28/29] Modify .goreleaser.yml --- .goreleaser.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index 6216c8b..2f15afe 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -4,6 +4,7 @@ env: builds: - env: - CGO_ENABLED=0 + ldflags: -s -w goos: - linux - windows From fed7de9d2a69d011ccd4405929cc6c5e6a934c60 Mon Sep 17 00:00:00 2001 From: iyear Date: Tue, 6 Jul 2021 21:51:41 +0800 Subject: [PATCH 29/29] Modify .goreleaser.yml --- .goreleaser.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index 2f15afe..8d8c66f 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -29,6 +29,11 @@ archives: format_overrides: - goos: windows format: zip + files: + - README.md + - README_zhCN.md + - config.yml.example + - LICENSE snapshot: name_template: "{{ .Tag }}-next" changelog: