From 80a17cdd8186fdb9f99e5197ac61ff49477edfc3 Mon Sep 17 00:00:00 2001 From: RicheyJang <773602577@qq.com> Date: Fri, 28 Jan 2022 20:35:26 +0800 Subject: [PATCH] add plugin: Pixiv Rank --- README.md | 3 +- cmd/main.go | 1 + plugins/pixiv/download.go | 25 ++++-- plugins/pixiv/init.go | 2 +- plugins/pixiv_rank/hibi.go | 78 ++++++++++++++++++ plugins/pixiv_rank/init.go | 158 +++++++++++++++++++++++++++++++++++++ 6 files changed, 259 insertions(+), 8 deletions(-) create mode 100644 plugins/pixiv_rank/hibi.go create mode 100644 plugins/pixiv_rank/init.go diff --git a/README.md b/README.md index a37e622..ef7627b 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,8 @@ ### 好康的 - [x] 涩图 (pixiv) -- [ ] Pixiv排行榜 +- [x] Pixiv排行榜 (pixiv_rank) +- [ ] 查看Pixiv插图所有分P - [ ] coser diff --git a/cmd/main.go b/cmd/main.go index adc9ded..b7c8e5a 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -29,6 +29,7 @@ import ( _ "github.com/RicheyJang/PaimengBot/plugins/inspection" _ "github.com/RicheyJang/PaimengBot/plugins/music" _ "github.com/RicheyJang/PaimengBot/plugins/pixiv" + _ "github.com/RicheyJang/PaimengBot/plugins/pixiv_rank" _ "github.com/RicheyJang/PaimengBot/plugins/random" _ "github.com/RicheyJang/PaimengBot/plugins/short_url" _ "github.com/RicheyJang/PaimengBot/plugins/statistic" diff --git a/plugins/pixiv/download.go b/plugins/pixiv/download.go index 4ae74c4..35c73b2 100644 --- a/plugins/pixiv/download.go +++ b/plugins/pixiv/download.go @@ -128,6 +128,12 @@ func (pic *PictureInfo) GenSinglePicMsg() (message.Message, error) { return nil, err } // 文字 + tip := pic.GetDescribe() + return message.Message{message.Text(pic.Title), picMsg, message.Text(tip)}, nil +} + +// GetDescribe 获取图片说明 +func (pic *PictureInfo) GetDescribe() string { var tags []string for _, tag := range pic.Tags { if isCNOrEn(tag) { @@ -147,7 +153,7 @@ func (pic *PictureInfo) GenSinglePicMsg() (message.Message, error) { if len(tags) > 0 { tip += fmt.Sprintf("\n标签: %v", strings.Join(tags, ",")) } - return message.Message{message.Text(pic.Title), picMsg, message.Text(tip)}, nil + return tip } // GetURLByPID 通过PID获取图片下载URL @@ -181,11 +187,7 @@ func (pic *PictureInfo) GetURLByPID() (err error) { if err == nil && len(pic.URL) == 0 { err = fmt.Errorf("unexpected error") } else if len(pic.URL) > 0 { - p := proxy.GetConfigString("proxy") - if len(p) > 0 { - pic.URL = strings.ReplaceAll(pic.URL, "i.pximg.net", p) - pic.URL = strings.ReplaceAll(pic.URL, "i.pixiv.net", p) - } + pic.ReplaceURLToProxy() } }() // 解析 @@ -197,6 +199,17 @@ func (pic *PictureInfo) GetURLByPID() (err error) { return nil } +// ReplaceURLToProxy 将图片URL替换为反代地址 +func (pic *PictureInfo) ReplaceURLToProxy() { + if len(pic.URL) > 0 { + p := proxy.GetConfigString("proxy") + if len(p) > 0 { + pic.URL = strings.ReplaceAll(pic.URL, "i.pximg.net", p) + pic.URL = strings.ReplaceAll(pic.URL, "i.pixiv.net", p) + } + } +} + func getTimeout() time.Duration { s := proxy.GetConfigString("timeout") if len(s) == 0 { // 未设置 diff --git a/plugins/pixiv/init.go b/plugins/pixiv/init.go index c6888ad..73cb83b 100644 --- a/plugins/pixiv/init.go +++ b/plugins/pixiv/init.go @@ -22,7 +22,7 @@ var info = manager.PluginInfo{ 另外,高级用法询问管理员哦~[dog]`, SuperUsage: `特别用法:(在私聊中) 色图r [Tag]* [数量num]?:你懂得 -配置项: +config-plugin配置项: pixiv.timeout: 下载图片超时时长,至少为1s;越长下载成功率越高、等待时间越长 pixiv.proxy: Pixiv反代网站,默认为i.pixiv.re,令外可选i.pixiv.cat pixiv.scale:从各个图库取图的比例,导入Omega图库后,将pixiv.scale.omega设为非0值才可使其生效 diff --git a/plugins/pixiv_rank/hibi.go b/plugins/pixiv_rank/hibi.go new file mode 100644 index 0000000..19332a6 --- /dev/null +++ b/plugins/pixiv_rank/hibi.go @@ -0,0 +1,78 @@ +package pixiv_rank + +import ( + "fmt" + "strconv" + "strings" + + "github.com/RicheyJang/PaimengBot/plugins/pixiv" + "github.com/RicheyJang/PaimengBot/utils" + "github.com/RicheyJang/PaimengBot/utils/client" + "github.com/RicheyJang/PaimengBot/utils/consts" + + "github.com/tidwall/gjson" +) + +func getPixivRankByHIBI(rankType string, num int, date string) ([]pixiv.PictureInfo, error) { + // 整理API URL + api := proxy.GetAPIConfig(consts.APIOfHibiAPIKey) + if len(api) == 0 { + return nil, fmt.Errorf("API of HibiAPI is empty") + } + if !strings.HasPrefix(api, "http://") && !strings.HasPrefix(api, "https://") { + api = "https://" + api + } + if !strings.HasSuffix(api, "/") { + api += "/" + } + api = fmt.Sprintf("%sapi/pixiv/rank?mode=%v&size=%v", api, rankType, num) + if len(date) > 0 { + api += "&date=" + date + } + // 调用 + c := client.NewHttpClient(nil) + rsp, err := c.GetGJson(api) + if err != nil { + return nil, err + } + rsp = rsp.Get("illusts") + if !rsp.Exists() { + return nil, fmt.Errorf("illusts is not found") + } + // 解析 + var pics []pixiv.PictureInfo + illusts := rsp.Array() + for i, illust := range illusts { + if i >= num { // 限制数量 + break + } + pics = append(pics, analysisHIBIIllust(illust)) + } + return pics, nil +} + +// 分析单张插图信息 +func analysisHIBIIllust(illust gjson.Result) pixiv.PictureInfo { + pic := pixiv.PictureInfo{ + Title: illust.Get("title").String(), + PID: illust.Get("id").Int(), + P: 0, + Author: illust.Get("user.name").String(), + UID: illust.Get("user.id").Int(), + } + for _, tag := range illust.Get("tags").Array() { + if tag.Get("name").Type != gjson.Null { + pic.Tags = append(pic.Tags, tag.Get("name").String()) + } + if tag.Get("translated_name").Type != gjson.Null { + pic.Tags = append(pic.Tags, tag.Get("translated_name").String()) + } + } + pic.Tags = utils.MergeStringSlices(pic.Tags) // 去重 + if illust.Get("page_count").Int() == 1 { + pic.URL = illust.Get("meta_single_page.original_image_url").String() + } else if illust.Get("page_count").Int() > int64(pic.P) { + pic.URL = illust.Get("meta_pages." + strconv.Itoa(pic.P) + ".image_urls.original").String() + } + return pic +} diff --git a/plugins/pixiv_rank/init.go b/plugins/pixiv_rank/init.go new file mode 100644 index 0000000..a177a40 --- /dev/null +++ b/plugins/pixiv_rank/init.go @@ -0,0 +1,158 @@ +package pixiv_rank + +import ( + "fmt" + "strconv" + "strings" + "time" + + "github.com/RicheyJang/PaimengBot/manager" + "github.com/RicheyJang/PaimengBot/utils" + "github.com/RicheyJang/PaimengBot/utils/consts" + + log "github.com/sirupsen/logrus" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" +) + +var info = manager.PluginInfo{ + Name: "pixiv排行榜", + Usage: `用法: + pixiv排行榜 [类型]? [数量]? [日期]?:获取指定日期指定数量指定类型的Pixiv排行榜图片 +可选类型(左侧数字): + 1. 日排行 + 2. 周排行 + 3. 月排行 + 4. 男性向日排行 + 5. 女性向日排行 + 6. 原创排行 + 7. 新人排行 +以下类型仅限私聊: + 8. R18日排行 + 9. R18周排行 + 10. R18男性向日排行 + 11. R18女性向日排行 +示例: + pixiv排行榜:默认当日排行5张 + pixiv排行榜 4:男性向当日排行5张 + pixiv排行榜 4 20:男性向当日排行20张 + pixiv排行榜 4 20 2022-01-28:男性向2022年1月28日排行10张`, + SuperUsage: ` +备注:config-plugin配置项沿用pixiv插件`, + Classify: "好康的", +} +var proxy *manager.PluginProxy + +func init() { + proxy = manager.RegisterPlugin(info) + if proxy == nil { + return + } + proxy.OnCommands([]string{"pixiv排行榜", "Pixiv排行榜"}).SetBlock(true).SetPriority(3).Handle(getRankPictures) + + proxy.AddAPIConfig(consts.APIOfHibiAPIKey, "api.obfs.dev") +} + +func getRankPictures(ctx *zero.Ctx) { + if proxy.LockUser(ctx.Event.UserID) { + ctx.Send("正在发送中呢,稍等一下嘛") + return + } + defer proxy.UnlockUser(ctx.Event.UserID) + + rankType, num, date := analysisArgs(utils.GetArgs(ctx)) + if !utils.IsMessagePrimary(ctx) && strings.Contains(rankType, "r18") { + ctx.Send("滚滚滚去私聊") + return + } + // 获取图片信息 + pics, err := getPixivRankByHIBI(rankType, num, date) + if err != nil { + log.Errorf("getPixivRankByHIBI type=%v,num=%v,date=%v error: %v", rankType, num, date, err) + ctx.Send("失败了...") + return + } + if len(pics) == 0 { + log.Warnf("No Pics : type=%v,num=%v,date=%v", rankType, num, date) + ctx.Send("没图了...") + return + } + // 开始发送 + if len(date) == 0 { + date = "今天" + } + if transType, ok := translateRankTypeMap[rankType]; ok { + rankType = transType + } + ctx.Send(fmt.Sprintf("开始发送%v的%v排行榜,共计%v张", date, rankType, len(pics))) + for _, pic := range pics { + pic.ReplaceURLToProxy() // 使用反代 + // 生成消息 + msg, err := pic.GenSinglePicMsg() + if err != nil { // 下载图片失败 + log.Warnf("GenSinglePicMsg failed: pid=%v, err=%v", pic.PID, err) + msg = message.Message{message.Text(pic.Title + "\n图片下载失败\n" + pic.GetDescribe())} + } + ctx.Send(msg) + } +} + +var rankTypeMap = map[int]string{ + 1: "day", + 2: "week", + 3: "month", + 4: "day_male", + 5: "day_female", + 6: "week_original", + 7: "week_rookie", + 8: "day_r18", + 9: "week_r18", + 10: "day_male_r18", + 11: "day_female_r18", +} + +var translateRankTypeMap = map[string]string{ + "day": "日", + "week": "周", + "month": "月", + "day_male": "男性向日", + "day_female": "女性向日", + "week_original": "原创", + "week_rookie": "新人", + "day_r18": "日R-18", + "week_r18": "周R-18", + "day_male_r18": "男性向R-18", + "day_female_r18": "女性向R-18", +} + +// 分析参数 +func analysisArgs(args string) (rankType string, num int, date string) { + rankType = rankTypeMap[1] + num = 5 // 默认5张 + args = strings.TrimSpace(args) + if len(args) == 0 { + return + } + subs := strings.Split(args, " ") + if len(subs) >= 1 { + tpID, err := strconv.Atoi(subs[0]) + if err != nil || tpID < 1 || tpID > len(rankTypeMap) { + tpID = 1 + } + rankType = rankTypeMap[tpID] + } + if len(subs) >= 2 { + var err error + num, err = strconv.Atoi(subs[1]) + if err != nil || num < 1 || num > 20 { // 最多20张 + num = 5 + } + } + if len(subs) >= 3 { + _, err := time.Parse("2006-01-02", subs[2]) + if err == nil { + date = subs[2] + } + } + return +}