2
0
Fork 0
FLIK/big-sort.go
2023-05-30 16:52:08 -04:00

163 lines
4 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 {
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)
}
}