Fetching playlists work

This commit is contained in:
Thomas Forgione 2020-10-03 19:39:45 +02:00
parent e1a234e3e8
commit 34f7ddb015
1 changed files with 88 additions and 9 deletions

View File

@ -15,6 +15,7 @@ type alias Playlist =
type alias Video = type alias Video =
{ name : String { name : String
, url : String , url : String
, duration : Float
} }
@ -47,8 +48,50 @@ fetchPlaylist : String -> Task x Playlist
fetchPlaylist name = fetchPlaylist name =
get get
{ url = "/videos/" ++ name ++ "/description.json" { url = "/videos/" ++ name ++ "/description.json"
, resolver = Http.stringResolver parsePlaylist , resolver = Http.stringResolver parsePlaylistName
} }
|> Task.andThen
(\a ->
Task.map (\b -> Playlist a b)
(get
{ url = "/videos/" ++ name
, resolver = Http.stringResolver parsePlaylistVideoPaths
}
|> Task.andThen (\c -> fetchVideos name c)
)
)
fetchVideo : String -> String -> Task x Video
fetchVideo playlist video =
let
url =
"/videos/" ++ playlist ++ video
in
get
{ url = "/videos/" ++ playlist ++ "/" ++ video ++ "/description.json"
, resolver = Http.stringResolver (parseVideo url)
}
fetchVideos : String -> List String -> Task x (List Video)
fetchVideos playlist videos =
Task.sequence (List.map (fetchVideo playlist) videos)
parseVideo : String -> Http.Response String -> Result x Video
parseVideo url result =
case result of
Http.GoodStatus_ _ content ->
case Decode.decodeString (decodeVideo url) content of
Ok v ->
Ok v
_ ->
Ok { name = "", url = url, duration = 0 }
_ ->
Ok { name = "", url = url, duration = 0 }
fetchPlaylistsMapper : List String -> Task x (List Playlist) fetchPlaylistsMapper : List String -> Task x (List Playlist)
@ -56,19 +99,48 @@ fetchPlaylistsMapper names =
Task.sequence (List.map fetchPlaylist names) Task.sequence (List.map fetchPlaylist names)
parsePlaylist : Http.Response String -> Result x Playlist parsePlaylistName : Http.Response String -> Result x String
parsePlaylist result = parsePlaylistName result =
case result of case result of
Http.GoodStatus_ _ content -> Http.GoodStatus_ _ content ->
case Decode.decodeString decodePlaylist content of case Decode.decodeString decodePlaylistName content of
Ok p -> Ok p ->
Ok p Ok p
_ -> _ ->
Ok { name = "", videos = [] } Ok ""
_ -> _ ->
Ok { name = "", videos = [] } Ok ""
parsePlaylistVideoPaths : Http.Response String -> Result x (List String)
parsePlaylistVideoPaths result =
case result of
Http.GoodStatus_ _ content ->
let
withoutDoctype =
if String.startsWith "<!doctype" (String.toLower content) then
String.lines content |> 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 (List.filter (String.endsWith "/") h)
_ ->
Ok []
_ ->
Ok []
parsePlaylistPath : Http.Response String -> Result x (List String) parsePlaylistPath : Http.Response String -> Result x (List String)
@ -130,6 +202,13 @@ findHrefs x =
findHrefsAux [] (Html.Parser.Element "" [] x) findHrefsAux [] (Html.Parser.Element "" [] x)
decodePlaylist : Decode.Decoder Playlist decodePlaylistName : Decode.Decoder String
decodePlaylist = decodePlaylistName =
Decode.map (\x -> Playlist x []) (Decode.field "title" Decode.string) Decode.field "title" Decode.string
decodeVideo : String -> Decode.Decoder Video
decodeVideo url =
Decode.map2 (\x y -> Video x url y)
(Decode.field "title" Decode.string)
(Decode.field "duration" Decode.float)