diff --git a/README.md b/README.md index 56de53c2..44e341b0 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,9 @@ zerobot -h -t token -u url [-d|w] [-g] qq1 qq2 qq3 ... - 注:本插件来源于[tgbot](https://github.com/YukariChiba/tgbot/blob/main/modules/Reborn.py) - **翻译** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_translation"` - [x] >TL 你好 +- **vtb语录** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation"` + - [x] vtb语录 + - [x] 随机vtb - **TODO...** ## 使用方法 diff --git a/data/VtbQuotation/vtb.db b/data/VtbQuotation/vtb.db new file mode 100644 index 00000000..97d2c6d6 Binary files /dev/null and b/data/VtbQuotation/vtb.db differ diff --git a/go.mod b/go.mod index 8c0e56d4..72900144 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,8 @@ require ( github.com/gin-gonic/gin v1.7.4 github.com/golang/protobuf v1.5.2 github.com/gorilla/websocket v1.4.2 + github.com/jinzhu/gorm v1.9.16 + github.com/logoove/sqlite v1.13.0 github.com/mroth/weightedrand v0.4.1 github.com/shirou/gopsutil v3.21.10+incompatible github.com/sirupsen/logrus v1.8.1 diff --git a/go.sum b/go.sum index eb12167b..047e62ba 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,10 @@ github.com/FloatTech/bot-manager v1.0.1-0.20211112011524-85b9895271ed h1:GEOgDVb github.com/FloatTech/bot-manager v1.0.1-0.20211112011524-85b9895271ed/go.mod h1:8YYRJ16oroGHQGD2En0oVnmcKJkxR9O/jd5BPSfWfOQ= github.com/FloatTech/imgfactory v0.1.1 h1:ooL2+fV8yrMhv1ShGGKsN0Rm/flWoKnvqXaUD+dC3DQ= github.com/FloatTech/imgfactory v0.1.1/go.mod h1:ThDALab8aOuU6KVYESVWFqmjcqtm03e0SvGlTw6s+aw= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/antchfx/htmlquery v1.2.3 h1:sP3NFDneHx2stfNXCKbhHFo8XgNjCACnU/4AO5gWz6M= github.com/antchfx/htmlquery v1.2.3/go.mod h1:B0ABL+F5irhhMWg54ymEZinzMSi0Kt3I2if0BLYa3V0= github.com/antchfx/xpath v1.1.6 h1:6sVh6hB5T6phw1pFpHRQ+C4bd8sNI+O58flqtg7h0R0= @@ -20,12 +22,16 @@ github.com/antchfx/xpath v1.1.6/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNY 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/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4 h1:BBade+JlV/f7JstZ4pitd4tHhpN+w+6I+LyOS7B4fyU= github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4/go.mod h1:H7chHJglrhPPzetLdzBleF8d22WYOv7UM/lEKYiwlKM= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -49,6 +55,10 @@ 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.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +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/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= @@ -69,6 +79,12 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imroc/req v0.3.0/go.mod h1:F+NZ+2EFSo6EFXdeIbpfE9hcC233id70kf0byW97Caw= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= +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.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M= +github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -77,8 +93,13 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:C github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 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/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/logoove/sqlite v1.13.0 h1:XM7QKK9R3tm8o7bI75R3zmwYBFQ5S3Jqg+XCaqsAMQQ= +github.com/logoove/sqlite v1.13.0/go.mod h1:MRpE/o3qQhT7AgfIdnBue5c63+//xT+KXV0gHeVAUAg= 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.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= @@ -142,7 +163,9 @@ github.com/wdvxdr1123/ZeroBot v1.4.1 h1:fk/8RH2D1gB3YeC1eI/SZi/kG31Rh7Z8lAiDc60V github.com/wdvxdr1123/ZeroBot v1.4.1/go.mod h1:7t9m4vDZPwWAmzKlhP6IvUoisOIiqNdm/3AJgiY3+ew= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -150,9 +173,12 @@ golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jp golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= diff --git a/main.go b/main.go index c259ef61..51337018 100644 --- a/main.go +++ b/main.go @@ -42,13 +42,14 @@ import ( _ "github.com/FloatTech/ZeroBot-Plugin/plugin_diana" // 嘉心糖发病 // 二次元图片 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_acgimage" // 随机图片与AI点评 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_aiwife" // 随机老婆 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_image_finder" // 关键字搜图 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_lolicon" // lolicon 随机图片 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_saucenao" // 以图搜图 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_setutime" // 来份涩图 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_tracemoe" // 搜番 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_acgimage" // 随机图片与AI点评 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_aiwife" // 随机老婆 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_image_finder" // 关键字搜图 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_lolicon" // lolicon 随机图片 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_saucenao" // 以图搜图 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_setutime" // 来份涩图 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_tracemoe" // 搜番 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation" // vtb语录 // 以下为内置依赖,勿动 "github.com/sirupsen/logrus" diff --git a/plugin_vtb_quotation/cron.go b/plugin_vtb_quotation/cron.go new file mode 100644 index 00000000..9514c248 --- /dev/null +++ b/plugin_vtb_quotation/cron.go @@ -0,0 +1,50 @@ +package plugin_vtb_quotation + +import ( + "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation/firstVtb" + "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation/model" + "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation/secondVtb" + "github.com/fumiama/cron" + log "github.com/sirupsen/logrus" + zero "github.com/wdvxdr1123/ZeroBot" +) + +var ( + AtriRule = true +) + +func init() { + engine.OnMessage(atriRule).SetBlock(false).Handle(func(ctx *zero.Ctx) { + log.Println("定时任务只创建一次") + AtriRule = false + log.Println("开启vtb数据库日常更新") + vtbDaily() + }) +} + +func vtbDaily() { + log.Println("创建vtb数据库定时任务") + c := cron.New() + _, err := c.AddFunc("37 11 * * *", func() { vtbData() }) + if err != nil { + log.Println("定时任务有错误:", err) + } else { + log.Println("开启vtb数据库定时任务") + c.Start() + } +} +func vtbData() { + model.Init() + vtbListStr := firstVtb.GetVtbListStr() + uidList := firstVtb.DealVtbListStr(vtbListStr) + log.Println(uidList) + for _, v := range uidList { + vtbStr := secondVtb.GetVtbStr(v) + secondVtb.DealVtbStr(vtbStr, v) + } + model.Db.Close() +} + +func atriRule(ctx *zero.Ctx) bool { + return AtriRule +} diff --git a/plugin_vtb_quotation/firstVtb/firstVtb.go b/plugin_vtb_quotation/firstVtb/firstVtb.go new file mode 100644 index 00000000..755ad519 --- /dev/null +++ b/plugin_vtb_quotation/firstVtb/firstVtb.go @@ -0,0 +1,78 @@ +package firstVtb + +import ( + "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation/model" + "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation/utils" + "github.com/jinzhu/gorm" + log "github.com/sirupsen/logrus" + "github.com/tidwall/gjson" + "io/ioutil" + "net/http" + "strconv" + "strings" +) + +var vtbUrl = "https://vtbkeyboard.moe/api/get_vtb_list" + +func GetVtbListStr() string { + client := &http.Client{} + req, err := http.NewRequest("GET", vtbUrl, nil) + if err != nil { + log.Println(err) + } + // 自定义Header + req.Header.Set("User-Agent", utils.GetAgent()) + resp, err := client.Do(req) + if err != nil { + log.Println(err) + } + + defer resp.Body.Close() + bytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Println(err) + } + //log.Println(string(bytes)) + vtbListStr, err := strconv.Unquote(strings.Replace(strconv.Quote(string(bytes)), `\\u`, `\u`, -1)) + if err != nil { + log.Println(err) + } + log.Println(vtbListStr) + return vtbListStr +} +func DealVtbListStr(vtbListStr string) []string { + uidList := make([]string, 0) + count := gjson.Get(vtbListStr, "#").Int() + for i := int64(0); i < count; i++ { + item := gjson.Get(vtbListStr, strconv.FormatInt(i, 10)) + log.Println(item) + fc := model.FirstCategory{ + FirstCategoryIndex: i, + FirstCategoryName: item.Get("name").String(), + FirstCategoryDescription: item.Get("description").String(), + FirstCategoryIconPath: item.Get("icon_path").String(), + FirstCategoryUid: item.Get("uid").String(), + } + log.Println(fc) + //model.Db.Model(FirstCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUid).FirstOrCreate(&fc) + if err := model.Db.Debug().Model(&model.FirstCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUid).First(&fc).Error; err != nil { + // error handling... + if gorm.IsRecordNotFoundError(err) { + model.Db.Debug().Model(&model.FirstCategory{}).Create(&fc) // newUser not user + } + } else { + model.Db.Debug().Model(&model.FirstCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUid).Update( + map[string]interface{}{ + "first_category_index": i, + "first_category_name": item.Get("name").String(), + "first_category_description": item.Get("description").String(), + "first_category_icon_path": item.Get("icon_path").String(), + }) + } + uidList = append(uidList, fc.FirstCategoryUid) + + } + + log.Println(uidList) + return uidList +} diff --git a/plugin_vtb_quotation/model/model.go b/plugin_vtb_quotation/model/model.go new file mode 100644 index 00000000..0de4aa62 --- /dev/null +++ b/plugin_vtb_quotation/model/model.go @@ -0,0 +1,169 @@ +package model + +import ( + "github.com/jinzhu/gorm" + _ "github.com/logoove/sqlite" + log "github.com/sirupsen/logrus" + + "math/rand" + "os" + "strconv" + "time" +) + +var ( + Db *gorm.DB + path = "data/VtbQuotation/vtb.db" +) + +func Init() { + var err error + if _, err = os.Stat(path); err != nil || os.IsNotExist(err) { + // 生成文件 + f, err := os.Create(path) + if err != nil { + return + } + defer f.Close() + } + Db, err = gorm.Open("sqlite3", path) + if err != nil { + panic("failed to connect database") + } + Db.AutoMigrate(FirstCategory{}).AutoMigrate(SecondCategory{}).AutoMigrate(ThirdCategory{}) +} + +//第一品类 +type FirstCategory struct { + gorm.Model + FirstCategoryIndex int64 `gorm:"column:first_category_index"` + FirstCategoryName string `gorm:"column:first_category_name"` + FirstCategoryUid string `gorm:"column:first_category_uid"` + FirstCategoryDescription string `gorm:"column:first_category_description;type:varchar(1024)"` + FirstCategoryIconPath string `gorm:"column:first_category_icon_path"` +} + +func (FirstCategory) TableName() string { + return "first_category" +} + +//第二品类 +type SecondCategory struct { + gorm.Model + SecondCategoryIndex int64 `gorm:"column:second_category_index"` + FirstCategoryUid string `gorm:"column:first_category_uid;association_foreignkey:first_category_uid"` + SecondCategoryName string `gorm:"column:second_category_name"` + SecondCategoryAuthor string `gorm:"column:second_category_author"` + SecondCategoryDescription string `gorm:"column:second_category_description"` +} + +func (SecondCategory) TableName() string { + return "second_category" +} + +//第三品类 +type ThirdCategory struct { + gorm.Model + ThirdCategoryIndex int64 `gorm:"column:third_category_index"` + SecondCategoryIndex int64 `gorm:"column:second_category_index"` + FirstCategoryUid string `gorm:"column:first_category_uid"` + ThirdCategoryName string `gorm:"column:third_category_name"` + ThirdCategoryPath string `gorm:"column:third_category_path"` + ThirdCategoryAuthor string `gorm:"column:third_category_author"` + ThirdCategoryDescription string `gorm:"column:third_category_description"` +} + +func (ThirdCategory) TableName() string { + return "third_category" +} + +//取出所有vtb +func GetAllFirstCategoryMessage(db *gorm.DB) string { + firstStepMessage := "请选择一个vtb并发送序号:\n" + var fc FirstCategory + rows, err := db.Model(&FirstCategory{}).Rows() + if err != nil { + log.Println("数据库读取错误", err) + } + if rows == nil { + return "" + } + for rows.Next() { + db.ScanRows(rows, &fc) + log.Println(fc) + firstStepMessage = firstStepMessage + strconv.FormatInt(fc.FirstCategoryIndex, 10) + ". " + fc.FirstCategoryName + "\n" + } + return firstStepMessage +} + +//取得同一个vtb所有语录类别 +func GetAllSecondCategoryMessageByFirstIndex(db *gorm.DB, firstIndex int) string { + SecondStepMessage := "请选择一个语录类别并发送序号:\n" + var sc SecondCategory + var count int + var fc FirstCategory + db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc) + db.Model(&SecondCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUid).Count(&count) + if count == 0 { + return "" + } + rows, err := db.Model(&SecondCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUid).Rows() + if err != nil { + log.Println("数据库读取错误", err) + } + + for rows.Next() { + db.ScanRows(rows, &sc) + log.Println(sc) + SecondStepMessage = SecondStepMessage + strconv.FormatInt(sc.SecondCategoryIndex, 10) + ". " + sc.SecondCategoryName + "\n" + } + return SecondStepMessage +} + +//取得同一个vtb同个类别的所有语录 +func GetAllThirdCategoryMessageByFirstIndexAndSecondIndex(db *gorm.DB, firstIndex, secondIndex int) string { + ThirdStepMessage := "请选择一个语录并发送序号:\n" + var fc FirstCategory + db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc) + var count int + db.Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ?", fc.FirstCategoryUid, secondIndex).Count(&count) + if count == 0 { + return "" + } + var tc ThirdCategory + rows, err := db.Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ?", fc.FirstCategoryUid, secondIndex).Rows() + if err != nil { + log.Println("数据库读取错误", err) + } + for rows.Next() { + db.ScanRows(rows, &tc) + log.Println(tc) + ThirdStepMessage = ThirdStepMessage + strconv.FormatInt(tc.ThirdCategoryIndex, 10) + ". " + tc.ThirdCategoryName + "\n" + } + return ThirdStepMessage +} +func GetThirdCategory(db *gorm.DB, firstIndex, secondIndex, thirdIndex int) ThirdCategory { + var fc FirstCategory + db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc) + var tc ThirdCategory + db.Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ? and third_category_index = ?", fc.FirstCategoryUid, secondIndex, thirdIndex).Take(&tc) + return tc +} + +func RandomVtb(db *gorm.DB) ThirdCategory { + rand.Seed(time.Now().UnixNano()) + var count int + db.Model(&ThirdCategory{}).Count(&count) + log.Info("一共有", count, "个") + var tc ThirdCategory + db.Model(&ThirdCategory{}).Offset(rand.Intn(count)).Take(&tc) + log.Info(tc) + return tc +} + +func GetFirstCategoryByFirstUid(db *gorm.DB, firstUid string) FirstCategory { + var fc FirstCategory + db.Model(FirstCategory{}).Where("first_category_uid = ?", firstUid).Take(&fc) + log.Info(fc) + return fc +} diff --git a/plugin_vtb_quotation/secondVtb/secondVtb.go b/plugin_vtb_quotation/secondVtb/secondVtb.go new file mode 100644 index 00000000..ab109e24 --- /dev/null +++ b/plugin_vtb_quotation/secondVtb/secondVtb.go @@ -0,0 +1,108 @@ +package secondVtb + +import ( + "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation/model" + "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation/utils" + "github.com/jinzhu/gorm" + log "github.com/sirupsen/logrus" + "github.com/tidwall/gjson" + "io/ioutil" + "net/http" + "strconv" + "strings" +) + +func GetVtbStr(uid string) string { + vtbUrl := "https://vtbkeyboard.moe/api/get_vtb_page?uid=" + uid + client := &http.Client{} + req, err := http.NewRequest("GET", vtbUrl, nil) + if err != nil { + log.Println(err) + } + // 自定义Header + req.Header.Set("User-Agent", utils.GetAgent()) + resp, err := client.Do(req) + if err != nil { + log.Println(err) + } + + defer resp.Body.Close() + bytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Println(err) + } + //log.Println(string(bytes)) + vtbListStr, err := strconv.Unquote(strings.Replace(strconv.Quote(string(bytes)), `\\u`, `\u`, -1)) + if err != nil { + log.Println(err) + } + log.Println(vtbListStr) + return vtbListStr + +} + +func DealVtbStr(vtbStr, uid string) { + secondCount := gjson.Get(vtbStr, "data.voices.#").Int() + log.Println("二级品类一共有", secondCount) + for secondIndex := int64(0); secondIndex < secondCount; secondIndex++ { + secondItem := gjson.Get(vtbStr, "data.voices."+strconv.FormatInt(secondIndex, 10)) + log.Println(secondItem) + sc := model.SecondCategory{ + SecondCategoryName: secondItem.Get("categoryName").String(), + SecondCategoryIndex: secondIndex, + SecondCategoryAuthor: secondItem.Get("author").String(), + SecondCategoryDescription: secondItem.Get("categoryDescription.zh-CN").String(), + FirstCategoryUid: uid, + } + log.Println(sc) + //model.Db.Model(SecondCategory{}).Where("first_category_uid = ? and second_category_index = ?", uid, secondIndex).FirstOrCreate(&sc) + if err := model.Db.Debug().Model(&model.SecondCategory{}).Where("first_category_uid = ? and second_category_index = ?", uid, secondIndex).First(&sc).Error; err != nil { + // error handling... + if gorm.IsRecordNotFoundError(err) { + model.Db.Debug().Model(&model.SecondCategory{}).Create(&sc) // newUser not user + } + } else { + model.Db.Debug().Model(&model.SecondCategory{}).Where("first_category_uid = ? and second_category_index = ?", uid, secondIndex).Update( + map[string]interface{}{ + "second_category_name": secondItem.Get("categoryName").String(), + "second_category_author": secondItem.Get("author").String(), + "second_category_description": secondItem.Get("categoryDescription.zh-CN").String(), + }) + } + thirdCount := secondItem.Get("voiceList.#").Int() + log.Println("三级品类一共有", thirdCount) + for thirdIndex := int64(0); thirdIndex < thirdCount; thirdIndex++ { + thirdItem := secondItem.Get("voiceList." + strconv.FormatInt(thirdIndex, 10)) + log.Println(thirdItem) + tc := model.ThirdCategory{ + ThirdCategoryName: thirdItem.Get("name").String(), + ThirdCategoryIndex: thirdIndex, + ThirdCategoryDescription: thirdItem.Get("description.zh-CN").String(), + FirstCategoryUid: uid, + SecondCategoryIndex: secondIndex, + ThirdCategoryPath: thirdItem.Get("path").String(), + ThirdCategoryAuthor: thirdItem.Get("author").String(), + } + log.Println(tc) + //model.Db.Model(ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ? and third_category_index = ?", + // uid, secondIndex, thirdIndex).FirstOrCreate(&tc) + if err := model.Db.Debug().Model(&model.ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ? and third_category_index = ?", + uid, secondIndex, thirdIndex).First(&tc).Error; err != nil { + // error handling... + if gorm.IsRecordNotFoundError(err) { + model.Db.Debug().Model(&model.ThirdCategory{}).Create(&tc) // newUser not user + } + } else { + model.Db.Debug().Model(&model.ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ? and third_category_index = ?", + uid, secondIndex, thirdIndex).Update( + map[string]interface{}{ + "third_category_name": thirdItem.Get("name").String(), + "third_category_description": thirdItem.Get("description.zh-CN").String(), + "third_category_path": thirdItem.Get("path").String(), + "third_category_author": thirdItem.Get("author").String(), + }) + } + } + } + +} diff --git a/plugin_vtb_quotation/utils/utils.go b/plugin_vtb_quotation/utils/utils.go new file mode 100644 index 00000000..21434437 --- /dev/null +++ b/plugin_vtb_quotation/utils/utils.go @@ -0,0 +1,24 @@ +package utils + +import ( + "math/rand" + "time" +) + +var agent = [...]string{ + "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0", + "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11", + "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)", + "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; The World)", + "User-Agent,Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50", + "User-Agent, Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)", + "User-Agent,Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50", +} + +func GetAgent() string { + r := rand.New(rand.NewSource(time.Now().UnixNano())) + len1 := len(agent) + return agent[r.Intn(len1)] +} diff --git a/plugin_vtb_quotation/vtb_quotation.go b/plugin_vtb_quotation/vtb_quotation.go new file mode 100644 index 00000000..74ef3c4e --- /dev/null +++ b/plugin_vtb_quotation/vtb_quotation.go @@ -0,0 +1,161 @@ +package plugin_vtb_quotation + +import ( + "fmt" + "github.com/FloatTech/ZeroBot-Plugin/control" + "github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation/model" + "github.com/jinzhu/gorm" + _ "github.com/logoove/sqlite" + log "github.com/sirupsen/logrus" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" + "net/url" + "regexp" + "strconv" + "strings" + "time" +) + +var ( + regStr = ".*/(.*)" +) + +var engine = control.Register("vtbquotation", &control.Options{ + DisableOnDefault: false, + Help: "vtb语录\n" + + "随机vtb\n", +}) + +func init() { + engine.OnFullMatch("vtb语录").SetBlock(true). + Handle(func(ctx *zero.Ctx) { + var firstIndex int + var secondIndex int + var thirdIndex int + echo, cancel := ctx.FutureEvent("message", + ctx.CheckSession()). // 只复读开启复读模式的人的消息 + Repeat() // 不断监听复读 + db, err := gorm.Open("sqlite3", "data/VtbQuotation/vtb.db") + if err != nil { + panic("failed to connect database") + } + defer db.Close() + firstStepMessage := model.GetAllFirstCategoryMessage(db) + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(firstStepMessage)) + //步骤1,2,3,依次选择3个类别 + step := 1 + //错误次数 + errorCount := 0 + for { + select { + case e := <-echo: // 接收到需要复读的消息 + //错误次数达到3次,结束命令 + if errorCount == 3 { + ctx.SendChain(message.Reply(e.MessageID), message.Text("输入错误太多,请重新发指令")) + cancel() + return + } + if step == 1 { + firstIndex, err = strconv.Atoi(e.RawMessage) + log.Println(fmt.Sprintf("当前在第%d步", step)) + log.Println(fmt.Sprintf("firstIndex:%d,secondIndex:%d,thirdIndex:%d", firstIndex, secondIndex, thirdIndex)) + if err != nil { + ctx.SendChain(message.Reply(e.MessageID), message.Text("请输入正确的序号,三次输入错误,指令可退出重输")) + errorCount++ + } else { + SecondStepMessage := model.GetAllSecondCategoryMessageByFirstIndex(db, firstIndex) + log.Println(SecondStepMessage) + if SecondStepMessage == "" { + ctx.SendChain(message.Reply(e.MessageID), message.Text("你选择的序号没有内容,请重新选择,三次输入错误,指令可退出重输")) + ctx.SendChain(message.Reply(e.MessageID), message.Text(model.GetAllFirstCategoryMessage(db))) + errorCount++ + } else { + ctx.SendChain(message.Reply(e.MessageID), message.Text(SecondStepMessage)) + step++ + } + + } + } else if step == 2 { + secondIndex, err = strconv.Atoi(e.RawMessage) + log.Println(fmt.Sprintf("当前在第%d步", step)) + log.Println(fmt.Sprintf("firstIndex:%d,secondIndex:%d,thirdIndex:%d", firstIndex, secondIndex, thirdIndex)) + if err != nil { + ctx.SendChain(message.Reply(e.MessageID), message.Text("请输入正确的序号,三次输入错误,指令可退出重输")) + errorCount++ + } else { + ThirdStepMessage := model.GetAllThirdCategoryMessageByFirstIndexAndSecondIndex(db, firstIndex, secondIndex) + log.Println(ThirdStepMessage) + if ThirdStepMessage == "" { + ctx.SendChain(message.Reply(e.MessageID), message.Text("你选择的序号没有内容,请重新选择,三次输入错误,指令可退出重输")) + ctx.SendChain(message.Reply(e.MessageID), message.Text(model.GetAllSecondCategoryMessageByFirstIndex(db, firstIndex))) + errorCount++ + } else { + ctx.SendChain(message.Reply(e.MessageID), message.Text(ThirdStepMessage)) + step++ + } + + } + } else if step == 3 { + thirdIndex, err = strconv.Atoi(e.RawMessage) + log.Println(fmt.Sprintf("当前在第%d步", step)) + log.Println(fmt.Sprintf("firstIndex:%d,secondIndex:%d,thirdIndex:%d", firstIndex, secondIndex, thirdIndex)) + if err != nil { + ctx.SendChain(message.Reply(e.MessageID), message.Text("请输入正确的序号,三次输入错误,指令可退出重输")) + errorCount++ + } else { + tc := model.GetThirdCategory(db, firstIndex, secondIndex, thirdIndex) + reg := regexp.MustCompile(regStr) + recordUrl := tc.ThirdCategoryPath + if recordUrl == "" { + ctx.SendChain(message.Reply(e.MessageID), message.Text("没有内容请重新选择,三次输入错误,指令可退出重输")) + ctx.SendChain(message.Reply(e.MessageID), message.Text(model.GetAllFirstCategoryMessage(db))) + errorCount++ + step = 1 + } else { + if reg.MatchString(recordUrl) { + log.Println(reg.FindStringSubmatch(recordUrl)[1]) + log.Println(url.QueryEscape(reg.FindStringSubmatch(recordUrl)[1])) + recordUrl = strings.Replace(recordUrl, reg.FindStringSubmatch(recordUrl)[1], url.QueryEscape(reg.FindStringSubmatch(recordUrl)[1]), -1) + recordUrl = strings.Replace(recordUrl, "+", "%20", -1) + log.Println(recordUrl) + } + ctx.SendChain(message.Reply(e.MessageID), message.Text("请欣赏《"+tc.ThirdCategoryName+"》")) + ctx.SendChain(message.Record(recordUrl)) + cancel() + return + } + + } + } + case <-time.After(time.Second * 60): + cancel() + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("vtb语录指令过期")) + return + } + } + }) + engine.OnFullMatch("随机vtb").SetBlock(true). + Handle(func(ctx *zero.Ctx) { + db, err := gorm.Open("sqlite3", "data/VtbQuotation/vtb.db") + if err != nil { + panic("failed to connect database") + } + defer db.Close() + tc := model.RandomVtb(db) + fc := model.GetFirstCategoryByFirstUid(db, tc.FirstCategoryUid) + if (tc != model.ThirdCategory{}) && (fc != model.FirstCategory{}) { + reg := regexp.MustCompile(regStr) + recordUrl := tc.ThirdCategoryPath + if reg.MatchString(recordUrl) { + log.Println(reg.FindStringSubmatch(recordUrl)[1]) + log.Println(url.QueryEscape(reg.FindStringSubmatch(recordUrl)[1])) + recordUrl = strings.Replace(recordUrl, reg.FindStringSubmatch(recordUrl)[1], url.QueryEscape(reg.FindStringSubmatch(recordUrl)[1]), -1) + recordUrl = strings.Replace(recordUrl, "+", "%20", -1) + log.Println(recordUrl) + } + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请欣赏"+fc.FirstCategoryName+"的《"+tc.ThirdCategoryName+"》")) + ctx.SendChain(message.Record(recordUrl)) + } + + }) +}