tremble/cli/main.go

152 lines
3.3 KiB
Go
Raw Normal View History

2025-07-31 15:27:22 +00:00
// Just a program to display information about twitch.
// Token can be found at https://dev.twitch.tv/console
// Also can be obtained at the console I beleive, but twitch-cli token also
// gives a valid token.
package main
import (
"auth"
"context"
"fmt"
"os"
"github.com/charmbracelet/log"
"github.com/nicklaw5/helix/v2"
)
var authCtx, authCancel = context.WithCancel(context.Background())
var helixOptions helix.Options
var defaultUserID string
func init() {
config, err := read_config()
if err != nil {
fmt.Printf("Error with config: %v\n", err)
fmt.Println("Use the init subcommand to initialize a config file.")
} else {
helixOptions.ClientID = config.ClientID
helixOptions.ClientSecret = config.ClientSecret
defaultUserID = config.UserID
}
maybeSet := func(out *string, env string) {
val, isSet := os.LookupEnv(env)
if isSet {
*out = val
}
}
// Override any argument if a corresponding environment variable is set.
maybeSet(&helixOptions.ClientID, "TWITCH_CLIENT_ID")
// maybeSet(&helixOptions.AppAccessToken, "TWITCH_APP_TOKEN")
maybeSet(&helixOptions.ClientSecret, "TWITCH_CLIENT_SECRET")
}
func printHelp() {
fmt.Println("Print help about commands here.")
}
// Note:
// Currently everything is intended to just have all the scopes possible for
// us to need to be requested..
func main() {
ctx := context.Background()
runAuth := func() *helix.Client {
client, err := helix.NewClient(&helixOptions)
if err != nil {
panic(err)
}
// Ask for all scopes up front. Not handling scope renegotiation at the
// moment.
a, err := auth.New(&ctx, client, []string{"user:read:follows"})
if err != nil {
log.Info("Need to reauth")
}
if !a.HaveAuth {
ch, err := a.StartAuth("", []string{"user:read:follows"})
if err != nil {
panic(err)
}
<-ch
}
return client
}
if len(os.Args) < 2 {
printHelp()
panic("Insufficient arguments.")
}
switch os.Args[1] {
case "category":
{
client := runAuth()
categories(client, os.Args[2:])
}
case "search":
{
client := runAuth()
search(client, os.Args[2:])
}
case "live":
{
// TODO: FlagSet
client := runAuth()
// Always assume config has ID for now.
err := getFollowedLive(client, defaultUserID)
if err != nil {
panic("Couldn't get followed streams.")
}
}
case "games":
{
// TODO: FlagSet
// XXX: Handle a list of game search terms maybe.
client := runAuth()
if err := printGames(client, []string{os.Args[2]}); err != nil {
panic("Couldn't list games")
}
}
case "init":
{
newConfig, err := setupAuth()
if err != nil {
panic("Something went wrong with init.")
}
helixOptions.ClientID = newConfig.ClientID
helixOptions.ClientSecret = newConfig.ClientSecret
client := runAuth()
users, err := getUsersByName(client, []string{newConfig.UserName})
if err != nil {
log.Fatalf("Couldn't look up user '%v': %v\n", newConfig.UserName, err)
}
newConfig.UserID = users[0].ID
// Hopefully the config is safe to write.
write_config(newConfig)
}
case "user":
{
// TODO: FlagSet
client := runAuth()
users, err := getUsersByName(client, []string{os.Args[2]})
if err != nil {
panic("Something went wrong with user fetch.")
}
for _, user := range users {
fmt.Printf("%+v\n", user)
}
}
default:
printHelp()
}
}