packages feed

liblastfm 0.1.1.1 → 0.1.1.2

raw patch · 15 files changed

+1010/−2 lines, 15 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

liblastfm.cabal view
@@ -1,5 +1,5 @@ name: liblastfm-version: 0.1.1.1+version: 0.1.1.2 synopsis: Lastfm API interface license: MIT license-file: LICENSE@@ -59,8 +59,22 @@                  text,                  liblastfm   type: exitcode-stdio-1.0-  main-is: json.hs   hs-source-dirs: tests+  main-is: json.hs+  other-modules: Common+                 Venue+                 User+                 Track+                 Tasteometer+                 Tag+                 Playlist+                 Library+                 Group+                 Geo+                 Event+                 Chart+                 Artist+                 Album   ghc-options: -Wall                -fno-warn-unused-do-bind                -fno-warn-orphans
+ tests/Album.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Album (auth, noauth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.Album+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++auth ∷ Request JSON Sign APIKey → Request JSON Sign SessionKey → Secret → [Test]+auth ak sk s =+  [ testCase "Album.addTags" testAddTags+  , testCase "Album.getTags-authenticated" testGetTagsAuth+  , testCase "Album.removeTag" testRemoveTag+  , testCase "Album.share" testShare+  ]+ where+  testAddTags = check ok . sign s $+    addTags <*> artist "Pink Floyd" <*> album "The Wall" <*> tags ["70s", "awesome", "classic"]+      <*> ak <*> sk++  testGetTagsAuth = check gt . sign s $+    getTags <*> artist "Pink Floyd" <*> album "The Wall"+      <*> ak <* sk++  testRemoveTag = check ok . sign s $+    removeTag <*> artist "Pink Floyd" <*> album "The Wall" <*> tag "awesome"+      <*> ak <*> sk++  testShare = check ok . sign s $+    share <*> album "Jerusalem" <*> artist "Sleep" <*> recipient "liblastfm" <* message "Just listen!"+      <*> ak <*> sk+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "Album.getBuyLinks" testGetBuylinks+  , testCase "Album.getBuyLinks_mbid" testGetBuylinks_mbid+  , testCase "Album.getInfo" testGetInfo+  , testCase "Album.getInfo_mbid" testGetInfo_mbid+  , testCase "Album.getShouts" testGetShouts+  , testCase "Album.getShouts_mbid" testGetShouts_mbid+  , testCase "Album.getTags" testGetTags+  , testCase "Album.getTags_mbid" testGetTags_mbid+  , testCase "Album.getTopTags" testGetTopTags+  , testCase "Album.getTopTags_mbid" testGetTopTags_mbid+  , testCase "Album.search" testSearch+  ]+ where+  testGetBuylinks = check gbl $+    getBuyLinks <*> country "United Kingdom" <*> artist "Pink Floyd" <*> album "The Wall" <*> ak+  testGetBuylinks_mbid = check gbl $+    getBuyLinks <*> country "United Kingdom" <*> mbid "3a16c04b-922b-35c5-a29b-cbe9111fbe79" <*> ak++  testGetInfo = check gi $+    getInfo <*> artist "Pink Floyd" <*> album "The Wall" <*> ak+  testGetInfo_mbid = check gi $+    getInfo <*> mbid "3a16c04b-922b-35c5-a29b-cbe9111fbe79" <*> ak++  testGetShouts = check gs $+    getShouts <*> artist "Pink Floyd" <*> album "The Wall" <* limit 7 <*> ak+  testGetShouts_mbid = check gs $+    getShouts <*> mbid "3a16c04b-922b-35c5-a29b-cbe9111fbe79" <* limit 7 <*> ak++  testGetTags = check gt $+    getTags <*> artist "Pink Floyd" <*> album "The Wall" <* user "liblastfm" <*> ak+  testGetTags_mbid = check gt $+    getTags <*> mbid "3a16c04b-922b-35c5-a29b-cbe9111fbe79" <* user "liblastfm" <*> ak++  testGetTopTags = check gtt $+    getTopTags <*> artist "Pink Floyd" <*> album "The Wall" <*> ak+  testGetTopTags_mbid = check gtt $+    getTopTags <*> mbid "3a16c04b-922b-35c5-a29b-cbe9111fbe79" <*> ak++  testSearch = check se $+    search <*> album "wall" <* limit 5 <*> ak+++gbl, gi, gs, gt, gtt, se ∷ Value → Parser [String]+gbl o = parseJSON o >>= (.: "affiliations") >>= (.: "physicals") >>= (.: "affiliation") >>= mapM (.: "supplierName")+gi o = parseJSON o >>= (.: "album") >>= (.: "toptags") >>= (.: "tag") >>= mapM (.: "name")+gs o = parseJSON o >>= (.: "shouts") >>= (.: "shout") >>= mapM (.: "body")+gt o = parseJSON o >>= (.: "tags") >>= (.: "tag") >>= mapM (.: "name")+gtt o = parseJSON o >>= (.: "toptags") >>= (.: "tag") >>= mapM (.: "count")+se o = parseJSON o >>= (.: "results") >>= (.: "albummatches") >>= (.: "album") >>= mapM (.: "name")
+ tests/Artist.hs view
@@ -0,0 +1,140 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Artist (auth, noauth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.Artist+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++auth ∷ Request JSON Sign APIKey → Request JSON Sign SessionKey → Secret → [Test]+auth ak sk s =+  [ testCase "Artist.addTags" testAddTags+  , testCase "Artist.getTags-authenticated" testGetTagsAuth+  , testCase "Artist.removeTag" testRemoveTag+  , testCase "Artist.share" testShare+  ]+ where+  testAddTags = check ok . sign s $+    addTags <*> artist "Егор Летов" <*> tags ["russian", "black metal"] <*> ak <*> sk++  testGetTagsAuth = check gt . sign s $+    getTags <*> artist "Егор Летов" <*> ak <* sk++  testRemoveTag = check ok . sign s $+    removeTag <*> artist "Егор Летов" <*> tag "russian" <*> ak <*> sk++  testShare = check ok . sign s $+    share <*> artist "Sleep" <*> recipient "liblastfm" <* message "Just listen!" <*> ak <*> sk+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "Artist.getCorrection" testGetCorrection+  , testCase "Artist.getEvents" testGetEvents+  , testCase "Artist.getEvents_mbid" testGetEvents_mbid+  , testCase "Artist.getInfo" testGetInfo+  , testCase "Artist.getInfo_mbid" testGetInfo_mbid+  , testCase "Artist.getPastEvents" testGetPastEvents+  , testCase "Artist.getPastEvents_mbid" testGetPastEvents_mbid+  , testCase "Artist.getPodcast" testGetPodcast+  , testCase "Artist.getPodcast_mbid" testGetPodcast_mbid+  , testCase "Artist.getShouts" testGetShouts+  , testCase "Artist.getShouts_mbid" testGetShouts_mbid+  , testCase "Artist.getSimilar" testGetSimilar+  , testCase "Artist.getSimilar_mbid" testGetSimilar_mbid+  , testCase "Artist.getTags" testGetTags+  , testCase "Artist.getTags_mbid" testGetTags_mbid+  , testCase "Artist.getTopAlbums" testGetTopAlbums+  , testCase "Artist.getTopAlbums_mbid" testGetTopAlbums_mbid+  , testCase "Artist.getTopFans" testGetTopFans+  , testCase "Artist.getTopFans_mbid" testGetTopFans_mbid+  , testCase "Artist.getTopTags" testGetTopTags+  , testCase "Artist.getTopTags_mbid" testGetTopTags_mbid+  , testCase "Artist.getTopTracks" testGetTopTracks+  , testCase "Artist.getTopTracks_mbid" testGetTopTracks_mbid+  , testCase "Artist.search" testSearch+  ]+ where+  testGetCorrection = check gc $+    getCorrection <*> artist "Meshugah" <*> ak++  testGetEvents = check ge $+    getEvents <*> artist "Meshuggah" <* limit 2 <*> ak+  testGetEvents_mbid = check ge $+    getEvents <*> mbid "cf8b3b8c-118e-4136-8d1d-c37091173413" <* limit 2 <*> ak++  testGetInfo = check gin $+    getInfo <*> artist "Meshuggah" <*> ak+  testGetInfo_mbid = check gin $+    getInfo <*> mbid "cf8b3b8c-118e-4136-8d1d-c37091173413" <*> ak++  testGetPastEvents = check gpe $+    getPastEvents <*> artist "Meshuggah" <* autocorrect True <*> ak+  testGetPastEvents_mbid = check gpe $+    getPastEvents <*> mbid "cf8b3b8c-118e-4136-8d1d-c37091173413" <* autocorrect True <*> ak++  testGetPodcast = check gp $+    getPodcast <*> artist "Meshuggah" <*> ak+  testGetPodcast_mbid = check gp $+    getPodcast <*> mbid "cf8b3b8c-118e-4136-8d1d-c37091173413" <*> ak++  testGetShouts = check gs $+    getShouts <*> artist "Meshuggah" <* limit 5 <*> ak+  testGetShouts_mbid = check gs $+    getShouts <*> mbid "cf8b3b8c-118e-4136-8d1d-c37091173413" <* limit 5 <*> ak++  testGetSimilar = check gsi $+    getSimilar <*> artist "Meshuggah" <* limit 3 <*> ak+  testGetSimilar_mbid = check gsi $+    getSimilar <*> mbid "cf8b3b8c-118e-4136-8d1d-c37091173413" <* limit 3 <*> ak++  testGetTags = check gt $+    getTags <*> artist "Егор Летов" <* user "liblastfm" <*> ak+  testGetTags_mbid = check gt $+    getTags <*> mbid "cfb3d32e-d095-4d63-946d-9daf06932180" <* user "liblastfm" <*> ak++  testGetTopAlbums = check gta $+    getTopAlbums <*> artist "Meshuggah" <* limit 3 <*> ak+  testGetTopAlbums_mbid = check gta $+    getTopAlbums <*> mbid "cf8b3b8c-118e-4136-8d1d-c37091173413" <* limit 3 <*> ak++  testGetTopFans = check gtf $+    getTopFans <*> artist "Meshuggah" <*> ak+  testGetTopFans_mbid = check gtf $+    getTopFans <*> mbid "cf8b3b8c-118e-4136-8d1d-c37091173413" <*> ak++  testGetTopTags = check gtt $+    getTopTags <*> artist "Meshuggah" <*> ak+  testGetTopTags_mbid = check gtt $+    getTopTags <*> mbid "cf8b3b8c-118e-4136-8d1d-c37091173413" <*> ak++  testGetTopTracks = check gttr $+    getTopTracks <*> artist "Meshuggah" <* limit 3 <*> ak+  testGetTopTracks_mbid = check gttr $+    getTopTracks <*> mbid "cf8b3b8c-118e-4136-8d1d-c37091173413" <* limit 3 <*> ak++  testSearch = check se $+    search <*> artist "Mesh" <* limit 3 <*> ak+++gc, gin, gp ∷ Value → Parser String+ge, gpe, gs, gsi, gt, gta, gtf, gtt, gttr, se ∷ Value → Parser [String]+gc o = parseJSON o >>= (.: "corrections") >>= (.: "correction") >>= (.: "artist") >>= (.: "name")+ge o = parseJSON o >>= (.: "events") >>= (.: "event") >>= mapM (\o' → (o' .: "venue") >>= (.: "name"))+gin o = parseJSON o >>= (.: "artist") >>= (.: "stats") >>= (.: "listeners")+gp o = parseJSON o >>= (.: "rss") >>= (.: "channel") >>= (.: "description")+gpe o = parseJSON o >>= (.: "events") >>= (.: "event") >>= mapM (.: "title")+gs o = parseJSON o >>= (.: "shouts") >>= (.: "shout") >>= mapM (.: "author")+gsi o = parseJSON o >>= (.: "similarartists") >>= (.: "artist") >>= mapM (.: "name")+gt o = parseJSON o >>= (.: "tags") >>= (.: "tag") >>= mapM (.: "name")+gta o = parseJSON o >>= (.: "topalbums") >>= (.: "album") >>= mapM (.: "name")+gtf o = parseJSON o >>= (.: "topfans") >>= (.: "user") >>= mapM (.: "name")+gtt o = parseJSON o >>= (.: "toptags") >>= (.: "tag") >>= mapM (.: "name")+gttr o = parseJSON o >>= (.: "toptracks") >>= (.: "track") >>= mapM (.: "name")+se o = parseJSON o >>= (.: "results") >>= (.: "artistmatches") >>= (.: "artist") >>= mapM (.: "name")
+ tests/Chart.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Chart (noauth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.Chart+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "Chart.getHypedArtists" testGetHypedArtists+  , testCase "Chart.getHypedTracks" testGetHypedTracks+  , testCase "Chart.getLovedTracks" testGetLovedTracks+  , testCase "Chart.getTopArtists" testGetTopArtists+  , testCase "Chart.getTopTags" testGetTopTags+  , testCase "Chart.getTopTracks" testGetTopTracks+  ]+ where+  testGetHypedArtists = check ga $+    getHypedArtists <* limit 3 <*> ak++  testGetHypedTracks = check gt $+    getHypedTracks <* limit 2 <*> ak++  testGetLovedTracks = check gt $+    getLovedTracks <* limit 3 <*> ak++  testGetTopArtists = check ga $+    getTopArtists <* limit 4 <*> ak++  testGetTopTags = check gta $+    getTopTags <* limit 5 <*> ak++  testGetTopTracks = check gt $+    getTopTracks <* limit 2 <*> ak+++ga, gt, gta ∷ Value → Parser [String]+ga o = parseJSON o >>= (.: "artists") >>= (.: "artist") >>= mapM (.: "name")+gt o = parseJSON o >>= (.: "tracks") >>= (.: "track") >>= mapM (.: "name")+gta o = parseJSON o >>= (.: "tags") >>= (.: "tag") >>= mapM (.: "name")
+ tests/Common.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Common where++import Data.Aeson.Types+import Network.Lastfm+import Test.HUnit+++check ∷ (Value → Parser a) → Request JSON Send Ready → Assertion+check p q = do+  r ← lastfm q+  case parse p `fmap` r of+    Just (Success _) → assertBool "success" True+    _                → assertFailure $ "Got: " ++ show r+++ok ∷ Value → Parser String+ok o = parseJSON o >>= (.: "status")
+ tests/Event.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Event (auth, noauth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.Event+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++auth ∷ Request JSON Sign APIKey → Request JSON Sign SessionKey → Secret → [Test]+auth ak sk s =+  [ testCase "Event.attend" testAttend+  , testCase "Event.share" testShare+  ]+ where+  testAttend = check ok . sign s $+    attend <*> event 3142549 <*> status Attending <*> ak <*> sk++  testShare = check ok . sign s $+    share <*> event 3142549 <*> recipient "liblastfm" <* message "Just listen!" <*> ak <*> sk+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "Event.getAttendees" testGetAttendees+  , testCase "Event.getInfo" testGetInfo+  , testCase "Event.getShouts" testGetShouts+  ]+ where+  testGetAttendees = check ga $+    getAttendees <*> event 3142549 <* limit 2 <*> ak++  testGetInfo = check gi $+    getInfo <*> event 3142549 <*> ak++  testGetShouts = check gs $+    getShouts <*> event 3142549 <* limit 1 <*> ak+++gi, gs ∷ Value → Parser String+ga ∷ Value → Parser [String]+ga o = parseJSON o >>= (.: "attendees") >>= (.: "user") >>= mapM (.: "name")+gi o = parseJSON o >>= (.: "event") >>= (.: "venue") >>= (.: "location") >>= (.: "city")+gs o = parseJSON o >>= (.: "shouts") >>= (.: "shout") >>= (.: "body")
+ tests/Geo.hs view
@@ -0,0 +1,70 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Geo (noauth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.Geo+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "Geo.getEvents" testGetEvents+  , testCase "Geo.getMetroArtistChart" testGetMetroArtistChart+  , testCase "Geo.getMetroHypeArtistChart" testGetMetroHypeArtistChart+  , testCase "Geo.getMetroHypeTrackChart" testGetMetroHypeTrackChart+  , testCase "Geo.getMetroTrackChart" testGetMetroTrackChart+  , testCase "Geo.getMetroUniqueArtistChart" testGetMetroUniqueArtistChart+  , testCase "Geo.getMetroUniqueTrackChart" testGetMetroUniqueTrackChart+  , testCase "Geo.getMetroWeeklyChartlist" testGetMetroWeeklyChartlist+  , testCase "Geo.getMetros" testGetMetros+  , testCase "Geo.getTopArtists" testGetTopArtists+  , testCase "Geo.getTopTracks" testGetTopTracks+  ]+ where+  testGetEvents = check ge $+    getEvents <* location "Moscow" <* limit 5 <*> ak++  testGetMetroArtistChart = check ga $+    getMetroArtistChart <*> metro "Saint Petersburg" <*> country "Russia" <*> ak++  testGetMetroHypeArtistChart = check ga $+    getMetroHypeArtistChart <*> metro "New York" <*> country "United States" <*> ak++  testGetMetroHypeTrackChart = check gt $+    getMetroHypeTrackChart <*> metro "Ufa" <*> country "Russia" <*> ak++  testGetMetroTrackChart = check gt $+    getMetroTrackChart <*> metro "Boston" <*> country "United States" <*> ak++  testGetMetroUniqueArtistChart = check ga $+    getMetroUniqueArtistChart <*> metro "Minsk" <*> country "Belarus" <*> ak++  testGetMetroUniqueTrackChart = check gt $+    getMetroUniqueTrackChart <*> metro "Moscow" <*> country "Russia" <*> ak++  testGetMetroWeeklyChartlist = check gc $+    getMetroWeeklyChartlist <*> metro "Moscow" <*> ak++  testGetMetros = check gm $+    getMetros <* country "Russia" <*> ak++  testGetTopArtists = check ga $+    getTopArtists <*> country "Belarus" <* limit 3 <*> ak++  testGetTopTracks = check gt $+    getTopTracks <*> country "Ukraine" <* limit 2 <*> ak+++ga, ge, gm, gt ∷ Value → Parser [String]+gc ∷ Value → Parser [(String, String)]+ga o = parseJSON o >>= (.: "topartists") >>= (.: "artist") >>= mapM (.: "name")+gc o = parseJSON o >>= (.: "weeklychartlist") >>= (.: "chart") >>= mapM (\t → (,) <$> (t .: "from") <*> (t .: "to"))+ge o = parseJSON o >>= (.: "events") >>= (.: "event") >>= mapM (.: "id")+gm o = parseJSON o >>= (.: "metros") >>= (.: "metro") >>= mapM (.: "name")+gt o = parseJSON o >>= (.: "toptracks") >>= (.: "track") >>= mapM (.: "name")
+ tests/Group.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Group (noauth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.Group+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "Group.getHype" testGetHype+  , testCase "Group.getMembers" testGetMembers+  , testCase "Group.getWeeklyAlbumChart" testGetWeeklyAlbumChart+  , testCase "Group.getWeeklyArtistChart" testGetWeeklyArtistChart+  , testCase "Group.getWeeklyChartList" testGetWeeklyChartList+  , testCase "Group.getWeeklyTrackChart" testGetWeeklyTrackChart+  ]+ where+  g = "People with no social lives that listen to more music than is healthy who are slightly scared of spiders and can never seem to find a pen"++  testGetHype = check gh $+    getHype <*> group g <*> ak++  testGetMembers = check gm $+    getMembers <*> group g <* limit 10 <*> ak++  testGetWeeklyAlbumChart = check ga $+    getWeeklyAlbumChart <*> group g <*> ak++  testGetWeeklyArtistChart = check gar $+    getWeeklyArtistChart <*> group g <*> ak++  testGetWeeklyChartList = check gc $+    getWeeklyChartList <*> group g <*> ak++  testGetWeeklyTrackChart = check gt $+    getWeeklyTrackChart <*> group g <*> ak+++ga, gar, gh, gm, gt ∷ Value → Parser [String]+gc ∷ Value → Parser [(String, String)]+ga o = parseJSON o >>= (.: "weeklyalbumchart") >>= (.: "album") >>= mapM (.: "playcount")+gar o = parseJSON o >>= (.: "weeklyartistchart") >>= (.: "artist") >>= mapM (.: "name")+gc o = parseJSON o >>= (.: "weeklychartlist") >>= (.: "chart") >>= mapM (\t → (,) <$> (t .: "from") <*> (t .: "to"))+gh o = parseJSON o >>= (.: "weeklyartistchart") >>= (.: "artist") >>= mapM (.: "mbid")+gm o = parseJSON o >>= (.: "members") >>= (.: "user") >>= mapM (.: "name")+gt o = parseJSON o >>= (.: "weeklytrackchart") >>= (.: "track") >>= mapM (.: "url")
+ tests/Library.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Library (auth, noauth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.Library+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++auth ∷ Request JSON Sign APIKey → Request JSON Sign SessionKey → Secret → [Test]+auth ak sk s =+  [ testCase "Library.addAlbum" testAddAlbum+  , testCase "Library.addArtist" testAddArtist+  , testCase "Library.addTrack" testAddTrack+  , testCase "Library.removeAlbum" testRemoveAlbum+  , testCase "Library.removeArtist" testRemoveArtist+  , testCase "Library.removeTrack" testRemoveTrack+  , testCase "Library.removeScrobble" testRemoveScrobble+  ]+ where+  testAddAlbum = check ok . sign s $+    addAlbum <*> artist "Franz Ferdinand" <*> album "Franz Ferdinand" <*> ak <*> sk++  testAddArtist = check ok . sign s $+    addArtist <*> artist "Mobthrow" <*> ak <*> sk++  testAddTrack = check ok . sign s $+    addTrack <*> artist "Eminem" <*> track "Kim" <*> ak <*> sk++  testRemoveAlbum = check ok . sign s $+    removeAlbum <*> artist "Franz Ferdinand" <*> album "Franz Ferdinand" <*> ak <*> sk++  testRemoveArtist = check ok . sign s $+    removeArtist <*> artist "Burzum" <*> ak <*> sk++  testRemoveTrack = check ok . sign s $+    removeTrack <*> artist "Eminem" <*> track "Kim" <*> ak <*> sk++  testRemoveScrobble = check ok . sign s $+    removeScrobble <*> artist "Gojira" <*> track "Ocean" <*> timestamp 1328905590 <*> ak <*> sk+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "Library.getAlbums" testGetAlbums+  , testCase "Library.getArtists" testGetArtists+  , testCase "Library.getTracks" testGetTracks+  ]+ where+  testGetAlbums = check ga $+    getAlbums <*> user "smpcln" <* artist "Burzum" <* limit 5 <*> ak++  testGetArtists = check gar $+    getArtists <*> user "smpcln" <* limit 7 <*> ak++  testGetTracks = check gt $+    getTracks <*> user "smpcln" <* artist "Burzum" <* limit 4 <*> ak+++ga, gar, gt ∷ Value → Parser [String]+ga o = parseJSON o >>= (.: "albums") >>= (.: "album") >>= mapM (.: "name")+gar o = parseJSON o >>= (.: "artists") >>= (.: "artist") >>= mapM (.: "name")+gt o = parseJSON o >>= (.: "tracks") >>= (.: "track") >>= mapM (.: "name")
+ tests/Playlist.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Playlist (auth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.Playlist+import Network.Lastfm.User+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++auth ∷ Request JSON Sign APIKey → Request JSON Sign SessionKey → Secret → [Test]+auth ak sk s =+  [ testCase "Playlist.create"   testCreate -- Order matters.+  , testCase "Playlist.addTrack" testAddTrack+  ]+ where+  ak' = "29effec263316a1f8a97f753caaa83e0"++  testAddTrack =+    do r ← lastfm $ getPlaylists <*> user "liblastfm" <*> apiKey ak' <* json+       case parseMaybe pl =<< r of+         Nothing → error "M"+         Just r' → let pid = read $ head r' in check ok . sign s $+           addTrack <*> playlist pid <*> artist "Ruby my dear" <*> track "Chazz" <*> ak <*> sk++  testCreate = check pn . sign s $+    create <* title "Awesome playlist" <*> ak <*> sk+++pl ∷ Value → Parser [String]+pl o = parseJSON o >>= (.: "playlists") >>= (.: "playlist") >>= mapM (.: "id")++pn ∷ Value → Parser String+pn o = parseJSON o >>= (.: "playlists") >>= (.: "playlist") >>= (.: "title")
+ tests/Tag.hs view
@@ -0,0 +1,67 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Tag (noauth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.Tag+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "Tag.getInfo" testGetInfo+  , testCase "Tag.getSimilar" testGetSimilar+  , testCase "Tag.getTopAlbums" testGetTopAlbums+  , testCase "Tag.getTopArtists" testGetTopArtists+  , testCase "Tag.getTopTags" testGetTopTags+  , testCase "Tag.getTopTracks" testGetTopTracks+  , testCase "Tag.getWeeklyArtistChart" testGetWeeklyArtistChart+  , testCase "Tag.getWeeklyChartList" testGetWeeklyChartList+  , testCase "Tag.search" testSearch+  ]+ where+  testGetInfo = check gi $+    getInfo <*> tag "depressive" <*> ak++  testGetSimilar = check gs $+    getSimilar <*> tag "depressive" <*> ak++  testGetTopAlbums = check gta $+    getTopAlbums <*> tag "depressive" <* limit 2 <*> ak++  testGetTopArtists = check gtar $+    getTopArtists <*> tag "depressive" <* limit 3 <*> ak++  testGetTopTags = check gtt $+    getTopTags <*> ak++  testGetTopTracks = check gttr $+    getTopTracks <*> tag "depressive" <* limit 2 <*> ak++  testGetWeeklyArtistChart = check gwac $+    getWeeklyArtistChart <*> tag "depressive" <* limit 3 <*> ak++  testGetWeeklyChartList = check gc $+    getWeeklyChartList <*> tag "depressive" <*> ak++  testSearch = check se $+    search <*> tag "depressive" <* limit 3 <*> ak+++gi ∷ Value → Parser String+gs, gta, gtar, gtt, gttr, gwac, se ∷ Value → Parser [String]+gc ∷ Value → Parser [(String, String)]+gi o = parseJSON o >>= (.: "tag") >>= (.: "taggings")+gc o = parseJSON o >>= (.: "weeklychartlist") >>= (.: "chart") >>= mapM (\t → (,) <$> (t .: "from") <*> (t .: "to"))+gs o = parseJSON o >>= (.: "similartags") >>= (.: "tag") >>= mapM (.: "name")+gta o = parseJSON o >>= (.: "topalbums") >>= (.: "album") >>= mapM (.: "url")+gtar o = parseJSON o >>= (.: "topartists") >>= (.: "artist") >>= mapM (.: "url")+gtt o = parseJSON o >>= (.: "toptags") >>= (.: "tag") >>= mapM (.: "name")+gttr o = parseJSON o >>= (.: "toptracks") >>= (.: "track") >>= mapM (.: "url")+gwac o = parseJSON o >>= (.: "weeklyartistchart") >>= (.: "artist") >>= mapM (.: "name")+se o = parseJSON o >>= (.: "results") >>= (.: "tagmatches") >>= (.: "tag") >>= mapM (.: "name")
+ tests/Tasteometer.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Tasteometer (noauth) where++import           Data.Aeson.Types+import           Network.Lastfm+import qualified Network.Lastfm.Tasteometer as T+import           Test.Framework+import           Test.Framework.Providers.HUnit++import Common+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "Tasteometer.compare"    testCompare+  , testCase "Tasteometer.compare'"   testCompare'+  , testCase "Tasteometer.compare''"  testCompare''+  , testCase "Tasteometer.compare'''" testCompare'''+  ]+ where+  testCompare = check cs $+    T.compare (user "smpcln") (user "MCDOOMDESTROYER") <*> ak+  testCompare' = check cs $+    T.compare (user "smpcln") (artists ["enduser", "venetian snares"]) <*> ak+  testCompare'' = check cs $+    T.compare (artists ["enduser", "venetian snares"]) (user "smpcln") <*> ak+  testCompare''' = check cs $+    T.compare (artists ["enduser", "venetian snares"]) (artists ["enduser", "venetian snares"]) <*> ak+++cs ∷ Value → Parser String+cs o = parseJSON o >>= (.: "comparison") >>= (.: "result") >>= (.: "score")
+ tests/Track.hs view
@@ -0,0 +1,132 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Track (auth, noauth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.Track+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++auth ∷ Request JSON Sign APIKey → Request JSON Sign SessionKey → Secret → [Test]+auth ak sk s =+  [ testCase "Track.addTags" testAddTags+  , testCase "Track.ban" testBan+  , testCase "Track.love" testLove+  , testCase "Track.removeTag" testRemoveTag+  , testCase "Track.share" testShare+  , testCase "Track.unban" testUnban+  , testCase "Track.unlove" testUnlove+  , testCase "Track.scrobble" testScrobble+  , testCase "Track.updateNowPlaying" testUpdateNowPlaying+  ]+ where+  testAddTags = check ok . sign s $+    addTags <*> artist "Jefferson Airplane" <*> track "White rabbit" <*> tags ["60s", "awesome"] <*> ak <*> sk++  testBan = check ok . sign s $+    ban <*> artist "Eminem" <*> track "Kim" <*> ak <*> sk++  testLove = check ok . sign s $+    love <*> artist "Gojira" <*> track "Ocean" <*> ak <*> sk++  testRemoveTag = check ok . sign s $+    removeTag <*> artist "Jefferson Airplane" <*> track "White rabbit" <*> tag "awesome" <*> ak <*> sk++  testShare = check ok . sign s $+    share <*> artist "Led Zeppelin" <*> track "When the Levee Breaks" <*> recipient "liblastfm" <* message "Just listen!" <*> ak <*> sk++  testUnban = check ok . sign s $+    unban <*> artist "Eminem" <*> track "Kim" <*> ak <*> sk++  testUnlove = check ok . sign s $+    unlove <*> artist "Gojira" <*> track "Ocean" <*> ak <*> sk++  testScrobble = check ss . sign s $+    scrobble <*> artist "Gojira" <*> track "Ocean" <*> timestamp 1300000000 <*> ak <*> sk++  testUpdateNowPlaying = check np . sign s $+    updateNowPlaying <*> artist "Gojira" <*> track "Ocean" <*> ak <*> sk+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "Track.getBuylinks" testGetBuylinks+  , testCase "Track.getCorrection" testGetCorrection+  , testCase "Track.getFingerprintMetadata" testGetFingerprintMetadata+  , testCase "Track.getInfo" testGetInfo+  , testCase "Track.getInfo_mbid" testGetInfo_mbid+  , testCase "Track.getShouts" testGetShouts+  , testCase "Track.getShouts_mbid" testGetShouts_mbid+  , testCase "Track.getSimilar" testGetSimilar+  , testCase "Track.getSimilar_mbid" testGetSimilar_mbid+  , testCase "Track.getTags" testGetTags+  , testCase "Track.getTags_mbid" testGetTags_mbid+  , testCase "Track.getTopFans" testGetTopFans+  , testCase "Track.getTopFans_mbid" testGetTopFans_mbid+  , testCase "Track.getTopTags" testGetTopTags+  , testCase "Track.getTopTags_mbid" testGetTopTags_mbid+  , testCase "Track.search" testSearch+  ]+ where+  testGetBuylinks = check gbl $+    getBuyLinks <*> country "United Kingdom" <*> artist "Pink Floyd" <*> track "Brain Damage" <*> ak++  testGetCorrection = check gc $+    getCorrection <*> artist "Pink Ployd" <*> track "Brain Damage" <*> ak++  testGetFingerprintMetadata = check gfm $+    getFingerprintMetadata <*> fingerprint 1234 <*> ak++  testGetInfo = check gi $+    getInfo <*> artist "Pink Floyd" <*> track "Comfortably Numb" <* username "aswalrus" <*> ak+  testGetInfo_mbid = check gi $+    getInfo <*> mbid "b6581c74-0b8c-4981-ab92-7eed0298a4bb" <* username "aswalrus" <*> ak++  testGetShouts = check gsh $+    getShouts <*> artist "Pink Floyd" <*> track "Comfortably Numb" <* limit 7 <*> ak+  testGetShouts_mbid = check gsh $+    getShouts <*> mbid "b6581c74-0b8c-4981-ab92-7eed0298a4bb" <* limit 7 <*> ak++  testGetSimilar = check gsi $+    getSimilar <*> artist "Pink Floyd" <*> track "Comfortably Numb" <* limit 4 <*> ak+  testGetSimilar_mbid = check gsi $+    getSimilar <*> mbid "b6581c74-0b8c-4981-ab92-7eed0298a4bb" <* limit 4 <*> ak++  testGetTags = check gt $+    getTags <*> artist "Jefferson Airplane" <*> track "White Rabbit" <* user "liblastfm" <*> ak+  testGetTags_mbid = check gt $+    getTags <*> mbid "1fc619ee-c612-4b2a-a8dc-bb8f1b8b2d6d"  <* user "liblastfm" <*> ak++  testGetTopFans = check gtf $+    getTopFans <*> artist "Pink Floyd" <*> track "Comfortably Numb" <*> ak+  testGetTopFans_mbid = check gtf $+    getTopFans <*> mbid "b6581c74-0b8c-4981-ab92-7eed0298a4bb" <*> ak++  testGetTopTags = check gtt $+    getTopTags <*> artist "Pink Floyd" <*> track "Comfortably Numb" <*> ak+  testGetTopTags_mbid = check gtt $+    getTopTags <*> mbid "b6581c74-0b8c-4981-ab92-7eed0298a4bb" <*> ak++  testSearch = check s' $+    search <*> track "Believe" <* limit 12 <*> ak+++gc, gi, gt, ss, np ∷ Value → Parser String+gbl, gfm, gsh, gsi{-, gta-}, gtf, gtt, s' ∷ Value → Parser [String]+gbl o = parseJSON o >>= (.: "affiliations") >>= (.: "downloads") >>= (.: "affiliation") >>= mapM (.: "supplierName")+gc o = parseJSON o >>= (.: "corrections") >>= (.: "correction") >>= (.: "track") >>= (.: "artist") >>= (.: "name")+gfm o = parseJSON o >>= (.: "tracks") >>= (.: "track") >>= mapM (.: "name")+gi o = parseJSON o >>= (.: "track") >>= (.: "userplaycount")+gsh o = parseJSON o >>= (.: "shouts") >>= (.: "shout") >>= mapM (.: "author")+gsi o = parseJSON o >>= (.: "similartracks") >>= (.: "track") >>= mapM (.: "name")+gt o = parseJSON o >>= (.: "tags") >>= (.: "@attr") >>= (.: "track")+gtf o = parseJSON o >>= (.: "topfans") >>= (.: "user") >>= mapM (.: "name")+gtt o = parseJSON o >>= (.: "toptags") >>= (.: "tag") >>= mapM (.: "name")+s' o = parseJSON o >>= (.: "results") >>= (.: "trackmatches") >>= (.: "track") >>= mapM (.: "name")+ss o = parseJSON o >>= (.: "scrobbles") >>= (.: "scrobble") >>= (.: "track") >>= (.: "#text")+np o = parseJSON o >>= (.: "nowplaying") >>= (.: "track") >>= (.: "#text")
+ tests/User.hs view
@@ -0,0 +1,150 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module User (auth, noauth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.User+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++auth ∷ Request JSON Sign APIKey → Request JSON Sign SessionKey → Secret → [Test]+auth ak sk s =+  [ testCase "User.getRecentStations" testGetRecentStations+  , testCase "User.getRecommendedArtists" testGetRecommendedArtists+  , testCase "User.getRecommendedEvents" testGetRecommendedEvents+  , testCase "User.shout" testShout+  ]+ where+  testGetRecentStations = check grs . sign s $+    getRecentStations <*> user "liblastfm" <* limit 10 <*> ak <*> sk++  testGetRecommendedArtists = check gra . sign s $+    getRecommendedArtists <* limit 10 <*> ak <*> sk++  testGetRecommendedEvents = check gre . sign s $+    getRecommendedEvents <* limit 10 <*> ak <*> sk++  testShout = check ok . sign s $+    shout <*> user "liblastfm" <*> message "test message" <*> ak <*> sk+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "User.getArtistTracks" testGetArtistTracks+  , testCase "User.getBannedTracks" testGetBannedTracks+  , testCase "User.getEvents" testGetEvents+  , testCase "User.getFriends" testGetFriends+  , testCase "User.getPlayCount" testGetPlayCount+  , testCase "User.getGetLovedTracks" testGetLovedTracks+  , testCase "User.getNeighbours" testGetNeighbours+  , testCase "User.getNewReleases" testGetNewReleases+  , testCase "User.getPastEvents" testGetPastEvents+  , testCase "User.getPersonalTags" testGetPersonalTags+  , testCase "User.getPlaylists" testGetPlaylists+  , testCase "User.getRecentTracks" testGetRecentTracks+  , testCase "User.getShouts" testGetShouts+  , testCase "User.getTopAlbums" testGetTopAlbums+  , testCase "User.getTopArtists" testGetTopArtists+  , testCase "User.getTopTags" testGetTopTags+  , testCase "User.getTopTracks" testGetTopTracks+  , testCase "User.getWeeklyAlbumChart" testGetWeeklyAlbumChart+  , testCase "User.getWeeklyArtistChart" testGetWeeklyArtistChart+  , testCase "User.getWeeklyChartList" testGetWeeklyChartList+  , testCase "User.getWeeklyTrackChart" testGetWeeklyTrackChart+  ]+ where+  testGetArtistTracks = check gat $+    getArtistTracks <*> user "smpcln" <*> artist "Dvar" <*> ak++  testGetBannedTracks = check gbt $+    getBannedTracks <*> user "smpcln" <* limit 10 <*> ak++  testGetEvents = check ge $+    getEvents <*> user "chansonnier" <* limit 5 <*> ak++  testGetFriends = check gf $+    getFriends <*> user "smpcln" <* limit 10 <*> ak++  testGetPlayCount = check gpc $+    getInfo <*> user "smpcln" <*> ak++  testGetLovedTracks = check glt $+    getLovedTracks <*> user "smpcln" <* limit 10 <*> ak++  testGetNeighbours = check gn $+    getNeighbours <*> user "smpcln" <* limit 10 <*> ak++  testGetNewReleases = check gnr $+    getNewReleases <*> user "smpcln" <*> ak++  testGetPastEvents = check gpe $+    getPastEvents <*> user "mokele" <* limit 5 <*> ak++  testGetPersonalTags = check gpt $+    getPersonalTags <*> user "crackedcore" <*> tag "rhythmic noise" <*> taggingType "artist" <* limit 10 <*> ak++  testGetPlaylists = check gp $+    getPlaylists <*> user "mokele" <*> ak++  testGetRecentTracks = check grt $+    getRecentTracks <*> user "smpcln" <* limit 10 <*> ak++  testGetShouts = check gs $+    getShouts <*> user "smpcln" <* limit 2 <*> ak++  testGetTopAlbums = check gtal $+    getTopAlbums <*> user "smpcln" <* limit 5 <*> ak++  testGetTopArtists = check gtar $+    getTopArtists <*> user "smpcln" <* limit 5 <*> ak++  testGetTopTags = check gtta $+    getTopTags <*> user "smpcln" <* limit 10 <*> ak++  testGetTopTracks = check gttr $+    getTopTracks <*> user "smpcln" <* limit 10 <*> ak++  testGetWeeklyAlbumChart = check gwalc $+    getWeeklyAlbumChart <*> user "smpcln" <*> ak++  testGetWeeklyArtistChart = check gwarc $+    getWeeklyArtistChart <*> user "smpcln" <*> ak++  testGetWeeklyChartList = check gwcl $+    getWeeklyChartList <*> user "smpcln" <*> ak++  testGetWeeklyTrackChart = check gwtc $+    getWeeklyTrackChart <*> user "smpcln" <*> ak+++gpc ∷ Value → Parser String+gat, gbt, ge, gf, glt, gn, gnr, gp, gpe, gpt, gra, gre, grs, grt, gs, gtal, gtar, gtta, gttr, gwalc, gwarc, gwcl, gwtc ∷ Value → Parser [String]+gat o = parseJSON o >>= (.: "artisttracks") >>= (.: "track") >>= mapM (.: "name")+gbt o = parseJSON o >>= (.: "bannedtracks") >>= (.: "track") >>= mapM (.: "name")+ge o = parseJSON o >>= (.: "events") >>= (.: "event") >>= mapM (.: "venue") >>= mapM (.: "url")+gf o = parseJSON o >>= (.: "friends") >>= (.: "user") >>= mapM (.: "name")+glt o = parseJSON o >>= (.: "lovedtracks") >>= (.: "track") >>= mapM (.: "name")+gn o = parseJSON o >>= (.: "neighbours") >>= (.: "user") >>= mapM (.: "name")+gnr o = parseJSON o >>= (.: "albums") >>= (.: "album") >>= mapM (.: "url")+gp o = parseJSON o >>= (.: "playlists") >>= (.: "playlist") >>= mapM (.: "title")+gpc o = parseJSON o >>= (.: "user") >>= (.: "playcount")+gpe o = parseJSON o >>= (.: "events") >>= (.: "event") >>= mapM (.: "url")+gpt o = parseJSON o >>= (.: "taggings") >>= (.: "artists") >>= (.: "artist") >>= mapM (.: "name")+gra o = parseJSON o >>= (.: "recommendations") >>= (.: "artist") >>= mapM (.: "name")+gre o = parseJSON o >>= (.: "events") >>= (.: "event") >>= mapM (.: "url")+grs o = parseJSON o >>= (.: "recentstations") >>= (.: "station") >>= mapM (.: "name")+grt o = parseJSON o >>= (.: "recenttracks") >>= (.: "track") >>= mapM (.: "name")+gs o = parseJSON o >>= (.: "shouts") >>= (.: "shout") >>= mapM (.: "body")+gtal o = parseJSON o >>= (.: "topalbums") >>= (.: "album") >>= mapM (.: "artist") >>= mapM (.: "name")+gtar o = parseJSON o >>= (.: "topartists") >>= (.: "artist") >>= mapM (.: "name")+gtta o = parseJSON o >>= (.: "toptags") >>= (.: "tag") >>= mapM (.: "name")+gttr o = parseJSON o >>= (.: "toptracks") >>= (.: "track") >>= mapM (.: "url")+gwalc o = parseJSON o >>= (.: "weeklyalbumchart") >>= (.: "album") >>= mapM (.: "url")+gwarc o = parseJSON o >>= (.: "weeklyartistchart") >>= (.: "artist") >>= mapM (.: "url")+gwcl o = take 5 `fmap` (parseJSON o >>= (.: "weeklychartlist") >>= (.: "chart") >>= mapM (.: "from"))+gwtc o = parseJSON o >>= (.: "weeklytrackchart") >>= (.: "track") >>= mapM (.: "url")
+ tests/Venue.hs view
@@ -0,0 +1,35 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UnicodeSyntax #-}+module Venue (noauth) where++import Data.Aeson.Types+import Network.Lastfm+import Network.Lastfm.Venue+import Test.Framework+import Test.Framework.Providers.HUnit++import Common+++noauth ∷ Request JSON Send APIKey → [Test]+noauth ak =+  [ testCase "Venue.getEvents" testGetEvents+  , testCase "Venue.getPastEvents" testGetPastEvents+  , testCase "Venue.search" testSearch+  ]+ where+  testGetEvents = check ge $+    getEvents <*> venue 9163107 <*> ak++  testGetPastEvents = check gpe $+    getPastEvents <*> venue 9163107 <* limit 2 <*> ak++  testSearch = check se $+    search <*> venueName "Arena" <*> ak+++ge, gpe, se ∷ Value → Parser [String]+ge o = parseJSON o >>= (.: "events") >>= (.: "event") >>= mapM (\t → (t .: "venue") >>= (.: "name"))+gpe o = parseJSON o >>= (.: "events") >>= (.: "event") >>= mapM (.: "title")+se o = parseJSON o >>= (.: "results") >>= (.: "venuematches") >>= (.: "venue") >>= mapM (.: "id")