{-# LANGUAGE OverloadedStrings, FlexibleContexts #-}

module Network.Protocol.MusicBrainz.XML2.WebService (
    getRecordingById
  , getReleaseById
  , searchReleasesByArtistAndRelease
) where

import Network.Protocol.MusicBrainz.Types

import Control.Applicative (liftA2, (<|>))
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.IO.Unlift (MonadUnliftIO)
import Control.Monad.Trans.Control (MonadBaseControl)
import Control.Monad.Trans.Resource (MonadThrow)
import qualified Data.ByteString.Lazy as BL
import Data.Conduit (ConduitM, (.|), runConduitRes)
import Data.Conduit.Binary (sourceLbs)
import Data.List (intercalate)
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Read as TR
import Data.Time.Format (parseTimeM)
import qualified Data.Vector as V
import Data.Void (Void)
import Data.XML.Types (Event)
import Network.HTTP.Base (urlEncode)
import Network.HTTP.Conduit (simpleHttp)
import Data.Time.Locale.Compat (defaultTimeLocale)
import Text.XML.Stream.Parse (parseBytes, def, content, tagNoAttr, tag', requireAttr, attr, force, many, AttrParser)
import Text.XML (Name(..))

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] -> 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

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] -> 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

getRecordingById :: (MonadBaseControl IO m, MonadIO m, MonadThrow m, MonadUnliftIO m) => MBID -> m Recording
getRecordingById :: MBID -> m 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"]
    [Recording]
rs <- ConduitT () Void (ResourceT m) [Recording] -> m [Recording]
forall (m :: * -> *) r.
MonadUnliftIO m =>
ConduitT () Void (ResourceT m) r -> m r
runConduitRes (ConduitT () Void (ResourceT m) [Recording] -> m [Recording])
-> ConduitT () Void (ResourceT m) [Recording] -> m [Recording]
forall a b. (a -> b) -> a -> b
$ ByteString -> ConduitT () ByteString (ResourceT m) ()
forall (m :: * -> *) i.
Monad m =>
ByteString -> ConduitT i ByteString m ()
sourceLbs ByteString
lbs ConduitT () ByteString (ResourceT m) ()
-> ConduitM ByteString Void (ResourceT m) [Recording]
-> ConduitT () Void (ResourceT m) [Recording]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ParseSettings -> ConduitT ByteString Event (ResourceT m) ()
forall (m :: * -> *).
MonadThrow m =>
ParseSettings -> ConduitT ByteString Event m ()
parseBytes ParseSettings
forall a. Default a => a
def ConduitT ByteString Event (ResourceT m) ()
-> ConduitM Event Void (ResourceT m) [Recording]
-> ConduitM ByteString Void (ResourceT m) [Recording]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ConduitM Event Void (ResourceT m) [Recording]
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m [Recording]
sinkRecordings
    Recording -> m Recording
forall (m :: * -> *) a. Monad m => a -> m a
return (Recording -> m Recording) -> Recording -> m Recording
forall a b. (a -> b) -> a -> b
$ [Recording] -> Recording
forall a. [a] -> a
head [Recording]
rs

getReleaseById :: (MonadBaseControl IO m, MonadIO m, MonadThrow m, MonadUnliftIO m) => MBID -> m Release
getReleaseById :: MBID -> m 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"]
    [Release]
rs <- ConduitT () Void (ResourceT m) [Release] -> m [Release]
forall (m :: * -> *) r.
MonadUnliftIO m =>
ConduitT () Void (ResourceT m) r -> m r
runConduitRes (ConduitT () Void (ResourceT m) [Release] -> m [Release])
-> ConduitT () Void (ResourceT m) [Release] -> m [Release]
forall a b. (a -> b) -> a -> b
$ ByteString -> ConduitT () ByteString (ResourceT m) ()
forall (m :: * -> *) i.
Monad m =>
ByteString -> ConduitT i ByteString m ()
sourceLbs ByteString
lbs ConduitT () ByteString (ResourceT m) ()
-> ConduitM ByteString Void (ResourceT m) [Release]
-> ConduitT () Void (ResourceT m) [Release]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ParseSettings -> ConduitT ByteString Event (ResourceT m) ()
forall (m :: * -> *).
MonadThrow m =>
ParseSettings -> ConduitT ByteString Event m ()
parseBytes ParseSettings
forall a. Default a => a
def ConduitT ByteString Event (ResourceT m) ()
-> ConduitM Event Void (ResourceT m) [Release]
-> ConduitM ByteString Void (ResourceT m) [Release]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ConduitM Event Void (ResourceT m) [Release]
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m [Release]
sinkReleases
    Release -> m Release
forall (m :: * -> *) a. Monad m => a -> m a
return (Release -> m Release) -> Release -> m Release
forall a b. (a -> b) -> a -> b
$ [Release] -> Release
forall a. [a] -> a
head [Release]
rs

sinkRecordings :: MonadThrow m => ConduitM Event Void m [Recording]
sinkRecordings :: ConduitM Event Void m [Recording]
sinkRecordings = [Char]
-> ConduitT Event Void m (Maybe [Recording])
-> ConduitM Event Void m [Recording]
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force "metadata required" (NameMatcher Name
-> ConduitM Event Void m [Recording]
-> ConduitT Event Void m (Maybe [Recording])
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}metadata" (ConduitM Event Void m [Recording]
 -> ConduitT Event Void m (Maybe [Recording]))
-> ConduitM Event Void m [Recording]
-> ConduitT Event Void m (Maybe [Recording])
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe Recording)
-> ConduitM Event Void m [Recording]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe Recording)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe Recording)
parseRecording)

