167 lines
4.1 KiB
Go
167 lines
4.1 KiB
Go
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 {
|
|
bodyBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("failed to read response body: %w", err)
|
|
}
|
|
body := string(bodyBytes)
|
|
fmt.Printf("Failed request: URL: %s, Status Code: %d, Response: %s\n", url, resp.StatusCode, 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)
|
|
}
|
|
}
|