{-# LANGUAGE OverloadedStrings, FlexibleContexts #-} module Network.Protocol.MusicBrainz.JSON.WebService ( getRecordingById , getReleaseById , searchReleasesByArtistAndRelease ) where import Network.Protocol.MusicBrainz.Types import Control.Monad.IO.Class (MonadIO) import Data.Aeson (eitherDecode) import qualified Data.ByteString.Lazy as BL import Data.List (intercalate) import Data.Text (Text) import qualified Data.Text as T import Network.HTTP.Base (urlEncode) import Network.HTTP.Conduit (simpleHttp) musicBrainzWSLookup :: MonadIO m => Text -> Text -> [Text] -> m BL.ByteString musicBrainzWSLookup :: Text -> Text -> [Text] -> m ByteString musicBrainzWSLookup reqtype :: Text reqtype param :: Text param incparams :: [Text] incparams = do let url :: [Char] url = "https://musicbrainz.org/ws/2/" [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ Text -> [Char] T.unpack Text reqtype [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ "/" [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ Text -> [Char] T.unpack Text param [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ [Text] -> [Char] incs [Text] incparams [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ [Char] fj [Char] -> m ByteString forall (m :: * -> *). MonadIO m => [Char] -> m ByteString simpleHttp [Char] url where incs :: [Text] -> [Char] incs [] = "" incs xs :: [Text] xs = ("?inc="[Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++) ([Char] -> [Char]) -> ([Text] -> [Char]) -> [Text] -> [Char] forall b c a. (b -> c) -> (a -> b) -> a -> c . [Char] -> [[Char]] -> [Char] forall a. [a] -> [[a]] -> [a] intercalate "+" ([[Char]] -> [Char]) -> ([Text] -> [[Char]]) -> [Text] -> [Char] forall b c a. (b -> c) -> (a -> b) -> a -> c . (Text -> [Char]) -> [Text] -> [[Char]] forall a b. (a -> b) -> [a] -> [b] map Text -> [Char] T.unpack ([Text] -> [Char]) -> [Text] -> [Char] forall a b. (a -> b) -> a -> b $ [Text] xs fj :: [Char] fj = "&fmt=json" musicBrainzWSSearch :: MonadIO m => Text -> Text -> Maybe Int -> Maybe Int -> m BL.ByteString musicBrainzWSSearch :: Text -> Text -> Maybe Int -> Maybe Int -> m ByteString musicBrainzWSSearch reqtype :: Text reqtype query :: Text query mlimit :: Maybe Int mlimit moffset :: Maybe Int moffset = do let url :: [Char] url = "https://musicbrainz.org/ws/2/" [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ Text -> [Char] T.unpack Text reqtype [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ "/?query=" [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ [Char] -> [Char] urlEncode (Text -> [Char] T.unpack Text query) [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ Maybe Int -> [Char] forall a. Show a => Maybe a -> [Char] limit Maybe Int mlimit [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ Maybe Int -> [Char] forall a. Show a => Maybe a -> [Char] offset Maybe Int moffset [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ [Char] fj [Char] -> m ByteString forall (m :: * -> *). MonadIO m => [Char] -> m ByteString simpleHttp [Char] url where limit :: Maybe a -> [Char] limit Nothing = "" limit (Just l :: a l) = "&limit=" [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ a -> [Char] forall a. Show a => a -> [Char] show a l offset :: Maybe a -> [Char] offset Nothing = "" offset (Just o :: a o) = "&offset=" [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ a -> [Char] forall a. Show a => a -> [Char] show a o fj :: [Char] fj = "&fmt=json" getRecordingById :: MonadIO m => MBID -> m (Either String Recording) getRecordingById :: MBID -> m (Either [Char] Recording) getRecordingById mbid :: MBID mbid = do ByteString lbs <- Text -> Text -> [Text] -> m ByteString forall (m :: * -> *). MonadIO m => Text -> Text -> [Text] -> m ByteString musicBrainzWSLookup "recording" (MBID -> Text unMBID MBID mbid) ["artist-credits"] Either [Char] Recording -> m (Either [Char] Recording) forall (m :: * -> *) a. Monad m => a -> m a return (Either [Char] Recording -> m (Either [Char] Recording)) -> Either [Char] Recording -> m (Either [Char] Recording) forall a b. (a -> b) -> a -> b $ ByteString -> Either [Char] Recording forall a. FromJSON a => ByteString -> Either [Char] a eitherDecode ByteString lbs getReleaseById :: MonadIO m => MBID -> m (Either String Release) getReleaseById :: MBID -> m (Either [Char] Release) getReleaseById mbid :: MBID mbid = do ByteString lbs <- Text -> Text -> [Text] -> m ByteString forall (m :: * -> *). MonadIO m => Text -> Text -> [Text] -> m ByteString musicBrainzWSLookup "release" (MBID -> Text unMBID MBID mbid) ["recordings", "artist-credits"] Either [Char] Release -> m (Either [Char] Release) forall (m :: * -> *) a. Monad m => a -> m a return (Either [Char] Release -> m (Either [Char] Release)) -> Either [Char] Release -> m (Either [Char] Release) forall a b. (a -> b) -> a -> b $ ByteString -> Either [Char] Release forall a. FromJSON a => ByteString -> Either [Char] a eitherDecode ByteString lbs searchReleasesByArtistAndRelease :: MonadIO m => Text -> Text -> Maybe Int -> Maybe Int -> m (Either String [(Int, Release)]) searchReleasesByArtistAndRelease :: Text -> Text -> Maybe Int -> Maybe Int -> m (Either [Char] [(Int, Release)]) searchReleasesByArtistAndRelease artist :: Text artist release :: Text release mlimit :: Maybe Int mlimit moffset :: Maybe Int moffset = do ByteString lbs <- Text -> Text -> Maybe Int -> Maybe Int -> m ByteString forall (m :: * -> *). MonadIO m => Text -> Text -> Maybe Int -> Maybe Int -> m ByteString musicBrainzWSSearch "release" ([Text] -> Text T.concat ["artist:\"", Text artist, "\" AND release:\"", Text release, "\""]) Maybe Int mlimit Maybe Int moffset Either [Char] [(Int, Release)] -> m (Either [Char] [(Int, Release)]) forall (m :: * -> *) a. Monad m => a -> m a return (Either [Char] [(Int, Release)] -> m (Either [Char] [(Int, Release)])) -> Either [Char] [(Int, Release)] -> m (Either [Char] [(Int, Release)]) forall a b. (a -> b) -> a -> b $ ByteString -> Either [Char] [(Int, Release)] forall a. FromJSON a => ByteString -> Either [Char] a eitherDecode ByteString lbs