{-# 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 :: forall (m :: * -> *).
MonadIO m =>
Text -> Text -> [Text] -> m ByteString
musicBrainzWSLookup Text
reqtype Text
param [Text]
incparams = do
    let url :: [Char]
url = [Char]
"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] -> [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 [] = [Char]
""
        incs [Text]
xs = ([Char]
"?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]] -> [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 :: forall (m :: * -> *).
MonadIO m =>
Text -> Text -> Maybe Int -> Maybe Int -> m ByteString
musicBrainzWSSearch Text
reqtype Text
query Maybe Int
mlimit Maybe Int
moffset = do
    let url :: [Char]
url = [Char]
"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]
"/?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 Maybe a
Nothing = [Char]
""
        limit (Just a
l) = [Char]
"&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 Maybe a
Nothing = [Char]
""
        offset (Just a
o) = [Char]
"&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 :: forall (m :: * -> *).
(MonadBaseControl IO m, MonadIO m, MonadThrow m,
 MonadUnliftIO m) =>
MBID -> m Recording
getRecordingById MBID
mbid = do
    ByteString
lbs <- Text -> Text -> [Text] -> m ByteString
forall (m :: * -> *).
MonadIO m =>
Text -> Text -> [Text] -> m ByteString
musicBrainzWSLookup Text
"recording" (MBID -> Text
unMBID MBID
mbid) [Text
"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) ()
-> ConduitT ByteString Void (ResourceT m) [Recording]
-> ConduitT () Void (ResourceT m) [Recording]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT 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) ()
-> ConduitT Event Void (ResourceT m) [Recording]
-> ConduitT ByteString Void (ResourceT m) [Recording]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
.| ConduitT Event Void (ResourceT m) [Recording]
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m [Recording]
sinkRecordings
    Recording -> m Recording
forall a. a -> m a
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. HasCallStack => [a] -> a
head [Recording]
rs

getReleaseById :: (MonadBaseControl IO m, MonadIO m, MonadThrow m, MonadUnliftIO m) => MBID -> m Release
getReleaseById :: forall (m :: * -> *).
(MonadBaseControl IO m, MonadIO m, MonadThrow m,
 MonadUnliftIO m) =>
MBID -> m Release
getReleaseById MBID
mbid = do
    ByteString
lbs <- Text -> Text -> [Text] -> m ByteString
forall (m :: * -> *).
MonadIO m =>
Text -> Text -> [Text] -> m ByteString
musicBrainzWSLookup Text
"release" (MBID -> Text
unMBID MBID
mbid) [Text
"recordings", Text
"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) ()
-> ConduitT ByteString Void (ResourceT m) [Release]
-> ConduitT () Void (ResourceT m) [Release]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT 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) ()
-> ConduitT Event Void (ResourceT m) [Release]
-> ConduitT ByteString Void (ResourceT m) [Release]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
.| ConduitT Event Void (ResourceT m) [Release]
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m [Release]
sinkReleases
    Release -> m Release
forall a. a -> m a
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. HasCallStack => [a] -> a
head [Release]
rs

sinkRecordings :: MonadThrow m => ConduitM Event Void m [Recording]
sinkRecordings :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m [Recording]
sinkRecordings = [Char]
-> ConduitT Event Void m (Maybe [Recording])
-> ConduitT Event Void m [Recording]
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force [Char]
"metadata required" (NameMatcher Name
-> ConduitT 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 NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}metadata" (ConduitT Event Void m [Recording]
 -> ConduitT Event Void m (Maybe [Recording]))
-> ConduitT Event Void m [Recording]
-> ConduitT Event Void m (Maybe [Recording])
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe Recording)
-> ConduitT 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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m [Release]
sinkReleases = [Char]
-> ConduitT Event Void m (Maybe [Release])
-> ConduitT Event Void m [Release]
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force [Char]
"metadata required" (NameMatcher Name
-> ConduitT 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 NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}metadata" (ConduitT Event Void m [Release]
 -> ConduitT Event Void m (Maybe [Release]))
-> ConduitT Event Void m [Release]
-> ConduitT Event Void m (Maybe [Release])
forall a b. (a -> b) -> a -> b
$ ConduitT Event Void m (Maybe Release)
-> ConduitT 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 a b.
(a -> b) -> ConduitT Event Void m a -> ConduitT Event Void m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Int, Release) -> Release)
-> Maybe (Int, Release) -> Maybe Release
forall a b. (a -> b) -> Maybe a -> Maybe b
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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m [(Int, Release)]
sinkReleaseList = [Char]
-> ConduitT Event Void m (Maybe [(Int, Release)])
-> ConduitT Event Void m [(Int, Release)]
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force [Char]
"metadata required" (NameMatcher Name
-> AttrParser (Maybe Text)
-> (Maybe Text -> ConduitT 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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}metadata" (Name -> AttrParser (Maybe Text)
attr Name
"created") ((Maybe Text -> ConduitT Event Void m [(Int, Release)])
 -> ConduitT Event Void m (Maybe [(Int, Release)]))