sinkReleases :: MonadThrow m => ConduitM Event Void m [Release]
sinkReleases :: ConduitM Event Void m [Release]
sinkReleases = [Char]
-> ConduitT Event Void m (Maybe [Release])
-> ConduitM Event Void m [Release]
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force "metadata required" (NameMatcher Name
-> ConduitM Event Void m [Release]
-> ConduitT Event Void m (Maybe [Release])
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}metadata" (ConduitM Event Void m [Release]
 -> ConduitT Event Void m (Maybe [Release]))
-> ConduitM Event Void m [Release]
-> ConduitT Event Void m (Maybe [Release])
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe Release)
-> ConduitM Event Void m [Release]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ((Maybe (Int, Release) -> Maybe Release)
-> ConduitT Event Void m (Maybe (Int, Release))
-> ConduitT Event Void m (Maybe Release)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Int, Release) -> Release)
-> Maybe (Int, Release) -> Maybe Release
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int, Release) -> Release
forall a b. (a, b) -> b
snd) ConduitT Event Void m (Maybe (Int, Release))
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe (Int, Release))
parseRelease))

sinkReleaseList :: MonadThrow m => ConduitM Event Void m [(Int, Release)]
sinkReleaseList :: ConduitM Event Void m [(Int, Release)]
sinkReleaseList = [Char]
-> ConduitT Event Void m (Maybe [(Int, Release)])
-> ConduitM Event Void m [(Int, Release)]
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force "metadata required" (NameMatcher Name
-> AttrParser (Maybe Text)
-> (Maybe Text -> ConduitM Event Void m [(Int, Release)])
-> ConduitT Event Void m (Maybe [(Int, Release)])
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}metadata" (Name -> AttrParser (Maybe Text)
attr "created") ((Maybe Text -> ConduitM Event Void m [(Int, Release)])
 -> ConduitT Event Void m (Maybe [(Int, Release)]))
-> (Maybe Text -> ConduitM Event Void m [(Int, Release)])
-> ConduitT Event Void m (Maybe [(Int, Release)])
forall a b. (a -> b) -> a -> b
$ \_ ->
    [Char]
-> ConduitT Event Void m (Maybe [(Int, Release)])
-> ConduitM Event Void m [(Int, Release)]
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force "release-list required" (NameMatcher Name
-> AttrParser (Text, Text)
-> ((Text, Text) -> ConduitM Event Void m [(Int, Release)])
-> ConduitT Event Void m (Maybe [(Int, Release)])
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}release-list" ((Text -> Text -> (Text, Text))
-> AttrParser Text -> AttrParser Text -> AttrParser (Text, Text)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (Name -> AttrParser Text
requireAttr "count") (Name -> AttrParser Text
requireAttr "offset")) (((Text, Text) -> ConduitM Event Void m [(Int, Release)])
 -> ConduitT Event Void m (Maybe [(Int, Release)]))
-> ((Text, Text) -> ConduitM Event Void m [(Int, Release)])
-> ConduitT Event Void m (Maybe [(Int, Release)])
forall a b. (a -> b) -> a -> b
$ \_ -> ConduitT Event Void m (Maybe (Int, Release))
-> ConduitM Event Void m [(Int, Release)]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe (Int, Release))
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe (Int, Release))
parseRelease))

parseRecording :: MonadThrow m => ConduitM Event Void m (Maybe Recording)
parseRecording :: ConduitM Event Void m (Maybe Recording)
parseRecording = NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m Recording)
-> ConduitM Event Void m (Maybe Recording)
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}recording" (Name -> AttrParser Text
requireAttr "id") ((Text -> ConduitT Event Void m Recording)
 -> ConduitM Event Void m (Maybe Recording))
-> (Text -> ConduitT Event Void m Recording)
-> ConduitM Event Void m (Maybe Recording)
forall a b. (a -> b) -> a -> b
$ \rid :: Text
rid -> do
    Maybe Text
title <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}title" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
len <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}length" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe [ArtistCredit]
ncs <- NameMatcher Name
-> ConduitT Event Void m [ArtistCredit]
-> ConduitT Event Void m (Maybe [ArtistCredit])
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}artist-credit" (ConduitT Event Void m [ArtistCredit]
 -> ConduitT Event Void m (Maybe [ArtistCredit]))
-> ConduitT Event Void m [ArtistCredit]
-> ConduitT Event Void m (Maybe [ArtistCredit])
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe ArtistCredit)
-> ConduitT Event Void m [ArtistCredit]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe ArtistCredit)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ArtistCredit)
parseArtistCredit
    Recording -> ConduitT Event Void m Recording
forall (m :: * -> *) a. Monad m => a -> m a
return Recording :: MBID -> Maybe Text -> Maybe Integer -> [ArtistCredit] -> Recording
Recording { _recordingId :: MBID
_recordingId = Text -> MBID
MBID Text
rid, _recordingTitle :: Maybe Text
_recordingTitle = Maybe Text
title, _recordingLength :: Maybe Integer
_recordingLength = (Text -> Integer) -> Maybe Text -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Integer
forall a. Integral a => Text -> a
forceReadDec Maybe Text
len, _recordingArtistCredit :: [ArtistCredit]
_recordingArtistCredit = [ArtistCredit] -> Maybe [ArtistCredit] -> [ArtistCredit]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [ArtistCredit]
ncs }

parseArtistCredit :: MonadThrow m => ConduitM Event Void m (Maybe ArtistCredit)
parseArtistCredit :: ConduitM Event Void m (Maybe ArtistCredit)
parseArtistCredit = NameMatcher Name
-> AttrParser (Maybe Text)
-> (Maybe Text -> ConduitT Event Void m ArtistCredit)
-> ConduitM Event Void m (Maybe ArtistCredit)
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}name-credit" (AttrParser (Maybe Text)
buggyJoinPhrase) ((Maybe Text -> ConduitT Event Void m ArtistCredit)
 -> ConduitM Event Void m (Maybe ArtistCredit))
