167 lines
3.9 KiB
Go
167 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"gitea.dcglab.co.uk/steve/arrman/cmd"
|
|
"gitea.dcglab.co.uk/steve/arrman/radarr"
|
|
"gitea.dcglab.co.uk/steve/arrman/sonarr"
|
|
)
|
|
|
|
// Version is set at build time via -ldflags.
|
|
var Version = "dev"
|
|
|
|
func main() {
|
|
loadEnv()
|
|
|
|
if len(os.Args) >= 2 && os.Args[1] == "version" {
|
|
fmt.Println(Version)
|
|
return
|
|
}
|
|
|
|
// Extract global --json flag from any position in args
|
|
filteredArgs, jsonOutput := extractFlag(os.Args[1:], "--json")
|
|
if len(filteredArgs) < 2 {
|
|
usage()
|
|
os.Exit(1)
|
|
}
|
|
|
|
domain := filteredArgs[0]
|
|
action := filteredArgs[1]
|
|
rest := filteredArgs[2:]
|
|
|
|
tlsSkip := strings.EqualFold(os.Getenv("ARRMAN_TLS_SKIP_VERIFY"), "true")
|
|
|
|
var err error
|
|
|
|
switch domain {
|
|
case "tv":
|
|
sonarrURL := requireEnv("SONARR_URL")
|
|
sonarrKey := requireEnv("SONARR_API_KEY")
|
|
client := sonarr.NewClient(sonarrURL, sonarrKey, tlsSkip)
|
|
err = runTV(client, action, rest, jsonOutput)
|
|
|
|
case "film", "films":
|
|
radarrURL := requireEnv("RADARR_URL")
|
|
radarrKey := requireEnv("RADARR_API_KEY")
|
|
client := radarr.NewClient(radarrURL, radarrKey, tlsSkip)
|
|
err = runFilm(client, action, rest, jsonOutput)
|
|
|
|
default:
|
|
fmt.Fprintf(os.Stderr, "Unknown domain: %s\n", domain)
|
|
usage()
|
|
os.Exit(1)
|
|
}
|
|
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func extractFlag(args []string, flag string) ([]string, bool) {
|
|
var remaining []string
|
|
found := false
|
|
for _, a := range args {
|
|
if a == flag {
|
|
found = true
|
|
} else {
|
|
remaining = append(remaining, a)
|
|
}
|
|
}
|
|
return remaining, found
|
|
}
|
|
|
|
func runTV(client cmd.SonarrClient, action string, args []string, jsonOutput bool) error {
|
|
switch action {
|
|
case "list":
|
|
rest, inclExt := extractFlag(args, "--include-external")
|
|
term := strings.Join(rest, " ")
|
|
return cmd.TVList(client, term, inclExt, jsonOutput)
|
|
case "add":
|
|
return cmd.TVAdd(client, args, jsonOutput)
|
|
case "summary":
|
|
term := strings.Join(args, " ")
|
|
return cmd.TVSummary(client, term, jsonOutput)
|
|
case "profiles":
|
|
return cmd.TVProfiles(client, jsonOutput)
|
|
case "rootfolders":
|
|
return cmd.TVRootFolders(client, jsonOutput)
|
|
default:
|
|
return fmt.Errorf("unknown tv action: %s", action)
|
|
}
|
|
}
|
|
|
|
func runFilm(client cmd.RadarrClient, action string, args []string, jsonOutput bool) error {
|
|
switch action {
|
|
case "list":
|
|
rest, inclExt := extractFlag(args, "--include-external")
|
|
term := strings.Join(rest, " ")
|
|
return cmd.FilmList(client, term, inclExt, jsonOutput)
|
|
case "add":
|
|
return cmd.FilmAdd(client, args, jsonOutput)
|
|
case "summary":
|
|
term := strings.Join(args, " ")
|
|
return cmd.FilmSummary(client, term, jsonOutput)
|
|
case "profiles":
|
|
return cmd.FilmProfiles(client, jsonOutput)
|
|
case "rootfolders":
|
|
return cmd.FilmRootFolders(client, jsonOutput)
|
|
default:
|
|
return fmt.Errorf("unknown film action: %s", action)
|
|
}
|
|
}
|
|
|
|
func usage() {
|
|
fmt.Fprintln(os.Stderr, `Usage: arrman [--json] <domain> <action> [args...]
|
|
|
|
Domains: tv, film, films
|
|
|
|
Actions:
|
|
list [title] [--include-external] List/search library (add flag to include external sources)
|
|
add <term> --profile <id> --rootfolder <path> Add new
|
|
summary <term> Show details
|
|
profiles List quality profiles
|
|
rootfolders List root folders
|
|
|
|
Global flags:
|
|
--json Output results as structured JSON`)
|
|
}
|
|
|
|
func loadEnv() {
|
|
f, err := os.Open(".env")
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer f.Close()
|
|
|
|
scanner := bufio.NewScanner(f)
|
|
for scanner.Scan() {
|
|
line := strings.TrimSpace(scanner.Text())
|
|
if line == "" || strings.HasPrefix(line, "#") {
|
|
continue
|
|
}
|
|
parts := strings.SplitN(line, "=", 2)
|
|
if len(parts) != 2 {
|
|
continue
|
|
}
|
|
key := strings.TrimSpace(parts[0])
|
|
val := strings.TrimSpace(parts[1])
|
|
if os.Getenv(key) == "" {
|
|
os.Setenv(key, val)
|
|
}
|
|
}
|
|
}
|
|
|
|
func requireEnv(key string) string {
|
|
val := os.Getenv(key)
|
|
if val == "" {
|
|
fmt.Fprintf(os.Stderr, "Error: %s is not set. Check your .env file.\n", key)
|
|
os.Exit(1)
|
|
}
|
|
return val
|
|
}
|