diff --git a/cmd/curd/main.go b/cmd/curd/main.go index 8b1cead..33b28f0 100644 --- a/cmd/curd/main.go +++ b/cmd/curd/main.go @@ -61,6 +61,7 @@ func main() { continueLast := flag.Bool("c", false, "Continue last episode") addNewAnime := flag.Bool("new", false, "Add new anime") rofiSelection := flag.Bool("rofi", false, "Open selection in rofi") + noRofi := flag.Bool("no-rofi", false, "No rofi") updateScript := flag.Bool("u", false, "Update the script") editConfig := flag.Bool("e", false, "Edit config") subFlag := flag.Bool("sub", false, "Watch sub version") @@ -94,6 +95,10 @@ func main() { userCurdConfig.RofiSelection = true } + if *noRofi { + userCurdConfig.RofiSelection = false + } + if *editConfig { internal.EditConfig(configFilePath) return @@ -112,8 +117,16 @@ func main() { internal.Log("Error reading token", logFile) } if user.Token == "" { - fmt.Println("No token found, please generate a token from https://anilist.co/api/v2/oauth/authorize?client_id=20686&response_type=token") - fmt.Scanln(&user.Token) + if userCurdConfig.RofiSelection { + user.Token, err = internal.GetTokenFromRofi() + } else { + fmt.Println("No token found, please generate a token from https://anilist.co/api/v2/oauth/authorize?client_id=20686&response_type=token") + fmt.Scanln(&user.Token) + } + if err != nil { + internal.Log("Error getting user input: "+err.Error(), logFile) + internal.ExitCurd(err) + } internal.WriteTokenToFile(user.Token, filepath.Join(os.ExpandEnv(userCurdConfig.StoragePath), "token")) } @@ -392,11 +405,12 @@ func main() { // internal.CurdOut(anime.Ep.Number, anime.TotalEpisodes, &userCurdConfig) if anime.Ep.Number-1 == anime.TotalEpisodes && userCurdConfig.ScoreOnCompletion { anime.Ep.Number = anime.Ep.Number - 1 - var userScore float64 internal.CurdOut("Completed anime.") - fmt.Println("Rate this anime: ") - fmt.Scanln(&userScore) - internal.RateAnime(user.Token, anime.AnilistId, userScore) + err = internal.RateAnime(user.Token, anime.AnilistId) + if err != nil { + internal.Log("Error rating anime: "+err.Error(), logFile) + internal.CurdOut("Error rating anime: "+err.Error()) + } internal.LocalDeleteAnime(databaseFile, anime.AnilistId, anime.AllanimeId) internal.ExitCurd(nil) } @@ -410,8 +424,15 @@ func main() { if userCurdConfig.NextEpisodePrompt { var answer string - fmt.Println("Start next episode? (y/n)") - fmt.Scanln(&answer) + if userCurdConfig.RofiSelection { + answer, err = internal.GetUserInputFromRofi("Start next episode? (y/n)") + if err != nil { + internal.ExitCurd(err) + } + } else { + fmt.Println("Start next episode? (y/n)") + fmt.Scanln(&answer) + } if answer == "y" || answer == "Y" || answer == "yes" || answer == "Yes" || answer == "YES" || answer == "" { } else { internal.ExitCurd(nil) diff --git a/internal/anilist.go b/internal/anilist.go index 8aed80a..7a1cef8 100644 --- a/internal/anilist.go +++ b/internal/anilist.go @@ -349,7 +349,29 @@ func UpdateAnimeProgress(token string, mediaID, progress int) error { } // Function to rate an anime on AniList -func RateAnime(token string, mediaID int, score float64) error { +func RateAnime(token string, mediaID int) error { + var score float64 + var err error + + userCurdConfig := GetGlobalConfig() + if userCurdConfig == nil { + return fmt.Errorf("failed to get curd config") + } + + if userCurdConfig.RofiSelection { + userInput, err := GetUserInputFromRofi("Enter a score for the anime (0-10):") + if err != nil { + return err + } + score, err = strconv.ParseFloat(userInput, 64) + if err != nil { + return err + } + } else { + fmt.Println("Rate this anime: ") + fmt.Scanln(&score) + } + url := "https://graphql.anilist.co" query := ` mutation($mediaId: Int, $score: Float) { @@ -370,7 +392,7 @@ func RateAnime(token string, mediaID int, score float64) error { "Content-Type": "application/json", } - _, err := makePostRequest(url, query, variables, headers) + _, err = makePostRequest(url, query, variables, headers) if err != nil { return err } diff --git a/internal/curd.go b/internal/curd.go index e71db86..e192bfb 100644 --- a/internal/curd.go +++ b/internal/curd.go @@ -220,9 +220,18 @@ func UpdateCurd(repo, fileName string) error { } func AddNewAnime(userCurdConfig *CurdConfig, anime *Anime, user *User, databaseAnimes *[]Anime, logFile string) { - CurdOut("Enter the anime name:") var query string - fmt.Scanln(&query) + if userCurdConfig.RofiSelection { + userInput, err := GetUserInputFromRofi("Enter the anime name:") + if err != nil { + Log("Error getting user input: "+err.Error(), logFile) + ExitCurd(fmt.Errorf("Error getting user input: "+err.Error())) + } + query = userInput + } else { + CurdOut("Enter the anime name:") + fmt.Scanln(&query) + } animeMap, err := SearchAnimeAnilist(query, user.Token) if err != nil { Log(fmt.Sprintf("Failed to search anime: %v", err), logFile) @@ -243,6 +252,13 @@ func AddNewAnime(userCurdConfig *CurdConfig, anime *Anime, user *User, databaseA Log(fmt.Sprintf("Failed to add anime to watching list: %v", err), logFile) ExitCurd(fmt.Errorf("Failed to add anime to watching list")) } + if user.Id == 0 { + user.Id, user.Username, err = GetAnilistUserID(user.Token) + if err != nil { + Log(fmt.Sprintf("Failed to get user ID: %v", err), logFile) + ExitCurd(fmt.Errorf("Failed to get user ID")) + } + } anilistUserData, err := GetUserData(user.Token, user.Id) if err != nil { Log(fmt.Sprintf("Failed to get user data: %v", err), logFile) @@ -407,18 +423,36 @@ func SetupCurd(userCurdConfig *CurdConfig, anime *Anime, user *User, databaseAni if anime.TotalEpisodes == 0 { CurdOut("Still unable to determine total episodes.") CurdOut(fmt.Sprintf("Your AniList progress: %d", selectedAnilistAnime.Progress)) - fmt.Print("Enter the episode you want to start from: ") var episodeNumber int - fmt.Scanln(&episodeNumber) + if userCurdConfig.RofiSelection { + userInput, err := GetUserInputFromRofi("Enter the episode you want to start from:") + if err != nil { + Log("Error getting user input: "+err.Error(), logFile) + ExitCurd(fmt.Errorf("Error getting user input: "+err.Error())) + } + episodeNumber, err = strconv.Atoi(userInput) + } else { + fmt.Print("Enter the episode you want to start from: ") + fmt.Scanln(&episodeNumber) + } anime.Ep.Number = episodeNumber } else { anime.Ep.Number = selectedAnilistAnime.Progress + 1 } } else if anime.TotalEpisodes < anime.Ep.Number { // Handle weird cases Log(fmt.Sprintf("Weird case: anime.TotalEpisodes < anime.Ep.Number: %v < %v", anime.TotalEpisodes, anime.Ep.Number), logFile) - fmt.Printf("Would like to start the anime from beginning? (y/n)\n") var answer string - fmt.Scanln(&answer) + if userCurdConfig.RofiSelection { + userInput, err := GetUserInputFromRofi("Would like to start the anime from beginning? (y/n)") + if err != nil { + Log("Error getting user input: "+err.Error(), logFile) + ExitCurd(fmt.Errorf("Error getting user input: "+err.Error())) + } + answer = userInput + } else { + fmt.Printf("Would like to start the anime from beginning? (y/n)\n") + fmt.Scanln(&answer) + } if answer == "y" { anime.Ep.Number = 1 } else { @@ -459,8 +493,17 @@ func StartCurd(userCurdConfig *CurdConfig, anime *Anime, logFile string) string RestoreScreen() os.Exit(1) } - CurdOut(fmt.Sprintf("Enter the episode (%v episodes)", episodeList[len(episodeList)-1])) - fmt.Scanln(&anime.Ep.Number) + if userCurdConfig.RofiSelection { + userInput, err := GetUserInputFromRofi(fmt.Sprintf("Enter the episode (%v episodes)", episodeList[len(episodeList)-1])) + if err != nil { + Log("Error getting user input: "+err.Error(), logFile) + ExitCurd(fmt.Errorf("Error getting user input: "+err.Error())) + } + anime.Ep.Number, err = strconv.Atoi(userInput) + } else { + CurdOut(fmt.Sprintf("Enter the episode (%v episodes)", episodeList[len(episodeList)-1])) + fmt.Scanln(&anime.Ep.Number) + } link, err = GetEpisodeURL(*userCurdConfig, anime.AllanimeId, anime.Ep.Number) if err != nil { CurdOut("Failed to get episode link") diff --git a/internal/rofi.go b/internal/rofi.go new file mode 100644 index 0000000..a1b05a5 --- /dev/null +++ b/internal/rofi.go @@ -0,0 +1,55 @@ +package internal + +import ( + "bytes" + "fmt" + "os/exec" + "strings" +) + +func GetTokenFromRofi() (string, error) { + // The URL to open + url := "https://anilist.co/api/v2/oauth/authorize?client_id=20686&response_type=token" + + // Use rofi to display a prompt with the URL + message := "Press enter to open the anilist token page in your browser" + _, err := GetUserInputFromRofi(message) + if err != nil { + return "", err + } + + // Open the URL in the default browser + err = exec.Command("xdg-open", url).Start() + if err != nil { + return "", err + } + + // Use rofi again to get the token input from the user + token, err := GetUserInputFromRofi("Enter the token:") + if err != nil { + return "", err + } + + return token, nil +} + +// GetUserInputFromRofi prompts the user for input using Rofi with a custom message +func GetUserInputFromRofi(message string) (string, error) { + // Create the Rofi command + cmd := exec.Command("rofi", "-dmenu", "-p", "Input", "-mesg", message) + + // Set up pipes for output + var out bytes.Buffer + cmd.Stdout = &out + + // Run the command + err := cmd.Run() + if err != nil { + return "", fmt.Errorf("failed to run Rofi: %w", err) + } + + // Get the entered input + userInput := strings.TrimSpace(out.String()) + + return userInput, nil +} \ No newline at end of file