-> (Maybe Text -> ConduitT Event Void m [(Int, Release)])
-> ConduitT Event Void m (Maybe [(Int, Release)])
forall a b. (a -> b) -> a -> b
$ \Maybe Text
_ ->
    [Char]
-> ConduitT Event Void m (Maybe [(Int, Release)])
-> ConduitT Event Void m [(Int, Release)]
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force [Char]
"release-list required" (NameMatcher Name
-> AttrParser (Text, Text)
-> ((Text, Text) -> ConduitT 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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}release-list" ((Text -> Text -> (Text, Text))
-> AttrParser Text -> AttrParser Text -> AttrParser (Text, Text)
forall a b c.
(a -> b -> c) -> AttrParser a -> AttrParser b -> AttrParser c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (Name -> AttrParser Text
requireAttr Name
"count") (Name -> AttrParser Text
requireAttr Name
"offset")) (((Text, Text) -> ConduitT Event Void m [(Int, Release)])
 -> ConduitT Event Void m (Maybe [(Int, Release)]))
-> ((Text, Text) -> ConduitT Event Void m [(Int, Release)])
-> ConduitT Event Void m (Maybe [(Int, Release)])
forall a b. (a -> b) -> a -> b
$ \(Text, Text)
_ -> ConduitT Event Void m (Maybe (Int, Release))
-> ConduitT 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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe Recording)
parseRecording = NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m Recording)
-> ConduitT 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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}recording" (Name -> AttrParser Text
requireAttr Name
"id") ((Text -> ConduitT Event Void m Recording)
 -> ConduitT Event Void m (Maybe Recording))
-> (Text -> ConduitT Event Void m Recording)
-> ConduitT Event Void m (Maybe Recording)
forall a b. (a -> b) -> a -> b
$ \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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return 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 a b. (a -> b) -> Maybe a -> Maybe b
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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ArtistCredit)
parseArtistCredit = NameMatcher Name
-> AttrParser (Maybe Text)
-> (Maybe Text -> ConduitT Event Void m ArtistCredit)
-> ConduitT 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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}name-credit" (AttrParser (Maybe Text)
buggyJoinPhrase) ((Maybe Text -> ConduitT Event Void m ArtistCredit)
 -> ConduitT Event Void m (Maybe ArtistCredit))
-> (Maybe Text -> ConduitT Event Void m ArtistCredit)
-> ConduitT Event Void m (Maybe ArtistCredit)
forall a b. (a -> b) -> a -> b
$ \Maybe Text
mjp -> [Char]
-> ConduitT Event Void m (Maybe ArtistCredit)
-> ConduitT Event Void m ArtistCredit
forall (m :: * -> *) a.
MonadThrow m =>
[Char] -> m (Maybe a) -> m a
force [Char]
"artist required" (NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m ArtistCredit)
-> ConduitT 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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}artist" (Name -> AttrParser Text
requireAttr Name
"id") ((Text -> ConduitT Event Void m ArtistCredit)
 -> ConduitT Event Void m (Maybe ArtistCredit))
-> (Text -> ConduitT Event Void m ArtistCredit)
-> ConduitT Event Void m (Maybe ArtistCredit)
forall a b. (a -> b) -> a -> b
$ \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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 { _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 a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return 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 a b. (a -> b) -> AttrParser a -> AttrParser b
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 Name
"{http://musicbrainz.org/ns/mmd-2.0#}joinphrase")
    AttrParser (Maybe Text)
-> AttrParser (Maybe Text) -> AttrParser (Maybe Text)
forall a. AttrParser a -> AttrParser a -> AttrParser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Name -> AttrParser (Maybe Text)
attr Name
"{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 :: forall a. Integral a => Text -> a
forceReadDec = (\(Right (a
d, Text
_)) -> 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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe (Int, Release))
parseRelease = NameMatcher Name
-> AttrParser (Text, Maybe Text)
-> ((Text, Maybe Text) -> ConduitT 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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}release" ((Text -> Maybe Text -> (Text, Maybe Text))
-> AttrParser Text
-> AttrParser (Maybe Text)
-> AttrParser (Text, Maybe Text)
forall a b c.
(a -> b -> c) -> AttrParser a -> AttrParser b -> AttrParser c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (Name -> AttrParser Text
requireAttr Name
"id") (Name -> AttrParser (Maybe Text)
attr Name
"{http://musicbrainz.org/ns/ext#-2.0}score")) (((Text, Maybe Text) -> ConduitT Event Void m (Int, Release))
 -> ConduitT Event Void m (Maybe (Int, Release)))
