From 0ee82d7bc18f10d52f21ce774f27b66625c36927 Mon Sep 17 00:00:00 2001 From: Fons van der Plas Date: Mon, 23 Mar 2020 00:34:12 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=83=E2=80=8D=E2=99=80=EF=B8=8F=20List?= =?UTF-8?q?=20running=20sessions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project.toml | 2 +- assets/client.js | 2 +- assets/editor.html | 4 +- assets/editor.js | 2 +- assets/welcome.html | 50 +++++++++++++------ assets/welcome.js | 60 +++++++++++++++++++++++ src/webserver/Dynamic.jl | 85 +++++++++++++++++++++++++++++++-- src/webserver/NotebookServer.jl | 16 ++++--- 8 files changed, 191 insertions(+), 30 deletions(-) create mode 100644 assets/welcome.js diff --git a/Project.toml b/Project.toml index 05893711e6..72fc926ac6 100644 --- a/Project.toml +++ b/Project.toml @@ -2,7 +2,7 @@ name = "Pluto" uuid = "c3e4b0f8-55cb-11ea-2926-15256bba5781" license = "MIT" authors = ["Fons van der Plas ", "Mikołaj Bochenski "] -version = "0.3.3" +version = "0.3.4" [deps] HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3" diff --git a/assets/client.js b/assets/client.js index 18840f89de..ef7b47f5d1 100644 --- a/assets/client.js +++ b/assets/client.js @@ -45,7 +45,7 @@ class PlutoConnection { clientID: this.clientID, body: body, } - if (notebookID) { + if (this.notebookID) { toSend.notebookID = this.notebookID } if (cellUUID) { diff --git a/assets/editor.html b/assets/editor.html index 3995e663d1..0284981964 100644 --- a/assets/editor.html +++ b/assets/editor.html @@ -379,8 +379,8 @@
-

- Pluto.jl

+

+ Pluto.jl

Loading...