-> (Maybe Text -> ConduitT Event Void m ArtistCredit)
-> ConduitM Event Void m (Maybe ArtistCredit)
forall a b. (a -> b) -> a -> b
$ \mjp :: Maybe Text
mjp -> [Char]
-> ConduitM Event Void m (Maybe ArtistCredit)
-> ConduitT Event Void m ArtistCredit
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force "artist required" (NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m ArtistCredit)
-> ConduitM Event Void m (Maybe ArtistCredit)
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}artist" (Name -> AttrParser Text
requireAttr "id") ((Text -> ConduitT Event Void m ArtistCredit)
 -> ConduitM Event Void m (Maybe ArtistCredit))
-> (Text -> ConduitT Event Void m ArtistCredit)
-> ConduitM Event Void m (Maybe ArtistCredit)
forall a b. (a -> b) -> a -> b
$ \aid :: Text
aid -> do
    Maybe Text
name <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}name" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
sortName <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}sort-name" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
_ <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}disambiguation" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    let a :: Artist
a = Artist :: MBID -> Maybe Text -> Maybe Text -> Maybe Text -> Artist
Artist { _artistId :: MBID
_artistId = Text -> MBID
MBID Text
aid, _artistName :: Maybe Text
_artistName = Maybe Text
name, _artistSortName :: Maybe Text
_artistSortName = Maybe Text
sortName, _artistDisambiguation :: Maybe Text
_artistDisambiguation = Maybe Text
forall a. Maybe a
Nothing }
    ArtistCredit -> ConduitT Event Void m ArtistCredit
forall (m :: * -> *) a. Monad m => a -> m a
return ArtistCredit :: Artist -> Maybe Text -> Maybe Text -> ArtistCredit
ArtistCredit { _artistCreditArtist :: Artist
_artistCreditArtist = Artist
a, _artistCreditJoinPhrase :: Maybe Text
_artistCreditJoinPhrase = Maybe Text
mjp, _artistCreditName :: Maybe Text
_artistCreditName = Maybe Text
name }
    )

-- what's up with this
buggyJoinPhrase :: AttrParser (Maybe Text)
buggyJoinPhrase :: AttrParser (Maybe Text)
buggyJoinPhrase = (Text -> Maybe Text) -> AttrParser Text -> AttrParser (Maybe Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Maybe Text
forall a. a -> Maybe a
Just (Name -> AttrParser Text
requireAttr "{http://musicbrainz.org/ns/mmd-2.0#}joinphrase")
    AttrParser (Maybe Text)
-> AttrParser (Maybe Text) -> AttrParser (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Name -> AttrParser (Maybe Text)
attr "{http://musicbrainz.org/ns/mmd-2.0#}joinphrase" { nameNamespace :: Maybe Text
nameNamespace = Maybe Text
forall a. Maybe a
Nothing }

forceReadDec :: Integral a => Text -> a
forceReadDec :: Text -> a
forceReadDec = (\(Right (d :: a
d, _)) -> a
d) (Either [Char] (a, Text) -> a)
-> (Text -> Either [Char] (a, Text)) -> Text -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either [Char] (a, Text)
forall a. Integral a => Reader a
TR.decimal

parseRelease :: MonadThrow m => ConduitM Event Void m (Maybe (Int, Release))
parseRelease :: ConduitM Event Void m (Maybe (Int, Release))
parseRelease = NameMatcher Name
-> AttrParser (Text, Maybe Text)
-> ((Text, Maybe Text) -> ConduitT Event Void m (Int, Release))
-> ConduitM Event Void m (Maybe (Int, Release))
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}release" ((Text -> Maybe Text -> (Text, Maybe Text))
-> AttrParser Text
-> AttrParser (Maybe Text)
-> AttrParser (Text, Maybe Text)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (Name -> AttrParser Text
requireAttr "id") (Name -> AttrParser (Maybe Text)
attr "{http://musicbrainz.org/ns/ext#-2.0}score")) (((Text, Maybe Text) -> ConduitT Event Void m (Int, Release))
 -> ConduitM Event Void m (Maybe (Int, Release)))
-> ((Text, Maybe Text) -> ConduitT Event Void m (Int, Release))
-> ConduitM Event Void m (Maybe (Int, Release))
forall a b. (a -> b) -> a -> b
$ \(rid :: Text
rid,score :: Maybe Text
score) -> do
    Text
title <- [Char]
-> ConduitT Event Void m (Maybe Text) -> ConduitT Event Void m Text
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force "title required" (NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}title" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content)
    Maybe Text
status <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}status" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
quality <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}quality" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
packaging <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}packaging" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe TextRepresentation
tr <- ConduitM Event Void m (Maybe TextRepresentation)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe TextRepresentation)
parseTextRepresentation
    Maybe [ArtistCredit]
ncs <- NameMatcher Name
-> ConduitT Event Void m [ArtistCredit]
-> ConduitT Event Void m (Maybe [ArtistCredit])
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}artist-credit" (ConduitT Event Void m [ArtistCredit]
 -> ConduitT Event Void m (Maybe [ArtistCredit]))
-> ConduitT Event Void m [ArtistCredit]
-> ConduitT Event Void m (Maybe [ArtistCredit])
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe ArtistCredit)
-> ConduitT Event Void m [ArtistCredit]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe ArtistCredit)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ArtistCredit)
parseArtistCredit
    Maybe ReleaseGroup
_ <- ConduitM Event Void m (Maybe ReleaseGroup)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ReleaseGroup)
parseReleaseGroup
    Maybe Text
