Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43a559bd55 | ||
|
|
6a4217960f | ||
|
|
d8b9f815c0 | ||
|
|
ef888b7256 |
+43
-27
@@ -3,6 +3,7 @@ package general
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
hc "neo/context"
|
||||
@@ -13,6 +14,38 @@ func init() {
|
||||
core.Default.Register(Help)
|
||||
}
|
||||
|
||||
var (
|
||||
cachedMenu string
|
||||
menuOnce sync.Once
|
||||
)
|
||||
|
||||
// buildMenuCache generates the static portion of the help menu with a {{PREFIX}} placeholder
|
||||
func buildMenuCache() {
|
||||
var sb strings.Builder
|
||||
|
||||
cmdMap := make(map[string][]string)
|
||||
for _, cmd := range core.Default.GetCommands() {
|
||||
cat := cmd.Category
|
||||
if cat == "" {
|
||||
cat = "general"
|
||||
}
|
||||
cmdMap[cat] = append(cmdMap[cat], cmd.Name)
|
||||
}
|
||||
|
||||
for cat, cmds := range cmdMap {
|
||||
sb.WriteString(fmt.Sprintf("\n*📃%s*\n", strings.ToUpper(cat)))
|
||||
for i, cmdName := range cmds {
|
||||
branch := "├"
|
||||
if i == len(cmds)-1 {
|
||||
branch = "└"
|
||||
}
|
||||
sb.WriteString(fmt.Sprintf("%s {{PREFIX}}%s\n", branch, cmdName))
|
||||
}
|
||||
}
|
||||
|
||||
cachedMenu = sb.String()
|
||||
}
|
||||
|
||||
var Help = &core.Command{
|
||||
Name: "help",
|
||||
Aliases: []string{"?", "h", "menu"},
|
||||
@@ -42,38 +75,21 @@ var Help = &core.Command{
|
||||
pushName = "User"
|
||||
}
|
||||
|
||||
// Header
|
||||
var sb strings.Builder
|
||||
sb.WriteString(fmt.Sprintf("%s *%s*👋\n📬 Need help? Here are all of my commands\n", greeting, pushName))
|
||||
|
||||
// Group commands by category (simulate json object array appending)
|
||||
cmdMap := make(map[string][]string)
|
||||
for _, cmd := range core.Default.GetCommands() {
|
||||
cat := cmd.Category
|
||||
if cat == "" {
|
||||
cat = "general"
|
||||
}
|
||||
cmdMap[cat] = append(cmdMap[cat], cmd.Name)
|
||||
}
|
||||
|
||||
prefix := ctx.Prefix()
|
||||
if prefix == "" {
|
||||
// fallback if they called it somehow internally without prefix
|
||||
prefix = "."
|
||||
}
|
||||
|
||||
// Print categories
|
||||
for cat, cmds := range cmdMap {
|
||||
sb.WriteString(fmt.Sprintf("\n*📃%s*\n", strings.ToUpper(cat)))
|
||||
for i, cmdName := range cmds {
|
||||
branch := "├"
|
||||
if i == len(cmds)-1 {
|
||||
branch = "└"
|
||||
}
|
||||
sb.WriteString(fmt.Sprintf("%s %s%s\n", branch, prefix, cmdName))
|
||||
}
|
||||
}
|
||||
// Calculate the static command layout part only once
|
||||
menuOnce.Do(func() {
|
||||
buildMenuCache()
|
||||
})
|
||||
|
||||
ctx.Reply(sb.String())
|
||||
// Replace placeholder with the dynamically used prefix
|
||||
finalMenu := strings.ReplaceAll(cachedMenu, "{{PREFIX}}", prefix)
|
||||
|
||||
header := fmt.Sprintf("%s *%s*👋\n📬 Need help? Here are all of my commands\n", greeting, pushName)
|
||||
|
||||
ctx.Reply(header + finalMenu)
|
||||
},
|
||||
}
|
||||
|
||||
+24
-17
@@ -9,6 +9,8 @@ import (
|
||||
hc "neo/context"
|
||||
"neo/core"
|
||||
"neo/helper"
|
||||
|
||||
"go.mau.fi/whatsmeow"
|
||||
)
|
||||
|
||||
func init() { core.Default.Register(Sticker) }
|
||||
@@ -50,29 +52,34 @@ var Sticker = &core.Command{
|
||||
var err error
|
||||
var rawWebp []byte
|
||||
var mediaData []byte
|
||||
var downloadable whatsmeow.DownloadableMessage
|
||||
var mediaType string
|
||||
|
||||
if img := msg.GetImageMessage(); img != nil {
|
||||
mediaData, err = ctx.Client().Download(context.Background(), img)
|
||||
switch {
|
||||
case msg.GetImageMessage() != nil:
|
||||
downloadable, mediaType = msg.GetImageMessage(), "image"
|
||||
case quoted != nil && quoted.GetImageMessage() != nil:
|
||||
downloadable, mediaType = quoted.GetImageMessage(), "image"
|
||||
case msg.GetVideoMessage() != nil:
|
||||
downloadable, mediaType = msg.GetVideoMessage(), "video"
|
||||
case quoted != nil && quoted.GetVideoMessage() != nil:
|
||||
downloadable, mediaType = quoted.GetVideoMessage(), "video"
|
||||
case quoted != nil && quoted.GetStickerMessage() != nil:
|
||||
downloadable, mediaType = quoted.GetStickerMessage(), "sticker"
|
||||
}
|
||||
|
||||
if downloadable != nil {
|
||||
mediaData, err = ctx.Client().Download(context.Background(), downloadable)
|
||||
if err == nil {
|
||||
switch mediaType {
|
||||
case "image":
|
||||
rawWebp, err = helper.ConvertImageToWebp(mediaData)
|
||||
}
|
||||
} else if img := quoted.GetImageMessage(); img != nil && quoted != nil {
|
||||
mediaData, err = ctx.Client().Download(context.Background(), img)
|
||||
if err == nil {
|
||||
rawWebp, err = helper.ConvertImageToWebp(mediaData)
|
||||
}
|
||||
} else if vid := msg.GetVideoMessage(); vid != nil {
|
||||
mediaData, err = ctx.Client().Download(context.Background(), vid)
|
||||
if err == nil {
|
||||
case "video":
|
||||
rawWebp, err = helper.ConvertVideoToWebp(mediaData)
|
||||
case "sticker":
|
||||
rawWebp = mediaData
|
||||
}
|
||||
} else if vid := quoted.GetVideoMessage(); vid != nil && quoted != nil {
|
||||
mediaData, err = ctx.Client().Download(context.Background(), vid)
|
||||
if err == nil {
|
||||
rawWebp, err = helper.ConvertVideoToWebp(mediaData)
|
||||
}
|
||||
} else if smsg := quoted.GetStickerMessage(); smsg != nil && quoted != nil {
|
||||
rawWebp, err = ctx.Client().Download(context.Background(), smsg)
|
||||
} else {
|
||||
ctx.Reply("error: reply to image/video/sticker or send with caption")
|
||||
return
|
||||
|
||||
+11
-23
@@ -3,11 +3,7 @@ package helper
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func ConvertImageToWebp(imgData []byte) ([]byte, error) {
|
||||
@@ -35,35 +31,27 @@ func ConvertImageToWebp(imgData []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
func ConvertVideoToWebp(vidData []byte) ([]byte, error) {
|
||||
id := uuid.New().String()
|
||||
gifPath := filepath.Join("temp", fmt.Sprintf("%s.gif", id))
|
||||
webpPath := filepath.Join("temp", fmt.Sprintf("%s.webp", id))
|
||||
|
||||
defer os.Remove(gifPath)
|
||||
defer os.Remove(webpPath)
|
||||
|
||||
ffmpegCmd := exec.Command("ffmpeg",
|
||||
"-y", "-hide_banner", "-loglevel", "error",
|
||||
"-i", "pipe:0",
|
||||
"-ss", "00:00:00", "-t", "00:00:15",
|
||||
"-vcodec", "libwebp",
|
||||
"-vf", "fps=10,scale=720:-1:flags=lanczos:force_original_aspect_ratio=increase,crop=512:512,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,setsar=1",
|
||||
"-loop", "0",
|
||||
"-preset", "default",
|
||||
"-an",
|
||||
"-f", "gif", gifPath,
|
||||
"-f", "webp", "pipe:1",
|
||||
)
|
||||
var stderr bytes.Buffer
|
||||
ffmpegCmd.Stderr = &stderr
|
||||
|
||||
ffmpegCmd.Stdin = bytes.NewReader(vidData)
|
||||
var outBuf bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
ffmpegCmd.Stdout = &outBuf
|
||||
ffmpegCmd.Stderr = &stderr
|
||||
|
||||
if err := ffmpegCmd.Run(); err != nil {
|
||||
return nil, fmt.Errorf("ffmpeg failed: %w, stderr: %s", err, stderr.String())
|
||||
return nil, fmt.Errorf("ffmpeg direct convert failed: %w, stderr: %s", err, stderr.String())
|
||||
}
|
||||
|
||||
gif2webpCmd := exec.Command("gif2webp", "-quiet", "-q", "60", "-m", "6", gifPath, "-o", webpPath)
|
||||
var g2wStderr bytes.Buffer
|
||||
gif2webpCmd.Stderr = &g2wStderr
|
||||
if err := gif2webpCmd.Run(); err != nil {
|
||||
return nil, fmt.Errorf("gif2webp failed: %w, stderr: %s", err, g2wStderr.String())
|
||||
}
|
||||
|
||||
return os.ReadFile(webpPath)
|
||||
return outBuf.Bytes(), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user