🎨 优化目录结构

This commit is contained in:
fumiama
2022-02-25 22:15:14 +08:00
parent 5ccf753af3
commit 0cfb2e4e06
101 changed files with 116 additions and 116 deletions

114
plugin/nativesetu/data.go Normal file
View File

@@ -0,0 +1,114 @@
package nativesetu
import (
"bytes"
"image"
"io/fs"
"os"
"strings"
"sync"
"github.com/corona10/goimagehash"
"github.com/sirupsen/logrus"
_ "golang.org/x/image/webp" // import webp decoding
sql "github.com/FloatTech/sqlite"
"github.com/FloatTech/zbputils/file"
)
// setuclass holds setus in a folder, which is the class name.
type setuclass struct {
ImgID int64 `db:"imgid"` // ImgID 图片唯一 id (dhash)
Name string `db:"name"` // Name 图片名
Path string `db:"path"` // Path 图片路径
}
var ns = &nsetu{db: &sql.Sqlite{}}
type nsetu struct {
db *sql.Sqlite
mu sync.RWMutex
}
func (n *nsetu) List() (l []string) {
if file.IsExist(n.db.DBPath) {
err := n.db.Open()
if err == nil {
l, err = n.db.ListTables()
}
if err != nil {
logrus.Errorln("[nsetu]", err)
}
}
return
}
func (n *nsetu) scanall(path string) error {
model := &setuclass{}
root := os.DirFS(path)
_ = n.db.Close()
_ = os.Remove(n.db.DBPath)
return fs.WalkDir(root, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
clsn := d.Name()
if clsn != "." {
n.mu.Lock()
err = n.db.Create(clsn, model)
n.mu.Unlock()
if err == nil {
err = n.scanclass(root, path, clsn)
if err != nil {
logrus.Errorln("[nsetu]", err)
return err
}
}
}
}
return nil
})
}
func (n *nsetu) scanclass(root fs.FS, path, clsn string) error {
ds, err := fs.ReadDir(root, path)
if err != nil {
return err
}
n.mu.Lock()
_ = n.db.Truncate(clsn)
n.mu.Unlock()
for _, d := range ds {
nm := d.Name()
ln := strings.ToLower(nm)
if !d.IsDir() &&
(strings.HasSuffix(ln, ".jpg") || strings.HasSuffix(ln, ".jpeg") ||
strings.HasSuffix(ln, ".png") || strings.HasSuffix(ln, ".gif") || strings.HasSuffix(ln, ".webp")) {
relpath := path + "/" + nm
logrus.Debugln("[nsetu] read", relpath)
f, e := fs.ReadFile(root, relpath)
if e != nil {
return e
}
b := bytes.NewReader(f)
img, _, e := image.Decode(b)
if e != nil {
return e
}
dh, e := goimagehash.DifferenceHash(img)
if e != nil {
return e
}
dhi := int64(dh.GetHash())
logrus.Debugln("[nsetu] insert", nm, "with id", dhi, "into", clsn)
n.mu.Lock()
err = n.db.Insert(clsn, &setuclass{ImgID: dhi, Name: nm, Path: relpath})
n.mu.Unlock()
if err != nil {
return err
}
}
}
return nil
}

105
plugin/nativesetu/main.go Normal file
View File

@@ -0,0 +1,105 @@
// Package nativesetu 本地setu
package nativesetu
import (
"fmt"
"os"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
"github.com/FloatTech/zbputils/file"
"github.com/FloatTech/zbputils/control/order"
)
var (
setupath = "/tmp" // 绝对路径,图片根目录
)
func init() {
engine := control.Register("nativesetu", order.AcquirePrio(), &control.Options{
DisableOnDefault: false,
Help: "本地涩图\n" +
"- 本地[xxx]\n" +
"- 刷新本地[xxx]\n" +
"- 设置本地setu绝对路径[xxx]\n" +
"- 刷新所有本地setu\n" +
"- 所有本地setu分类",
PrivateDataFolder: "nsetu",
})
ns.db.DBPath = engine.DataFolder() + "data.db"
cfgfile := engine.DataFolder() + "setupath.txt"
if file.IsExist(cfgfile) {
b, err := os.ReadFile(cfgfile)
if err == nil {
setupath = helper.BytesToString(b)
logrus.Println("[nsetu] set setu dir to", setupath)
}
}
engine.OnRegex(`^本地(.*)$`, ctxext.FirstValueInList(ns)).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
imgtype := ctx.State["regex_matched"].([]string)[1]
sc := new(setuclass)
ns.mu.RLock()
err := ns.db.Pick(imgtype, sc)
ns.mu.RUnlock()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
} else {
p := "file:///" + setupath + "/" + sc.Path
ctx.SendChain(message.Text(imgtype, ": ", sc.Name, "\n"), message.Image(p))
}
})
engine.OnRegex(`^刷新本地(.*)$`, ctxext.FirstValueInList(ns), zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
imgtype := ctx.State["regex_matched"].([]string)[1]
err := ns.scanclass(os.DirFS(setupath), imgtype, imgtype)
if err == nil {
ctx.SendChain(message.Text("成功!"))
} else {
ctx.SendChain(message.Text("ERROR: ", err))
}
})
engine.OnRegex(`^设置本地setu绝对路径(.*)$`, zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
setupath = ctx.State["regex_matched"].([]string)[1]
err := os.WriteFile(cfgfile, helper.StringToBytes(setupath), 0644)
if err == nil {
ctx.SendChain(message.Text("成功!"))
} else {
ctx.SendChain(message.Text("ERROR: ", err))
}
})
engine.OnFullMatch("刷新所有本地setu", zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
err := ns.scanall(setupath)
if err == nil {
ctx.SendChain(message.Text("成功!"))
} else {
ctx.SendChain(message.Text("ERROR: ", err))
}
})
engine.OnFullMatch("所有本地setu分类").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
msg := "所有本地setu分类"
ns.mu.RLock()
for i, c := range ns.List() {
n, err := ns.db.Count(c)
if err == nil {
msg += fmt.Sprintf("\n%02d. %s(%d)", i, c, n)
} else {
msg += fmt.Sprintf("\n%02d. %s(error)", i, c)
logrus.Errorln("[nsetu]", err)
}
}
ns.mu.RUnlock()
ctx.SendChain(message.Text(msg))
})
}