date <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}date" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
country <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}country" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe [ReleaseEvent]
rel <- NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m [ReleaseEvent])
-> ConduitT Event Void m (Maybe [ReleaseEvent])
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}release-event-list" (Name -> AttrParser Text
requireAttr "count") ((Text -> ConduitT Event Void m [ReleaseEvent])
 -> ConduitT Event Void m (Maybe [ReleaseEvent]))
-> (Text -> ConduitT Event Void m [ReleaseEvent])
-> ConduitT Event Void m (Maybe [ReleaseEvent])
forall a b. (a -> b) -> a -> b
$ \_ -> ConduitT Event Void m (Maybe ReleaseEvent)
-> ConduitT Event Void m [ReleaseEvent]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe ReleaseEvent)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ReleaseEvent)
parseReleaseEvent
    Maybe Text
barcode <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}barcode" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
amazonASIN <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}asin" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe CoverArtArchive
coverArtArchive <- ConduitM Event Void m (Maybe CoverArtArchive)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe CoverArtArchive)
parseCoverArtArchive
    Maybe (Maybe LabelInfo)
_ <- NameMatcher Name
-> ConduitT Event Void m (Maybe LabelInfo)
-> ConduitT Event Void m (Maybe (Maybe LabelInfo))
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}label-info-list" (ConduitT Event Void m (Maybe LabelInfo)
 -> ConduitT Event Void m (Maybe (Maybe LabelInfo)))
-> ConduitT Event Void m (Maybe LabelInfo)
-> ConduitT Event Void m (Maybe (Maybe LabelInfo))
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe LabelInfo)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe LabelInfo)
parseLabelInfo
    Maybe [Medium]
media <- NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m [Medium])
-> ConduitT Event Void m (Maybe [Medium])
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}medium-list" (Name -> AttrParser Text
requireAttr "count") ((Text -> ConduitT Event Void m [Medium])
 -> ConduitT Event Void m (Maybe [Medium]))
-> (Text -> ConduitT Event Void m [Medium])
-> ConduitT Event Void m (Maybe [Medium])
forall a b. (a -> b) -> a -> b
$ \_ -> (NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}track-count" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content ConduitT Event Void m (Maybe Text)
-> ConduitT Event Void m [Medium] -> ConduitT Event Void m [Medium]
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ConduitT Event Void m (Maybe Medium)
-> ConduitT Event Void m [Medium]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe Medium)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe Medium)
parseMedium)
    (Int, Release) -> ConduitT Event Void m (Int, Release)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> (Text -> Int) -> Maybe Text -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe 0 Text -> Int
forall a. Integral a => Text -> a
forceReadDec Maybe Text
score, Release :: MBID
-> Text
-> Maybe Text
-> Maybe Text
-> Maybe Text
-> Maybe TextRepresentation
-> [ArtistCredit]
-> Maybe Day
-> Maybe Text
-> [ReleaseEvent]
-> Maybe Text
-> Maybe Text
-> Maybe CoverArtArchive
-> Vector Medium
-> Release
Release {
        _releaseId :: MBID
_releaseId = Text -> MBID
MBID Text
rid
      , _releaseTitle :: Text
_releaseTitle = Text
title
      , _releaseStatus :: Maybe Text
_releaseStatus = Maybe Text
status
      , _releaseQuality :: Maybe Text
_releaseQuality = Maybe Text
quality
      , _releasePackaging :: Maybe Text
_releasePackaging = Maybe Text
packaging
      , _releaseTextRepresentation :: Maybe TextRepresentation
_releaseTextRepresentation = Maybe TextRepresentation
tr
      , _releaseArtistCredit :: [ArtistCredit]
_releaseArtistCredit = [ArtistCredit] -> Maybe [ArtistCredit] -> [ArtistCredit]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [ArtistCredit]
ncs
      , _releaseDate :: Maybe Day
_releaseDate = Bool -> TimeLocale -> [Char] -> [Char] -> Maybe Day
forall (m :: * -> *) t.
(MonadFail m, ParseTime t) =>
Bool -> TimeLocale -> [Char] -> [Char] -> m t
parseTimeM Bool
True TimeLocale
defaultTimeLocale "%Y-%m-%d" ([Char] -> Maybe Day) -> (Text -> [Char]) -> Text -> Maybe Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> Maybe Day) -> Maybe Text -> Maybe Day
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe Text
date
      , _releaseCountry :: Maybe Text
_releaseCountry = Maybe Text
country
      , _releaseEvents :: [ReleaseEvent]
_releaseEvents = [ReleaseEvent] -> Maybe [ReleaseEvent] -> [ReleaseEvent]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [ReleaseEvent]
rel
      , _releaseBarcode :: Maybe Text
_releaseBarcode = Maybe Text
barcode
      , _releaseASIN :: Maybe Text
_releaseASIN = Maybe Text
amazonASIN
      , _releaseCoverArtArchive :: Maybe CoverArtArchive
_releaseCoverArtArchive = Maybe CoverArtArchive
coverArtArchive
      , _releaseMedia :: Vector Medium
_releaseMedia = [Medium] -> Vector Medium
forall a. [a] -> Vector a
V.fromList ([Medium] -> Maybe [Medium] -> [Medium]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [Medium]
media)
    })

parseTextRepresentation :: MonadThrow m => ConduitM Event Void m (Maybe TextRepresentation)
parseTextRepresentation :: ConduitM Event Void m (Maybe TextRepresentation)
parseTextRepresentation = NameMatcher Name
-> ConduitT Event Void m TextRepresentation
-> ConduitM Event Void m (Maybe TextRepresentation)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}text-representation" (ConduitT Event Void m TextRepresentation
 -> ConduitM Event Void m (Maybe TextRepresentation))
-> ConduitT Event Void m TextRepresentation
-> ConduitM Event Void m (Maybe TextRepresentation)
forall a b. (a -> b) -> a -> b
$ do
    Maybe Text
