package main import ( "database/sql" "fmt" "log" "os" "strconv" "strings" "time" "runtime" "github.com/charmbracelet/huh" "github.com/charmbracelet/huh/spinner" "github.com/imroc/req/v3" _ "github.com/mattn/go-sqlite3" "github.com/spf13/cobra" "github.com/tidwall/gjson" ) func entryExists(db *sql.DB, name string) (bool, error) { var count int row := db.QueryRow("SELECT COUNT(*) FROM movies WHERE imdb = ?", name) err := row.Scan(&count) if err != nil { return false, err } return count > 0, nil } type Movie struct { Title string Plot string RelasedDate time.Time imdbID string WatchedOn time.Time Rating int Opinion string Recommended bool } func logMovie() { // get the watched movie var inputstring string huh.NewForm(huh.NewGroup(huh.NewInput().Title("what did you watch today ?").Value(&inputstring)).WithShowHelp(true)).Run() replacedinput := strings.Replace(inputstring, " ", "+", -1) // search it on tmdb url := "https://api.themoviedb.org/3/search/movie?query=" + replacedinput + "&page=1" client := req.C() client.SetCommonHeader("accept", "application/json") client.SetCommonHeader("Authorization", "Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIzZDllYmUxOTNhMGU4OWFjMjM0MzZjNGJhNDg1NTY5ZCIsInN1YiI6IjY1ZWQ3ZTFjYmRjMzRjMDE0NzMyMDgxYiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.cJ5Aws6Um2VEcyqjhii5IjEihYyGmw5ICbh8ldHVqIs") resp, err := client.R().Get(url) if err != nil { log.Fatal(err) } // parsing found json data MovieInfo := make(map[string]int64) var MovieList []string result := gjson.Get(resp.String(), "results") result.ForEach(func(key, value gjson.Result) bool { title := gjson.Get(value.String(), "title") id := gjson.Get(value.String(), "id") releaseDate := gjson.Get(value.String(), "release_date") datesplit := strings.Split(releaseDate.String(), "-") var releaseYear string if datesplit[0] == "" { releaseYear = "unknown" } else { releaseYear = datesplit[0] } comb := title.String() + " (" + releaseYear + ")" MovieInfo[comb] = id.Int() return true }) for key := range MovieInfo { MovieList = append(MovieList, key) } var watchedMovie string huh.NewSelect[string]().Title("so which one ?").Options(huh.NewOptions(MovieList[:]...)...).Value(&watchedMovie).Run() // fetch info about the watched movie movid := MovieInfo[watchedMovie] url = "https://api.themoviedb.org/3/movie/" + strconv.FormatInt(movid, 10) resp, err = client.R().Get(url) if err != nil { log.Fatal(err) } ogTitle := gjson.Get(resp.String(), "title") plot := gjson.Get(resp.String(), "overview") imdbid := gjson.Get(resp.String(), "imdb_id") releasedday := gjson.Get(resp.String(), "release_date") var ratingvalue string var movopinion string var recomend bool ratetitle := "how would you rate " + ogTitle.String() + "?" huh.NewForm(huh.NewGroup( huh.NewInput().Title(ratetitle).Value(&ratingvalue), huh.NewText().Title("what did you think of this movie ?").Value(&movopinion), huh.NewConfirm().Title("do you recomend this to others ?").Affirmative("absolutely").Negative("nah").Value(&recomend), )).Run() currentdata := time.Now() watchedDate := currentdata.Format("2006-01-02") // log info to the database var db *sql.DB switch runtime.GOOS { case "linux", "darwin": dbLocation := os.Getenv("HOME") + "/Documents/Databases/movies.db" d, err := sql.Open("sqlite3", dbLocation) db = d if err != nil { log.Fatal(err) } case "windows": userProfile := os.Getenv("USERPROFILE") dbLocation := userProfile + "\\Documents\\movies.db" d, err := sql.Open("sqlite3", dbLocation) db = d if err != nil { log.Fatal(err) } } defer db.Close() createTableSQL := `CREATE TABLE IF NOT EXISTS movies ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, plot TEXT, releasedDate DATETIME, imdb TEXT UNIQUE, watchedOn DATETIME, rating INTEGER, opinion TEXT, recommended INTEGER );` _, err = db.Exec(createTableSQL) if err != nil { log.Fatal(err) } action := func() { time.Sleep(2 * time.Second) } _ = spinner.New().Title("processing").Action(action).Run() entryExists, err := entryExists(db, imdbid.String()) if err != nil { log.Fatal(err) } if entryExists { fmt.Println("you already watched this movie silly >.<") } else if ogTitle.String() == "" || plot.String() == "" || releasedday.String() == "" || imdbid.String() == "" || watchedDate == "" || ratingvalue == "" || movopinion == "" { fmt.Println("you need the enter all the details silly >.<") } else { // Insert the drama into the database insertSQL := `INSERT INTO movies (title, plot, releasedDate, imdb, watchedOn, rating, opinion, recommended) VALUES (?, ?, ?, ?, ?, ?, ?, ?);` _, err = db.Exec(insertSQL, ogTitle.String(), plot.String(), releasedday.String(), imdbid.String(), watchedDate, ratingvalue, movopinion, recomend) if err != nil { log.Fatal(err) } textOnSuccess := ogTitle.String() + " was logged in your silly diary >.<" fmt.Println(textOnSuccess) } } func main() { cmdLog := &cobra.Command{ Use: "a", Short: "log movie", Long: `kind of like a movie diary with required information about the watched movies`, Run: func(cmd *cobra.Command, args []string) { logMovie() }, } cmdList := &cobra.Command{ Use: "l", Short: "list watched movies", Long: `kind of like a movie diary with required information about the watched movies`, Run: func(cmd *cobra.Command, args []string) { Listmovies() }, } rootCmd := &cobra.Command{Use: "boxd"} rootCmd.AddCommand(cmdLog) rootCmd.AddCommand(cmdList) rootCmd.Execute() }