-> ((Text, Maybe Text) -> ConduitT Event Void m (Int, Release))
-> ConduitT Event Void m (Maybe (Int, Release))
forall a b. (a -> b) -> a -> b
$ \(Text
rid,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 [Char]
"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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}release-event-list" (Name -> AttrParser Text
requireAttr Name
"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
$ \Text
_ -> 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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}medium-list" (Name -> AttrParser Text
requireAttr Name
"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
$ \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 NameMatcher Name
"{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 a b.
ConduitT Event Void m a
-> ConduitT Event Void m b -> ConduitT Event Void m b
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 a. a -> ConduitT Event Void m a
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 Int
0 Text -> Int
forall a. Integral a => Text -> a
forceReadDec Maybe Text
score, 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 [Char]
"%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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe TextRepresentation)
parseTextRepresentation = NameMatcher Name
-> ConduitT Event Void m TextRepresentation
-> ConduitT 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 NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}text-representation" (ConduitT Event Void m TextRepresentation
 -> ConduitT Event Void m (Maybe TextRepresentation))
-> ConduitT Event Void m TextRepresentation
-> ConduitT 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 NameMatcher Name
"{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 NameMatcher Name
"{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 a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return 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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe Medium)
parseMedium = NameMatcher Name
-> ConduitT Event Void m Medium
-> ConduitT 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 NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}medium" (ConduitT Event Void m Medium
 -> ConduitT Event Void m (Maybe Medium))
-> ConduitT Event Void m Medium
-> ConduitT 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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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)
-> 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' NameMatcher Name
"{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 a b c.
(a -> b -> c) -> AttrParser a -> AttrParser b -> AttrParser c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (Name -> AttrParser Text
requireAttr Name
"count") (Name -> AttrParser (Maybe Text)
attr Name
"offset")) (((Text, Maybe Text) -> ConduitT Event Void m Medium)
 -> ConduitT Event Void m (Maybe Medium))
-> ((Text, Maybe Text) -> ConduitT Event Void m Medium)
-> ConduitT Event Void m (Maybe Medium)
forall a b. (a -> b) -> a -> b
$ \(Text
c,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 a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return Medium {
            _mediumTitle :: Maybe Text
_mediumTitle = Maybe Text
title
          , _mediumPosition :: Maybe Integer
_mediumPosition = (Text -> Integer) -> Maybe Text -> Maybe Integer
forall a b. (a -> b) -> Maybe a -> Maybe b
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 a b. (a -> b) -> Maybe a -> Maybe b
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 Medium
med -> Medium -> ConduitT Event Void m Medium
forall a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return Medium
med
        Maybe Medium
Nothing -> [Char] -> ConduitT Event Void m Medium
forall a. HasCallStack => [Char] -> a
error [Char]
"Missing track list"

parseTrack :: MonadThrow m => ConduitM Event Void m (Maybe Track)
parseTrack :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe Track)
parseTrack = NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m Track)
-> ConduitT 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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}track" (Name -> AttrParser Text
requireAttr Name
"id") ((Text -> ConduitT Event Void m Track)
 -> ConduitT Event Void m (Maybe Track))
-> (Text -> ConduitT Event Void m Track)
-> ConduitT Event Void m (Maybe Track)
forall a b. (a -> b) -> a -> b
$ \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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 [Char]
"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 a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return 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 a b. (a -> b) -> Maybe a -> Maybe b
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 a b. (a -> b) -> Maybe a -> Maybe b
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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ReleaseGroup)
parseReleaseGroup = NameMatcher Name
-> AttrParser (Text, Text)
-> ((Text, Text) -> ConduitT Event Void m ReleaseGroup)
-> ConduitT 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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}release-group" ((Text -> Text -> (Text, Text))
-> AttrParser Text -> AttrParser Text -> AttrParser (Text, Text)
forall a b c.
(a -> b -> c) -> AttrParser a -> AttrParser b -> AttrParser c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (Name -> AttrParser Text
requireAttr Name
"type") (Name -> AttrParser Text
requireAttr Name
"id")) (((Text, Text) -> ConduitT Event Void m ReleaseGroup)
 -> ConduitT Event Void m (Maybe ReleaseGroup))
