-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathMovieData.purs
More file actions
161 lines (134 loc) · 4.89 KB
/
MovieData.purs
File metadata and controls
161 lines (134 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
module Movie.Data where
import Prelude
import Control.Monad.Error.Class (throwError)
import Data.Argonaut.Decode (class DecodeJson, decodeJson, (.?))
import Data.Argonaut.Decode.Combinators ((.??))
import Data.Argonaut.Parser (jsonParser)
import Data.Either (Either(..), either)
import Data.Int (floor)
import Data.Maybe (maybe)
import Data.String (Pattern(..), split)
import Effect.Aff (Aff, error)
import Global (readInt)
import Network.HTTP.Affjax (affjax, defaultRequest, get)
import Network.HTTP.Affjax.Response (string)
import Network.HTTP.RequestHeader (RequestHeader(..))
import ReactNative.PropTypes (ImageSource, uriSrc)
import ReactNative.PropTypes.Color (rgbi)
import ReactNative.Styles (Styles, staticStyles)
import ReactNative.Styles.Text (color)
type MovieR r = {
id :: String
, score :: Int
, title :: String
, year :: String
, thumbnail :: String
| r
}
type Movie = MovieR ()
type MovieDetails = MovieR (
mpaa_rating :: String
, synopsis :: String
, actors :: Array String
)
newtype RTMovie = RTMovie MovieDetails
newtype OMDBMovie = OMDBMovie (MovieR ())
newtype OMDBDetails = OMDBDetails MovieDetails
class MovieClass a where
unwrapMovie :: a -> Movie
loadDetails :: a -> Aff (Either String MovieDetails)
newtype RTActor = RTActor {
name :: String
}
instance rtActorIF :: DecodeJson RTActor where
decodeJson value = do
o <- decodeJson value
name <- o .? "name"
pure $ RTActor {name}
instance rtMovieIF :: DecodeJson RTMovie where
decodeJson value = do
o <- decodeJson value
id <- o .? "id"
title <- o .? "title"
score <- o .? "critics_score"
year <- o .? "year"
thumbnail <- o .? "thumbnail"
mpaa_rating <- o .? "mpaa_rating"
synopsis <- o .? "synopsis"
actorsM <- o .?? "actors"
let actors = maybe [] (map (\(RTActor {name}) -> name)) actorsM
pure $ RTMovie $ {id,title,score,year,thumbnail,mpaa_rating,synopsis,actors}
instance omdbMovieIF :: DecodeJson OMDBMovie where
decodeJson value = do
o <- decodeJson value
title <- o .? "Title"
year <- o .? "Year"
id <- o .? "imdbID"
thumbnail <- o .? "Poster"
pure $ OMDBMovie $ {id,title,year,thumbnail,score: -1}
instance omdbDetailsIF :: DecodeJson OMDBDetails where
decodeJson value = do
(OMDBMovie {id,title,year,thumbnail}) <- decodeJson value
o <- decodeJson value
synopsis <- o .? "Plot"
mpaa_rating <- o .? "Rated"
score <- parseInt (-1) <$> o .? "tomatoMeter"
actors_ <- o .? "Actors"
pure $ OMDBDetails $ {id,title,year,thumbnail,score,mpaa_rating, synopsis,actors:split (Pattern ",\\w.") actors_}
newtype OMDBResponse = OMDBResponse {
totalResults :: Int
, results :: Array OMDBMovie
}
parseInt :: Int -> String -> Int
parseInt d "N/A" = d
parseInt d s = floor $ readInt 10 s
instance omdbSR :: DecodeJson OMDBResponse where
decodeJson value = do
o <- decodeJson value
resp <- o .? "Response"
case resp of
"True" -> do
results <- o .? "Search"
totalResults <- parseInt (-1) <$> o .? "totalResults"
pure $ OMDBResponse {totalResults, results}
_ -> pure $ OMDBResponse {totalResults: -1, results:[]}
data Route = Search | ShowMovie MovieDetails
getImageSource :: forall r. MovieR r -> ImageSource
getImageSource m = uriSrc m.thumbnail
noScore :: Styles
noScore = staticStyles [
color $ rgbi 0x999999
]
getStyleFromScore :: Int -> Styles
getStyleFromScore _ = noScore
getTextFromScore :: Int -> String
getTextFromScore s = if s > 0 then show s <> "%" else "N/A"
apiUrl :: String
apiUrl = "http://api.rottentomatoes.com/api/public/v1.0/"
apiKey :: String
apiKey = "???"
omdbUrl :: String
omdbUrl = "http://www.omdbapi.com/"
omdbKey :: String
omdbKey = "16824787"
latestRTMovies :: Aff (Array RTMovie)
latestRTMovies = do
{response} <- get string (apiUrl <> "lists/movies/in_theaters.json?apikey=" <> apiKey <>"&page_limit=20&page=1")
either ((error <<< show) >>> throwError) pure $ (jsonParser response >>= decodeJson)
searchOMDB :: String -> Aff (Either String (Array OMDBMovie))
searchOMDB q = do
{response} <- affjax string $ defaultRequest { headers=[RequestHeader "Accept-Encoding" "identity"]
, url=searchUrl }
pure $ either (Left <<< show) handleResponse $ jsonParser response >>= decodeJson
where
handleResponse (OMDBResponse {results}) = pure results
searchUrl = omdbUrl <> "?apikey=" <> omdbKey <> "&type=movie&s=" <> q
instance omdbMovie :: MovieClass OMDBMovie where
unwrapMovie (OMDBMovie m) = m
loadDetails (OMDBMovie m) = do
{response} <- affjax string $ defaultRequest { headers=[RequestHeader "Accept-Encoding" "identity"]
, url= url m }
pure $ either (Left <<< show) (pure <<< unwrapDetails) $ jsonParser response >>= decodeJson
where
url movie = omdbUrl <> "?i=" <> movie.id <> "&plot=full&tomatoes=true&apikey=" <> omdbKey
unwrapDetails (OMDBDetails o) = o