lang <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}language" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
script <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}script" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    TextRepresentation -> ConduitT Event Void m TextRepresentation
forall (m :: * -> *) a. Monad m => a -> m a
return TextRepresentation :: Maybe Text -> Maybe Text -> TextRepresentation
TextRepresentation {
      _textRepLanguage :: Maybe Text
_textRepLanguage = Maybe Text
lang
    , _textRepScript :: Maybe Text
_textRepScript = Maybe Text
script
    }

parseMedium :: MonadThrow m => ConduitM Event Void m (Maybe Medium)
parseMedium :: ConduitM Event Void m (Maybe Medium)
parseMedium = NameMatcher Name
-> ConduitT Event Void m Medium
-> ConduitM Event Void m (Maybe Medium)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}medium" (ConduitT Event Void m Medium
 -> ConduitM Event Void m (Maybe Medium))
-> ConduitT Event Void m Medium
-> ConduitM Event Void m (Maybe Medium)
forall a b. (a -> b) -> a -> b
$ do
    Maybe Text
title <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}title" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
position <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}position" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
format <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}format" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Medium
mmed <- NameMatcher Name
-> AttrParser (Text, Maybe Text)
-> ((Text, Maybe Text) -> ConduitT Event Void m Medium)
-> ConduitM Event Void m (Maybe Medium)
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}track-list" ((Text -> Maybe Text -> (Text, Maybe Text))
-> AttrParser Text
-> AttrParser (Maybe Text)
-> AttrParser (Text, Maybe Text)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (Name -> AttrParser Text
requireAttr "count") (Name -> AttrParser (Maybe Text)
attr "offset")) (((Text, Maybe Text) -> ConduitT Event Void m Medium)
 -> ConduitM Event Void m (Maybe Medium))
-> ((Text, Maybe Text) -> ConduitT Event Void m Medium)
-> ConduitM Event Void m (Maybe Medium)
forall a b. (a -> b) -> a -> b
$ \(c :: Text
c,o :: Maybe Text
o) -> do -- not Just
        [Track]
tracks <- ConduitT Event Void m (Maybe Track)
-> ConduitT Event Void m [Track]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe Track)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe Track)
parseTrack
        Medium -> ConduitT Event Void m Medium
forall (m :: * -> *) a. Monad m => a -> m a
return Medium :: Maybe Text
-> Maybe Integer
-> Maybe Text
-> Integer
-> Maybe Integer
-> Maybe [Track]
-> Medium
Medium {
            _mediumTitle :: Maybe Text
_mediumTitle = Maybe Text
title
          , _mediumPosition :: Maybe Integer
_mediumPosition = (Text -> Integer) -> Maybe Text -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Integer
forall a. Integral a => Text -> a
forceReadDec Maybe Text
position
          , _mediumFormat :: Maybe Text
_mediumFormat = Maybe Text
format
          , _mediumTrackCount :: Integer
_mediumTrackCount = Text -> Integer
forall a. Integral a => Text -> a
forceReadDec Text
c
          , _mediumTrackOffset :: Maybe Integer
_mediumTrackOffset = (Text -> Integer) -> Maybe Text -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Integer
forall a. Integral a => Text -> a
forceReadDec Maybe Text
o
          , _mediumTrackList :: Maybe [Track]
_mediumTrackList = [Track] -> Maybe [Track]
forall a. a -> Maybe a
Just [Track]
tracks -- not Just
          }
    case Maybe Medium
mmed of
        Just med :: Medium
med -> Medium -> ConduitT Event Void m Medium
forall (m :: * -> *) a. Monad m => a -> m a
return Medium
med
        Nothing -> [Char] -> ConduitT Event Void m Medium
forall a. HasCallStack => [Char] -> a
error "Missing track list"

parseTrack :: MonadThrow m => ConduitM Event Void m (Maybe Track)
parseTrack :: ConduitM Event Void m (Maybe Track)
parseTrack = NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m Track)
-> ConduitM Event Void m (Maybe Track)
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}track" (Name -> AttrParser Text
requireAttr "id") ((Text -> ConduitT Event Void m Track)
 -> ConduitM Event Void m (Maybe Track))
-> (Text -> ConduitT Event Void m Track)
-> ConduitM Event Void m (Maybe Track)
forall a b. (a -> b) -> a -> b
$ \i :: Text
i -> do
    Maybe Text
position <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}position" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
number <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}number" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
len <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}length" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe [ArtistCredit]
artistcredit <- NameMatcher Name
-> ConduitT Event Void m [ArtistCredit]
-> ConduitT Event Void m (Maybe [ArtistCredit])
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}artist-credit" (ConduitT Event Void m [ArtistCredit]
 -> ConduitT Event Void m (Maybe [ArtistCredit]))
-> ConduitT Event Void m [ArtistCredit]
-> ConduitT Event Void m (Maybe [ArtistCredit])
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe ArtistCredit)
-> ConduitT Event Void m [ArtistCredit]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe ArtistCredit)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ArtistCredit)
parseArtistCredit
    Recording
recording <- [Char]
-> ConduitT Event Void m (Maybe Recording)
-> ConduitT Event Void m Recording
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force "recording required" ConduitT Event Void m (Maybe Recording)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe Recording)
parseRecording
    Track -> ConduitT Event Void m Track