-> ((Text, Text) -> ConduitT Event Void m ReleaseGroup)
-> ConduitT Event Void m (Maybe ReleaseGroup)
forall a b. (a -> b) -> a -> b
$ \(Text
t,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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return 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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe LabelInfo)
parseLabelInfo = NameMatcher Name
-> ConduitT Event Void m LabelInfo
-> ConduitT 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 NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}label-info" (ConduitT Event Void m LabelInfo
 -> ConduitT Event Void m (Maybe LabelInfo))
-> ConduitT Event Void m LabelInfo
-> ConduitT 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 NameMatcher Name
"{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 [Char]
"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 a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return LabelInfo {
      _labelInfoCatalogNumber :: Maybe Text
_labelInfoCatalogNumber = Maybe Text
catno
    , _labelInfoLabel :: Label
_labelInfoLabel = Label
label
    }

parseLabel :: MonadThrow m => ConduitM Event Void m (Maybe Label)
parseLabel :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe Label)
parseLabel = NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m Label)
-> ConduitT 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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}label" (Name -> AttrParser Text
requireAttr Name
"id") ((Text -> ConduitT Event Void m Label)
 -> ConduitT Event Void m (Maybe Label))
-> (Text -> ConduitT Event Void m Label)
-> ConduitT Event Void m (Maybe Label)
forall a b. (a -> b) -> a -> b
$ \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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return 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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ReleaseEvent)
parseReleaseEvent = NameMatcher Name
-> ConduitT Event Void m ReleaseEvent
-> ConduitT 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 NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}release-event" (ConduitT Event Void m ReleaseEvent
 -> ConduitT Event Void m (Maybe ReleaseEvent))
-> ConduitT Event Void m ReleaseEvent
-> ConduitT 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 NameMatcher Name
"{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 a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return 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 [Char]
"%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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe Area)
parseArea = NameMatcher Name
-> AttrParser Text
-> (Text -> ConduitT Event Void m Area)
-> ConduitT 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' NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}area" (Name -> AttrParser Text
requireAttr Name
"id") ((Text -> ConduitT Event Void m Area)
 -> ConduitT Event Void m (Maybe Area))
-> (Text -> ConduitT Event Void m Area)
-> ConduitT Event Void m (Maybe Area)
forall a b. (a -> b) -> a -> b
$ \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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return 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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe ISO3166Code)
parseISO3166Code = 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 NameMatcher Name
"{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 a b.
ConduitT Event Void m a
-> (a -> ConduitT Event Void m b) -> ConduitT Event Void m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (ISO3166Code -> ConduitT Event Void m ISO3166Code
forall a. a -> ConduitT Event Void m a
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 :: forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m (Maybe CoverArtArchive)
parseCoverArtArchive = NameMatcher Name
-> ConduitT Event Void m CoverArtArchive
-> ConduitT 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 NameMatcher Name
"{http://musicbrainz.org/ns/mmd-2.0#}cover-art-archive" (ConduitT Event Void m CoverArtArchive
 -> ConduitT Event Void m (Maybe CoverArtArchive))
-> ConduitT Event Void m CoverArtArchive
-> ConduitT 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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 NameMatcher Name
"{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 a. a -> ConduitT Event Void m a
forall (m :: * -> *) a. Monad m => a -> m a
return 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 Text
"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 a b. (a -> b) -> Maybe a -> Maybe b
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 Text
"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 Text
"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 :: forall (m :: * -> *).
(MonadIO m, MonadBaseControl IO m, MonadThrow m,
 MonadUnliftIO m) =>
Text -> Text -> Maybe Int -> Maybe Int -> m [(Int, Release)]
searchReleasesByArtistAndRelease Text
artist Text
release Maybe Int
mlimit 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 Text
"release" ([Text] -> Text
T.concat [Text
"artist:\"", Text
artist, Text
"\" AND release:\"", Text
release, Text
"\""]) 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) ()
-> ConduitT ByteString Void (ResourceT m) [(Int, Release)]
-> ConduitT () Void (ResourceT m) [(Int, Release)]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT 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) ()
-> ConduitT Event Void (ResourceT m) [(Int, Release)]
-> ConduitT ByteString Void (ResourceT m) [(Int, Release)]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
.| ConduitT Event Void (ResourceT m) [(Int, Release)]
forall (m :: * -> *).
MonadThrow m =>
ConduitM Event Void m [(Int, Release)]
sinkReleaseList
    [(Int, Release)] -> m [(Int, Release)]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return [(Int, Release)]
rs