module Twitch exposing (Playlist, Video, fetchPlaylists) import Html.Parser import Http import Json.Decode as Decode import Task exposing (Task) type alias Playlist = { name : String , videos : List Video } type alias Video = { name : String , url : String } get : { url : String, resolver : Http.Resolver x a } -> Task x a get { url, resolver } = Http.task { body = Http.emptyBody , headers = [] , method = "GET" , resolver = resolver , timeout = Nothing , url = url } fetchPlaylists : Task x (List Playlist) fetchPlaylists = fetchPlaylistPath |> Task.andThen fetchPlaylistsMapper fetchPlaylistPath : Task x (List String) fetchPlaylistPath = get { url = "/videos" , resolver = Http.stringResolver parsePlaylistPath } fetchPlaylist : String -> Task x Playlist fetchPlaylist name = get { url = "/videos/" ++ name ++ "/description.json" , resolver = Http.stringResolver parsePlaylist } fetchPlaylistsMapper : List String -> Task x (List Playlist) fetchPlaylistsMapper names = Task.sequence (List.map fetchPlaylist names) parsePlaylist : Http.Response String -> Result x Playlist parsePlaylist result = case result of Http.GoodStatus_ _ content -> case Decode.decodeString decodePlaylist content of Ok p -> Ok p _ -> Ok { name = "", videos = [] } _ -> Ok { name = "", videos = [] } parsePlaylistPath : Http.Response String -> Result x (List String) parsePlaylistPath result = case result of Http.GoodStatus_ _ content -> let withoutDoctype = if String.startsWith " List.drop 1 |> String.join "\n" else content decoded = Html.Parser.run withoutDoctype hrefs = Result.map findHrefs decoded in case hrefs of Ok h -> Ok h _ -> Ok [] _ -> Ok [] findHrefsAux : List String -> Html.Parser.Node -> List String findHrefsAux acc node = case node of Html.Parser.Element string (( key, value ) :: t) nodes -> let newAcc = if key == "href" then value :: acc else acc in findHrefsAux newAcc (Html.Parser.Element string t nodes) Html.Parser.Element string [] (h :: t) -> let attrs = findHrefsAux [] h in findHrefsAux (acc ++ attrs) (Html.Parser.Element string [] t) _ -> acc findHrefs : List Html.Parser.Node -> List String findHrefs x = findHrefsAux [] (Html.Parser.Element "" [] x) decodePlaylist : Decode.Decoder Playlist decodePlaylist = Decode.map (\x -> Playlist x []) (Decode.field "title" Decode.string)