discrawl/internal/cli/query_sync.go
2026-05-05 10:07:56 +01:00

99 lines
2.3 KiB
Go

package cli
import (
"errors"
"fmt"
"slices"
"strings"
"github.com/openclaw/discrawl/internal/syncer"
)
func (r *runtime) syncMessagesQuery(channel, guild, guilds string) error {
if r.syncer == nil {
return usageErr(errors.New("messages --sync requires Discord access"))
}
opts, err := r.messageSyncOptions(channel, guild, guilds)
if err != nil {
return usageErr(err)
}
_, err = r.syncer.Sync(r.ctx, opts)
return err
}
func (r *runtime) messageSyncOptions(channel, guild, guilds string) (syncer.SyncOptions, error) {
requestedGuilds := r.resolveSyncGuilds(guild, guilds)
opts := syncer.SyncOptions{
GuildIDs: requestedGuilds,
Concurrency: r.cfg.Sync.Concurrency,
}
channelFilter := strings.TrimSpace(strings.TrimPrefix(strings.TrimSpace(channel), "#"))
if channelFilter == "" {
if len(opts.GuildIDs) == 0 {
return opts, errors.New("messages --sync needs --channel or --guild")
}
return opts, nil
}
if isDiscordID(channelFilter) {
opts.ChannelIDs = []string{channelFilter}
return opts, nil
}
rows, err := r.store.Channels(r.ctx, "")
if err != nil {
return opts, err
}
needle := strings.ToLower(channelFilter)
allowedGuilds := map[string]struct{}{}
for _, guildID := range requestedGuilds {
allowedGuilds[guildID] = struct{}{}
}
for _, row := range rows {
if len(allowedGuilds) > 0 {
if _, ok := allowedGuilds[row.GuildID]; !ok {
continue
}
}
if !channelMatches(row.ID, row.Name, channelFilter, needle) {
continue
}
opts.ChannelIDs = append(opts.ChannelIDs, row.ID)
if len(requestedGuilds) == 0 && !slices.Contains(opts.GuildIDs, row.GuildID) {
opts.GuildIDs = append(opts.GuildIDs, row.GuildID)
}
}
if len(opts.ChannelIDs) > 0 {
return opts, nil
}
if len(opts.GuildIDs) > 0 {
return opts, nil
}
return opts, fmt.Errorf("cannot resolve channel %q; pass a channel id or --guild", channel)
}
func channelMatches(id, name, raw, lowered string) bool {
return id == raw || name == raw || strings.Contains(strings.ToLower(name), lowered)
}
func isDiscordID(raw string) bool {
if len(raw) < 16 {
return false
}
for _, ch := range raw {
if ch < '0' || ch > '9' {
return false
}
}
return true
}
func hasBoolFlag(args []string, name string) bool {
for _, arg := range args {
if arg == name || strings.HasPrefix(arg, name+"=") {
return true
}
}
return false
}