{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} module Network.Lastfm ( Lastfm, Response, LastfmError(..) , Secret(..) , Argument(..) , Album(..) , AlbumArtist(..) , APIKey(..) , Artist(..) , AuthToken(..) , Autocorrect(..) , Bitrate(..) , ChosenByUser(..) , Context(..) , Country(..) , Description(..) , Group(..) , Language(..) , Latitude(..) , Location(..) , Longitude(..) , Mbid(..) , Message(..) , Method(..) , Metro(..) , Multiplier(..) , Name(..) , Order(..) , Period(..) , Recipient(..) , SessionKey(..) , Status(..) , Station(..) , StreamId(..) , Tag(..) , TaggingType(..) , Title(..) , Token(..) , Track(..) , User(..) , Username(..) , Value(..) , Venuename(..) , BuyLinks(..) , Discovery(..) , FestivalsOnly(..) , Public(..) , RecentTracks(..) , RTP(..) , UseRecs(..) , Distance(..) , Duration(..) , Event(..) , Limit(..) , Page(..) , Playlist(..) , TrackNumber(..) , Venue(..) , End(..) , EndTimestamp(..) , Fingerprint(..) , From(..) , Start(..) , StartTimestamp(..) , Timestamp(..) , To(..) , simple ) where import Control.Applicative ((<$>), empty) import Control.Monad (liftM) import Data.List (intercalate) import Data.Maybe (fromJust) import Data.Aeson ((.:), FromJSON, decode, parseJSON) import qualified Data.Aeson import Data.ByteString.Lazy.Char8 (ByteString) import Network.Lastfm.Error import Network.Lastfm.TH type Lastfm a = IO (Either LastfmError a) type Response = ByteString newtype Secret = Secret String deriving Show $(newtypes "String" ["Album", "AlbumArtist", "APIKey", "Artist", "AuthToken", "Context", "Country", "Description", "Group", "Language", "Latitude", "Location", "Longitude", "Mbid", "Message", "Method", "Metro", "Name", "Recipient", "SessionKey", "Station", "StreamId", "Tag", "TaggingType", "Title", "Token", "Track", "User", "Username", "Venuename", "ChosenByUser"]) $(newtypes "Bool" ["Autocorrect", "BuyLinks", "Discovery", "FestivalsOnly", "Public", "RecentTracks", "RTP", "UseRecs"]) $(newtypes "Int" ["Distance", "Duration", "Event", "Limit", "Page", "Playlist", "TrackNumber", "Venue"]) $(newtypes "Integer" ["End", "EndTimestamp", "Fingerprint", "From", "Start", "StartTimestamp", "Timestamp", "To"]) data Bitrate = B64 | B128 deriving Show data Multiplier = M1 | M2 deriving Show data Order = Popularity | DateAdded deriving Show data Status = Yes | Maybe | No deriving Show data Value = ValueUser User | ValueArtists [Artist] data Period = Week | Quater | HalfYear | Year | Overall deriving Show instance Show Value where show (ValueUser _) = "user" show (ValueArtists _) = "artists" instance FromJSON Token where parseJSON (Data.Aeson.Object v) = Token <$> v .: "token" parseJSON _ = empty instance FromJSON SessionKey where parseJSON (Data.Aeson.Object v) = SessionKey <$> ((v .: "session") >>= (.: "key")) parseJSON _ = empty simple ∷ (FromJSON a, Monad m) ⇒ m ByteString → m a simple = liftM (fromJust . decode) class Argument a where key ∷ a → String value ∷ a → String instance Argument a ⇒ Argument (Maybe a) where key = maybe "" key; value = maybe "" value instance Argument a ⇒ Argument [a] where key (a:_) = key a ++ "s" key [] = "" value = intercalate "," . map value boolToString ∷ Bool → String boolToString True = "1" boolToString False = "0" --instance Argument $first where key = const $second; value ($first a) = $func a $(instances "id" [ ("Album","album") , ("AlbumArtist", "albumartist") , ("APIKey", "api_key") , ("Artist", "artist") , ("AuthToken", "authToken") , ("ChosenByUser", "chosenByUser") , ("Context", "context") , ("Country", "country") , ("Description", "description") , ("Group", "group") , ("Language", "lang") , ("Latitude", "lat") , ("Location", "location") , ("Longitude", "long") , ("Mbid", "mbid") , ("Message", "message") , ("Method", "method") , ("Metro", "metro") , ("Name", "name") , ("Recipient", "recipient") , ("SessionKey", "sk") , ("Station", "station") , ("StreamId", "streamId") , ("Tag", "tag") , ("TaggingType", "taggingtype") , ("Title", "title") , ("Token", "token") , ("Track", "track") , ("User", "user") , ("Username", "username") , ("Venuename", "venue") ]) $( instances "boolToString" [ ("Autocorrect", "autocorrect") , ("BuyLinks", "buylinks") , ("Discovery", "discovery") , ("FestivalsOnly", "festivalsonly") , ("Public", "public") , ("RecentTracks", "recenttracks") , ("RTP", "rtp") , ("UseRecs", "userecs") ]) $( instances "show" [ ("Distance", "distance") , ("Duration", "duration") , ("Event", "event") , ("Limit", "limit") , ("Page", "page") , ("Playlist", "playlistID") , ("TrackNumber", "tracknumber") , ("Venue", "venue") , ("End", "end") , ("EndTimestamp", "endTimestamp") , ("Fingerprint", "fingerprintid") , ("From", "from") , ("Start", "start") , ("StartTimestamp", "startTimestamp") , ("Timestamp", "timestamp") , ("To", "to") ]) instance Argument Bitrate where key = const "bitrate" value B64 = "64" value B128 = "128" instance Argument Multiplier where key = const "speed_multiplier" value M1 = "1.0" value M2 = "2.0" instance Argument Order where key = const "order" value Popularity = "popularity" value DateAdded = "dateadded" instance Argument Status where key = const "status" value Yes = "0" value Maybe = "1" value No = "2" instance Argument Value where key = const "value" value (ValueUser u) = value u value (ValueArtists as) = value as instance Argument Period where key = const "period" value Week = "7day" value Quater = "3month" value HalfYear = "6month" value Year = "12month" value Overall = "overall"