package main import ( "bufio" "encoding/csv" "encoding/json" "fmt" "io" "net/http" "net/url" "os" "strings" ) type Movie struct { Adult bool Backdrop_path string Genre_ids []int Id int Original_language string Original_title string Overview string Popularity float64 Poster_path string Release_date string Title string Video bool Vote_average float64 Vote_count int } type Response struct { Page int Results []Movie Total_pages int Total_results int } func main() { fmt.Println("Enter the input CSV file name:") inputFileName := getInput() fmt.Println("Enter the TMDB API Key:") apiKey := getInput() outputFileName := "movies.csv" outputFile, err := os.Create(outputFileName) if err != nil { fmt.Printf("Error creating output file: %v\n", err) return } defer outputFile.Close() writer := csv.NewWriter(outputFile) defer writer.Flush() processFile(inputFileName, apiKey, writer) checkFailedCsv(apiKey, writer) } func getInput() string { scanner := bufio.NewScanner(os.Stdin) scanner.Scan() return scanner.Text() } func processFile(inputFileName, apiKey string, writer *csv.Writer) { file, err := os.Open(inputFileName) if err != nil { fmt.Printf("Error opening file: %v\n", err) return } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { movie := scanner.Text() title, year, err := parseMovieTitleYear(movie) if err != nil { fmt.Printf("Failed to parse movie: %s, Error: %v\n", movie, err) continue } fmt.Printf("Searching for movie: %s\n", movie) popularity, err := getMovieData(title, year, apiKey) if err != nil { fmt.Printf("Failed to get data for movie: %s, Error: %v\n", movie, err) continue } record := []string{fmt.Sprintf("%q", title), year, fmt.Sprintf("%f", popularity)} _ = writer.Write(record) fmt.Printf("Movie: %s, Popularity: %f\n", movie, popularity) } } func parseMovieTitleYear(movie string) (string, string, error) { parts := strings.SplitN(movie, ",", 2) if len(parts) < 2 { return "", "", fmt.Errorf("invalid movie format: %s", movie) } title := parts[0] year := strings.TrimSpace(parts[1]) return title, year, nil } func getMovieData(title, year, apiKey string) (float64, error) { title = url.QueryEscape(title) url := fmt.Sprintf("https://api.themoviedb.org/3/search/movie?api_key=%s&query=%s&year=%s", apiKey, title, year) resp, err := http.Get(url) if err != nil { return 0, fmt.Errorf("failed to send request to TMDB: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) fmt.Printf("Failed request: URL: %s, Status Code: %d, Response: %s\n", url, resp.StatusCode, string(body)) return 0, fmt.Errorf("failed request with status code: %d", resp.StatusCode) } var response Response err = json.NewDecoder(resp.Body).Decode(&response) if err != nil { return 0, fmt.Errorf("failed to decode response from TMDB: %w", err) } if len(response.Results) == 0 { fmt.Printf("No results found for: URL: %s\n", url) return 0, fmt.Errorf("no results found") } return response.Results[0].Popularity, nil } func checkFailedCsv(apiKey string, writer *csv.Writer) { failedFile, err := os.Open("failed.csv") if err != nil { fmt.Printf("Error opening failed.csv: %v\n", err) return } defer failedFile.Close() scanner := bufio.NewScanner(failedFile) for scanner.Scan() { movie := scanner.Text() title, year, err := parseMovieTitleYear(movie) if err != nil { fmt.Printf("Failed to parse movie from failed.csv: %s, Error: %v\n", movie, err) continue } popularity, err := getMovieData(title, year, apiKey) if err == nil { record := []string{fmt.Sprintf("%q", title), year, fmt.Sprintf("%f", popularity)} _ = writer.Write(record) fmt.Printf("Retrieved previously failed movie: %s, Popularity: %f\n", movie, popularity) } } err = os.Remove("failed.csv") if err != nil { fmt.Printf("Error deleting failed.csv: %v\n", err) } }