Compare commits

..

8 Commits

Author SHA1 Message Date
源文雨
41c499840f fix #197: 猜单词出现空指针报警 2022-04-18 22:59:33 +08:00
himawari
f5cef170f0 🚑️ 修复查看其他群聊热词的问题 (#195) 2022-04-18 16:31:09 +08:00
源文雨
d7922a7c9b ️ 优化pool 2022-04-18 16:29:09 +08:00
github-actions[bot]
23fc77e8e1 🎨 改进代码样式 2022-04-17 13:25:27 +00:00
himawari
51f3eda09a 👍 添加聊天热词 (#192)
*  添加聊天热词

*  添加聊天热词

*  添加聊天热词

* 🚨 修lint

* 🚨 修lint
2022-04-17 21:24:07 +08:00
源文雨
6ec08a5227 🐛 reg 时序 2022-04-17 21:22:08 +08:00
源文雨
4855f694cb 🎨 edit README 2022-04-17 00:11:54 +08:00
源文雨
eaef37a831 Update README.md 2022-04-16 19:10:06 +08:00
7 changed files with 199 additions and 20 deletions

View File

@@ -11,7 +11,7 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/FloatTech/ZeroBot-Plugin?style=flat-square&logo=go)](https://goreportcard.com/report/github.com/github.com/FloatTech/ZeroBot-Plugin)
[![Badge](https://img.shields.io/badge/onebot-v11-black?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAABwCAMAAADxPgR5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAxQTFRF////29vbr6+vAAAAk1hCcwAAAAR0Uk5T////AEAqqfQAAAKcSURBVHja7NrbctswDATQXfD//zlpO7FlmwAWIOnOtNaTM5JwDMa8E+PNFz7g3waJ24fviyDPgfhz8fHP39cBcBL9KoJbQUxjA2iYqHL3FAnvzhL4GtVNUcoSZe6eSHizBcK5LL7dBr2AUZlev1ARRHCljzRALIEog6H3U6bCIyqIZdAT0eBuJYaGiJaHSjmkYIZd+qSGWAQnIaz2OArVnX6vrItQvbhZJtVGB5qX9wKqCMkb9W7aexfCO/rwQRBzsDIsYx4AOz0nhAtWu7bqkEQBO0Pr+Ftjt5fFCUEbm0Sbgdu8WSgJ5NgH2iu46R/o1UcBXJsFusWF/QUaz3RwJMEgngfaGGdSxJkE/Yg4lOBryBiMwvAhZrVMUUvwqU7F05b5WLaUIN4M4hRocQQRnEedgsn7TZB3UCpRrIJwQfqvGwsg18EnI2uSVNC8t+0QmMXogvbPg/xk+Mnw/6kW/rraUlvqgmFreAA09xW5t0AFlHrQZ3CsgvZm0FbHNKyBmheBKIF2cCA8A600aHPmFtRB1XvMsJAiza7LpPog0UJwccKdzw8rdf8MyN2ePYF896LC5hTzdZqxb6VNXInaupARLDNBWgI8spq4T0Qb5H4vWfPmHo8OyB1ito+AysNNz0oglj1U955sjUN9d41LnrX2D/u7eRwxyOaOpfyevCWbTgDEoilsOnu7zsKhjRCsnD/QzhdkYLBLXjiK4f3UWmcx2M7PO21CKVTH84638NTplt6JIQH0ZwCNuiWAfvuLhdrcOYPVO9eW3A67l7hZtgaY9GZo9AFc6cryjoeFBIWeU+npnk/nLE0OxCHL1eQsc1IciehjpJv5mqCsjeopaH6r15/MrxNnVhu7tmcslay2gO2Z1QfcfX0JMACG41/u0RrI9QAAAABJRU5ErkJggg==)](https://github.com/howmanybots/onebot)
[![Badge](https://img.shields.io/badge/zerobot-v1.4.1-black?style=flat-square&logo=go)](https://github.com/wdvxdr1123/ZeroBot)
[![Badge](https://img.shields.io/badge/zerobot-v1.5.0-black?style=flat-square&logo=go)](https://github.com/wdvxdr1123/ZeroBot)
[![License](https://img.shields.io/github/license/FloatTech/ZeroBot-Plugin.svg?style=flat-square&logo=gnu)](https://raw.githubusercontent.com/FloatTech/ZeroBot-Plugin/master/LICENSE)
[![qq group](https://img.shields.io/badge/group-1048452984-red?style=flat-square&logo=tencent-qq)](https://jq.qq.com/?_wv=1027&k=QMb7x1mM)
@@ -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...**
## 使用方法
@@ -469,7 +471,3 @@ GOOS=linux GOARCH=mips GOMIPS=softfloat CGO_ENABLED=0 go build -ldflags "-s -w"
- [ZeroBot](https://github.com/wdvxdr1123/ZeroBot)
- [ATRI](https://github.com/Kyomotoi/ATRI)
## License
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FFloatTech%2FZeroBot-Plugin.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FFloatTech%2FZeroBot-Plugin?ref=badge_large)

2
data

Submodule data updated: 7d6739a9b7...b3d25c45fd

6
go.mod
View File

@@ -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.20220418145633-c1d3c00da628
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

16
go.sum
View File

@@ -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.20220418145633-c1d3c00da628 h1:NC7m06uyenwt4TRyCEkK5lFNId3TB5gKEeOYNQpYTBI=
github.com/FloatTech/zbputils v1.3.3-0.20220418145633-c1d3c00da628/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=
@@ -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=

View File

@@ -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" // 早报

View File

@@ -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": gid, "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] }

View File

@@ -13,6 +13,7 @@ import (
"time"
"github.com/FloatTech/AnimeAPI/tl"
"github.com/sirupsen/logrus"
"github.com/FloatTech/zbputils/binary"
"github.com/FloatTech/zbputils/control"
@@ -77,7 +78,7 @@ func init() {
}),
))
en.OnRegex(`(个人|团队)(五阶|六阶|七阶)?猜单词`, zero.OnlyGroup, ctxext.DoOnceOnSuccess(
en.OnRegex(`^(个人|团队)(五阶|六阶|七阶)?猜单词$`, zero.OnlyGroup, ctxext.DoOnceOnSuccess(
func(ctx *zero.Ctx) bool {
var errcnt uint32
var wg sync.WaitGroup
@@ -87,6 +88,7 @@ func init() {
go func(i int) {
defer wg.Done()
dc, err := file.GetLazyData(fmt.Sprintf("%scet-4_%d.txt", en.DataFolder(), i), true, true)
logrus.Debugln("[wordle] get", fmt.Sprintf("%scet-4_%d.txt", en.DataFolder(), i))
if err != nil {
atomic.AddUint32(&errcnt, 1)
return
@@ -102,6 +104,7 @@ func init() {
go func(i int) {
defer wg.Done()
dd, err := file.GetLazyData(fmt.Sprintf("%sdict_%d.txt", en.DataFolder(), i), true, true)
logrus.Debugln("[wordle] get", fmt.Sprintf("%sdict_%d.txt", en.DataFolder(), i))
if err != nil {
atomic.AddUint32(&errcnt, 1)
return