Scopes can now be passed in, most of the spotify user object is returned in the credentials

This commit is contained in:
Paul Harper 2014-09-21 23:42:13 -07:00
parent 04a5aad6c1
commit 261cbc30aa

View File

@ -9,37 +9,63 @@ import Control.Applicative ((<$>), (<*>))
import Control.Exception.Lifted import Control.Exception.Lifted
import Control.Monad (mzero) import Control.Monad (mzero)
import Data.Aeson import Data.Aeson
import Data.Text (Text)
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import Data.Maybe
import Data.Text (Text)
import Data.Text.Encoding (encodeUtf8) import Data.Text.Encoding (encodeUtf8)
import Network.HTTP.Conduit(Manager) import Network.HTTP.Conduit(Manager)
import Yesod.Auth import Yesod.Auth
import Yesod.Auth.OAuth2 import Yesod.Auth.OAuth2
import qualified Data.ByteString as B
import qualified Data.Text as T
data SpotifyUserImage = SpotifyUserImage
{ spotifyUserImageHeight :: Maybe Int
, spotifyUserImageWidth :: Maybe Int
, spotifyUserImageUrl :: Text
}
instance FromJSON SpotifyUserImage where
parseJSON (Object v) = SpotifyUserImage <$>
v .: "height" <*>
v .: "width" <*>
v .: "url"
parseJSON _ = mzero
data SpotifyUser = SpotifyUser data SpotifyUser = SpotifyUser
{ spotifyUserId :: Text { spotifyUserId :: Text
, spotifyUserHref :: Text , spotifyUserHref :: Text
, spotifyUserDisplayName :: Text , spotifyUserUri :: Text
, spotifyProduct :: Text , spotifyUserDisplayName :: Maybe Text
, spotifyUserProduct :: Maybe Text
, spotifyUserCountry :: Maybe Text
, spotifyUserEmail :: Maybe Text
, spotifyUserImages :: Maybe [SpotifyUserImage]
} }
instance FromJSON SpotifyUser where instance FromJSON SpotifyUser where
parseJSON (Object v) = SpotifyUser <$> parseJSON (Object v) = SpotifyUser <$>
v .: "id" <*> v .: "id" <*>
v .: "href" <*> v .: "href" <*>
v .: "display_name" <*> v .: "uri" <*>
v .: "product" v .:? "display_name" <*>
v .:? "product" <*>
v .:? "country" <*>
v .:? "email" <*>
v .:? "images"
parseJSON _ = mzero parseJSON _ = mzero
oauth2Spotify :: YesodAuth m oauth2Spotify :: YesodAuth m
=> Text -- ^ Client ID => Text -- ^ Client ID
-> Text -- ^ Client Secret -> Text -- ^ Client Secret
-> [ByteString] -- ^ Scopes
-> AuthPlugin m -> AuthPlugin m
oauth2Spotify clientId clientSecret = authOAuth2 "spotify" oauth2Spotify clientId clientSecret scope = authOAuth2 "spotify"
(OAuth2 (OAuth2
{ oauthClientId = encodeUtf8 clientId { oauthClientId = encodeUtf8 clientId
, oauthClientSecret = encodeUtf8 clientSecret , oauthClientSecret = encodeUtf8 clientSecret
, oauthOAuthorizeEndpoint = "https://accounts.spotify.com/authorize" , oauthOAuthorizeEndpoint = B.append "https://accounts.spotify.com/authorize?scope=" (B.intercalate "%20" scope)
, oauthAccessTokenEndpoint = "https://accounts.spotify.com/api/token" , oauthAccessTokenEndpoint = "https://accounts.spotify.com/api/token"
, oauthCallback = Nothing , oauthCallback = Nothing
}) })
@ -55,7 +81,28 @@ fetchSpotifyProfile manager token = do
toCreds :: SpotifyUser -> Creds m toCreds :: SpotifyUser -> Creds m
toCreds user = Creds "spotify" toCreds user = Creds "spotify"
(spotifyUserId user) (spotifyUserId user)
[ ("href" , spotifyUserHref user) (mapMaybe getExtra extrasTemplate)
, ("display_name", spotifyUserDisplayName user)
, ("product" , spotifyProduct user) where
] userImage :: Maybe SpotifyUserImage
userImage = spotifyUserImages user >>= listToMaybe
userImagePart :: (SpotifyUserImage -> Maybe a) -> Maybe a
userImagePart getter = userImage >>= getter
extrasTemplate = [ ("href" , Just $ spotifyUserHref user)
, ("uri" , Just $ spotifyUserUri user)
, ("display_name", spotifyUserDisplayName user)
, ("product" , spotifyUserProduct user)
, ("country" , spotifyUserCountry user)
, ("email" , spotifyUserEmail user)
, ("image_url" , userImage >>=
return . spotifyUserImageUrl)
, ("image_height", userImagePart spotifyUserImageHeight >>=
return . T.pack . show)
, ("image_width" , userImagePart spotifyUserImageWidth >>=
return . T.pack . show)
]
getExtra :: (Text, Maybe Text) -> Maybe (Text, Text)
getExtra (key, val) = fmap ((,) key) val