Skip to content

Commit

Permalink
Merge branch 'FloatTech:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Jiang-Red authored Apr 17, 2022
2 parents d2574e1 + 23fc77e commit c974e18
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 14 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ print("run[CQ:image,file="+j["img"]+"]")
```
- **舔狗日记** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/tiangou"`
- [x] 舔狗日记
- **聊天热词** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/word_count"`
- [x] 热词 [群号] [消息数目]|热词 123456 1000
- **TODO...**

## 使用方法
Expand Down
2 changes: 1 addition & 1 deletion data
Submodule data updated 1 files
+22 −6 main.go
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ module github.com/FloatTech/ZeroBot-Plugin
go 1.18

require (
github.com/FloatTech/AnimeAPI v1.3.3-0.20220415110058-2e4bd994628f
github.com/FloatTech/AnimeAPI v1.3.3-0.20220417132103-df55797131af
github.com/FloatTech/sqlite v0.2.1
github.com/FloatTech/zbputils v1.3.3-0.20220415163049-e00f8d44fadb
github.com/FloatTech/zbputils v1.3.3-0.20220417132003-a50e9afdc0c6
github.com/antchfx/htmlquery v1.2.4
github.com/corona10/goimagehash v1.0.3
github.com/fogleman/gg v1.3.0
github.com/fumiama/cron v1.3.0
github.com/fumiama/go-base16384 v1.4.0
github.com/fumiama/go-registry v0.1.3
github.com/fumiama/go-registry v0.1.5
github.com/fumiama/gofastTEA v0.0.10
github.com/fumiama/gotracemoe v0.0.3
github.com/fumiama/sqlite3 v1.14.6
Expand Down
16 changes: 6 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
github.com/FloatTech/AnimeAPI v1.3.3-0.20220415110058-2e4bd994628f h1:z+VXjigJ1QtHz5ArGbvh7/YfXf94Qs5KKc0kSe7IbnE=
github.com/FloatTech/AnimeAPI v1.3.3-0.20220415110058-2e4bd994628f/go.mod h1:HXlKP24hAdQocJcOIG2ZEFYd789fRyatSflt2wUT/b4=
github.com/FloatTech/AnimeAPI v1.3.3-0.20220417132103-df55797131af h1:K7Cdrd1jgiTUe8hcITgmwJeIdwfCMM+phw8DD1tALXA=
github.com/FloatTech/AnimeAPI v1.3.3-0.20220417132103-df55797131af/go.mod h1:jUOit4oeiKOtRDy5ZLTJQa7aE0972R/KPF15b22Q3vY=
github.com/FloatTech/sqlite v0.2.1 h1:9t6Me48XJJCIoPy4nLRvcdhcVKfT0c2lilp7SEKROG8=
github.com/FloatTech/sqlite v0.2.1/go.mod h1:6NfHRzqOo9RWeMJEoAQVuo51Omd5LFNxCNQhMF02/9U=
github.com/FloatTech/zbputils v1.3.3-0.20220415150756-e428c8ec6615 h1:Bi/lMkR43Y30vemaAsKCANanN+cU42jOndCiy8Ni1VA=
github.com/FloatTech/zbputils v1.3.3-0.20220415150756-e428c8ec6615/go.mod h1:a6vKTjBt//Mr4M8VSSj5ER597/ZjJ+dJAIQSVU/M/oY=
github.com/FloatTech/zbputils v1.3.3-0.20220415152725-74a07dd318ad h1:bhZUiOA5WvCXWF8hT0keeX65jBbMWwxGyyfoVlFtMjA=
github.com/FloatTech/zbputils v1.3.3-0.20220415152725-74a07dd318ad/go.mod h1:a6vKTjBt//Mr4M8VSSj5ER597/ZjJ+dJAIQSVU/M/oY=
github.com/FloatTech/zbputils v1.3.3-0.20220415163049-e00f8d44fadb h1:VLFBrg+YhCxsRj2sbrPsoiB1KroYOzvUS6dZvdxEFqU=
github.com/FloatTech/zbputils v1.3.3-0.20220415163049-e00f8d44fadb/go.mod h1:a6vKTjBt//Mr4M8VSSj5ER597/ZjJ+dJAIQSVU/M/oY=
github.com/FloatTech/zbputils v1.3.3-0.20220417132003-a50e9afdc0c6 h1:O1qoV79PMehjyfruFOWOctFLFlEWLVkEypxVyQZnVx0=
github.com/FloatTech/zbputils v1.3.3-0.20220417132003-a50e9afdc0c6/go.mod h1:K2IVrhwmrVKZSHSHmNoO9JthN1As9RcnQplf+stQ5BY=
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/RomiChan/syncx v0.0.0-20220404072119-d7ea0ae15a4c h1:cNPOdTNiVwxLpROLjXCgbIPvdkE+BwvxDvgmdYmWx6Q=
github.com/RomiChan/syncx v0.0.0-20220404072119-d7ea0ae15a4c/go.mod h1:KqZzu7slNKROh3TSYEH/IUMG6f4M+1qubZ5e52QypsE=
Expand Down Expand Up @@ -38,8 +34,8 @@ github.com/fumiama/cron v1.3.0 h1:ZWlwuexF+HQHl3cYytEE5HNwD99q+3vNZF1GrEiXCFo=
github.com/fumiama/cron v1.3.0/go.mod h1:bz5Izvgi/xEUI8tlBN8BI2jr9Moo8N4or0KV8xXuPDY=
github.com/fumiama/go-base16384 v1.4.0 h1:4KrtewnmAChrZjPA7/QYc72t+vvsKF+DYB0q1iRPdpo=
github.com/fumiama/go-base16384 v1.4.0/go.mod h1:OEn+947GV5gsbTAnyuUW/SrfxJYUdYupSIQXOuGOcXM=
github.com/fumiama/go-registry v0.1.3 h1:WvUN2wdziB2+LyYs4zNy1FHGQOvZeto7lbADfSqbMPw=
github.com/fumiama/go-registry v0.1.3/go.mod h1:iJT3DVgH7KXpJZs6waXEjnWtJPUBBGhF+ByJIMRfngk=
github.com/fumiama/go-registry v0.1.5 h1:5a7n+JwwKQrnW3U0+gOKSx+2x4Zv+2A3BhyQthJL4Ng=
github.com/fumiama/go-registry v0.1.5/go.mod h1:dIUVbiOgfk9oZcsgwDvNLC72i+ctibVukSXR/9bLviI=
github.com/fumiama/gofastTEA v0.0.10 h1:JJJ+brWD4kie+mmK2TkspDXKzqq0IjXm89aGYfoGhhQ=
github.com/fumiama/gofastTEA v0.0.10/go.mod h1:RIdbYZyB4MbH6ZBlPymRaXn3cD6SedlCu5W/HHfMPBk=
github.com/fumiama/gotracemoe v0.0.3 h1:iI5EbE9A3UUbfukG6+/soYPjp1S31eCNYf4tw7s6/Jc=
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/translation" // 翻译
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtb_quotation" // vtb语录
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wangyiyun" // 网易云音乐热评
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/word_count" // 聊天热词
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal" // 月幕galgame
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/zaobao" // 早报
Expand Down
181 changes: 181 additions & 0 deletions plugin/word_count/word_count.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// Package wordcount 聊天热词
package wordcount

import (
"fmt"
"os"
"regexp"
"sort"
"strconv"
"strings"
"time"

"github.com/FloatTech/zbputils/binary"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
"github.com/FloatTech/zbputils/file"
"github.com/FloatTech/zbputils/img/text"
"github.com/golang/freetype"
"github.com/sirupsen/logrus"
"github.com/wcharczuk/go-chart/v2"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)

var (
re = regexp.MustCompile(`^[一-龥]+$`)
stopwords []string
)

func init() {
engine := control.Register("wordcount", &control.Options{
DisableOnDefault: false,
Help: "聊天热词\n" +
"- 热词 [群号] [消息数目]|热词 123456 1000",
PublicDataFolder: "WordCount",
})
cachePath := engine.DataFolder() + "cache/"
_ = os.RemoveAll(cachePath)
_ = os.MkdirAll(cachePath, 0755)
engine.OnRegex(`^热词\s?(\d*)\s?(\d*)$`, zero.OnlyGroup, ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
_, err := file.GetLazyData(engine.DataFolder()+"stopwords.txt", false, false)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return false
}
data, err := os.ReadFile(engine.DataFolder() + "stopwords.txt")
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return false
}
stopwords = strings.Split(binary.BytesToString(data), "\r\n")
sort.Strings(stopwords)
logrus.Infoln("[wordcount]加载", len(stopwords), "条停用词")
return true
})).Limit(ctxext.LimitByUser).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
ctx.SendChain(message.Text("少女祈祷中..."))
gid, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64)
p, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[2], 10, 64)
if p > 10000 {
p = 10000
}
if p == 0 {
p = 1000
}
if gid == 0 {
gid = ctx.Event.GroupID
}
group := ctx.GetGroupInfo(gid, false)
if group.MemberCount == 0 {
ctx.SendChain(message.Text(zero.BotConfig.NickName[0], "未加入", group.Name, "(", gid, "),无法获得热词呢"))
return
}
today := time.Now().Format("20060102")
drawedFile := fmt.Sprintf("%s%d%s%dwordCount.png", cachePath, gid, today, p)
if file.IsExist(drawedFile) {
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
return
}
messageMap := make(map[string]int)
h := ctx.CallAction("get_group_msg_history", zero.Params{"group_id": gid}).Data
messageSeq := h.Get("messages.0.message_seq").Int()
for i := 0; i < int(p/20) && messageSeq != 0; i++ {
if i != 0 {
h = ctx.CallAction("get_group_msg_history", zero.Params{"group_id": ctx.Event.GroupID, "message_seq": messageSeq}).Data
}
for _, v := range h.Get("messages.#.message").Array() {
tex := strings.TrimSpace(message.ParseMessageFromString(v.Str).ExtractPlainText())
if tex == "" {
continue
}
for _, t := range ctx.GetWordSlices(tex).Get("slices").Array() {
tex := strings.TrimSpace(t.Str)
i := sort.SearchStrings(stopwords, tex)
if re.MatchString(tex) && (i >= len(stopwords) || stopwords[i] != tex) {
messageMap[tex]++
}
}
}
messageSeq = h.Get("messages.0.message_seq").Int()
}
wc := rankByWordCount(messageMap)
if len(wc) > 20 {
wc = wc[:20]
}
// 绘图
if len(wc) == 0 {
ctx.SendChain(message.Text("ERROR:历史消息为空或者无法获得历史消息"))
return
}
_, err := file.GetLazyData(text.FontFile, false, true)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
b, err := os.ReadFile(text.FontFile)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
font, err := freetype.ParseFont(b)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
bars := make([]chart.Value, len(wc))
for i, v := range wc {
bars[i] = chart.Value{
Value: float64(v.Value),
Label: v.Key,
}
}
graph := chart.BarChart{
Font: font,
Title: fmt.Sprintf("%s(%d)在%s号的%d条消息的热词top20", group.Name, gid, time.Now().Format("2006-01-02"), p),
Background: chart.Style{
Padding: chart.Box{
Top: 40,
},
},
Height: 500,
BarWidth: 25,
Bars: bars,
}
f, err := os.Create(drawedFile)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
err = graph.Render(chart.PNG, f)
_ = f.Close()
if err != nil {
_ = os.Remove(drawedFile)
ctx.SendChain(message.Text("ERROR:", err))
return
}
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
})
}

func rankByWordCount(wordFrequencies map[string]int) pairlist {
pl := make(pairlist, len(wordFrequencies))
i := 0
for k, v := range wordFrequencies {
pl[i] = pair{k, v}
i++
}
sort.Sort(sort.Reverse(pl))
return pl
}

type pair struct {
Key string
Value int
}

type pairlist []pair

func (p pairlist) Len() int { return len(p) }
func (p pairlist) Less(i, j int) bool { return p[i].Value < p[j].Value }
func (p pairlist) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

0 comments on commit c974e18

Please sign in to comment.