forall (m :: * -> *) a. Monad m => a -> m a
return Track :: MBID
-> [ArtistCredit]
-> Maybe Integer
-> Maybe Text
-> Maybe Integer
-> Recording
-> Track
Track {
      _trackId :: MBID
_trackId = Text -> MBID
MBID Text
i
    , _trackArtistCredit :: [ArtistCredit]
_trackArtistCredit = [ArtistCredit] -> Maybe [ArtistCredit] -> [ArtistCredit]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [ArtistCredit]
artistcredit
    , _trackPosition :: Maybe Integer
_trackPosition = (Text -> Integer) -> Maybe Text -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Integer
forall a. Integral a => Text -> a
forceReadDec Maybe Text
position
    , _trackNumber :: Maybe Text
_trackNumber = Maybe Text
number
    , _trackLength :: Maybe Integer
_trackLength = (Text -> Integer) -> Maybe Text -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Integer
forall a. Integral a => Text -> a
forceReadDec Maybe Text
len
    , _trackRecording :: Recording
_trackRecording = Recording
recording
    }

parseReleaseGroup :: MonadThrow m => ConduitM Event Void m (Maybe ReleaseGroup)
parseReleaseGroup :: ConduitM Event Void m (Maybe ReleaseGroup)
parseReleaseGroup = NameMatcher Name
-> AttrParser (Text, Text)
-> ((Text, Text) -> ConduitT Event Void m ReleaseGroup)
-> ConduitM Event Void m (Maybe ReleaseGroup)
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}release-group" ((Text -> Text -> (Text, Text))
-> AttrParser Text -> AttrParser Text -> AttrParser (Text, Text)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (Name -> AttrParser Text
requireAttr "type") (Name -> AttrParser Text
requireAttr "id")) (((Text, Text) -> ConduitT Event Void m ReleaseGroup)
 -> ConduitM Event Void m (Maybe ReleaseGroup))
-> ((Text, Text) -> ConduitT Event Void m ReleaseGroup)
-> ConduitM Event Void m (Maybe ReleaseGroup)
forall a b. (a -> b) -> a -> b
$ \(t :: Text
t,i :: Text
i) -> do
    Maybe Text
title <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}title" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
frd <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}first-release-date" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
pt <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}primary-type" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe [ArtistCredit]
ncs <- NameMatcher Name
-> ConduitT Event Void m [ArtistCredit]
-> ConduitT Event Void m (Maybe [ArtistCredit])
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}artist-credit" (ConduitT Event Void m [ArtistCredit]
 -> ConduitT Event Void m (Maybe [ArtistCredit]))
-> ConduitT Event Void m [ArtistCredit]
-> ConduitT Event Void m (Maybe [ArtistCredit])
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe ArtistCredit)
-> ConduitT Event Void m [ArtistCredit]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe ArtistCredit)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ArtistCredit)
parseArtistCredit
    ReleaseGroup -> ConduitT Event Void m ReleaseGroup
forall (m :: * -> *) a. Monad m => a -> m a
return ReleaseGroup :: MBID
-> Text
-> Maybe Text
-> Maybe Text
-> Maybe Text
-> [ArtistCredit]
-> ReleaseGroup
ReleaseGroup {
      _releaseGroupId :: MBID
_releaseGroupId = Text -> MBID
MBID Text
i
    , _releaseGroupType :: Text
_releaseGroupType = Text
t
    , _releaseGroupTitle :: Maybe Text
_releaseGroupTitle = Maybe Text
title
    , _releaseGroupFirstReleaseDate :: Maybe Text
_releaseGroupFirstReleaseDate = Maybe Text
frd
    , _releaseGroupPrimaryType :: Maybe Text
_releaseGroupPrimaryType = Maybe Text
pt
    , _releaseGroupArtistCredit :: [ArtistCredit]
_releaseGroupArtistCredit = [ArtistCredit] -> Maybe [ArtistCredit] -> [ArtistCredit]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [ArtistCredit]
ncs
    }

parseLabelInfo :: MonadThrow m => ConduitM Event Void m (Maybe LabelInfo)
parseLabelInfo :: ConduitM Event Void m (Maybe LabelInfo)
parseLabelInfo = NameMatcher Name
-> ConduitT Event Void m LabelInfo
-> ConduitM Event Void m (Maybe LabelInfo)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}label-info" (ConduitT Event Void m LabelInfo
 -> ConduitM Event Void m (Maybe LabelInfo))
-> ConduitT Event Void m LabelInfo
-> ConduitM Event Void m (Maybe LabelInfo)
forall a b. (a -> b) -> a -> b
$ do
    Maybe Text
catno <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}catalog-number" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Label
label <- [Char]
-> ConduitT Event Void m (Maybe Label)
-> ConduitT Event Void m Label
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force "label required" ConduitT Event Void m (Maybe Label)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe Label)
parseLabel
    LabelInfo -> ConduitT Event Void m LabelInfo
forall (m :: * -> *) a. Monad m => a -> m a
return LabelInfo :: Maybe Text -> Label -> LabelInfo
LabelInfo {
      _labelInfoCatalogNumber :: Maybe Text
_labelInfoCatalogNumber = Maybe Text
catno
    , _labelInfoLabel :: Label
_labelInfoLabel = Label
label
    }

parseLabel :: MonadThrow m => ConduitM Event Void m (Maybe Label)
parseLabel :: ConduitM Event Void m (Maybe Label)
parseLabel = NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m Label)
-> ConduitM Event Void m (Maybe Label)
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}label" (Name -> AttrParser Text
requireAttr "id") ((Text -> ConduitT Event Void m Label)
 -> ConduitM Event Void m (Maybe Label))
-> (Text -> ConduitT Event Void m Label)
-> ConduitM Event Void m (Maybe Label)
forall a b. (a -> b) -> a -> b
$ \i :: Text
i -> do
    Maybe Text
name <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}name" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
sortname <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}sort-name" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
labelcode <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}label-code" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Label -> ConduitT Event Void m Label
forall (m :: * -> *) a. Monad m => a -> m a
return Label :: MBID -> Maybe Text -> Maybe Text -> Maybe Text -> Label
Label {
      _labelId :: MBID
_labelId = Text -> MBID
MBID Text
i
    , _labelName :: Maybe Text
_labelName = Maybe Text
name
    , _labelSortName :: Maybe Text
_labelSortName = Maybe Text
sortname
    , _labelLabelCode :: Maybe Text
_labelLabelCode = Maybe Text
labelcode
    }

