diff --git a/.gitignore b/.gitignore index 945acc2..2666aab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ data.db -test.json \ No newline at end of file +test.json +config.toml +*.exe \ No newline at end of file diff --git a/config example.toml b/config example.toml new file mode 100644 index 0000000..fc3a200 --- /dev/null +++ b/config example.toml @@ -0,0 +1,10 @@ +[Server] +APIURL = "0.0.0.0:5580" +POSTURL = "http://0.0.0.0:5700" + +[Group] +AllowGroup = [] +AllowUser = [] +AllowRole = [] +BlockGroup = [] +BlockUser = [] \ No newline at end of file diff --git a/go.mod b/go.mod index 5667b21..91eeedc 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,10 @@ module go-bot -go 1.21.0 +go 1.22.2 require github.com/BurntSushi/toml v1.3.2 -require golang.org/x/net v0.17.0 // indirect - require ( - github.com/goccy/go-json v0.10.2 // indirect - github.com/gorilla/websocket v1.5.1 + github.com/goccy/go-json v0.10.2 github.com/mattn/go-sqlite3 v1.14.22 ) diff --git a/main.go b/main.go index 6e649f7..94a1c6c 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,6 @@ package main import ( "database/sql" - "encoding/json" "fmt" "go-bot/config" "go-bot/utils" @@ -11,6 +10,8 @@ import ( "net/http" "time" + "github.com/goccy/go-json" + _ "github.com/mattn/go-sqlite3" ) diff --git a/tools/get_history_message.go b/tools/get_history_message.go new file mode 100644 index 0000000..c5b14e6 --- /dev/null +++ b/tools/get_history_message.go @@ -0,0 +1,141 @@ +package main + +import ( + "database/sql" + "fmt" + "io" + "log" + "net/http" + "time" + + "github.com/goccy/go-json" + _ "github.com/mattn/go-sqlite3" +) + +func main() { + db, err := sql.Open("sqlite3", "./data.db") + if err != nil { + panic(err) + } + defer db.Close() + + rows, err := db.Query("SELECT DISTINCT group_id FROM messages") + if err != nil { + panic(err) + } + defer rows.Close() + var groupIDs []int + for rows.Next() { + var groupID int + err := rows.Scan(&groupID) + if err != nil { + panic(err) + } + groupIDs = append(groupIDs, groupID) + } + for _, groupID := range groupIDs { + minSeq := get_min_seqs(db, groupID) + println("minSeq:", minSeq) + // if minSeq == 0 { + // continue + // } + for minSeq != 0 { + fetchHistoryMessages(db, minSeq, groupID) + temp := get_min_seqs(db, groupID) + if temp == minSeq { + println("已获取到最久数据!") + time.Sleep(time.Second * 2) + break + } + minSeq = temp + // println("minSeq_changed:", minSeq) + + } + } + +} +func get_min_seqs(db *sql.DB, groupID int) int { + var minMessageSeq int + err := db.QueryRow("SELECT MIN(message_seq) FROM messages WHERE group_id = ?", groupID).Scan(&minMessageSeq) + if err != nil { + panic(err) + } + // println("minMessageSeq:", minMessageSeq) + var count int + err = db.QueryRow("SELECT COUNT(*) FROM messages WHERE group_id = ? AND message_seq = ?", groupID, minMessageSeq-1).Scan(&count) + if err != nil { + panic(err) + } + // println("count:", count) + if count > 0 { + return 0 + } + fmt.Printf("Group ID: %d, Min Message Seq: %d\n", groupID, minMessageSeq) + return minMessageSeq +} +func fetchHistoryMessages(db *sql.DB, message_seq int, group_id int) (int, error) { + url := fmt.Sprintf("http://127.0.0.1:5700/get_group_msg_history?message_seq=%d&group_id=%d", message_seq, group_id) + println("min message_seq :", message_seq, "min group_id: ", group_id) + println(url) + resp, err := http.Get(url) + if err != nil { + panic(err) + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + return 0, err + } + // println("Body:", string(body)) + var messageResp map[string]interface{} + err = json.Unmarshal(body, &messageResp) + if err != nil { + return 0, err + } + data := messageResp["data"].(map[string]interface{}) + messages := data["messages"].([]interface{}) + for _, message := range messages { + messageMap := message.(map[string]interface{}) + insertMessage(db, messageMap) + + } + time.Sleep(time.Second * 1) + return 0, nil +} + +func insertMessage(db *sql.DB, data map[string]interface{}) error { + + if data["post_type"] == "message" { + // id := data["message_id"].(float64) + post_type := data["post_type"].(string) + message_type := data["message_type"].(string) + // 设置东八区时间 + loc, err := time.LoadLocation("Asia/Shanghai") + if err != nil { + log.Fatal(err) + } + message_time := (time.Unix(int64(data["time"].(float64)), 0).In(loc)).Format("2006-01-02 15:04:05") + group_id := data["group_id"].(float64) + message_id := data["message_id"].(float64) + raw_message := data["raw_message"].(string) + sender := data["sender"].(map[string]interface{}) + sender_user_id := sender["user_id"].(float64) + sender_nickname := sender["nickname"].(string) + sender_card := sender["card"].(string) + if sender_card == "" { + sender_card = sender_nickname + } + sender_role := sender["role"].(string) + message_seq := data["message_seq"].(float64) + + fmt.Println(post_type, message_type, message_time, group_id, message_id, raw_message, sender_user_id, sender_nickname, sender_card, sender_role, message_seq) + // Insert data into database + _, err = db.Exec("INSERT INTO messages ( post_type, message_type, time, group_id, message_id, raw_message, sender_user_id, sender_nickname, sender_card, sender_role, message_seq) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + post_type, message_type, message_time, group_id, message_id, raw_message, sender_user_id, sender_nickname, sender_card, sender_role, message_seq) + fmt.Println("Data inserted successfully!") + if err != nil { + log.Fatal(err) + } + } + return nil +} diff --git a/workers/lsp.go b/workers/lsp.go new file mode 100644 index 0000000..0255b5b --- /dev/null +++ b/workers/lsp.go @@ -0,0 +1,44 @@ +package workers + +import ( + "fmt" + + "github.com/goccy/go-json" + + "io" + "net/http" +) + +type Lsp struct { + *StdAns +} + +func (a *Lsp) GetMsg() string { + a.AllowGroup = []string{"313047773"} + url := "https://api.lolicon.app/setu/v2?r18=0&size=small" + resp, err := http.Get(url) + if err != nil { + return "获取失败" + } + defer resp.Body.Close() + budy, err := io.ReadAll(resp.Body) + var res map[string]interface{} + err = json.Unmarshal(budy, &res) + if err != nil { + return "解析失败" + } + code := res["error"].(string) + if code != "" { + return "获取失败" + } + data := res["data"].([]interface{}) + uid := data[0].(map[string]interface{})["uid"].(float64) + urls := data[0].(map[string]interface{})["urls"].(map[string]interface{}) + imgUrl := urls["small"].(string) + // title := data[0].(map[string]interface{})["title"].(string) + // println("标题:" + title + "\n" + imgUrl) + msg := fmt.Sprintf("[CQ:reply,id=%s]Pixiv ID:%d", a.MID, int64(uid)) + a.SendMsg(msg) + return fmt.Sprintf("[CQ:image,file=%s]", imgUrl) + +} diff --git a/workers/newworker.go b/workers/newworker.go index 8d14c8c..9992d51 100644 --- a/workers/newworker.go +++ b/workers/newworker.go @@ -22,6 +22,10 @@ func NewWorker(parms []string, uid, gid, role, mid, rawMsg string) Worker { return &Ip{ StdAns: NewStdAns(parms, uid, gid, role, mid, rawMsg), } + case "lsp": + return &Lsp{ + StdAns: NewStdAns(parms, uid, gid, role, mid, rawMsg), + } default: return &Emm{ StdAns: NewStdAns(parms, uid, gid, role, mid, rawMsg)} diff --git a/workers/pkg.go b/workers/pkg.go index b481c52..2531e54 100644 --- a/workers/pkg.go +++ b/workers/pkg.go @@ -1,12 +1,13 @@ package workers import ( - "encoding/json" "fmt" "io" "net/http" "strings" "time" + + "github.com/goccy/go-json" ) type Pkg struct { @@ -20,23 +21,25 @@ func (a *Pkg) GetMsg() string { } // 去除换行符 raw_msg := strings.TrimRight(a.RawMsg, "\n") + raw_msg = strings.TrimRight(raw_msg, "\r") + fmt.Println("raw_msg:", raw_msg) parms := strings.Split(raw_msg, " ") url := "https://archlinux.org/packages/search/json/?name=" + parms[1] - if len(parms) > 2 { + if len(parms) > 2 && parms[1] != "" { url += "&repo=" + strings.ToUpper(parms[2][:1]) + parms[2][1:] } // 输出请求地址 fmt.Println("pkg url:", url) req, err := http.Get(url) if err != nil { - return err.Error() + return "服务器网络错误!" } defer req.Body.Close() body, err := io.ReadAll(req.Body) if err != nil { - return err.Error() + return "数据解析错误!" } // fmt.Println("pkg body:", string(body)) // var pkg []Package @@ -56,7 +59,7 @@ func (a *Pkg) GetMsg() string { } defer req.Body.Close() - fmt.Println("aur url:", url) + fmt.Println("aur suggest url:", url) re, err := io.ReadAll(req.Body) // fmt.Println(string(re)) if err != nil { @@ -67,43 +70,62 @@ func (a *Pkg) GetMsg() string { if err != nil { fmt.Println(err) } - if len(suggestions) > 0 { - searchUrl := "https://aur.archlinux.org/rpc/v5/search/" + suggestions[0] + "?by=name" - searchReq, err := http.Get(searchUrl) - if err != nil { - fmt.Println(err) - } - defer searchReq.Body.Close() - searchRe, err := io.ReadAll(searchReq.Body) - if err != nil { - fmt.Println(err) - } - var searchMap map[string]interface{} - err = json.Unmarshal(searchRe, &searchMap) - if err != nil { - fmt.Println(err) - } - searchResults := searchMap["results"].([]interface{}) - searchResult := searchResults[0].(map[string]interface{}) - maintainer, ok := searchResult["Maintainer"].(string) - if !ok { - maintainer = "孤儿包" - } - last_update := time.Unix(int64(searchResult["LastModified"].(float64)), 0).Format("2006-01-02 15:04:05") - var msg string - msg += "仓库:AUR\n" - msg += "包名:" + searchResult["Name"].(string) + "\n" - msg += "版本:" + searchResult["Version"].(string) + "\n" - msg += "描述:" + searchResult["Description"].(string) + "\n" - msg += "维护者:" + maintainer + "\n" - msg += "链接:" + searchResult["URL"].(string) + "\n" - msg += "更新时间:" + last_update + "\n" - - fmt.Println(msg) - return msg - } else { + // println(len(suggestions)) + if len(suggestions) == 0 { return "没有找到相关软件" } + searchUrl := "https://aur.archlinux.org/rpc/v5/search/" + suggestions[0] + "?by=name" + searchReq, err := http.Get(searchUrl) + if err != nil { + fmt.Println(err) + } + defer searchReq.Body.Close() + searchRe, err := io.ReadAll(searchReq.Body) + if err != nil { + fmt.Println(err) + } + var searchMap map[string]interface{} + err = json.Unmarshal(searchRe, &searchMap) + if err != nil { + fmt.Println(err) + } + searchResults := searchMap["results"].([]interface{}) + // println("searchResults:", len(searchResults)) + maxVotes := 0.0 + var searchResult map[string]interface{} + // 增加根据投票人数排序 + if len(searchResults) > 1 { + for _, result := range searchResults { + resultMap := result.(map[string]interface{}) + numVotes := resultMap["NumVotes"].(float64) + if numVotes > maxVotes { + maxVotes = numVotes + searchResult = resultMap + } + } + fmt.Println(len(searchResult)) + } else if len(searchResults) == 1 { + searchResult = searchResults[0].(map[string]interface{}) + } + maintainer, ok := searchResult["Maintainer"].(string) + if !ok { + maintainer = "孤儿包" + } + println("maintainer:", maintainer) + // last_update := '' + last_update := time.Unix(int64(searchResult["LastModified"].(float64)), 0).Format("2006-01-02 15:04:05") + + var msg string + msg += "仓库:AUR\n" + msg += "包名:" + searchResult["Name"].(string) + "\n" + msg += "版本:" + searchResult["Version"].(string) + "\n" + msg += "描述:" + searchResult["Description"].(string) + "\n" + msg += "维护者:" + maintainer + "\n" + msg += "链接:" + searchResult["URL"].(string) + "\n" + msg += "更新时间:" + last_update + + fmt.Println(msg) + return msg } result := resultSlipe[0].(map[string]interface{})