Browse Source

Add the ability to fetch movies (posters are still only paths)

tags/v0.2.2.0
Peter J. Jones 6 years ago
parent
commit
4d9ddc223c

+ 5
- 0
Network/API/TheMovieDB.hs View File

@@ -13,11 +13,16 @@ module Network.API.TheMovieDB
, APIError
, SearchTerm
, ReleaseDate(..)
, GenreID
, Genre(..)
, MovieID
, Movie(..)
, fetchErr
, fetch
, searchErr
, search
) where

import Network.API.TheMovieDB.Types
import Network.API.TheMovieDB.Fetch
import Network.API.TheMovieDB.Search

+ 36
- 0
Network/API/TheMovieDB/Fetch.hs View File

@@ -0,0 +1,36 @@
{-

This file is part of the Haskell package themoviedb. It is subject to
the license terms in the LICENSE file found in the top-level directory
of this distribution and at git://pmade.com/themoviedb/LICENSE. No
part of themoviedb package, including this file, may be copied,
modified, propagated, or distributed except according to the terms
contained in the LICENSE file.

-}
module Network.API.TheMovieDB.Fetch
( fetchErr
, fetch
) where

-- Imports.
import Network.API.TheMovieDB.Types
import Network.API.TheMovieDB.HTTP
import Data.Aeson

-- | Fetch the metadata for the movie with the given ID. Returns
-- either an APIError or a Movie.
fetchErr :: APIKey -> MovieID -> IO (Either APIError Movie)
fetchErr key movieID =
do r <- apiGET key ("movie/" ++ show movieID) []
case r of
Left err -> return $ Left err
Right body -> return $ maybe (Left parseError) Right $ decode body
where parseError = ParseError "failed to parse movie JSON"

-- | Fetch the metadata for the movie with the given ID and fail if
-- any errors are encountered along the way.
fetch :: APIKey -> MovieID -> IO Movie
fetch key movieID =
do r <- fetchErr key movieID
either (fail . show) return r

+ 6
- 10
Network/API/TheMovieDB/Search.hs View File

@@ -39,16 +39,12 @@ moviesFromSearchJSON body =

--
searchErr :: APIKey -> SearchTerm -> IO (Either APIError [Movie])
searchErr key term =
do result <- apiGET key "search/movie" [("query", term)]
case result of
Left err -> return $ Left $ NetworkError $ show err
Right body -> return $ moviesFromSearchJSON body
searchErr key term = do
result <- apiGET key "search/movie" [("query", term)]
return $ either (Left . NetworkError . show) moviesFromSearchJSON result

--
search :: APIKey -> SearchTerm -> IO [Movie]
search key term =
do result <- searchErr key term
case result of
Left e -> return []
Right m -> return m
search key term = do
result <- searchErr key term
either (const $ return []) return result

+ 18
- 10
Network/API/TheMovieDB/Types.hs View File

@@ -14,7 +14,9 @@ module Network.API.TheMovieDB.Types
( APIKey
, APIError(..)
, ReleaseDate(..)
, GenreID
, Genre(..)
, MovieID
, Movie(..)
) where

@@ -47,21 +49,27 @@ instance FromJSON ReleaseDate where
_ -> fail "could not parse release_date"
parseJSON v = typeMismatch "ReleaseDate" v

-- | Type for representing unique genre IDs.
type GenreID = Int

-- | Metadata for a genre.
data Genre =
Genre
{ genreID :: Int -- ^ TheMovieDB unique ID.
, genreName :: String -- ^ The name of the genre.
{ genreID :: GenreID -- ^ TheMovieDB unique ID.
, genreName :: String -- ^ The name of the genre.
} deriving (Eq, Show)

instance FromJSON Genre where
parseJSON (Object v) = Genre <$> v .: "id" <*> v .: "name"
parseJSON v = typeMismatch "Genre" v

-- | Type for representing unique movie IDs.
type MovieID = Int

-- | Metadata for a movie.
data Movie =
Movie
{ movieID :: Int -- ^ TheMovieDB unique ID.
{ movieID :: MovieID -- ^ TheMovieDB unique ID.
, movieTitle :: String -- ^ The name/title of the movie.
, movieOverview :: String -- ^ Short plot summary.
, movieGenres :: [Genre] -- ^ List of genre names.
@@ -72,16 +80,16 @@ data Movie =

instance FromJSON Movie where
parseJSON (Object v) = do
genresMaybe <- v .:? "genres"
genres <- case genresMaybe of
Just a -> parseJSON a
_ -> return []
genres <- maybe (pure []) parseJSON <$> (v .:? "genres")
poster <- maybe (pure defaultPoster) posterURL <$> (v .:? "poster_path")
Movie <$> v .: "id"
<*> v .: "title"
<*> v .:? "overview" .!= ""
<*> return genres
<*> genres
<*> v .:? "popularity" .!= 0.0
<*> v .:? "poster_path" .!= ""
<*> poster
<*> v .:? "release_date" .!= defaultDate
where defaultDate = ReleaseDate $ ModifiedJulianDay 0
where defaultDate = ReleaseDate $ ModifiedJulianDay 0
defaultPoster = "" :: String
posterURL p = parseJSON p
parseJSON _ = empty

+ 9
- 8
themoviedb.cabal View File

@@ -18,19 +18,20 @@ cabal-version: >=1.8

library
exposed-modules: Network.API.TheMovieDB
other-modules: Network.API.TheMovieDB.Search,
Network.API.TheMovieDB.HTTP,
other-modules: Network.API.TheMovieDB.Fetch,
Network.API.TheMovieDB.Search,
Network.API.TheMovieDB.HTTP,
Network.API.TheMovieDB.Types
build-depends:
base ==4.3.*,
build-depends:
base ==4.3.*,
old-locale ==1.0.*,
time ==1.2.*,
HTTP ==4000.2.*,
network ==2.3.*,
bytestring ==0.9.*,
HTTP ==4000.2.*,
network ==2.3.*,
bytestring ==0.9.*,
text ==0.11.*,
aeson ==0.6.*

source-repository head
type: git
location: git://github.com/pjones/themoviedb.git
location: git://github.com/pjones/themoviedb.git

Loading…
Cancel
Save