parseReleaseEvent :: MonadThrow m => ConduitM Event Void m (Maybe ReleaseEvent)
parseReleaseEvent :: ConduitM Event Void m (Maybe ReleaseEvent)
parseReleaseEvent = NameMatcher Name
-> ConduitT Event Void m ReleaseEvent
-> ConduitM Event Void m (Maybe ReleaseEvent)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}release-event" (ConduitT Event Void m ReleaseEvent
 -> ConduitM Event Void m (Maybe ReleaseEvent))
-> ConduitT Event Void m ReleaseEvent
-> ConduitM Event Void m (Maybe ReleaseEvent)
forall a b. (a -> b) -> a -> b
$ do
    Maybe Text
date <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}date" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Area
area <- ConduitM Event Void m (Maybe Area)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe Area)
parseArea
    ReleaseEvent -> ConduitT Event Void m ReleaseEvent
forall (m :: * -> *) a. Monad m => a -> m a
return ReleaseEvent :: Maybe Day -> Maybe Area -> ReleaseEvent
ReleaseEvent {
      _releaseEventDate :: Maybe Day
_releaseEventDate = Bool -> TimeLocale -> [Char] -> [Char] -> Maybe Day
forall (m :: * -> *) t.
(MonadFail m, ParseTime t) =>
Bool -> TimeLocale -> [Char] -> [Char] -> m t
parseTimeM Bool
True TimeLocale
defaultTimeLocale "%Y-%m-%d" ([Char] -> Maybe Day) -> (Text -> [Char]) -> Text -> Maybe Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> Maybe Day) -> Maybe Text -> Maybe Day
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe Text
date
    , _releaseEventArea :: Maybe Area
_releaseEventArea = Maybe Area
area
    }

parseArea :: MonadThrow m => ConduitM Event Void m (Maybe Area)
parseArea :: ConduitM Event Void m (Maybe Area)
parseArea = NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m Area)
-> ConduitM Event Void m (Maybe Area)
forall (m :: * -> *) a b o c.
MonadThrow m =>
NameMatcher a
-> AttrParser b
-> (b -> ConduitT Event o m c)
-> ConduitT Event o m (Maybe c)
tag' "{http://musicbrainz.org/ns/mmd-2.0#}area" (Name -> AttrParser Text
requireAttr "id") ((Text -> ConduitT Event Void m Area)
 -> ConduitM Event Void m (Maybe Area))
-> (Text -> ConduitT Event Void m Area)
-> ConduitM Event Void m (Maybe Area)
forall a b. (a -> b) -> a -> b
$ \i :: Text
i -> do
    Maybe Text
name <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}name" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
sortname <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}sort-name" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe [ISO3166Code]
isocodes1 <- NameMatcher Name
-> ConduitT Event Void m [ISO3166Code]
-> ConduitT Event Void m (Maybe [ISO3166Code])
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}iso-3166-1-code-list" (ConduitT Event Void m [ISO3166Code]
 -> ConduitT Event Void m (Maybe [ISO3166Code]))
-> ConduitT Event Void m [ISO3166Code]
-> ConduitT Event Void m (Maybe [ISO3166Code])
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe ISO3166Code)
-> ConduitT Event Void m [ISO3166Code]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe ISO3166Code)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ISO3166Code)
parseISO3166Code
    Maybe [ISO3166Code]
isocodes2 <- NameMatcher Name
-> ConduitT Event Void m [ISO3166Code]
-> ConduitT Event Void m (Maybe [ISO3166Code])
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}iso-3166-2-code-list" (ConduitT Event Void m [ISO3166Code]
 -> ConduitT Event Void m (Maybe [ISO3166Code]))
-> ConduitT Event Void m [ISO3166Code]
-> ConduitT Event Void m (Maybe [ISO3166Code])
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe ISO3166Code)
-> ConduitT Event Void m [ISO3166Code]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe ISO3166Code)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ISO3166Code)
parseISO3166Code
    Maybe [ISO3166Code]
isocodes3 <- NameMatcher Name
-> ConduitT Event Void m [ISO3166Code]
-> ConduitT Event Void m (Maybe [ISO3166Code])
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}iso-3166-3-code-list" (ConduitT Event Void m [ISO3166Code]
 -> ConduitT Event Void m (Maybe [ISO3166Code]))
-> ConduitT Event Void m [ISO3166Code]
-> ConduitT Event Void m (Maybe [ISO3166Code])
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe ISO3166Code)
-> ConduitT Event Void m [ISO3166Code]
forall (m :: * -> *) o a.
Monad m =>
ConduitT Event o m (Maybe a) -> ConduitT Event o m [a]
many ConduitT Event Void m (Maybe ISO3166Code)
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ISO3166Code)
parseISO3166Code
    Area -> ConduitT Event Void m Area
forall (m :: * -> *) a. Monad m => a -> m a
return Area :: MBID
-> Maybe Text
-> Maybe Text
-> [ISO3166Code]
-> [ISO3166Code]
-> [ISO3166Code]
-> Area
Area {
      _areaId :: MBID
_areaId = Text -> MBID
MBID Text
i
    , _areaName :: Maybe Text
_areaName = Maybe Text
name
    , _areaSortName :: Maybe Text
_areaSortName = Maybe Text
sortname
    , _areaISO3166_1Codes :: [ISO3166Code]
_areaISO3166_1Codes = [ISO3166Code] -> Maybe [ISO3166Code] -> [ISO3166Code]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [ISO3166Code]
isocodes1
    , _areaISO3166_2Codes :: [ISO3166Code]
_areaISO3166_2Codes = [ISO3166Code] -> Maybe [ISO3166Code] -> [ISO3166Code]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [ISO3166Code]
isocodes2
    , _areaISO3166_3Codes :: [ISO3166Code]
_areaISO3166_3Codes = [ISO3166Code] -> Maybe [ISO3166Code] -> [ISO3166Code]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [ISO3166Code]
isocodes3
    }

