No 1 at Christmas
This is my post for the 2015 F# advent calendar series for the 5th of December. I wanted to do a post using F# Type Providers and data. For this post I’ve used FSharp.Data’s HTML and JSON providers to read data about UK Christmas No 1 singles and show some details.
Using the HTML Type Provider I was able to easily get all the Christmas No 1s from a table on the Official Charts website:
type Number1s = HtmlProvider<"http://www.officialcharts.com/chart-news/every-official-christmas-number-1-ever-__3618/"> let number1s = Number1s.GetSample() [for row in number1s.Tables.Table1.Rows -> row.YEAR, row.ARTIST, row.TITLE ]
Next I wanted to get pictures for all the Christmas singles. Last.fm has a handy API which lets you search for track information using the title and artist name and returns some JSON, which can be fed into the JSON Type Provider:
let [<Literal>] sample = "http://ws.audioscrobbler.com/2.0/?method=track.search&track=save%20your%20love&artist=REN%C3%89E%20AND%20RENATO&format=json&api_key=" + api_key type TrackSearch = JsonProvider<sample> let trackSearch = TrackSearch.GetSample() let track = trackSearch.Results.Trackmatches.Track.[0] let pic = track.Image.[1].Text
Finally I wanted to make a table in HTML. For this I got a little help from dad and his static HTML library:
table [ thead [tr [th %"Play"; th %"Year"; th %"Artist"; th %"Title"]] tbody [for row in number1s.Tables.Table1.Rows |> Array.rev -> let artist = match row.ARTIST with | "MICHAEL ANDREWS & GARY JULES" -> "MICHAEL ANDREWS" | "MILITARY WIVES WITH GARETH MALONE" -> "MILITARY WIVES" | name -> name printfn "Album %d %s %s" row.YEAR row.ARTIST row.TITLE let trackSearchRequest = "http://ws.audioscrobbler.com/2.0/" + "?method=track.search" + "&track=" + HttpUtility.UrlPathEncode (row.TITLE.Replace("?","").Replace("&","AND")) + "&artist=" + HttpUtility.UrlPathEncode (artist.Replace("&","AND")) + "&api_key=" + api_key + "&format=json" let search = TrackSearch.Load(trackSearchRequest) let track0 = search.Results.Trackmatches.Track.[0] let mediumImage = track0.Image.[1].Text tr [ td [a (("href"%=track0.Url)::[img ["src"%=mediumImage]])] td %(sprintf "%d" row.YEAR) td %(row.ARTIST) td %(row.TITLE) ] ] ] |> Html.toString
Here’s all the UK Christmas No 1s from 2014 until 1952 (my favourite is Rage Against the Machine):
Merry Christmas and a happy New Year!