Compare commits

..
4 Commits
3 changed files with 81 additions and 70 deletions
+43 -27
View File
@@ -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)
},
}
+27 -20
View File
@@ -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 {
rawWebp, err = helper.ConvertImageToWebp(mediaData)
switch mediaType {
case "image":
rawWebp, err = helper.ConvertImageToWebp(mediaData)
case "video":
rawWebp, err = helper.ConvertVideoToWebp(mediaData)
case "sticker":
rawWebp = 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 {
rawWebp, err = helper.ConvertVideoToWebp(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
View File
@@ -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
}