parseISO3166Code :: MonadThrow m => ConduitM Event Void m (Maybe ISO3166Code)
parseISO3166Code :: ConduitM Event Void m (Maybe ISO3166Code)
parseISO3166Code = NameMatcher Name
-> ConduitT Event Void m ISO3166Code
-> ConduitM Event Void m (Maybe ISO3166Code)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}iso-3166-1-code" (ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content ConduitT Event Void m Text
-> (Text -> ConduitT Event Void m ISO3166Code)
-> ConduitT Event Void m ISO3166Code
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (ISO3166Code -> ConduitT Event Void m ISO3166Code
forall (m :: * -> *) a. Monad m => a -> m a
return (ISO3166Code -> ConduitT Event Void m ISO3166Code)
-> (Text -> ISO3166Code)
-> Text
-> ConduitT Event Void m ISO3166Code
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ISO3166Code
ISO3166Code))

parseCoverArtArchive :: MonadThrow m => ConduitM Event Void m (Maybe CoverArtArchive)
parseCoverArtArchive :: ConduitM Event Void m (Maybe CoverArtArchive)
parseCoverArtArchive = NameMatcher Name
-> ConduitT Event Void m CoverArtArchive
-> ConduitM Event Void m (Maybe CoverArtArchive)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}cover-art-archive" (ConduitT Event Void m CoverArtArchive
 -> ConduitM Event Void m (Maybe CoverArtArchive))
-> ConduitT Event Void m CoverArtArchive
-> ConduitM Event Void m (Maybe CoverArtArchive)
forall a b. (a -> b) -> a -> b
$ do
    Maybe Text
artwork <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}artwork" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
count <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}count" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
front <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}front" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    Maybe Text
back <- NameMatcher Name
-> ConduitT Event Void m Text -> ConduitT Event Void m (Maybe Text)
forall (m :: * -> *) a o b.
MonadThrow m =>
NameMatcher a
-> ConduitT Event o m b -> ConduitT Event o m (Maybe b)
tagNoAttr "{http://musicbrainz.org/ns/mmd-2.0#}back" ConduitT Event Void m Text
forall (m :: * -> *) o. MonadThrow m => ConduitT Event o m Text
content
    CoverArtArchive -> ConduitT Event Void m CoverArtArchive
forall (m :: * -> *) a. Monad m => a -> m a
return CoverArtArchive :: Maybe Bool
-> Maybe Integer -> Maybe Bool -> Maybe Bool -> CoverArtArchive
CoverArtArchive {
      _coverArtArchiveArtwork :: Maybe Bool
_coverArtArchiveArtwork = if Maybe Text
artwork Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Maybe Text
forall a. a -> Maybe a
Just "true" then Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True else Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
    , _coverArtArchiveCount :: Maybe Integer
_coverArtArchiveCount = (Text -> Integer) -> Maybe Text -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Integer
forall a. Integral a => Text -> a
forceReadDec Maybe Text
count
    , _coverArtArchiveFront :: Maybe Bool
_coverArtArchiveFront = if Maybe Text
front Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Maybe Text
forall a. a -> Maybe a
Just "true" then Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True else Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
    , _coverArtArchiveBack :: Maybe Bool
_coverArtArchiveBack = if Maybe Text
back Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Maybe Text
forall a. a -> Maybe a
Just "true" then Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True else Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
    }

searchReleasesByArtistAndRelease :: (MonadIO m, MonadBaseControl IO m, MonadThrow m, MonadUnliftIO m) => Text -> Text -> Maybe Int -> Maybe Int -> m [(Int, Release)]
searchReleasesByArtistAndRelease :: Text -> Text -> Maybe Int -> Maybe Int -> m [(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
    [(Int, Release)]
rs <- ConduitT () Void (ResourceT m) [(Int, Release)]
-> m [(Int, Release)]
forall (m :: * -> *) r.
MonadUnliftIO m =>
ConduitT () Void (ResourceT m) r -> m r
runConduitRes (ConduitT () Void (ResourceT m) [(Int, Release)]
 -> m [(Int, Release)])
-> ConduitT () Void (ResourceT m) [(Int, Release)]
-> m [(Int, Release)]
forall a b. (a -> b) -> a -> b
$ ByteString -> ConduitT () ByteString (ResourceT m) ()
forall (m :: * -> *) i.
Monad m =>
ByteString -> ConduitT i ByteString m ()
sourceLbs ByteString
lbs ConduitT () ByteString (ResourceT m) ()
-> ConduitM ByteString Void (ResourceT m) [(Int, Release)]
-> ConduitT () Void (ResourceT m) [(Int, Release)]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ParseSettings -> ConduitT ByteString Event (ResourceT m) ()
forall (m :: * -> *).
MonadThrow m =>
ParseSettings -> ConduitT ByteString Event m ()
parseBytes ParseSettings
forall a. Default a => a
def ConduitT ByteString Event (ResourceT m) ()
-> ConduitM Event Void (ResourceT m) [(Int, Release)]
-> ConduitM ByteString Void (ResourceT m) [(Int, Release)]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ConduitM Event Void (ResourceT m) [(Int, Release)]
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m [(Int, Release)]
sinkReleaseList
    [(Int, Release)] -> m [(Int, Release)]
forall (m :: * -> *) a. Monad m => a -> m a
return [(Int, Release)]
rs