Skip to content

Commit

Permalink
feat(cmd): create imdb command
Browse files Browse the repository at this point in the history
Does not support advanced search yet. Way too many args.
  • Loading branch information
Jisin0 committed Sep 24, 2024
1 parent 1ae59f8 commit 18fbbed
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 1 deletion.
73 changes: 73 additions & 0 deletions cmd/imdb/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package imdbcmd

import (
"encoding/json"
"errors"
"fmt"
"time"

"github.com/Jisin0/filmigo/imdb"
"github.com/Jisin0/filmigo/internal/id"
"github.com/spf13/cobra"
)

var (
getCmd = &cobra.Command{
Use: "get",
Short: "Get Full Data of a Movie or Person",
Long: `Get Movie Using It's imdb/justwatch id or URL.`,
Args: cobra.ExactArgs(1),
RunE: runGet,
}
)

func runGet(_ *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("not enough arguments")
}

input := args[0]

idSource, idType := id.RecognizeID(input)
if idSource != id.IDSourceImdb {
return errors.New("id or url invalid")
}

client := imdb.NewClient(imdb.ImdbClientOpts{DisableCaching: noCache, CacheExpiration: time.Minute * time.Duration(cacheExpiration)})

switch idType {
case id.IDTypeTitle:
movie, err := client.GetMovie(input)
if err != nil {
return err
}

if outputJson {
bytes, err := json.MarshalIndent(movie, "", " ")
if err != nil {
return err
}

fmt.Println(string(bytes))
break
}

movie.PrettyPrint()
case id.IDTypePerson:
person, err := client.GetPerson(input)
if err != nil {
return err
}

bytes, err := json.MarshalIndent(person, "", " ")
if err != nil {
return err
}

fmt.Println(string(bytes))
default:
return errors.ErrUnsupported
}

return nil
}
27 changes: 27 additions & 0 deletions cmd/imdb/imdb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package imdbcmd

import (
"github.com/spf13/cobra"
)

var (
noCache bool
cacheExpiration int64
outputJson bool
)

func NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "imdb",
Short: "Get Data From the Internet Movie Database (IMDb)",
Long: `Search People & Shows, Get Data On Movies etc.`,
}

cmd.PersistentFlags().BoolVar(&noCache, "nocache", false, "disable caching (not recommended)")
cmd.PersistentFlags().Int64Var(&cacheExpiration, "cache-expires", 0, "cache expiration in minutes")
cmd.PersistentFlags().BoolVar(&outputJson, "json", false, "output result as json")

cmd.AddCommand(getCmd, searchCmd)

return cmd
}
66 changes: 66 additions & 0 deletions cmd/imdb/search.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package imdbcmd

import (
"encoding/json"
"errors"
"fmt"
"time"

"github.com/Jisin0/filmigo/imdb"
"github.com/spf13/cobra"
)

var (
includeVideos bool
onlyTitles bool
onlyNames bool
searchCmd = &cobra.Command{
Use: "search",
Short: "Search For a Movie or Person",
Long: `Search Both Movies and Stars Using Their Name or ID.`,
Args: cobra.ExactArgs(1),
RunE: runSearch,
}
)

func init() {
searchCmd.Flags().BoolVar(&includeVideos, "include-videos", false, "include trailer videos")
searchCmd.Flags().BoolVar(&onlyTitles, "only-titles", false, "only search titles (movies & shows)")
searchCmd.Flags().BoolVar(&onlyNames, "only-names", false, "only search people")
}

func runSearch(_ *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("not enough arguments")
}

input := args[0]

client := imdb.NewClient(imdb.ImdbClientOpts{DisableCaching: noCache, CacheExpiration: time.Minute * time.Duration(cacheExpiration)})

var (
result *imdb.SearchResults
err error
)

switch {
case onlyTitles:
result, err = client.SearchTitles(input, &imdb.SearchConfigs{IncludeVideos: includeVideos})
case onlyNames:
result, err = client.SearchNames(input, &imdb.SearchConfigs{IncludeVideos: includeVideos})
default:
result, err = client.SearchAll(input, &imdb.SearchConfigs{IncludeVideos: includeVideos})
}

if err != nil {
return err
}

bytes, err := json.MarshalIndent(result, "", " ")
if err != nil {
return err
}

fmt.Println(string(bytes))
return nil
}
6 changes: 5 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package cmd

import "github.com/spf13/cobra"
import (
imdbcmd "github.com/Jisin0/filmigo/cmd/imdb"
"github.com/spf13/cobra"
)

var (
rootCmd = &cobra.Command{
Expand All @@ -15,6 +18,7 @@ use "filmigo sites" to get a list of all supported sites.`,
func init() {
rootCmd.AddCommand(searchCmd)
rootCmd.AddCommand(getCmd)
rootCmd.AddCommand(imdbcmd.NewCommand())
}

// Execute executes the root command.
Expand Down
46 changes: 46 additions & 0 deletions internal/id/id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package id

import (
"regexp"
"strings"
)

type IDSource int

const (
IDSourceUnknown IDSource = iota
IDSourceImdb
IDSourceJW
)

type IDType int

const (
IDTypeUnknown IDType = iota
IDTypeTitle
IDTypePerson
IDTypeURL
)

// Regexes for each engine
var (
imdbTitleRegex = regexp.MustCompile(`tt\d+`)
imdbNameRegex = regexp.MustCompile(`nm\d+`)
justwatchIdRegex = regexp.MustCompile(`tm\d+`)
)

// RecognizeID uses regex to identify the source and type of an id.
func RecognizeID(input string) (IDSource, IDType) {
switch {
case imdbTitleRegex.MatchString(input):
return IDSourceImdb, IDTypeTitle
case imdbNameRegex.MatchString(input):
return IDSourceImdb, IDTypePerson
case justwatchIdRegex.MatchString(input):
return IDSourceJW, IDTypeTitle
case strings.Contains(input, "justwatch.com"): //TODO: use regex for safer checks
return IDSourceJW, IDTypeURL
default:
return IDSourceUnknown, IDTypeUnknown
}
}

0 comments on commit 18fbbed

Please sign in to comment.