package plugins import ( "bytes" "encoding/json" "fmt" "strings" "time" "ymgb/database" "ymgb/database/mdb" "ymgb/utils" "git.nix13.pw/scuroneko/extypes" "git.nix13.pw/scuroneko/laniakea" "git.nix13.pw/scuroneko/slog" ) func RegisterLogs() *laniakea.Plugin[database.Context] { p := laniakea.NewPlugin[database.Context]("Logs") p.AddCommand(p.NewCommand(getLogs, "logs").SkipCommandAutoGen()) p.AddCommand(p.NewCommand(getMsgLogs, "msglogs").SkipCommandAutoGen()) p.AddMiddleware(AdminMiddleware()) return p } func InitLogMiddleware() laniakea.Middleware[database.Context] { return *laniakea.NewMiddleware("LogMiddleware", logMiddleware).SetAsync(true) } func getLogs(ctx *laniakea.MsgContext, db *database.Context) { logs, err := mdb.GetConsoleLogs(db) if err != nil { ctx.Error(err) return } out := encodeLogs(logs) ctx.Answer(strings.Join(out, "")) } func getMsgLogs(ctx *laniakea.MsgContext, db *database.Context) { logs, err := mdb.GetMessageLogs(db) if err != nil { ctx.Error(err) return } out := encodeLogs(logs) ctx.Answer(strings.Join(out, "")) } // Utils func encodeLogs[T comparable](logs extypes.Slice[T]) extypes.Slice[string] { out := make(extypes.Slice[string], len(logs)) buf := bytes.NewBuffer(nil) enc := json.NewEncoder(buf) enc.SetEscapeHTML(false) enc.SetIndent("", " ") for i, log := range logs { _ = enc.Encode(log) out[i] = fmt.Sprintf("`%s`", buf.String()) buf.Reset() } return out } func logMiddleware(ctx *laniakea.MsgContext, db *database.Context) bool { if ctx.Msg == nil { return true } entry := &mdb.MessageLogEntry{ MessageID: ctx.Msg.MessageID, SenderID: ctx.FromID, ChatID: ctx.Msg.Chat.ID, Text: ctx.Msg.Text, TimeStamp: int64(ctx.Msg.Date), } err := mdb.WriteMessageLog(db, entry) if err != nil { ctx.Error(err) } return true } type DatabaseWriter struct { slog.LoggerWriter db *database.Context } func (w *DatabaseWriter) Print(level slog.LogLevel, prefix string, traceback []*slog.MethodTraceback, messages ...any) error { t := time.Now() if messages[len(messages)-1] == "\n" { messages = messages[:len(messages)-1] } entry := mdb.ConsoleLogEntry{ Level: level.GetName(), Prefix: prefix, Traceback: slog.FormatFullTraceback(traceback), Message: strings.Join(utils.Map(messages, func(el any) string { return fmt.Sprintf("%v", el) }), "\n"), Time: t, TimeStamp: t.Unix(), } err := mdb.WriteConsoleLog(w.db, entry) return err } func DatabaseLogger(db *database.Context) slog.LoggerWriter { return &DatabaseWriter{db: db} }