diff --git a/assets/editor.js b/assets/editor.js index 01d973f034..527d975da1 100644 --- a/assets/editor.js +++ b/assets/editor.js @@ -14,7 +14,7 @@ document.addEventListener("DOMContentLoaded", () => { document.title = cuteName } - remoteNotebookList = null + window.remoteNotebookList = null function updateRemoteNotebooks(list) { remoteNotebookList = list diff --git a/assets/welcome.html b/assets/welcome.html index 786d3e22a0..8709b0a0a5 100644 --- a/assets/welcome.html +++ b/assets/welcome.html @@ -54,26 +54,36 @@ body { margin: 0px; - } - - main { position: absolute; width: 100%; height: 100%; background: white; } - ul { - padding-left: 0px; + main { + width: 15em; margin: 0 auto; - margin-top: 25vh; + margin-top: 20vh; + text-align: left; - list-style: none; font-family: 'Roboto Mono', monospace; color: hsl(0, 0%, 60%); } + p { + color: hsl(0, 0%, 30%); + } + + ul { + padding-left: .5em; + list-style: none; + } + + ul.running { + margin-bottom: 10em; + } + li { margin-bottom: .9em; } @@ -97,14 +107,20 @@ width: 20%; font-family: inherit; } + + body.loading .running, + body.nosessions .running{ + display: none; + } - -
-
-

welcome to ot emoclew

-
    + +
    +

    welcome to ot emoclew

    +
    +

    New session:

    + -
    -
+
+

Running sessions:

+
    + + + + + \ No newline at end of file diff --git a/assets/welcome.js b/assets/welcome.js new file mode 100644 index 0000000000..0a4c7d0731 --- /dev/null +++ b/assets/welcome.js @@ -0,0 +1,60 @@ +document.addEventListener("DOMContentLoaded", () => { + + /* REMOTE NOTEBOOK LIST */ + + window.remoteNotebookList = null + + function updateRemoteNotebooks(list) { + remoteNotebookList = list + + var listEl = document.querySelector("ul.running") + listEl.innerHTML = "" + document.body.classList.add("nosessions") + list.forEach(nb => { + document.body.classList.remove("nosessions") + var a = document.createElement("a") + a.href = "/edit?uuid=" + nb.uuid + a.innerText = nb.shortpath + + var li = document.createElement("li") + li.appendChild(a) + + listEl.appendChild(li) + }) + console.log(list) + } + + /* SERVER CONNECTION */ + + function onUpdate(update, byMe) { + var message = update.message + + switch (update.type) { + case "notebook_list": + // TODO: catch exception + updateRemoteNotebooks(message.notebooks) + break + default: + console.error("Received unknown update type!") + break + } + } + + function onEstablishConnection(){ + // on socket success + // TODO: we should when exactly this happens + document.body.classList.remove("loading") + } + + function onConnect() { + console.info("connected") + } + + function onDisconnect() { + console.info("disconnected") + } + + window.client = new PlutoConnection(onUpdate, onEstablishConnection, onConnect, onDisconnect) + client.initialize() +}); + diff --git a/src/webserver/Dynamic.jl b/src/webserver/Dynamic.jl index 984d632fdc..08b3a7c156 100644 --- a/src/webserver/Dynamic.jl +++ b/src/webserver/Dynamic.jl @@ -73,11 +73,84 @@ function clientupdate_cell_running(initiator::Client, notebook::Notebook, cell:: Dict(), notebook, cell, initiator) end +"To be used in `make_distinct!`" +mutable struct NotebookPath + uuid + path_split + current_path + current_depth +end + +function count_occurances(vals) + counts = Dict() + for v in vals + old = get(counts, v, 0) + counts[v] = old + 1 + end + counts +end + +"""For internal use. Takes a Set of `NotebookPath`s and gives each a short path (e.g. `to/file.jl` from `/path/to/file.jl`), with the guarantee that all final short paths will be distinct. + +For example, the set + +`/a/b/c.jl`, `/a/P/c.jl`, `/Q/b/c.jl`, '/a/b/R.jl' + +will become + +`/a/b/c.jl`, `P/c.jl`, `/Q/b/c.jl`, 'R.jl'""" +function make_distinct!(notebookpaths::Set{NotebookPath}) + counts = count_occurances(np.current_path for np in notebookpaths) + for (current_path, count) in counts + if count == 1 && !isempty(current_path) + # done! + else + # these need to be made distinct by extending their paths + + not_yet_distinct = filter(notebookpaths) do np + np.current_path == current_path + end + + for np in not_yet_distinct + np.current_depth += 1 + np.current_path = joinpath(np.path_split[end-np.current_depth : end]...) + if np.current_depth == length(np.path_split) - 1 + delete!(not_yet_distinct, np) + if !Sys.iswindows() + np.current_path = '/' * np.current_path + end + end + end + + make_distinct!(not_yet_distinct) + end + end +end + function clientupdate_notebook_list(initiator::Client, notebook_list) + short_paths = Dict() + + notebookpaths = map(notebook_list) do notebook + pathsep = Sys.iswindows() ? '\\' : '/' + path_split = split(notebook.path, pathsep) + if path_split[1] == "" + path_split = path_split[2:end] + end + NotebookPath(notebook.uuid, path_split, "", -1) + end + + make_distinct!(Set(notebookpaths)) + + short_paths = Dict(map(notebookpaths) do np + np.uuid => np.current_path + end...) + return UpdateMessage(:notebook_list, - Dict(:notebooks => [Dict(:uuid => string(notebook.uuid), - :path => notebook.path, - ) for notebook in notebook_list]), nothing, nothing, initiator) + Dict(:notebooks => [Dict( + :uuid => string(notebook.uuid), + :path => notebook.path, + :shortpath => short_paths[notebook.uuid] + ) for notebook in notebook_list]), nothing, nothing, initiator) end @@ -173,9 +246,11 @@ addresponse(:getallcells) do (initiator, body, notebook) end # [clientupdate_cell_added(notebook, c, i) for (i, c) in enumerate(notebook.cells)] - updates + putnotebookupdates!(notebook, updates...) + nothing end addresponse(:getallnotebooks) do (initiator, body) - [clientupdate_notebook_list(initiator, values(notebooks))] + putplutoupdates!(clientupdate_notebook_list(initiator, values(notebooks))) + nothing end \ No newline at end of file diff --git a/src/webserver/NotebookServer.jl b/src/webserver/NotebookServer.jl index 705cb6d1c7..234b066a24 100644 --- a/src/webserver/NotebookServer.jl +++ b/src/webserver/NotebookServer.jl @@ -17,7 +17,10 @@ notebooks = Dict{UUID,Notebook}() function putnotebookupdates!(notebook, messages...) - listeners = filter(c->c.connected_notebook.uuid == notebook.uuid, collect(values(connectedclients))) + listeners = filter(collect(values(connectedclients))) do c + c.connected_notebook !== nothing && + c.connected_notebook.uuid == notebook.uuid + end if isempty(listeners) @info "no clients connected to this notebook!" else @@ -30,7 +33,7 @@ function putnotebookupdates!(notebook, messages...) end -function putplutoupdates!(notebook, messages...) +function putplutoupdates!(messages...) listeners = collect(values(connectedclients)) if isempty(listeners) @info "no clients connected to pluto!" @@ -159,9 +162,9 @@ function run(port = 1234, launchbrowser = false) if haskey(responses, messagetype) responsefunc = responses[messagetype] response = responsefunc((client, body, args...)) - if response !== nothing - putplutoupdates!(notebook, response...) - end + # if response !== nothing + # putplutoupdates!(response...) + # end else @warn "Message of type $(messagetype) not recognised" end @@ -175,7 +178,8 @@ function run(port = 1234, launchbrowser = false) # that's fine! this is a (fixed) HTTP.jl bug: https://github.com/JuliaWeb/HTTP.jl/issues/471 # TODO: remove this switch else - @warn "Reading WebSocket client stream failed for unknown reason:" e + bt = stacktrace(catch_backtrace()) + @warn "Reading WebSocket client stream failed for unknown reason:" e bt end end end