packages feed

liblastfm (empty) → 0.0.1.0

raw patch · 20 files changed

+2063/−0 lines, 20 filesdep +basedep +bytestringdep +curlsetup-changed

Dependencies added: base, bytestring, curl, pureMD5, urlencoded, utf8-string, xml

Files

+ LICENSE view
@@ -0,0 +1,19 @@+Copyright (C) 2012 Matvey Aksenov, Dmitry Malikov++Permission is hereby granted, free of charge, to any person obtaining a copy of+this software and associated documentation files (the "Software"), to deal in+the Software without restriction, including without limitation the rights to+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+of the Software, and to permit persons to whom the Software is furnished to do+so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ Network/Lastfm/API/Album.hs view
@@ -0,0 +1,145 @@+-- | Album API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Album+  ( addTags, getBuyLinks, getInfo, getShouts, getTags+  , getTopTags, removeTag, search, share+  ) where++import Control.Exception (throw)+import Control.Monad (void)++import Network.Lastfm.Response+import Network.Lastfm.Types ( (?<), Album, APIKey, Artist, Autocorrect, Country, Language, Limit+                            , Mbid, Message, Page, Public, Recipient, SessionKey, Tag, User)++-- | Tag an album using a list of user supplied tags.+--+-- More: <http://www.lastfm.ru/api/show/album.addTags>+addTags :: (Artist, Album) -> [Tag] -> APIKey -> SessionKey -> Lastfm ()+addTags (artist, album) tags apiKey sessionKey = dispatch go+  where go+          | null tags        = throw $ WrapperCallError method "empty tag list."+          | length tags > 10 = throw $ WrapperCallError method "tag list length has exceeded maximum."+          | otherwise        = void $ callAPI method+          [ "artist" ?< artist+          , "album" ?< album+          , "tags" ?< tags+          , "api_key" ?< apiKey+          , "sk" ?< sessionKey+          ]+          where method = "album.addTags"++-- | Get a list of Buy Links for a particular Album. It is required that you supply either the artist and track params or the mbid param.+--+-- More: <http://www.lastfm.ru/api/show/album.getBuylinks>+getBuyLinks :: Either (Artist, Album) Mbid -> Maybe Autocorrect -> Country -> APIKey -> Lastfm Response+getBuyLinks a autocorrect country apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "country" ?< country+  , "api_key" ?< apiKey+  ]+  where method = "album.getBuyLinks"+        target = case a of+                   Left (artist, album) -> ["artist" ?< artist, "album" ?< album]+                   Right mbid           -> ["mbid" ?< mbid]++-- | Get the metadata for an album on Last.fm using the album name or a musicbrainz id. See playlist.fetch on how to get the album playlist.+--+-- More: <http://www.lastfm.ru/api/show/album.getInfo>+getInfo :: Either (Artist, Album) Mbid -> Maybe Autocorrect -> Maybe Language -> Maybe User -> APIKey -> Lastfm Response+getInfo a autocorrect lang username apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "lang" ?< lang+  , "username" ?< username+  , "api_key" ?< apiKey+  ]+  where method = "album.getInfo"+        target = case a of+                   Left (artist, album) -> ["artist" ?< artist, "album" ?< album]+                   Right mbid           -> ["mbid" ?< mbid]++-- | Get shouts for this album.+--+-- More: <http://www.lastfm.ru/api/show/album.getShouts>+getShouts :: Either (Artist, Album) Mbid -> Maybe Autocorrect -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getShouts a autocorrect page limit apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]+  where method = "album.getShouts"+        target = case a of+                   Left (artist, album) -> ["artist" ?< artist, "album" ?< album]+                   Right mbid           -> ["mbid" ?< mbid]++-- | Get the tags applied by an individual user to an album on Last.fm.+--+-- More: <http://www.lastfm.ru/api/show/album.getTags>+getTags :: Either (Artist, Album) Mbid -> Maybe Autocorrect -> Either User SessionKey -> APIKey -> Lastfm Response+getTags a autocorrect b apiKey = dispatch $ callAPI method $ target ++ auth +++  [ "autocorrect" ?< autocorrect+  , "api_key" ?< apiKey+  ]+  where method = "album.getTags"+        target = case a of+                   Left (artist, album) -> ["artist" ?< artist, "album" ?< album]+                   Right mbid           -> ["mbid" ?< mbid]+        auth = case b of+                 Left user        -> ["user" ?< user]+                 Right sessionKey -> ["sk" ?< sessionKey]++-- | Get the top tags for an album on Last.fm, ordered by popularity.+--+-- More: <http://www.lastfm.ru/api/show/album.getTopTags>+getTopTags :: Either (Artist, Album) Mbid -> Maybe Autocorrect -> APIKey -> Lastfm Response+getTopTags a autocorrect apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "api_key" ?< apiKey+  ]+  where method = "album.getTopTags"+        target = case a of+                   Left (artist, album) -> ["artist" ?< artist, "album" ?< album]+                   Right mbid           -> ["mbid" ?< mbid]++-- | Remove a user's tag from an album.+--+-- More: <http://www.lastfm.ru/api/show/album.removeTag>+removeTag :: Artist -> Album -> Tag -> APIKey -> SessionKey -> Lastfm ()+removeTag artist album tag apiKey sessionKey = dispatch $ void $ callAPI "album.removeTag"+  [ "artist" ?< artist+  , "album" ?< album+  , "tag" ?< tag+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Search for an album by name. Returns album matches sorted by relevance.+--+-- More: <http://www.lastfm.ru/api/show/album.search>+search :: Album -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+search album page limit apiKey = dispatch $ callAPI "album.search"+  [ "album" ?< album+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Share an album with one or more Last.fm users or other friends.+--+-- More: <http://www.lastfm.ru/api/show/album.share>+share :: Artist -> Album -> [Recipient] -> Maybe Message -> Maybe Public -> APIKey -> SessionKey -> Lastfm ()+share artist album recipients message public apiKey sessionKey = dispatch go+  where go+          | null recipients        = throw $ WrapperCallError method "empty recipient list."+          | length recipients > 10 = throw $ WrapperCallError method "recipient list length has exceeded maximum."+          | otherwise              = void $ callAPI method+            [ "artist" ?< artist+            , "album" ?< album+            , "public" ?< public+            , "message" ?< message+            , "recipient" ?< recipients+            , "api_key" ?< apiKey+            , "sk" ?< sessionKey+            ]+            where method = "album.share"
+ Network/Lastfm/API/Artist.hs view
@@ -0,0 +1,267 @@+-- | Artist API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Artist+  ( addTags, getCorrection, getEvents, getImages, getInfo+  , getPastEvents, getPodcast, getShouts, getSimilar, getTags, getTopAlbums+  , getTopFans, getTopTags, getTopTracks, removeTag, search, share, shout+  ) where++import Control.Exception (throw)+import Control.Monad (void)++import Network.Lastfm.Response+import Network.Lastfm.Types ( (?<), APIKey, Artist, Autocorrect, FestivalsOnly, Language, Limit+                            , Mbid, Message, Order, Page, Public, Recipient, SessionKey, Tag, User+                            )++-- | Tag an album using a list of user supplied tags.+--+-- More: <http://www.lastfm.ru/api/show/artist.addTags>+addTags :: Artist -> [Tag] -> APIKey -> SessionKey -> Lastfm ()+addTags artist tags apiKey sessionKey = dispatch go+  where go+          | null tags        = throw $ WrapperCallError method "empty tag list."+          | length tags > 10 = throw $ WrapperCallError method "tag list length has exceeded maximum."+          | otherwise        = void $ callAPI method+            [ "artist" ?< artist+            , "tags" ?< tags+            , "api_key" ?< apiKey+            , "sk" ?< sessionKey+            ]+            where method = "artist.addTags"++-- | Use the last.fm corrections data to check whether the supplied artist has a correction to a canonical artist+--+-- More: <http://www.lastfm.ru/api/show/artist.getCorrection>+getCorrection :: Artist -> APIKey -> Lastfm Response+getCorrection artist apiKey = dispatch $ callAPI "artist.getCorrection"+  [ "artist" ?< artist+  , "api_key" ?< apiKey+  ]++-- | Get a list of upcoming events for this artist.+--+-- More: <http://www.lastfm.ru/api/show/artist.getEvents>+getEvents :: Either Artist Mbid -> Maybe Autocorrect -> Maybe Page -> Maybe Limit -> Maybe FestivalsOnly -> APIKey -> Lastfm Response+getEvents a autocorrect page limit festivalsOnly apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "page" ?< page+  , "limit" ?< limit+  , "festivalsonly" ?< festivalsOnly+  , "api_key" ?< apiKey+  ]+  where method = "artist.getEvents"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]++-- | Get Images for this artist in a variety of sizes.+--+-- More: <http://www.lastfm.ru/api/show/artist.getImages>+getImages :: Either Artist Mbid -> Maybe Autocorrect -> Maybe Page -> Maybe Limit -> Maybe Order -> APIKey -> Lastfm Response+getImages a autocorrect page limit order apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "page" ?< page+  , "limit" ?< limit+  , "order" ?< order+  , "api_key" ?< apiKey+  ]+  where method = "artist.getImages"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]++-- | Get the metadata for an artist. Includes biography.+--+-- More: <http://www.lastfm.ru/api/show/artist.getInfo>+getInfo :: Either Artist Mbid -> Maybe Autocorrect -> Maybe Language -> Maybe User -> APIKey -> Lastfm Response+getInfo a autocorrect language user apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "lang" ?< language+  , "username" ?< user+  , "api_key" ?< apiKey+  ]+  where method = "artist.getInfo"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]++-- | Get a paginated list of all the events this artist has played at in the past.+--+-- More: <http://www.lastfm.ru/api/show/artist.getPastEvents>+getPastEvents :: Either Artist Mbid -> Maybe Autocorrect -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getPastEvents a autocorrect page limit apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]+  where method = "artist.getPastEvents"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]++-- | Get a podcast of free mp3s based on an artist.+--+-- More: <http://www.lastfm.ru/api/show/artist.getPodcast>+getPodcast :: Either Artist Mbid -> Maybe Autocorrect -> APIKey -> Lastfm Response+getPodcast a autocorrect apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "api_key" ?< apiKey+  ]+  where method = "artist.getPodcast"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]++-- | Get shouts for this artist. Also available as an rss feed.+--+-- More: <http://www.lastfm.ru/api/show/artist.getShouts>+getShouts :: Either Artist Mbid -> Maybe Autocorrect -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getShouts a autocorrect page limit apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]+  where method = "artist.getShouts"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]++-- | Get all the artists similar to this artist.+--+-- More: <http://www.lastfm.ru/api/show/artist.getSimilar>+getSimilar :: Either Artist Mbid -> Maybe Autocorrect -> Maybe Limit -> APIKey -> Lastfm Response+getSimilar a autocorrect limit apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]+  where method = "artist.getSimilar"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]++-- | Get the tags applied by an individual user to an artist on Last.fm. If accessed as an authenticated service /and/ you don't supply a user parameter then this service will return tags for the authenticated user.+--+-- More: <http://www.lastfm.ru/api/show/artist.getTags>+getTags :: Either Artist Mbid -> Maybe Autocorrect -> Either User SessionKey -> APIKey -> Lastfm Response+getTags a autocorrect b apiKey = dispatch $ callAPI method $ target ++ auth +++  [ "autocorrect" ?< autocorrect+  , "api_key" ?< apiKey+  ]+  where method = "artist.getTags"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]+        auth = case b of+                 Left user        -> ["user" ?< user]+                 Right sessionKey -> ["sk" ?< sessionKey]++-- | Get the top albums for an artist on Last.fm, ordered by popularity.+--+-- More: <http://www.lastfm.ru/api/show/artist.getTopAlbums>+getTopAlbums :: Either Artist Mbid -> Maybe Autocorrect -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopAlbums a autocorrect page limit apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]+  where method = "artist.getTopAlbums"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]++-- | Get the top fans for an artist on Last.fm, based on listening data.+--+-- More: <http://www.lastfm.ru/api/show/artist.getTopFans>+getTopFans :: Either Artist Mbid -> Maybe Autocorrect -> APIKey -> Lastfm Response+getTopFans a autocorrect apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "api_key" ?< apiKey+  ]+  where method = "artist.getTopFans"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]++-- | Get the top tags for an artist on Last.fm, ordered by popularity.+--+-- More: <http://www.lastfm.ru/api/show/artist.getTopTags>+getTopTags :: Either Artist Mbid -> Maybe Autocorrect -> APIKey -> Lastfm Response+getTopTags a autocorrect apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "api_key" ?< apiKey+  ]+  where method = "artist.getTopTags"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]++-- | Get the top tracks by an artist on Last.fm, ordered by popularity.+--+-- More: <http://www.lastfm.ru/api/show/artist.getTopTracks>+getTopTracks :: Either Artist Mbid -> Maybe Autocorrect -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopTracks a autocorrect page limit apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]+  where method = "artist.getTopTracks"+        target = case a of+                   Left artist -> ["artist" ?< artist]+                   Right mbid  -> ["mbid" ?< mbid]++-- | Remove a user's tag from an artist.+--+-- More: <http://www.lastfm.ru/api/show/artist.removeTag>+removeTag :: Artist -> Tag -> APIKey -> SessionKey -> Lastfm ()+removeTag artist tag apiKey sessionKey = dispatch $ void $ callAPI "artist.removeTag"+  [ "artist" ?< artist+  , "tag" ?< tag+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Search for an artist by name. Returns artist matches sorted by relevance.+--+-- More: <http://www.lastfm.ru/api/show/artist.search>+search :: Artist -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+search artist page limit apiKey = dispatch $ callAPI "artist.search"+  [ "artist" ?< artist+  , "api_key" ?< apiKey+  , "page" ?< page+  , "limit" ?< limit+  ]++-- | Share an artist with Last.fm users or other friends.+--+-- More: <http://www.lastfm.ru/api/show/artist.share>+share :: Artist -> [Recipient] -> Maybe Message -> Maybe Public -> APIKey -> SessionKey -> Lastfm ()+share artist recipients message public apiKey sessionKey = dispatch go+  where go+          | null recipients        = throw $ WrapperCallError method "empty recipient list."+          | length recipients > 10 = throw $ WrapperCallError method "recipient list length has exceeded maximum."+          | otherwise              = void $ callAPI method+            [ "artist" ?< artist+            , "recipient" ?< recipients+            , "api_key" ?< apiKey+            , "sk" ?< sessionKey+            , "public" ?< public+            , "message" ?< message+            ]+            where method = "artist.share"++-- | Shout in this artist's shoutbox.+--+-- More: <http://www.lastfm.ru/api/show/artist.shout>+shout :: Artist -> Message -> APIKey -> SessionKey -> Lastfm ()+shout artist message apiKey sessionKey = dispatch $ void $ callAPI "artist.shout"+  [ "artist" ?< artist+  , "message" ?< message+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]
+ Network/Lastfm/API/Auth.hs view
@@ -0,0 +1,38 @@+-- | Auth API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Auth+  ( getMobileSession, getSession, getToken+  , getAuthorizeTokenLink+  ) where++import Control.Applicative ((<$>))+import Control.Monad ((<=<), liftM)++import Network.Lastfm.Response+import Network.Lastfm.Types ((?<), APIKey, AuthToken, SessionKey(..), Token(..), User, unpack)++-- | Create a web service session for a user. Used for authenticating a user when the password can be inputted by the user. Only suitable for standalone mobile devices.+--+-- More: <http://www.lastfm.ru/api/show/auth.getMobileSession>+getMobileSession :: User -> APIKey -> AuthToken -> Lastfm Response+getMobileSession user apiKey token = dispatch $ callAPI "auth.getMobileSession"+  [ "username" ?< user+  , "authToken" ?< token+  , "api_key" ?< apiKey+  ]++-- | Fetch a session key for a user.+--+-- More: <http://www.lastfm.ru/api/show/auth.getSession>+getSession :: APIKey -> Token -> Lastfm Response+getSession apiKey token = dispatch $ callAPI "auth.getSession" ["api_key" ?< apiKey, "token" ?< token]++-- | Fetch an unathorized request token for an API account.+--+-- More: <http://www.lastfm.ru/api/show/auth.getToken>+getToken :: APIKey -> Lastfm Response+getToken apiKey = dispatch $ callAPI "auth.getToken" ["api_key" ?< apiKey]++-- | Construct the link to authorize token.+getAuthorizeTokenLink :: APIKey -> Token -> String+getAuthorizeTokenLink apiKey token = "http://www.last.fm/api/auth/?api_key=" ++ unpack apiKey ++ "&token=" ++ unpack token
+ Network/Lastfm/API/Chart.hs view
@@ -0,0 +1,52 @@+-- | Chart API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Chart+  ( getHypedArtists, getHypedTracks, getLovedTracks+  , getTopArtists, getTopTags, getTopTracks+  ) where++import Network.Lastfm.Response+import Network.Lastfm.Types ((?<), APIKey, Limit, Page)++-- | Get the hyped artists chart.+--+-- More: <http://www.lastfm.ru/api/show/chart.getHypedArtists>+getHypedArtists :: Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getHypedArtists = get "getHypedArtists"++-- | Get the hyped tracks chart.+--+-- More: <http://www.lastfm.ru/api/show/chart.getHypedTracks>+getHypedTracks :: Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getHypedTracks = get "getHypedTracks"++-- | Get the most loved tracks chart.+--+-- More: <http://www.lastfm.ru/api/show/chart.getLovedTracks>+getLovedTracks :: Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getLovedTracks = get "getLovedTracks"++-- | Get the top artists chart.+--+-- More: <http://www.lastfm.ru/api/show/chart.getTopArtists>+getTopArtists :: Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopArtists = get "getTopArtists"++-- | Get top tags chart.+--+-- More: <http://www.lastfm.ru/api/show/chart.getTopTags>+getTopTags :: Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopTags = get "getTopTags"++-- | Get the top tracks chart.+--+-- More: <http://www.lastfm.ru/api/show/chart.getTopTracks>+getTopTracks :: Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopTracks = get "getTopTracks"++get :: String -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+get method page limit apiKey = dispatch $ callAPI ("chart." ++ method)+  [ "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]
+ Network/Lastfm/API/Event.hs view
@@ -0,0 +1,84 @@+-- | Event API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Event+  ( attend, getAttendees, getInfo, getShouts, share, shout+  ) where++import Control.Exception (throw)+import Control.Monad (void)++import Network.Lastfm.Response+import Network.Lastfm.Types ( (?<), APIKey, Event, Limit, Message, Page+                            , Public, Recipient, SessionKey, Status+                            )++-- | Set a user's attendance status for an event.+--+-- More: <http://www.lastfm.ru/api/show/event.attend>+attend :: Event -> Status -> APIKey -> SessionKey -> Lastfm ()+attend event status apiKey sessionKey = dispatch $ void $ callAPI "event.attend"+  [ "event" ?< event+  , "status" ?< status+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Get a list of attendees for an event.+--+-- More: <http://www.lastfm.ru/api/show/event.getAttendees>+getAttendees :: Event -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getAttendees event page limit apiKey = dispatch $ callAPI "event.getAttendees"+  [ "event" ?< event+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get the metadata for an event on Last.fm. Includes attendance and lineup information.+--+-- More: <http://www.lastfm.ru/api/show/event.getInfo>+getInfo :: Event -> APIKey -> Lastfm Response+getInfo event apiKey = dispatch $ callAPI "event.getInfo"+  [ "event" ?< event+  , "api_key" ?< apiKey+  ]++-- | Get shouts for this event.+--+-- More: <http://www.lastfm.ru/api/show/event.getShouts>+getShouts :: Event -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getShouts event page limit apiKey = dispatch $ callAPI "event.getShouts"+  [ "event" ?< event+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Share an event with one or more Last.fm users or other friends.+--+-- More: <http://www.lastfm.ru/api/show/event.share>+share :: Event -> [Recipient] -> Maybe Message -> Maybe Public -> APIKey -> SessionKey -> Lastfm ()+share event recipients message public apiKey sessionKey = dispatch go+  where go+          | null recipients        = throw $ WrapperCallError method "empty recipient list."+          | length recipients > 10 = throw $ WrapperCallError method "recipient list length has exceeded maximum."+          | otherwise              = void $ callAPI method+            [ "event" ?< event+            , "public" ?< public+            , "message" ?< message+            , "recipient" ?< recipients+            , "api_key" ?< apiKey+            , "sk" ?< sessionKey+            ]+            where method = "event.share"++-- | Shout in this event's shoutbox.+--+-- More: <http://www.lastfm.ru/api/show/event.shout>+shout :: Event -> Message -> APIKey -> SessionKey -> Lastfm ()+shout event message apiKey sessionKey = dispatch $ void $ callAPI "event.shout"+  [ "event" ?< event+  , "message" ?< message+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]
+ Network/Lastfm/API/Geo.hs view
@@ -0,0 +1,116 @@+-- | Geo API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Geo+  ( getEvents, getMetroArtistChart, getMetroHypeArtistChart, getMetroHypeTrackChart+  , getMetroTrackChart, getMetroUniqueArtistChart, getMetroUniqueTrackChart+  , getMetroWeeklyChartlist, getMetros, getTopArtists, getTopTracks+  ) where++import Network.Lastfm.Response+import Network.Lastfm.Types ( (?<), APIKey, Country, Distance, From, Latitude+                            , Limit, Location, Longitude, Metro, Page, To+                            )++-- | Get all events in a specific location by country or city name.+--+-- More: <http://www.lastfm.ru/api/show/geo.getEvents>+getEvents :: Maybe Latitude+          -> Maybe Longitude+          -> Maybe Location+          -> Maybe Distance+          -> Maybe Page+          -> Maybe Limit+          -> APIKey+          -> Lastfm Response+getEvents latitude longitude location distance page limit apiKey = dispatch $ callAPI "geo.getEvents"+  [ "lat" ?< latitude+  , "long" ?< longitude+  , "location" ?< location+  , "distance" ?< distance+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get a chart of artists for a metro.+--+-- More: <http://www.lastfm.ru/api/show/geo.getMetroArtistChart>+getMetroArtistChart :: Country -> Metro -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getMetroArtistChart = getMetroChart "geo.getMetroArtistChart"++-- | Get a chart of hyped (up and coming) artists for a metro.+--+-- More: <http://www.lastfm.ru/api/show/geo.getMetroHypeArtistChart>+getMetroHypeArtistChart :: Country -> Metro -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getMetroHypeArtistChart = getMetroChart "geo.getMetroHypeArtistChart"++-- | Get a chart of hyped (up and coming) tracks for a metro.+--+-- More: <http://www.lastfm.ru/api/show/geo.getMetroHypeTrackChart>+getMetroHypeTrackChart :: Country -> Metro -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getMetroHypeTrackChart = getMetroChart "geo.getMetroHypeTrackChart"++-- | Get a chart of tracks for a metro.+--+-- More: <http://www.lastfm.ru/api/show/geo.getMetroTrackChart>+getMetroTrackChart :: Country -> Metro -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getMetroTrackChart = getMetroChart "geo.getMetroTrackChart"++-- | Get a chart of the artists which make that metro unique.+--+-- More: <http://www.lastfm.ru/api/show/geo.getMetroUniqueArtistChart>+getMetroUniqueArtistChart :: Country -> Metro -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getMetroUniqueArtistChart = getMetroChart "geo.getMetroUniqueArtistChart"++-- | Get a chart of the tracks which make that metro unique.+--+-- More: <http://www.lastfm.ru/api/show/geo.getMetroUniqueTrackChart>+getMetroUniqueTrackChart :: Country -> Metro -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getMetroUniqueTrackChart = getMetroChart "geo.getMetroUniqueTrackChart"++-- | Get a list of available chart periods for this metro, expressed as date ranges which can be sent to the chart services.+--+-- More: <http://www.lastfm.ru/api/show/geo.getMetroWeeklyChartlist>+getMetroWeeklyChartlist :: Metro -> APIKey -> Lastfm Response+getMetroWeeklyChartlist metro apiKey = dispatch $ callAPI "geo.getMetroWeeklyChartlist" ["metro" ?< metro, "api_key" ?< apiKey]++-- | Get a list of valid countries and metros for use in the other webservices.+--+-- More: <http://www.lastfm.ru/api/show/geo.getMetros>+getMetros :: Maybe Country -> APIKey -> Lastfm Response+getMetros country apiKey = dispatch $ callAPI "geo.getMetros"+  [ "country" ?< country+  , "api_key" ?< apiKey+  ]++-- | Get the most popular artists on Last.fm by country.+--+-- More: <http://www.lastfm.ru/api/show/geo.getTopArtists>+getTopArtists :: Country -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopArtists country page limit apiKey = dispatch $ callAPI "geo.getTopArtists"+  [ "country" ?< country+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get the most popular tracks on Last.fm last week by country.+--+-- More: <http://www.lastfm.ru/api/show/geo.getTopTracks>+getTopTracks :: Country -> Maybe Location -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopTracks country location page limit apiKey = dispatch $ callAPI "geo.getTopTracks"+  [ "country" ?< country+  , "location" ?< location+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++getMetroChart :: String -> Country -> Metro -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getMetroChart method country metro from to apiKey = dispatch $ callAPI method+  [ "country" ?< country+  , "metro" ?< metro+  , "start" ?< from+  , "end" ?< to+  , "api_key" ?< apiKey+  ]
+ Network/Lastfm/API/Group.hs view
@@ -0,0 +1,68 @@+-- | Group API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Group+  ( getHype, getMembers, getWeeklyChartList, getWeeklyAlbumChart, getWeeklyArtistChart, getWeeklyTrackChart+  ) where++import Network.Lastfm.Response+import Network.Lastfm.Types ((?<), APIKey, From, Group, Limit, Page, To)++-- | Get the hype list for a group.+--+-- More: <http://www.lastfm.ru/api/show/group.getHype>+getHype :: Group -> APIKey -> Lastfm Response+getHype group apiKey = dispatch $ callAPI "group.getHype"+  [ "group" ?< group+  , "api_key" ?< apiKey+  ]++-- | Get a list of members for this group.+--+-- More: <http://www.lastfm.ru/api/show/group.getMembers>+getMembers :: Group -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getMembers group page limit apiKey = dispatch $ callAPI "group.getMembers"+  [ "group" ?< group+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get an album chart for a group, for a given date range. If no date range is supplied, it will return the most recent album chart for this group.+--+-- More: <http://www.lastfm.ru/api/show/group.getWeeklyAlbumChart>+getWeeklyChartList :: Group -> APIKey -> Lastfm Response+getWeeklyChartList group apiKey = dispatch $ callAPI "group.getWeeklyChartList" ["group" ?< group, "api_key" ?< apiKey]++-- | Get an artist chart for a group, for a given date range. If no date range is supplied, it will return the most recent artist chart for this group.+--+-- More: <http://www.lastfm.ru/api/show/group.getWeeklyArtistChart>+getWeeklyAlbumChart :: Group -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getWeeklyAlbumChart group from to apiKey = dispatch $ callAPI "group.getWeeklyAlbumChart"+  [ "group" ?< group+  , "api_key" ?< apiKey+  , "from" ?< from+  , "to" ?< to+  ]++-- | Get a list of available charts for this group, expressed as date ranges which can be sent to the chart services.+--+-- More: <http://www.lastfm.ru/api/show/group.getWeeklyChartList>+getWeeklyArtistChart :: Group -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getWeeklyArtistChart group from to apiKey = dispatch $ callAPI "group.getWeeklyArtistChart"+  [ "group" ?< group+  , "api_key" ?< apiKey+  , "from" ?< from+  , "to" ?< to+  ]+++-- | Get a track chart for a group, for a given date range. If no date range is supplied, it will return the most recent track chart for this group.+--+-- More: <http://www.lastfm.ru/api/show/group.getWeeklyTrackChart>+getWeeklyTrackChart :: Group -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getWeeklyTrackChart group from to apiKey = dispatch $ callAPI "group.getWeeklyTrackChart"+  [ "group" ?< group+  , "api_key" ?< apiKey+  , "from" ?< from+  , "to" ?< to+  ]
+ Network/Lastfm/API/Library.hs view
@@ -0,0 +1,123 @@+-- | Library API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Library+  ( addAlbum, addArtist, addTrack, getAlbums, getArtists, getTracks+  , removeAlbum, removeArtist, removeScrobble, removeTrack+  ) where++import Control.Monad (void)++import Network.Lastfm.Response+import Network.Lastfm.Types ((?<), Album, APIKey, Artist, Limit, Page, SessionKey, Timestamp, Track, User)++-- | Add an album or collection of albums to a user's Last.fm library.+--+-- More: <http://www.lastfm.ru/api/show/library.addAlbum>+addAlbum :: Artist -> Album -> APIKey -> SessionKey -> Lastfm ()+addAlbum artist album apiKey sessionKey = dispatch $ void $ callAPI "library.addAlbum"+  [ "artist" ?< artist+  , "album" ?< album+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Add an artist to a user's Last.fm library.+--+-- More: <http://www.lastfm.ru/api/show/library.addArtist>+addArtist :: Artist -> APIKey -> SessionKey -> Lastfm ()+addArtist artist apiKey sessionKey = dispatch $ void $ callAPI "library.addArtist"+  [ "artist" ?< artist+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Add a track to a user's Last.fm library.+--+-- More: <http://www.lastfm.ru/api/show/library.addTrack>+addTrack :: Artist -> Track -> APIKey -> SessionKey -> Lastfm ()+addTrack artist track apiKey sessionKey = dispatch $ void $ callAPI "library.addTrack"+  [ "artist" ?< artist+  , "track" ?< track+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | A paginated list of all the albums in a user's library, with play counts and tag counts.+--+-- More: <http://www.lastfm.ru/api/show/library.getAlbums>+getAlbums :: User -> Maybe Artist -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getAlbums user artist page limit apiKey = dispatch $ callAPI "library.getAlbums"+  [ "user" ?< user+  , "artist" ?< artist+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | A paginated list of all the artists in a user's library, with play counts and tag counts.+--+-- More: <http://www.lastfm.ru/api/show/library.getArtists>+getArtists :: User -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getArtists user page limit apiKey = dispatch $ callAPI "library.getArtists"+  [ "user" ?< user+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | A paginated list of all the tracks in a user's library, with play counts and tag counts.+--+-- More: <http://www.lastfm.ru/api/show/library.getTracks>+getTracks :: User -> Maybe Artist -> Maybe Album -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTracks user artist album page limit apiKey = dispatch $ callAPI "library.getTracks"+  [ "user" ?< user+  , "artist" ?< artist+  , "album" ?< album+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Remove an album from a user's Last.fm library.+--+-- More: <http://www.lastfm.ru/api/show/library.removeAlbum>+removeAlbum :: Artist -> Album -> APIKey -> SessionKey -> Lastfm ()+removeAlbum artist album apiKey sessionKey = dispatch $ void $ callAPI "library.removeAlbum"+  [ "artist" ?< artist+  , "album" ?< album+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Remove an artist from a user's Last.fm library.+--+-- More: <http://www.lastfm.ru/api/show/library.removeArtist>+removeArtist :: Artist -> APIKey -> SessionKey -> Lastfm ()+removeArtist artist apiKey sessionKey = dispatch $ void $ callAPI "library.removeArtist"+  [ "artist" ?< artist+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Remove a scrobble from a user's Last.fm library.+--+-- More: <http://www.lastfm.ru/api/show/library.removeScrobble>+removeScrobble :: Artist -> Track -> Timestamp -> APIKey -> SessionKey -> Lastfm ()+removeScrobble artist track timestamp apiKey sessionKey = dispatch $ void $ callAPI "library.removeScrobble"+  [ "artist" ?< artist+  , "track" ?< track+  , "timestamp" ?< timestamp+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Remove a track from a user's Last.fm library.+--+-- More: <http://www.lastfm.ru/api/show/library.removeTrack>+removeTrack :: Artist -> Track -> APIKey -> SessionKey -> Lastfm ()+removeTrack artist track apiKey sessionKey = dispatch $ void $ callAPI "library.removeTrack"+  [ "artist" ?< artist+  , "track" ?< track+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]
+ Network/Lastfm/API/Playlist.hs view
@@ -0,0 +1,33 @@+-- | Playlist API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Playlist+  ( addTrack, create+  ) where++import Control.Monad (void)++import Network.Lastfm.Response+import Network.Lastfm.Types ((?<), APIKey, Artist, Playlist, SessionKey, Title, Description, Track)++-- | Add a track to a Last.fm user's playlist.+--+-- More: <http://www.lastfm.ru/api/show/playlist.addTrack>+addTrack :: Playlist -> Artist -> Track -> APIKey -> SessionKey -> Lastfm ()+addTrack playlist artist track apiKey sessionKey = dispatch $ void $ callAPI "playlist.addTrack"+  [ "playlistID" ?< playlist+  , "artist" ?< artist+  , "track" ?< track+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Create a Last.fm playlist on behalf of a user.+--+-- More: <http://www.lastfm.ru/api/show/playlist.create>+create :: Maybe Title -> Maybe Description -> APIKey -> SessionKey -> Lastfm ()+create title description apiKey sessionKey = dispatch $ void $ callAPI "playlist.create"+  [ "api_key" ?< apiKey+  , "sk" ?< sessionKey+  , "title" ?< title+  , "description" ?< description+  ]
+ Network/Lastfm/API/Radio.hs view
@@ -0,0 +1,58 @@+-- | Radio API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Radio+  ( getPlaylist, search, tune+  ) where++import Control.Exception (throw)++import Network.Lastfm.Response+import Network.Lastfm.Types ( (?<), APIKey, Bitrate, BuyLinks, Discovery, Language+                            , Multiplier, Name, RTP, Station, SessionKey, unpack+                            )++-- | Fetch new radio content periodically in an XSPF format.+--+-- More: <http://www.lastfm.ru/api/show/radio.getPlaylist>+getPlaylist :: Maybe Discovery+            -> Maybe RTP+            -> Maybe BuyLinks+            -> Multiplier+            -> Bitrate+            -> APIKey+            -> SessionKey+            -> Lastfm Response+getPlaylist discovery rtp buylinks multiplier bitrate apiKey sessionKey = dispatch go+  where go+          | unpack multiplier /= "1.0" && unpack multiplier /= "2.0" = throw $ WrapperCallError method "unsupported multiplier."+          | unpack bitrate /= "64" && unpack bitrate /= "128" = throw $ WrapperCallError method "unsupported bitrate."+          | otherwise = callAPI method+            [ "discovery" ?< discovery+            , "rtp" ?< rtp+            , "buylinks" ?< buylinks+            , "speed_multiplier" ?< multiplier+            , "bitrate" ?< bitrate+            , "api_key" ?< apiKey+            , "sk" ?< sessionKey+            ]+            where method = "radio.getPlaylist"++-- | Resolve the name of a resource into a station depending on which resource it is most likely to represent.+--+-- More: <http://www.lastfm.ru/api/show/radio.search>+search :: Name -> APIKey -> Lastfm Response+search name apiKey = dispatch $ callAPI "radio.search"+  [ "name" ?< name+  , "api_key" ?< apiKey+  ]++-- | Tune in to a Last.fm radio station.+--+-- More: <http://www.lastfm.ru/api/show/radio.tune>+tune :: Maybe Language -> Station -> APIKey -> SessionKey -> Lastfm Response+tune language station apiKey sessionKey = dispatch $ callAPI "radio.tune"+  [ "lang" ?< language+  , "station" ?< station+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]
+ Network/Lastfm/API/Tag.hs view
@@ -0,0 +1,99 @@+-- | Tag API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Tag+  ( getInfo, getSimilar, getTopAlbums, getTopArtists, getTopTags, getTopTracks+  , getWeeklyArtistChart, getWeeklyChartList, search+  ) where++import Network.Lastfm.Response+import Network.Lastfm.Types ((?<), APIKey, From, Language, Limit, Page, Tag, To)++-- | Get the metadata for a tag.+--+-- More: <http://www.lastfm.ru/api/show/tag.getInfo>+getInfo :: Tag -> Maybe Language -> APIKey -> Lastfm Response+getInfo tag language apiKey = dispatch $ callAPI "tag.getInfo"+  [ "tag" ?< tag+  , "lang" ?< language+  , "api_key" ?< apiKey+  ]++-- | Search for tags similar to this one. Returns tags ranked by similarity, based on listening data.+--+-- More: <http://www.lastfm.ru/api/show/tag.getSimilar>+getSimilar :: Tag -> APIKey -> Lastfm Response+getSimilar tag apiKey = dispatch $ callAPI "tag.getSimilar"+  [ "tag" ?< tag+  , "api_key" ?< apiKey+  ]++-- | Get the top albums tagged by this tag, ordered by tag count.+--+-- More: <http://www.lastfm.ru/api/show/tag.getTopAlbums>+getTopAlbums :: Tag -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopAlbums tag page limit apiKey = dispatch $ callAPI "tag.getTopAlbums"+  [ "tag" ?< tag+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get the top artists tagged by this tag, ordered by tag count.+--+-- More: <http://www.lastfm.ru/api/show/tag.getTopArtists>+getTopArtists :: Tag -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopArtists tag limit page apiKey = dispatch $ callAPI "tag.getTopArtists"+  [ "tag" ?< tag+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Fetches the top global tags on Last.fm, sorted by popularity (number of times used).+--+-- More: <http://www.lastfm.ru/api/show/tag.getTopTags>+getTopTags :: APIKey -> Lastfm Response+getTopTags apiKey = dispatch $ callAPI "tag.getTopArtists" ["api_key" ?< apiKey]++-- | Get the top tracks tagged by this tag, ordered by tag count.+--+-- More: <http://www.lastfm.ru/api/show/tag.getTopTracks>+getTopTracks :: Tag -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopTracks tag limit page apiKey = dispatch $ callAPI "tag.getTopTracks"+  [ "tag" ?< tag+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get an artist chart for a tag, for a given date range. If no date range is supplied, it will return the most recent artist chart for this tag.+--+-- More: <http://www.lastfm.ru/api/show/tag.getWeeklyArtistChart>+getWeeklyArtistChart :: Tag -> Maybe From -> Maybe To -> Maybe Limit -> APIKey -> Lastfm Response+getWeeklyArtistChart tag from to limit apiKey = dispatch $ callAPI "tag.getWeeklyArtistChart"+  [ "tag" ?< tag+  , "from" ?< from+  , "to" ?< to+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get a list of available charts for this tag, expressed as date ranges which can be sent to the chart services.+--+-- More: <http://www.lastfm.ru/api/show/tag.getWeeklyChartList>+getWeeklyChartList :: Tag -> APIKey -> Lastfm Response+getWeeklyChartList tag apiKey = dispatch $ callAPI "tag.getWeeklyChartList"+  [ "tag" ?< tag+  , "api_key" ?< apiKey+  ]++-- | Search for a tag by name. Returns matches sorted by relevance.+--+-- More: <http://www.lastfm.ru/api/show/tag.search>+search :: Tag -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+search tag page limit apiKey = dispatch $ callAPI "tag.search"+  [ "tag" ?< tag+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]
+ Network/Lastfm/API/Tasteometer.hs view
@@ -0,0 +1,42 @@+-- | Tasteometer API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Tasteometer+  ( compare+  ) where++import Control.Exception (throw)+import Prelude hiding (compare)++import Network.Lastfm.Response+import Network.Lastfm.Types ((?<), APIKey, Limit, Value(..))++-- | Get a Tasteometer score from two inputs, along with a list of shared artists. If the input is a User some additional information is returned.+--+-- More: <http://www.lastfm.ru/api/show/tasteometer.compare>+compare :: Value -> Value -> Maybe Limit -> APIKey -> Lastfm Response+compare value1 value2 limit apiKey = dispatch go+  where go+          | isNull value1 = throw $ WrapperCallError method "empty first artists list."+          | isNull value2 = throw $ WrapperCallError method "empty second artists list."+          | isExceededMaximum value1 = throw $ WrapperCallError method "first artists list length has exceeded maximum (100)."+          | isExceededMaximum value2 = throw $ WrapperCallError method "second artists list length has exceeded maximum (100)."+          | otherwise = callAPI method+            [ "type1" ?< type1+            , "type2" ?< type2+            , "value1" ?< value1+            , "value2" ?< value2+            , "limit" ?< limit+            , "api_key" ?< apiKey+            ]+            where method = "tasteometer.compare"++                  type1 = show value1+                  type2 = show value2++                  isNull :: Value -> Bool+                  isNull (ValueUser _) = False+                  isNull (ValueArtists as) = null as++                  isExceededMaximum :: Value -> Bool+                  isExceededMaximum (ValueUser _) = False+                  isExceededMaximum (ValueArtists as) = length as > 100
+ Network/Lastfm/API/Track.hs view
@@ -0,0 +1,291 @@+-- | Track API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Track+  ( addTags, ban, getBuyLinks, getCorrection, getFingerprintMetadata+  , getInfo, getShouts, getSimilar, getTags, getTopFans, getTopTags+  , love, removeTag, scrobble, search, share, unban, unlove, updateNowPlaying+  ) where++import Control.Exception (throw)+import Control.Monad (void)++import Network.Lastfm.Response+import Network.Lastfm.Types ( (?<), Album, AlbumArtist, APIKey, Artist, Autocorrect, ChosenByUser, Context, Country+                            , Duration, Fingerprint, Limit, Mbid, Message, Page, Public, Recipient, SessionKey+                            , StreamId, Tag, Timestamp, Track, TrackNumber, User+                            )++-- | Tag a track using a list of user supplied tags.+--+-- More: <http://www.lastfm.ru/api/show/track.addTags>+addTags :: Artist -> Track -> [Tag] -> APIKey -> SessionKey -> Lastfm ()+addTags artist track tags apiKey sessionKey = dispatch go+  where go+          | null tags        = throw $ WrapperCallError method "empty tag list."+          | length tags > 10 = throw $ WrapperCallError method "tag list length has exceeded maximum."+          | otherwise        = void $ callAPI method+            [ "artist" ?< artist+            , "track" ?< track+            , "tags" ?< tags+            , "api_key" ?< apiKey+            , "sk" ?< sessionKey+            ]+            where method = "track.addTags"++-- | Ban a track for a given user profile.+--+-- More: <http://www.lastfm.ru/api/show/track.ban>+ban :: Artist -> Track -> APIKey -> SessionKey -> Lastfm ()+ban artist track apiKey sessionKey = dispatch $ void $ callAPI "track.ban"+  [ "artist" ?< artist+  , "track" ?< track+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Get a list of Buy Links for a particular track.+--+-- More: <http://www.lastfm.ru/api/show/track.getBuylinks>+getBuyLinks :: Either (Artist, Track) Mbid -> Maybe Autocorrect -> Country -> APIKey -> Lastfm Response+getBuyLinks a autocorrect country apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "country" ?< country+  , "api_key" ?< apiKey+  ]+  where method = "track.getBuyLinks"+        target = case a of+                   Left (artist, track) -> ["artist" ?< artist, "track" ?< track]+                   Right mbid           -> ["mbid" ?< mbid]++-- | Use the last.fm corrections data to check whether the supplied track has a correction to a canonical track.+--+-- More: <http://www.lastfm.ru/api/show/track.getCorrection>+getCorrection :: Artist -> Track -> APIKey -> Lastfm Response+getCorrection artist track apiKey = dispatch $ callAPI "track.getCorrection"+  [ "artist" ?< artist+  , "track" ?< track+  , "api_key" ?< apiKey+  ]++-- | Retrieve track metadata associated with a fingerprint id generated by the Last.fm Fingerprinter. Returns track elements, along with a 'rank' value between 0 and 1 reflecting the confidence for each match.+--+-- More: <http://www.lastfm.ru/api/show/track.getFingerprintMetadata>+getFingerprintMetadata :: Fingerprint -> APIKey -> Lastfm Response+getFingerprintMetadata fingerprint apiKey = dispatch $ callAPI "track.getFingerprintMetadata"+  [ "fingerprintid" ?< fingerprint+  , "api_key" ?< apiKey+  ]++-- | Get the metadata for a track on Last.fm.+--+-- More: <http://www.lastfm.ru/api/show/track.getInfo>+getInfo :: Either (Artist, Track) Mbid -> Maybe Autocorrect -> Maybe User -> APIKey -> Lastfm Response+getInfo a autocorrect username apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "username" ?< username+  , "api_key" ?< apiKey+  ]+  where method = "track.getInfo"+        target = case a of+                   Left (artist, track) -> ["artist" ?< artist, "track" ?< track]+                   Right mbid           -> ["mbid" ?< mbid]++-- | Get shouts for this track. Also available as an rss feed.+--+-- More: <http://www.lastfm.ru/api/show/track.getShouts>+getShouts :: Either (Artist, Track) Mbid -> Maybe Autocorrect -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getShouts a autocorrect page limit apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]+  where method = "track.getShouts"+        target = case a of+                   Left (artist, track) -> ["artist" ?< artist, "track" ?< track]+                   Right mbid           -> ["mbid" ?< mbid]++-- | Get the similar tracks for this track on Last.fm, based on listening data.+--+-- More: <http://www.lastfm.ru/api/show/track.getSimilar>+getSimilar :: Either (Artist, Track) Mbid -> Maybe Autocorrect -> Maybe Limit -> APIKey -> Lastfm Response+getSimilar a autocorrect limit apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]+  where method = "track.getSimilar"+        target = case a of+                   Left (artist, track) -> ["artist" ?< artist, "track" ?< track]+                   Right mbid           -> ["mbid" ?< mbid]++-- | Get the tags applied by an individual user to a track on Last.fm.+--+-- More: <http://www.lastfm.ru/api/show/track.getTags>+getTags :: Either (Artist, Track) Mbid -> Maybe Autocorrect -> Either User SessionKey -> APIKey -> Lastfm Response+getTags a autocorrect b apiKey = dispatch $ callAPI method $ target ++ auth +++  [ "autocorrect" ?< autocorrect+  , "api_key" ?< apiKey+  ]+  where method = "track.getTags"+        target = case a of+                   Left (artist, track) -> ["artist" ?< artist, "track" ?< track]+                   Right mbid           -> ["mbid" ?< mbid]+        auth = case b of+                 Left user        -> ["user" ?< user]+                 Right sessionKey -> ["sk" ?< sessionKey]++-- | Get the top fans for this track on Last.fm, based on listening data.+--+-- More: <http://www.lastfm.ru/api/show/track.getTopFans>+getTopFans :: Either (Artist, Track) Mbid -> Maybe Autocorrect -> APIKey -> Lastfm Response+getTopFans a autocorrect apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "api_key" ?< apiKey+  ]+  where method = "track.getTopFans"+        target = case a of+                   Left (artist, track) -> ["artist" ?< artist, "track" ?< track]+                   Right mbid           -> ["mbid" ?< mbid]++-- | Get the top tags for this track on Last.fm, ordered by tag count.+--+-- More: <http://www.lastfm.ru/api/show/track.getTopTags>+getTopTags :: Either (Artist, Track) Mbid -> Maybe Autocorrect -> APIKey -> Lastfm Response+getTopTags a autocorrect apiKey = dispatch $ callAPI method $ target +++  [ "autocorrect" ?< autocorrect+  , "api_key" ?< apiKey+  ]+  where method = "track.getTopTags"+        target = case a of+                   Left (artist, track) -> ["artist" ?< artist, "track" ?< track]+                   Right mbid           -> ["mbid" ?< mbid]++-- | Love a track for a user profile.+--+-- More: <http://www.lastfm.ru/api/show/track.love>+love :: Artist -> Track -> APIKey -> SessionKey -> Lastfm ()+love artist track apiKey sessionKey = dispatch $ void $ callAPI "track.love"+  [ "artist" ?< artist+  , "track" ?< track+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Remove a user's tag from a track.+--+-- More: <http://www.lastfm.ru/api/show/track.removeTag>+removeTag :: Artist -> Track -> Tag -> APIKey -> SessionKey -> Lastfm ()+removeTag artist track tag apiKey sessionKey = dispatch $ void $ callAPI "track.removeTag"+  [ "artist" ?< artist+  , "track" ?< track+  , "tag" ?< tag+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Used to add a track-play to a user's profile.+--+-- More; <http://www.lastfm.ru/api/show/track.scrobble>+scrobble :: ( Timestamp, Maybe Album, Artist, Track, Maybe AlbumArtist+           , Maybe Duration, Maybe StreamId, Maybe ChosenByUser+           , Maybe Context, Maybe TrackNumber, Maybe Mbid )+         -> APIKey+         -> SessionKey+         -> Lastfm ()+scrobble (timestamp, album, artist, track, albumArtist, duration, streamId, chosenByUser, context, trackNumber, mbid) apiKey sessionKey = dispatch $ void $ callAPI "track.scrobble"+  [ "timestamp" ?< timestamp+  , "artist" ?< artist+  , "track" ?< track+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  , "album" ?< album+  , "albumArtist" ?< albumArtist+  , "duration" ?< duration+  , "streamId" ?< streamId+  , "chosenByUser" ?< chosenByUser+  , "context" ?< context+  , "trackNumber" ?< trackNumber+  , "mbid" ?< mbid+  ]++-- | Search for a track by track name. Returns track matches sorted by relevance.+--+-- More: <http://www.lastfm.ru/api/show/track.search>+search :: Track -> Maybe Page -> Maybe Limit -> Maybe Artist -> APIKey -> Lastfm Response+search limit page track artist apiKey = dispatch $ callAPI "track.search"+  [ "track" ?< track+  , "page" ?< page+  , "limit" ?< limit+  , "artist" ?< artist+  , "api_key" ?< apiKey+  ]++-- | Share a track twith one or more Last.fm users or other friends.+--+-- More: <http://www.lastfm.ru/api/show/track.share>+share :: Artist -> Track -> [Recipient] -> Maybe Message -> Maybe Public -> APIKey -> SessionKey -> Lastfm ()+share artist track recipients message public apiKey sessionKey = dispatch go+  where go+          | null recipients        = throw $ WrapperCallError method "empty recipient list."+          | length recipients > 10 = throw $ WrapperCallError method "recipient list length has exceeded maximum."+          | otherwise              = void $ callAPI method+            [ "artist" ?< artist+            , "track" ?< track+            , "recipient" ?< recipients+            , "api_key" ?< apiKey+            , "sk" ?< sessionKey+            , "public" ?< public+            , "message" ?< message+            ]+            where method = "track.share"++-- | Unban a track for a user profile.+--+-- More: <http://www.lastfm.ru/api/show/track.unban>+unban :: Artist -> Track -> APIKey -> SessionKey -> Lastfm ()+unban artist track apiKey sessionKey = dispatch $ void $ callAPI "track.unban"+  [ "artist" ?< artist+  , "track" ?< track+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Unlove a track for a user profile.+--+-- More: <http://www.lastfm.ru/api/show/track.unlove>+unlove :: Artist -> Track -> APIKey -> SessionKey -> Lastfm ()+unlove artist track apiKey sessionKey = dispatch $ void $ callAPI "track.unlove"+  [ "artist" ?< artist+  , "track" ?< track+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]+++-- | Used to notify Last.fm that a user has started listening to a track. Parameter names are case sensitive.+--+-- More: <http://www.lastfm.ru/api/show/track.updateNowPlaying>+updateNowPlaying :: Artist+                 -> Track+                 -> Maybe Album+                 -> Maybe AlbumArtist+                 -> Maybe Context+                 -> Maybe TrackNumber+                 -> Maybe Mbid+                 -> Maybe Duration+                 -> APIKey+                 -> SessionKey+                 -> Lastfm ()+updateNowPlaying artist track album albumArtist context trackNumber mbid duration apiKey sessionKey = dispatch $ void $ callAPI "track.updateNowPlaying"+  [ "artist" ?< artist+  , "track" ?< track+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  , "album" ?< album+  , "albumArtist" ?< albumArtist+  , "context" ?< context+  , "trackNumber" ?< trackNumber+  , "mbid" ?< mbid+  , "duration" ?< duration+  ]
+ Network/Lastfm/API/User.hs view
@@ -0,0 +1,303 @@+-- | User API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.User+  ( getArtistTracks, getBannedTracks, getEvents, getFriends, getInfo, getLovedTracks+  , getNeighbours, getNewReleases, getPastEvents, getPersonalTags, getPlaylists, getRecentStations+  , getRecentTracks, getRecommendedArtists, getRecommendedEvents, getShouts, getTopAlbums+  , getTopArtists, getTopTags, getTopTracks, getWeeklyAlbumChart, getWeeklyArtistChart+  , getWeeklyChartList, getWeeklyTrackChart, shout+  ) where++import Control.Monad (void)++import Network.Lastfm.Response+import Network.Lastfm.Types ( (?<), APIKey, Artist, FestivalsOnly, From, Limit, Message, Page+                            , Period, RecentTracks, SessionKey, Tag, TaggingType, To, User, UseRecs+                            )++-- | Get a list of tracks by a given artist scrobbled by this user, including scrobble time. Can be limited to specific timeranges, defaults to all time.+--+-- More: <http://www.lastfm.ru/api/show/user.getArtistTracks>+getArtistTracks :: User+                -> Artist+                -> Maybe From+                -> Maybe To+                -> Maybe Page+                -> APIKey+                -> Lastfm Response+getArtistTracks user artist startTimestamp endTimestamp page apiKey = dispatch $ callAPI "user.getArtistTracks"+  [ "user" ?< user+  , "artist" ?< artist+  , "startTimestamp" ?< startTimestamp+  , "page" ?< page+  , "endTimestamp" ?< endTimestamp+  , "api_key" ?< apiKey+  ]++-- | Returns the tracks banned by the user.+--+-- More: <http://www.lastfm.ru/api/show/user.getBannedTracks>+getBannedTracks :: User -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getBannedTracks user page limit apiKey = dispatch $ callAPI "user.getBannedTracks"+  [ "user" ?< user+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get a list of upcoming events that this user is attending.+--+-- Mpre: <http://www.lastfm.ru/api/show/user.getEvents>+getEvents :: User -> Maybe Page -> Maybe Limit -> Maybe FestivalsOnly -> APIKey -> Lastfm Response+getEvents user page limit festivalsOnly apiKey = dispatch $ callAPI "user.getEvents"+  [ "user" ?< user+  , "page" ?< page+  , "limit" ?< limit+  , "festivalsonly" ?< festivalsOnly+  , "api_key" ?< apiKey+  ]++-- | Get a list of the user's friends on Last.fm.+--+-- More: <http://www.lastfm.ru/api/show/user.getFriends>+getFriends :: User -> Maybe RecentTracks -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getFriends user recentTracks page limit apiKey = dispatch $ callAPI "user.getFriends"+  [ "user" ?< user+  , "recenttracks" ?< recentTracks+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get information about a user profile.+--+-- More: <http://www.lastfm.ru/api/show/user.getInfo>+getInfo :: Maybe User -> APIKey -> Lastfm Response+getInfo user apiKey = dispatch $ callAPI "user.getInfo"+  [ "user" ?< user+  , "api_key" ?< apiKey+  ]++-- | Get tracks loved by a user.+--+-- More: <http://www.lastfm.ru/api/show/user.getLovedTracks>+getLovedTracks :: User -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getLovedTracks user page limit apiKey = dispatch $ callAPI "user.getLovedTracks"+  [ "user" ?< user+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get a list of a user's neighbours on Last.fm.+--+-- More: <http://www.lastfm.ru/api/show/user.getNeighbours>+getNeighbours :: User -> Maybe Limit -> APIKey -> Lastfm Response+getNeighbours user limit apiKey = dispatch $ callAPI "user.getNeighbours"+  [ "user" ?< user+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Gets a list of forthcoming releases based on a user's musical taste.+--+-- More: <http://www.lastfm.ru/api/show/user.getNewReleases>+getNewReleases :: User -> Maybe UseRecs -> APIKey -> Lastfm Response+getNewReleases user useRecs apiKey = dispatch $ callAPI "user.getNewReleases"+  [ "user" ?< user+  , "userecs" ?< useRecs+  , "api_key" ?< apiKey+  ]++-- | Get a paginated list of all events a user has attended in the past.+--+-- More: <http://www.lastfm.ru/api/show/user.getPastEvents>+getPastEvents :: User -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getPastEvents user page limit apiKey = dispatch $ callAPI "user.getPastEvents"+  [ "user" ?< user+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get the user's personal tags.+--+-- More: <http://www.lastfm.ru/api/show/user.getPersonalTags>+getPersonalTags :: User+                -> Tag+                -> TaggingType+                -> Maybe Page+                -> Maybe Limit+                -> APIKey+                -> Lastfm Response+getPersonalTags user tag taggingType page limit apiKey = dispatch $ callAPI "user.getPersonalTags"+  [ "user" ?< user+  , "tag" ?< tag+  , "taggingtype" ?< taggingType+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get a list of a user's playlists on Last.fm.+--+-- More: <http://www.lastfm.ru/api/show/user.getPlaylists>+getPlaylists :: User -> APIKey -> Lastfm Response+getPlaylists user apiKey = dispatch $ callAPI "user.getPlaylists"+  [ "user" ?< user+  , "api_key" ?< apiKey+  ]++-- | Get a list of the recent Stations listened to by this user.+--+-- More: <http://www.lastfm.ru/api/show/user.getRecentStations>+getRecentStations :: User -> Maybe Page -> Maybe Limit -> APIKey -> SessionKey -> Lastfm Response+getRecentStations user page limit apiKey sessionKey = dispatch $ callAPI "user.getRecentStations"+  [ "user" ?< user+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Get a list of the recent tracks listened to by this user. Also includes the currently playing track with the nowplaying="true" attribute if the user is currently listening.+--+-- More: <http://www.lastfm.ru/api/show/user.getRecentTracks>+getRecentTracks :: User -> Maybe Page -> Maybe Limit -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getRecentTracks user page limit from to apiKey = dispatch $ callAPI "user.getRecentTracks"+  [ "user" ?< user+  , "page" ?< page+  , "limit" ?< limit+  , "from" ?< from+  , "to" ?< to+  , "api_key" ?< apiKey+  ]++-- | Get Last.fm artist recommendations for a user.+--+-- Mpre: <http://www.lastfm.ru/api/show/user.getRecommendedArtists>+getRecommendedArtists :: Maybe Page -> Maybe Limit -> APIKey -> SessionKey -> Lastfm Response+getRecommendedArtists page limit apiKey sessionKey = dispatch $ callAPI "user.getRecommendedArtists"+  [ "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Get a paginated list of all events recommended to a user by Last.fm, based on their listening profile.+--+-- More: <http://www.lastfm.ru/api/show/user.getRecommendedEvents>+getRecommendedEvents :: Maybe Page -> Maybe Limit -> APIKey -> SessionKey -> Lastfm Response+getRecommendedEvents page limit apiKey sessionKey = dispatch $ callAPI "user.getRecommendedEvents"+  [ "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]++-- | Get shouts for this user. Also available as an rss feed.+--+-- More: <http://www.lastfm.ru/api/show/user.getShouts>+getShouts :: User -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getShouts user page limit apiKey = dispatch $ callAPI "user.getShouts"+  [ "user" ?< user+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get the top albums listened to by a user. You can stipulate a time period. Sends the overall chart by default.+--+-- More: <http://www.lastfm.ru/api/show/user.getTopAlbums>+getTopAlbums :: User -> Maybe Period -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopAlbums user period page limit apiKey = dispatch $ callAPI "user.getTopAlbums"+  [ "user" ?< user+  , "period" ?< period+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get the top artists listened to by a user. You can stipulate a time period. Sends the overall chart by default.+--+-- More: <http://www.lastfm.ru/api/show/user.getTopArtists>+getTopArtists :: User -> Maybe Period -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopArtists user period page limit apiKey = dispatch $ callAPI "user.getTopArtists"+  [ "user" ?< user+  , "period" ?< period+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get the top tags used by this user.+--+-- More: <http://www.lastfm.ru/api/show/user.getTopTags>+getTopTags :: User -> Maybe Limit -> APIKey -> Lastfm Response+getTopTags user limit apiKey = dispatch $ callAPI "user.getTopTags"+  [ "user" ?< user+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get the top tracks listened to by a user. You can stipulate a time period. Sends the overall chart by default.+--+-- More: <http://www.lastfm.ru/api/show/user.getTopTracks>+getTopTracks :: User -> Maybe Period -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getTopTracks user period page limit apiKey = dispatch $ callAPI "user.getTopTracks"+  [ "user" ?< user+  , "period" ?< period+  , "page" ?< page+  , "limit" ?< limit+  , "api_key" ?< apiKey+  ]++-- | Get an album chart for a user profile, for a given date range. If no date range is supplied, it will return the most recent album chart for this user.+--+-- More: <http://www.lastfm.ru/api/show/user.getWeeklyAlbumChart>+getWeeklyAlbumChart :: User -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getWeeklyAlbumChart user from to apiKey = dispatch $ callAPI "user.getWeeklyAlbumChart"+  [ "user" ?< user+  , "from" ?< from+  , "to" ?< to+  , "api_key" ?< apiKey+  ]++-- | Get an artist chart for a user profile, for a given date range. If no date range is supplied, it will return the most recent artist chart for this user.+--+-- More: <http://www.lastfm.ru/api/show/user.getWeeklyArtistChart>+getWeeklyArtistChart :: User -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getWeeklyArtistChart user from to apiKey = dispatch $ callAPI "user.getWeeklyArtistChart"+  [ "user" ?< user+  , "from" ?< from+  , "to" ?< to+  , "api_key" ?< apiKey+  ]++-- | Get a list of available charts for this user, expressed as date ranges which can be sent to the chart services.+--+-- More: <http://www.lastfm.ru/api/show/user.getWeeklyChartList>+getWeeklyChartList :: User -> APIKey -> Lastfm Response+getWeeklyChartList user apiKey = dispatch $ callAPI "user.getWeeklyChartList" ["user" ?< user, "api_key" ?< apiKey]++-- | Get a track chart for a user profile, for a given date range. If no date range is supplied, it will return the most recent track chart for this user.+--+-- More: <http://www.lastfm.ru/api/show/user.getWeeklyTrackChart>+getWeeklyTrackChart :: User -> Maybe From -> Maybe To -> APIKey -> Lastfm Response+getWeeklyTrackChart user from to apiKey = dispatch $ callAPI "user.getWeeklyTrackChart"+  [ "user" ?< user+  , "from" ?< from+  , "to" ?< to+  , "api_key" ?< apiKey+  ]++-- | Shout on this user's shoutbox.+--+-- More: <http://www.lastfm.ru/api/show/user.shout>+shout :: User -> Message -> APIKey -> SessionKey -> Lastfm ()+shout user message apiKey sessionKey = dispatch $ void $ callAPI "user.shout"+  [ "user" ?< user+  , "message" ?< message+  , "api_key" ?< apiKey+  , "sk" ?< sessionKey+  ]
+ Network/Lastfm/API/Venue.hs view
@@ -0,0 +1,42 @@+-- | Venue API module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.API.Venue+  ( getEvents, getPastEvents, search+  ) where++import Network.Lastfm.Response+import Network.Lastfm.Types ((?<), APIKey, Country, FestivalsOnly, Limit, Name, Page, Venue)++-- | Get a list of upcoming events at this venue.+--+-- More: <http://www.lastfm.ru/api/show/venue.getEvents>+getEvents :: Venue -> Maybe FestivalsOnly -> APIKey -> Lastfm Response+getEvents venue festivalsOnly apiKey = dispatch $ callAPI "venue.getEvents"+  [ "venue" ?< venue+  , "api_key" ?< apiKey+  , "festivalsonly" ?< festivalsOnly+  ]++-- | Get a paginated list of all the events held at this venue in the past.+--+-- More: <http://www.lastfm.ru/api/show/venue.getPastEvents>+getPastEvents :: Venue -> Maybe FestivalsOnly -> Maybe Page -> Maybe Limit -> APIKey -> Lastfm Response+getPastEvents venue festivalsOnly page limit apiKey = dispatch $ callAPI "venue.getPastEvents"+  [ "venue" ?< venue+  , "api_key" ?< apiKey+  , "festivalsonly" ?< festivalsOnly+  , "page" ?< page+  , "limit" ?< limit+  ]++-- | Search for a venue by venue name.+--+-- More: <http://www.lastfm.ru/api/show/venue.search>+search :: Name -> Maybe Page -> Maybe Limit -> Maybe Country -> APIKey -> Lastfm Response+search venue page limit country apiKey = dispatch $ callAPI "venue.search"+  [ "venue" ?< venue+  , "api_key" ?< apiKey+  , "page" ?< page+  , "limit" ?< limit+  , "country" ?< country+  ]
+ Network/Lastfm/Response.hs view
@@ -0,0 +1,143 @@+{-# LANGUAGE ScopedTypeVariables, DeriveDataTypeable #-}+-- | Response module+{-# OPTIONS_HADDOCK prune #-}+module Network.Lastfm.Response+  ( Lastfm, Response, LastfmError(WrapperCallError), dispatch+  , withSecret+  , callAPI+  ) where++import Codec.Binary.UTF8.String (encodeString)+import Control.Applicative ((<$>))+import Control.Arrow (second)+import Control.Exception (Exception, handle, throw)+import Control.Monad ((<=<), liftM)+import Data.Digest.Pure.MD5 (md5)+import Data.Function (on)+import Data.IORef+import Data.List (sortBy)+import Data.Typeable (Typeable)+import Data.URLEncoded (urlEncode, export)+import Network.Curl hiding (Content)+import System.IO.Unsafe (unsafePerformIO)+import Text.XML.Light++import qualified Data.ByteString.Lazy.Char8 as BS++data APIError+  = DoesntExist+  | InvalidService+  | InvalidMethod+  | AuthenticationFailed+  | InvalidFormat+  | InvalidParameters+  | InvalidResource+  | OperationFailed+  | InvalidSessionKey+  | InvalidAPIKey+  | ServiceOffline+  | SubscribersOnly+  | InvalidMethodSignature+  | TokenHasNotAuthorized+  | NotForStreaming+  | TemporaryUnavailable+  | LoginRequired+  | TrialExpired+  | DoesntExistAgain+  | NotEnoughContent+  | NotEnoughMembers+  | NotEnoughFans+  | NotEnoughNeighbours+  | NoPeakRadio+  | RadioNotFound+  | SuspendedAPIKey+  | Deprecated+  | RateLimitExceeded+    deriving (Enum)++instance Show APIError where+  show DoesntExist = "DoesntExist: This error does not exist"+  show InvalidService = "InvalidService: This service does not exist"+  show InvalidMethod = "InvalidMethod: No method with that name in this package"+  show AuthenticationFailed = "AuthenticationFailed: You do not have permissions to access the service"+  show InvalidFormat = "InvalidFormat: This service doesn't exist in that format"+  show InvalidParameters = "InvalidParameters: Your request is missing a required parameter"+  show InvalidResource = "InvalidResource: Invalid resource specified"+  show OperationFailed = "OperationFailed: Something else went wrong"+  show InvalidSessionKey = "InvalidSessionKey: Please re-authenticate"+  show InvalidAPIKey = "InvalidAPIKey: You must be granted a valid key by last.fm"+  show ServiceOffline = "ServiceOffline: This service is temporarily offline. Try again later."+  show SubscribersOnly  = "SubscribersOnly : This station is only available to paid last.fm subscribers"+  show InvalidMethodSignature = "InvalidMethodSignature: Invalid method signature supplied"+  show TokenHasNotAuthorized = "TokenHasNotAuthorized: This token has not been authorized"+  show NotForStreaming = "NotForStreaming: This item is not available for streaming."+  show TemporaryUnavailable = "TemporaryUnavailable: The service is temporarily unavailable, please try again."+  show LoginRequired = "LoginRequired: Login: User requires to be logged in"+  show TrialExpired = "TrialExpired: This user has no free radio plays left. Subscription required."+  show DoesntExistAgain = "DoesntExistAgain: This error does not exist"+  show NotEnoughContent = "NotEnoughContent: There is not enough content to play this station"+  show NotEnoughMembers = "NotEnoughMembers: This group does not have enough members for radio"+  show NotEnoughFans = "NotEnoughFans: This artist does not have enough fans for for radio"+  show NotEnoughNeighbours = "NotEnoughNeighbours: There are not enough neighbours for radio"+  show NoPeakRadio = "NoPeakRadio: This user is not allowed to listen to radio during peak usage"+  show RadioNotFound = "RadioNotFound: Radio station not found"+  show SuspendedAPIKey = "SuspendedAPIKey: Access for your account has been suspended, please contact Last.fm"+  show Deprecated = "Deprecated: This type of request is no longer supported"+  show RateLimitExceeded = "RateLimitExceeded: Your IP has made too many requests in a short period"++-- Various Lastfm errors.+data LastfmError+  = LastfmAPIError APIError -- ^ Internal Lastfm errors+  | WrapperCallError Method Message -- ^ Wrapper errors+    deriving (Show, Typeable)++instance Exception LastfmError++-- | Type synonym for Lastfm response or error.+type Lastfm a = IO (Either LastfmError a)+-- | Type synonym for Lastfm response+type Response = String+type Key = String+type Value = String+type Secret = String+type Sign = String+type Method = String+type Message = String++secret :: IORef Secret+secret = unsafePerformIO $ newIORef ""++-- | All authentication requiring functions should be wrapped into 'withSecret'+withSecret :: Secret -> IO a -> IO a+withSecret s f = writeIORef secret s >> f++url :: String+url = "http://ws.audioscrobbler.com/2.0/?"++-- | Low level function. Captures all exceptions and transform them into Either Error type.+dispatch :: IO a -> Lastfm a+dispatch f = handle (\(e :: LastfmError) -> return (Left e)) (liftM Right f)++-- | Low level function. Sends POST query to Lastfm API.+callAPI :: Method -> [(Key, Value)] -> IO Response+callAPI m xs = withCurlDo $ do+                 s <- readIORef secret+                 let ys = ("method", m) : (map (second encodeString) . filter (not . null . snd) $ xs)+                 let zs = if not $ null s then ("api_sig", sign s ys) : ys else ys+                 response <- respBody <$> (curlGetResponse_ url+                                            [ CurlPostFields . map (export . urlEncode) $ zs+                                            , CurlFailOnError False+                                            , CurlUserAgent "Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0 Iceweasel/10.0"+                                            ]+                                            :: IO CurlResponse)+                 case isError response of+                   Just n  -> throw $ LastfmAPIError (toEnum $ n - 1)+                   Nothing -> return response++  where -- | Some API calls should be signed. (http://www.lastfm.ru/api/authspec Section 8)+        sign :: Secret -> [(Key, Value)] -> Sign+        sign s = show . md5 . BS.pack . (++ s) . concatMap (uncurry (++)) . sortBy (compare `on` fst)++        isError :: String -> Maybe Int+        isError response = do xml <- parseXMLDoc response+                              read <$> (findAttr (unqual "code") <=< findChild (unqual "error")) xml
+ Network/Lastfm/Types.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE FlexibleInstances, OverlappingInstances, TypeSynonymInstances, GeneralizedNewtypeDeriving #-}+module Network.Lastfm.Types where++import Data.List (intercalate)++newtype Album = Album String deriving (Show, LastfmValue)+newtype AlbumArtist = AlbumArtist String deriving (Show, LastfmValue)+newtype APIKey = APIKey String deriving (Show, LastfmValue)+newtype Artist = Artist String deriving (Show, LastfmValue)+newtype AuthToken = AuthToken String deriving (Show, LastfmValue)+newtype Autocorrect = Autocorrect Bool deriving (Show, LastfmValue)+newtype Bitrate = Bitrate Int deriving (Show, LastfmValue)+newtype BuyLinks = BuyLinks Bool deriving (Show, LastfmValue)+newtype ChosenByUser = ChosenByUser String deriving (Show, LastfmValue)+newtype Context = Context String deriving (Show, LastfmValue)+newtype Country = Country String deriving (Show, LastfmValue)+newtype Description = Description String deriving (Show, LastfmValue)+newtype Discovery = Discovery Bool deriving (Show, LastfmValue)+newtype Distance = Distance Int deriving (Show, LastfmValue)+newtype Duration = Duration String deriving (Show, LastfmValue)+newtype Event = Event Int deriving (Show, LastfmValue)+newtype FestivalsOnly = FestivalsOnly Bool deriving (Show, LastfmValue)+newtype Fingerprint = Fingerprint Integer deriving (Show, LastfmValue)+newtype From = From Integer deriving (Show, LastfmValue)+newtype Group = Group String deriving (Show, LastfmValue)+newtype Language = Language String deriving (Show, LastfmValue)+newtype Latitude = Latitude String deriving (Show, LastfmValue)+newtype Limit = Limit Int deriving (Show, LastfmValue)+newtype Location = Location String deriving (Show, LastfmValue)+newtype Longitude = Longitude String deriving (Show, LastfmValue)+newtype Mbid = Mbid String deriving (Show, LastfmValue)+newtype Message = Message String deriving (Show, LastfmValue)+newtype Metro = Metro String deriving (Show, LastfmValue)+newtype Multiplier = Multiplier Double deriving (Show, LastfmValue)+newtype Name = Name String deriving (Show, LastfmValue)+newtype Page = Page Int deriving (Show, LastfmValue)+newtype Playlist = Playlist Int deriving (Show, LastfmValue)+newtype Public = Public Bool deriving (Show, LastfmValue)+newtype RecentTracks = RecentTracks Bool deriving (Show, LastfmValue)+newtype Recipient = Recipient String deriving (Show, LastfmValue)+newtype RTP = RTP Bool deriving (Show, LastfmValue)+newtype SessionKey = SessionKey String deriving (Show, LastfmValue)+newtype Station = Station String deriving (Show, LastfmValue)+newtype StreamId = StreamId String deriving (Show, LastfmValue)+newtype Tag = Tag String deriving (Show, LastfmValue)+newtype TaggingType = TaggingType String deriving (Show, LastfmValue)+newtype Timestamp = Timestamp Integer deriving (Show, LastfmValue)+newtype Title = Title String deriving (Show, LastfmValue)+newtype To = To Integer deriving (Show, LastfmValue)+newtype Token = Token String deriving (Show, LastfmValue)+newtype Track = Track String deriving (Show, LastfmValue)+newtype TrackNumber = TrackNumber String deriving (Show, LastfmValue)+newtype User = User String deriving (Show, LastfmValue)+newtype UseRecs = UseRecs Bool deriving (Show, LastfmValue)+newtype Venue = Venue Int deriving (Show, LastfmValue)++data Order = Popularity | DateAdded deriving Show++instance LastfmValue Order where+  unpack Popularity = "popularity"+  unpack DateAdded  = "dateadded"++data Status = Yes | Maybe | No deriving Show++instance LastfmValue Status where+  unpack Yes = "0"+  unpack Maybe = "1"+  unpack No = "2"++class LastfmValue a where+  unpack :: a -> String++data Value = ValueUser User+           | ValueArtists [Artist]++instance Show Value where+  show (ValueUser _)    = "user"+  show (ValueArtists _) = "artists"++instance LastfmValue Value where+  unpack (ValueUser u)     = unpack u+  unpack (ValueArtists as) = unpack as++data Period = Week | Quater | HalfYear | Year | Overall+              deriving (Show)++instance LastfmValue Period where+  unpack Week     = "7day"+  unpack Quater   = "3month"+  unpack HalfYear = "6month"+  unpack Year     = "12month"+  unpack Overall  = "overall"++instance LastfmValue Bool where+  unpack True = "1"+  unpack False = "0"+instance LastfmValue Int where+  unpack = show+instance LastfmValue Integer where+  unpack = show+instance LastfmValue Double where+  unpack = show+instance LastfmValue String where+  unpack = id+instance LastfmValue a => LastfmValue [a] where+  unpack = intercalate "," . map unpack+instance LastfmValue a => LastfmValue (Maybe a) where+  unpack (Just a) = unpack a+  unpack Nothing  = ""++(?<) :: LastfmValue a => String -> a -> (String, String)+a ?< b = (a, unpack b)+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ liblastfm.cabal view
@@ -0,0 +1,25 @@+Name:		liblastfm+Version:	0.0.1.0+Description:	Wrapper to Lastfm API+License:	MIT+License-file:	LICENSE+Author:		Matvey Aksenov, Dmitry Malikov+Maintainer:	Matvey Aksenov <matvey.aksenov@gmail.com>+Category:	Network+Synopsis:	Wrapper to Lastfm API+Cabal-Version:	>= 1.6+Build-Type:	Simple++Library+  Build-Depends:	base >= 3 && < 5, bytestring, curl, pureMD5, urlencoded, xml, utf8-string+  Exposed-Modules:	Network.Lastfm.Response, Network.Lastfm.Types, Network.Lastfm.API.Album, Network.Lastfm.API.Artist, Network.Lastfm.API.Auth, Network.Lastfm.API.Chart, Network.Lastfm.API.Event, Network.Lastfm.API.Geo, Network.Lastfm.API.Group, Network.Lastfm.API.Library, Network.Lastfm.API.Playlist, Network.Lastfm.API.Radio, Network.Lastfm.API.Tag, Network.Lastfm.API.Tasteometer, Network.Lastfm.API.Track, Network.Lastfm.API.User, Network.Lastfm.API.Venue+  Extensions:		FlexibleInstances, OverlappingInstances, GeneralizedNewtypeDeriving, ScopedTypeVariables, TypeSynonymInstances++source-repository head+  type:     git+  location: https://github.com/supki/haskell-liblastfm++source-repository this+  type:     git+  location: https://github.com/supki/haskell-liblastfm+  tag:      v0.0.1.0