discogs-haskell-0.0.5.0: src/Discogs/Types/Discogs.hs
module Discogs.Types.Discogs
( Discogs
, DiscogsT(..)
, DiscogsF(..)
, runRoute
, receiveRoute
, nest
, failWith
, Modhash(..)
, LoginDetails(..)
, withBaseURL
, builder
, mainBaseURL
, loginBaseURL
, addHeader
, addAPIType ) where
import Discogs.Types.Error
import Control.Applicative
import Control.Monad.IO.Class
import Control.Monad.Trans.Free
import Control.Monad.Trans.Class
import Data.Aeson
import Data.ByteString.Lazy (ByteString)
import Data.Monoid
import Data.Text (Text)
import Data.Time.Clock
import Network.API.Builder hiding (runRoute)
import Network.HTTP.Client hiding (path)
import Network.HTTP.Types
import Prelude
import Text.Read (readMaybe)
import qualified Data.ByteString.Char8 as BS
type Discogs a = DiscogsT IO a
data DiscogsF m a where
FailWith :: APIError DiscogsError -> DiscogsF m a
Nest :: DiscogsT m b -> (Either (APIError DiscogsError) b -> a) -> DiscogsF m a
NestResuming :: DiscogsT m b -> (Either (APIError DiscogsError, Maybe (DiscogsT m b)) b -> a) -> DiscogsF m a
ReceiveRoute :: Receivable b => Route -> (b -> a) -> DiscogsF m a
RunRoute :: FromJSON b => Route -> (b -> a) -> DiscogsF m a
WithBaseURL :: Text -> DiscogsT m b -> (b -> a) -> DiscogsF m a
instance Functor (DiscogsF m) where
fmap _ (FailWith x) = FailWith x
fmap f (Nest a x) = Nest a (fmap f x)
fmap f (NestResuming a x) = NestResuming a (fmap f x)
fmap f (ReceiveRoute r x) = ReceiveRoute r (fmap f x)
fmap f (RunRoute r x) = RunRoute r (fmap f x)
fmap f (WithBaseURL u a x) = WithBaseURL u a (fmap f x)
newtype DiscogsT m a = DiscogsT (FreeT (DiscogsF m) m a)
deriving (Functor, Applicative, Monad)
instance MonadTrans DiscogsT where
lift = DiscogsT . lift
instance MonadIO m => MonadIO (DiscogsT m) where
liftIO = DiscogsT . liftIO
runRoute :: (FromJSON a, Monad m) => Route -> DiscogsT m a
runRoute r = DiscogsT $ liftF $ RunRoute r id
receiveRoute :: (Receivable a, Monad m) => Route -> DiscogsT m a
receiveRoute r = DiscogsT $ liftF $ ReceiveRoute r id
nest :: Monad m => DiscogsT m a -> DiscogsT m (Either (APIError DiscogsError) a)
nest f = DiscogsT $ liftF $ Nest f id
withBaseURL :: Monad m => Text -> DiscogsT m a -> DiscogsT m a
withBaseURL u f = DiscogsT $ liftF $ WithBaseURL u f id
failWith :: Monad m => APIError DiscogsError -> DiscogsT m a
failWith = DiscogsT . liftF . FailWith
newtype Modhash = Modhash Text
deriving (Show, Read, Eq)
instance FromJSON Modhash where
parseJSON (Object o) =
Modhash <$> ((o .: "json") >>= (.: "data") >>= (.: "modhash"))
parseJSON _ = mempty
data LoginDetails = LoginDetails Modhash CookieJar
deriving (Show, Eq)
instance Receivable LoginDetails where
receive x = do
(resp, mh) <- receive x
return $ LoginDetails (unwrapJSON mh) (responseCookieJar (resp :: Response ByteString))
newtype POSTWrapped a = POSTWrapped a
deriving (Show, Read, Eq)
instance Functor POSTWrapped where
fmap f (POSTWrapped a) = POSTWrapped (f a)
builder :: Builder
builder = Builder "Discogs API"
mainBaseURL
addAPIType
(addHeader Nothing)
addHeader :: Maybe BS.ByteString -> Request -> Request
addHeader Nothing req = req { requestHeaders =
("User-Agent", "discogs-haskell 0.1.0.0 / accraze") : requestHeaders req }
addHeader (Just hdr) req = req { requestHeaders =
("User-Agent", hdr) : requestHeaders req }
addAPIType :: Route -> Route
addAPIType (Route fs ps m) = Route fs ps m
mainBaseURL :: Text
mainBaseURL = "https://api.discogs.com"
loginBaseURL :: Text
loginBaseURL = "https://api.discogs.com"