{-# LANGUAGE DeriveDataTypeable #-} -- | Scrobbling data types. module Scrobble.Types where import Control.Exception import Data.Data import Data.Time import Network import Network.URI (URI) -- | Server configuration. data Config = Config { cfgPort :: PortNumber -- ^ Port to listen on. , cfgHost :: String -- ^ Host name used for server (probably just localhost). , cfgExpire :: NominalDiffTime -- ^ Number of seconds of inactivity before a session expires. } deriving (Show) -- | Event handlers. data Handlers = Handlers { handleHandshake :: Session -> IO () -- ^ Initial connection hand-shake. , handleExpire :: Session -> IO () -- ^ Session expiry. , handleNowPlaying :: Session -> NowPlaying -> IO () -- ^ Now-playing notification. , handleSubmissions :: Session -> [Submission] -> IO Bool -- ^ Played tracks submission. } -- | A scrobbling session. data Session = Session { sesHandshake :: Bool -- ^ Does the session require handshake? , sesVersion :: String -- ^ Version of the protocol. , sesClientId :: String -- ^ Client (music player's) id. , sesClientVer :: String -- ^ Client version. , sesUser :: String -- ^ Username. , sesTimestamp :: UTCTime -- ^ Timestamp of connection. , sesToken :: String -- ^ Session token. } deriving (Show) -- | A now playing track. data NowPlaying = NowPlaying { npArtist :: String -- ^ Artist name. , npTrack :: String -- ^ Track title. , npAlbum :: Maybe String -- ^ Album name (if any). , npLength :: Maybe Integer -- ^ Track length in seconds (if known). , npPosition :: Maybe Integer -- ^ Track position (if known). , npMusicBrainz :: Maybe String -- ^ MusicBrainz track id (if known). } deriving (Show) -- | A track submission. data Submission = Submission { subArtist :: String -- ^ Artist name. , subTrack :: String -- ^ Track title. , subTimestamp :: UTCTime -- ^ Track timestamp. , subSource :: Source -- ^ Source of track. , subRating :: Maybe Rating -- ^ Rating (if any). , subLength :: Maybe Integer -- ^ Track length (if any). , subAlbum :: Maybe String -- ^ Album (if any). , subPosition :: Maybe Integer -- ^ Track position in album (if any). , subMusicBrainz :: Maybe String -- ^ MusicBrainz track id (if any). } deriving (Show) -- | A rating of a track. -- -- Note: Currently, a web-service must also be called to set love/ban -- status. We anticipate that this will be phased out soon, and the -- submission service will handle the whole process. data Rating = Love -- ^ Love (on any mode if the user has manually loved the -- track). This implies a listen. | Ban -- ^ Ban (only if source=L). This implies a skip, and the -- client should skip to the next track when a ban happens. | Skip -- ^ Skip (only if source=L). deriving (Enum,Eq,Show,Read) -- | The source of the track. Required, must be one of the following -- codes: -- -- Please note, for the time being, sources other than P and L are not -- supported. data Source = UserChosen -- ^ Chosen by the user | NonPersonlizedBroadcast -- ^ Non-personalised broadcast -- (e.g. Shoutcast, BBC Radio 1) | Personalized -- ^ Personalised recommendation except Last.fm -- (e.g. Pandora, Launchcast) | LastFm -- ^ Last.fm (any mode). In this case, the 5-digit Last.fm -- recommendation key must be appended to this source ID to -- prove the validity of the submission (for example, -- "o[0]=L1b48a"). | Unknown -- ^ Source unknown. deriving (Show,Enum,Eq,Read) -- | Server response. data Response = OK | BANNED | BADAUTH | FAILED String | BADSESSION deriving Show -- | A scrobbling client. data Client = Client { cliToken :: String -- ^ Session token. , cliNowPlaying :: URI -- ^ Now playing URL to submit to. , cliSubmit :: URI -- ^ URL to submit listened tracks to. } deriving (Show) -- | Details for creating a scrobbling client. data Details = Details { detPassword :: String , detUsername :: String , detClient :: String -- ^ E.g. “qlb”. , detVersion :: String -- ^ E.g. “0.9.2”. , detServer :: URI -- ^ See defaultServer in "Scrobble.Client". } deriving (Show) -- | Scrobble exception. data ScrobblerError = ScrobblerBanned | ScrobblerBadAuth | ScrobblerBadTime | ScrobblerFailed String | ScrobblerHardFail | ScrobblerSubmitFail String | ScrobblerNowPlayingFail String deriving (Show,Typeable,Data) instance Exception ScrobblerError