unarr/internal/cmd/search.go
Deivid Soto 5a7449b9e6 chore: rename module from torrentclaw-cli to unarr
- Rename Go module path github.com/torrentclaw/torrentclaw-cli → github.com/torrentclaw/unarr
- Update all imports, ldflags, scripts, docs, and Docker config
- Add GitHub Actions release workflow (goreleaser on tag push)
2026-03-30 13:06:07 +02:00

109 lines
4.3 KiB
Go

package cmd
import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
"github.com/spf13/cobra"
tc "github.com/torrentclaw/go-client"
"github.com/torrentclaw/unarr/internal/ui"
)
func newSearchCmd() *cobra.Command {
var (
contentType string
quality string
lang string
genre string
yearMin int
yearMax int
minRating float64
sort string
limit int
page int
country string
)
cmd := &cobra.Command{
Use: "search <query>",
Short: "Search for movies and TV shows",
Long: `Search the catalog for movies and TV shows with advanced filters.
Results include torrent quality scores (0-100), seed health, resolution, codec,
audio, and metadata aggregated from 30+ sources. Use --json for machine-readable
output that can be piped to jq or other tools.`,
Example: ` unarr search "breaking bad" --type show --quality 1080p
unarr search "oppenheimer" --sort seeders --limit 5
unarr search "inception" --lang es --min-rating 7
unarr search "matrix" --json | jq '.results[].title'`,
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
client := getClient()
params := tc.SearchParams{
Query: strings.Join(args, " "),
Type: contentType,
Quality: quality,
Language: lang,
Genre: genre,
YearMin: yearMin,
YearMax: yearMax,
MinRating: minRating,
Sort: sort,
Limit: limit,
Page: page,
Country: country,
}
resp, err := client.Search(context.Background(), params)
if err != nil {
return fmt.Errorf("search failed: %w", err)
}
if jsonOut {
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
return enc.Encode(resp)
}
ui.PrintSearchResults(resp)
return nil
},
}
cmd.Flags().StringVar(&contentType, "type", "", "content type: movie, show")
cmd.Flags().StringVar(&quality, "quality", "", "video quality: 480p, 720p, 1080p, 2160p")
cmd.Flags().StringVar(&lang, "lang", "", "audio language (ISO 639 code, e.g. es, en)")
cmd.Flags().StringVar(&genre, "genre", "", "genre filter (e.g. Action, Comedy, Drama)")
cmd.Flags().IntVar(&yearMin, "year-min", 0, "minimum release year")
cmd.Flags().IntVar(&yearMax, "year-max", 0, "maximum release year")
cmd.Flags().Float64Var(&minRating, "min-rating", 0, "minimum IMDb/TMDb rating (0-10)")
cmd.Flags().StringVar(&sort, "sort", "", "sort order: relevance, seeders, year, rating, added")
cmd.Flags().IntVar(&limit, "limit", 0, "results per page (1-50)")
cmd.Flags().IntVar(&page, "page", 0, "page number")
cmd.Flags().StringVar(&country, "country", "", "country code for streaming availability (e.g. US, ES)")
// Shell completion for flags with known values
cmd.RegisterFlagCompletionFunc("type", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"movie\tmovies only", "show\tTV shows only"}, cobra.ShellCompDirectiveNoFileComp
})
cmd.RegisterFlagCompletionFunc("quality", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"480p\tSD", "720p\tHD", "1080p\tFull HD", "2160p\t4K Ultra HD"}, cobra.ShellCompDirectiveNoFileComp
})
cmd.RegisterFlagCompletionFunc("sort", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"relevance\tbest match", "seeders\tmost seeders", "year\tnewest first", "rating\thighest rated", "added\trecently added"}, cobra.ShellCompDirectiveNoFileComp
})
cmd.RegisterFlagCompletionFunc("lang", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"en\tEnglish", "es\tSpanish", "fr\tFrench", "de\tGerman", "it\tItalian", "pt\tPortuguese", "ja\tJapanese", "ko\tKorean", "zh\tChinese", "ru\tRussian"}, cobra.ShellCompDirectiveNoFileComp
})
cmd.RegisterFlagCompletionFunc("genre", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"Action", "Adventure", "Animation", "Comedy", "Crime", "Documentary", "Drama", "Family", "Fantasy", "History", "Horror", "Music", "Mystery", "Romance", "Science Fiction", "Thriller", "War", "Western"}, cobra.ShellCompDirectiveNoFileComp
})
cmd.RegisterFlagCompletionFunc("country", completionCountryCodes)
return cmd
}