Types.purs (12815B)
1 module Types where 2 3 import Prelude 4 5 import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson, (.:), (.:?), (:=), (~>)) 6 import Data.Argonaut.Decode.Error (JsonDecodeError(..)) 7 import Data.Either (Either(..)) 8 import Data.Argonaut.Core (Json, toArray, jsonEmptyObject, toNumber, toString) 9 import Data.Int (fromString, fromNumber) 10 import Data.Maybe (Maybe(..), fromMaybe) 11 import Data.Generic.Rep (class Generic) 12 import Data.Show.Generic (genericShow) 13 14 newtype ListenBrainzSubmitPayload = ListenBrainzSubmitPayload 15 { listenType :: String 16 , payload :: Array ListenBrainzSubmitListen 17 } 18 19 derive instance eqListenBrainzSubmitPayload :: Eq ListenBrainzSubmitPayload 20 derive instance genericListenBrainzSubmitPayload :: Generic ListenBrainzSubmitPayload _ 21 instance showListenBrainzSubmitPayload :: Show ListenBrainzSubmitPayload where 22 show = genericShow 23 24 instance DecodeJson ListenBrainzSubmitPayload where 25 decodeJson json = do 26 obj <- decodeJson json 27 listenType <- obj .: "listen_type" 28 payload <- obj .: "payload" 29 pure $ ListenBrainzSubmitPayload { listenType, payload } 30 31 newtype ListenBrainzSubmitListen = ListenBrainzSubmitListen 32 { listenedAt :: Maybe Int 33 , trackMetadata :: ListenBrainzSubmitTrackMetadata 34 } 35 36 derive instance eqListenBrainzSubmitListen :: Eq ListenBrainzSubmitListen 37 derive instance genericListenBrainzSubmitListen :: Generic ListenBrainzSubmitListen _ 38 instance showListenBrainzSubmitListen :: Show ListenBrainzSubmitListen where 39 show = genericShow 40 41 instance DecodeJson ListenBrainzSubmitListen where 42 decodeJson json = do 43 obj <- decodeJson json 44 listenedAt <- obj .:? "listened_at" 45 trackMetadata <- obj .: "track_metadata" 46 pure $ ListenBrainzSubmitListen { listenedAt, trackMetadata } 47 48 newtype ListenBrainzSubmitTrackMetadata = ListenBrainzSubmitTrackMetadata 49 { trackName :: String 50 , artistName :: String 51 , releaseName :: Maybe String 52 , additionalInfo :: Maybe ListenBrainzAdditionalInfo 53 } 54 55 derive instance eqListenBrainzSubmitTrackMetadata :: Eq ListenBrainzSubmitTrackMetadata 56 derive instance genericListenBrainzSubmitTrackMetadata :: Generic ListenBrainzSubmitTrackMetadata _ 57 instance showListenBrainzSubmitTrackMetadata :: Show ListenBrainzSubmitTrackMetadata where 58 show = genericShow 59 60 instance DecodeJson ListenBrainzSubmitTrackMetadata where 61 decodeJson json = do 62 obj <- decodeJson json 63 trackName <- obj .: "track_name" 64 artistName <- obj .: "artist_name" 65 releaseName <- obj .:? "release_name" 66 additionalInfo <- obj .:? "additional_info" 67 pure $ ListenBrainzSubmitTrackMetadata { trackName, artistName, releaseName, additionalInfo } 68 69 newtype ListenBrainzAdditionalInfo = ListenBrainzAdditionalInfo 70 { releaseMbid :: Maybe String 71 , artistMbids :: Maybe (Array String) 72 , recordingMbid :: Maybe String 73 } 74 75 derive instance eqListenBrainzAdditionalInfo :: Eq ListenBrainzAdditionalInfo 76 derive instance genericListenBrainzAdditionalInfo :: Generic ListenBrainzAdditionalInfo _ 77 instance showListenBrainzAdditionalInfo :: Show ListenBrainzAdditionalInfo where 78 show = genericShow 79 80 instance DecodeJson ListenBrainzAdditionalInfo where 81 decodeJson json = do 82 obj <- decodeJson json 83 releaseMbid <- obj .:? "release_mbid" 84 artistMbids <- obj .:? "artist_mbids" 85 recordingMbid <- obj .:? "recording_mbid" 86 pure $ ListenBrainzAdditionalInfo { releaseMbid, artistMbids, recordingMbid } 87 88 newtype ListenBrainzResponse = ListenBrainzResponse 89 { payload :: Payload 90 } 91 92 derive instance eqListenBrainzResponse :: Eq ListenBrainzResponse 93 derive instance genericListenBrainzResponse :: Generic ListenBrainzResponse _ 94 instance showListenBrainzResponse :: Show ListenBrainzResponse where 95 show = genericShow 96 97 instance DecodeJson ListenBrainzResponse where 98 decodeJson json = do 99 obj <- decodeJson json 100 payload <- obj .: "payload" 101 pure $ ListenBrainzResponse { payload } 102 103 instance EncodeJson ListenBrainzResponse where 104 encodeJson (ListenBrainzResponse { payload }) = 105 "payload" := encodeJson payload 106 ~> jsonEmptyObject 107 108 newtype Payload = Payload 109 { listens :: Array Listen 110 } 111 112 derive instance eqPayload :: Eq Payload 113 derive instance genericPayload :: Generic Payload _ 114 instance showPayload :: Show Payload where 115 show = genericShow 116 117 instance DecodeJson Payload where 118 decodeJson json = do 119 obj <- decodeJson json 120 listens <- obj .: "listens" 121 pure $ Payload { listens } 122 123 instance EncodeJson Payload where 124 encodeJson (Payload { listens }) = 125 "listens" := encodeJson listens 126 ~> jsonEmptyObject 127 128 newtype Listen = Listen 129 { trackMetadata :: TrackMetadata 130 , listenedAt :: Maybe Int 131 } 132 133 derive instance eqListen :: Eq Listen 134 derive instance genericListen :: Generic Listen _ 135 instance showListen :: Show Listen where 136 show = genericShow 137 138 instance DecodeJson Listen where 139 decodeJson json = do 140 obj <- decodeJson json 141 trackMetadata <- obj .: "track_metadata" 142 listenedAt <- obj .:? "listened_at" 143 pure $ Listen { trackMetadata, listenedAt } 144 145 instance EncodeJson Listen where 146 encodeJson (Listen { trackMetadata, listenedAt }) = 147 "track_metadata" := encodeJson trackMetadata 148 ~> "listened_at" := encodeJson listenedAt 149 ~> jsonEmptyObject 150 151 newtype TrackMetadata = TrackMetadata 152 { trackName :: Maybe String 153 , artistName :: Maybe String 154 , releaseName :: Maybe String 155 , mbidMapping :: Maybe MbidMapping 156 , genre :: Maybe String 157 , label :: Maybe String 158 } 159 160 derive instance eqTrackMetadata :: Eq TrackMetadata 161 derive instance genericTrackMetadata :: Generic TrackMetadata _ 162 instance showTrackMetadata :: Show TrackMetadata where 163 show = genericShow 164 165 instance DecodeJson TrackMetadata where 166 decodeJson json = do 167 obj <- decodeJson json 168 trackName <- obj .:? "track_name" 169 artistName <- obj .:? "artist_name" 170 releaseName <- obj .:? "release_name" 171 mbidMapping <- obj .:? "mbid_mapping" 172 genre <- obj .:? "genre" 173 label <- obj .:? "label" 174 pure $ TrackMetadata { trackName, artistName, releaseName, mbidMapping, genre, label } 175 176 instance EncodeJson TrackMetadata where 177 encodeJson (TrackMetadata { trackName, artistName, releaseName, mbidMapping, genre, label }) = 178 "track_name" := encodeJson trackName 179 ~> "artist_name" := encodeJson artistName 180 ~> "release_name" := encodeJson releaseName 181 ~> "mbid_mapping" := encodeJson mbidMapping 182 ~> "genre" := encodeJson genre 183 ~> "label" := encodeJson label 184 ~> jsonEmptyObject 185 186 newtype MbidMapping = MbidMapping 187 { releaseMbid :: Maybe String 188 , caaReleaseMbid :: Maybe String 189 } 190 191 derive instance eqMbidMapping :: Eq MbidMapping 192 derive instance genericMbidMapping :: Generic MbidMapping _ 193 instance showMbidMapping :: Show MbidMapping where 194 show = genericShow 195 196 instance DecodeJson MbidMapping where 197 decodeJson json = do 198 obj <- decodeJson json 199 releaseMbid <- obj .:? "release_mbid" 200 caaReleaseMbid <- obj .:? "caa_release_mbid" 201 pure $ MbidMapping { releaseMbid, caaReleaseMbid } 202 203 instance EncodeJson MbidMapping where 204 encodeJson (MbidMapping { releaseMbid, caaReleaseMbid }) = 205 "release_mbid" := encodeJson releaseMbid 206 ~> "caa_release_mbid" := encodeJson caaReleaseMbid 207 ~> jsonEmptyObject 208 209 -- Last.fm API types 210 211 newtype LastfmAttr = LastfmAttr 212 { totalPages :: Int 213 } 214 215 derive instance genericLastfmAttr :: Generic LastfmAttr _ 216 instance showLastfmAttr :: Show LastfmAttr where 217 show = genericShow 218 219 instance decodeJsonLastfmAttr :: DecodeJson LastfmAttr where 220 decodeJson json = do 221 obj <- decodeJson json 222 tpJson <- obj .: "totalPages" 223 let 224 tpStr = toString tpJson 225 tpNum = toNumber tpJson 226 parsed = case tpStr >>= fromString of 227 Just n -> Just n 228 Nothing -> tpNum >>= fromNumber 229 case parsed of 230 Just n -> pure $ LastfmAttr { totalPages: n } 231 Nothing -> Left $ TypeMismatch "Invalid totalPages" 232 233 newtype LastfmTrackArray = LastfmTrackArray (Array Json) 234 newtype LastfmTrackSingle = LastfmTrackSingle Json 235 236 data LastfmTracks = LastfmTrackArray' (Array Json) | LastfmTrackSingle' Json 237 238 instance showLastfmTracks :: Show LastfmTracks where 239 show (LastfmTrackArray' _) = "LastfmTrackArray' _" 240 show (LastfmTrackSingle' _) = "LastfmTrackSingle' _" 241 242 newtype LastfmRecentTracks = LastfmRecentTracks 243 { track :: LastfmTracks 244 , attr :: LastfmAttr 245 } 246 247 derive instance genericLastfmRecentTracks :: Generic LastfmRecentTracks _ 248 instance showLastfmRecentTracks :: Show LastfmRecentTracks where 249 show = genericShow 250 251 instance decodeJsonLastfmRecentTracks :: DecodeJson LastfmRecentTracks where 252 decodeJson json = do 253 obj <- decodeJson json 254 attr <- obj .: "@attr" 255 trackResult <- obj .:? "track" 256 tracks <- case trackResult of 257 Nothing -> 258 pure $ LastfmTrackArray' [] 259 Just trackJson -> 260 case toArray trackJson of 261 Just arr -> 262 pure $ LastfmTrackArray' arr 263 Nothing -> 264 pure $ LastfmTrackSingle' trackJson 265 pure $ LastfmRecentTracks { track: tracks, attr } 266 267 newtype LastfmResponse = LastfmResponse 268 { recenttracks :: LastfmRecentTracks 269 } 270 271 derive instance genericLastfmResponse :: Generic LastfmResponse _ 272 instance showLastfmResponse :: Show LastfmResponse where 273 show = genericShow 274 275 instance decodeJsonLastfmResponse :: DecodeJson LastfmResponse where 276 decodeJson json = do 277 obj <- decodeJson json 278 recenttracks <- obj .: "recenttracks" 279 pure $ LastfmResponse { recenttracks } 280 281 newtype LastfmArtist = LastfmArtist { text :: String } 282 283 derive instance genericLastfmArtist :: Generic LastfmArtist _ 284 instance showLastfmArtist :: Show LastfmArtist where 285 show = genericShow 286 287 instance decodeJsonLastfmArtist :: DecodeJson LastfmArtist where 288 decodeJson json = do 289 obj <- decodeJson json 290 text <- obj .: "#text" 291 pure $ LastfmArtist { text } 292 293 newtype LastfmAlbum = LastfmAlbum 294 { text :: Maybe String 295 , mbid :: String 296 } 297 298 derive instance genericLastfmAlbum :: Generic LastfmAlbum _ 299 instance showLastfmAlbum :: Show LastfmAlbum where 300 show = genericShow 301 302 instance decodeJsonLastfmAlbum :: DecodeJson LastfmAlbum where 303 decodeJson json = do 304 obj <- decodeJson json 305 text <- obj .:? "#text" 306 mbid <- fromMaybe "" <$> obj .:? "mbid" 307 pure $ LastfmAlbum { text, mbid } 308 309 newtype LastfmDate = LastfmDate { uts :: Int } 310 311 derive instance genericLastfmDate :: Generic LastfmDate _ 312 instance showLastfmDate :: Show LastfmDate where 313 show = genericShow 314 315 instance decodeJsonLastfmDate :: DecodeJson LastfmDate where 316 decodeJson json = do 317 obj <- decodeJson json 318 utsStr <- obj .: "uts" 319 case fromString utsStr of 320 Just n -> pure $ LastfmDate { uts: n } 321 Nothing -> Left $ TypeMismatch $ "Invalid uts: " <> utsStr 322 323 newtype LastfmTrack = LastfmTrack 324 { name :: String 325 , artist :: LastfmArtist 326 , album :: Maybe LastfmAlbum 327 , date :: Maybe LastfmDate 328 } 329 330 derive instance genericLastfmTrack :: Generic LastfmTrack _ 331 instance showLastfmTrack :: Show LastfmTrack where 332 show = genericShow 333 334 instance decodeJsonLastfmTrack :: DecodeJson LastfmTrack where 335 decodeJson json = do 336 obj <- decodeJson json 337 name <- obj .: "name" 338 artist <- obj .: "artist" 339 album <- obj .:? "album" 340 date <- obj .:? "date" 341 pure $ LastfmTrack { name, artist, album, date } 342 343 newtype StatsEntry = StatsEntry 344 { name :: String 345 , count :: Int 346 } 347 348 derive instance eqStatsEntry :: Eq StatsEntry 349 derive instance genericStatsEntry :: Generic StatsEntry _ 350 instance showStatsEntry :: Show StatsEntry where 351 show = genericShow 352 353 instance DecodeJson StatsEntry where 354 decodeJson json = do 355 obj <- decodeJson json 356 name <- obj .: "name" 357 count <- obj .: "count" 358 pure $ StatsEntry { name, count } 359 360 instance EncodeJson StatsEntry where 361 encodeJson (StatsEntry { name, count }) = 362 "name" := encodeJson name 363 ~> "count" := encodeJson count 364 ~> jsonEmptyObject 365 366 newtype Stats = Stats 367 { genres :: Array StatsEntry 368 , labels :: Array StatsEntry 369 , years :: Array StatsEntry 370 , artists :: Array StatsEntry 371 , tracks :: Array StatsEntry 372 } 373 374 derive instance eqStats :: Eq Stats 375 derive instance genericStats :: Generic Stats _ 376 instance showStats :: Show Stats where 377 show = genericShow 378 379 instance DecodeJson Stats where 380 decodeJson json = do 381 obj <- decodeJson json 382 genres <- obj .: "genres" 383 labels <- obj .: "labels" 384 years <- obj .: "years" 385 artists <- obj .: "artists" 386 tracks <- obj .: "tracks" 387 pure $ Stats { genres, labels, years, artists, tracks } 388 389 instance EncodeJson Stats where 390 encodeJson (Stats { genres, labels, years, artists, tracks }) = 391 "genres" := encodeJson genres 392 ~> "labels" := encodeJson labels 393 ~> "years" := encodeJson years 394 ~> "artists" := encodeJson artists 395 ~> "tracks" := encodeJson tracks 396 ~> jsonEmptyObject