Initial commit
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
module Core exposing (Model(..), Msg(..), init)
|
||||
|
||||
import Browser.Navigation
|
||||
import Json.Decode as Decode
|
||||
import Task
|
||||
import Twitch
|
||||
import Url
|
||||
|
||||
|
||||
type Model
|
||||
= Home
|
||||
|
||||
|
||||
type Msg
|
||||
= Noop
|
||||
| ReceivedPlaylists (List Twitch.Playlist)
|
||||
|
||||
|
||||
init : Decode.Value -> Url.Url -> Browser.Navigation.Key -> ( Model, Cmd Msg )
|
||||
init _ _ _ =
|
||||
( Home
|
||||
, Task.perform ReceivedPlaylists Twitch.fetchPlaylists
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
module Main exposing (main)
|
||||
|
||||
import Browser
|
||||
import Core
|
||||
import Json.Decode as Decode
|
||||
import Updates
|
||||
import Url
|
||||
import Views
|
||||
|
||||
|
||||
main : Program Decode.Value Core.Model Core.Msg
|
||||
main =
|
||||
Browser.application
|
||||
{ init = Core.init
|
||||
, update = Updates.update
|
||||
, view = Views.view
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, onUrlChange = onUrlChange
|
||||
, onUrlRequest = onUrlRequest
|
||||
}
|
||||
|
||||
|
||||
onUrlChange : Url.Url -> Core.Msg
|
||||
onUrlChange _ =
|
||||
Core.Noop
|
||||
|
||||
|
||||
onUrlRequest : Browser.UrlRequest -> Core.Msg
|
||||
onUrlRequest _ =
|
||||
Core.Noop
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
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 "<!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 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)
|
||||
@@ -0,0 +1,17 @@
|
||||
module Updates exposing (update)
|
||||
|
||||
import Core
|
||||
|
||||
|
||||
update : Core.Msg -> Core.Model -> ( Core.Model, Cmd Core.Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
Core.Noop ->
|
||||
( model, Cmd.none )
|
||||
|
||||
Core.ReceivedPlaylists playlists ->
|
||||
let
|
||||
_ =
|
||||
Debug.log "p" playlists
|
||||
in
|
||||
( model, Cmd.none )
|
||||
@@ -0,0 +1,12 @@
|
||||
module Views exposing (view)
|
||||
|
||||
import Browser
|
||||
import Core
|
||||
import Element
|
||||
|
||||
|
||||
view : Core.Model -> Browser.Document Core.Msg
|
||||
view model =
|
||||
{ title = "twitch.tforgione.fr"
|
||||
, body = [ Element.layout [] (Element.text "sup") ]
|
||||
}
|
||||
Reference in New Issue
Block a user