From 56c3a61d8378644f0d3bd2467acc129e46b4f408 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20Renault?=
Date: Mon, 19 Oct 2020 19:57:15 +0200
Subject: [PATCH] Introduce a new updates page
---
public/script.js | 2 +-
public/updates-script.js | 37 +++++++++++++++++++
src/subcommand/serve.rs | 80 ++++++++++++++++++++++++++--------------
templates/index.html | 1 +
templates/updates.html | 48 ++++++++++++++++++++++++
5 files changed, 139 insertions(+), 29 deletions(-)
create mode 100644 public/updates-script.js
create mode 100644 templates/updates.html
diff --git a/public/script.js b/public/script.js
index 6825c4d9b..4b68d9835 100644
--- a/public/script.js
+++ b/public/script.js
@@ -51,7 +51,7 @@ $('#search').on('input', function () {
}
elem.appendChild(ol);
- results.appendChild(elem)
+ results.appendChild(elem);
}
},
diff --git a/public/updates-script.js b/public/updates-script.js
new file mode 100644
index 000000000..f2f68e920
--- /dev/null
+++ b/public/updates-script.js
@@ -0,0 +1,37 @@
+$(window).on('load', function () {
+ let url = 'ws://' + window.location.hostname + ':' + window.location.port + '/updates/ws';
+ var socket = new WebSocket(url);
+
+ socket.onmessage = function (event) {
+ console.log(event.data);
+
+ if (event.data.endsWith("processed")) {
+ const elem = document.createElement('li');
+ elem.classList.add("document");
+
+ const ol = document.createElement('ol');
+ const field = document.createElement('li');
+ field.classList.add("field");
+
+ const attribute = document.createElement('div');
+ attribute.classList.add("attribute");
+ attribute.innerHTML = "TEXT";
+
+ const content = document.createElement('div');
+ content.classList.add("content");
+ content.innerHTML = event.data;
+
+ field.appendChild(attribute);
+ field.appendChild(content);
+
+ ol.appendChild(field);
+ elem.appendChild(ol);
+
+ prependChild(results, elem);
+ }
+ }
+});
+
+function prependChild(parent, newFirstChild) {
+ parent.insertBefore(newFirstChild, parent.firstChild)
+}
diff --git a/src/subcommand/serve.rs b/src/subcommand/serve.rs
index 7dbfbd8c2..93f37b5cf 100644
--- a/src/subcommand/serve.rs
+++ b/src/subcommand/serve.rs
@@ -81,6 +81,13 @@ struct IndexTemplate {
docs_count: usize,
}
+#[derive(Template)]
+#[template(path = "updates.html")]
+struct UpdatesTemplate {
+ db_name: String,
+ updates: Vec,
+}
+
pub fn run(opt: Opt) -> anyhow::Result<()> {
stderrlog::new()
.verbosity(opt.verbose)
@@ -108,10 +115,10 @@ pub fn run(opt: Opt) -> anyhow::Result<()> {
let update_store = UpdateStore::open(
update_store_options,
update_store_path,
- move |_uid, meta: String, _content| {
- let _ = update_status_sender_cloned.try_send("processing update");
+ move |uid, meta: String, _content| {
+ let _ = update_status_sender_cloned.try_send(format!("processing update {}", uid));
std::thread::sleep(Duration::from_secs(3));
- let _ = update_status_sender_cloned.try_send("update processed");
+ let _ = update_status_sender_cloned.try_send(format!("update {} processed", uid));
Ok(meta)
})?;
@@ -127,9 +134,38 @@ pub fn run(opt: Opt) -> anyhow::Result<()> {
// We run and wait on the HTTP server
// Expose an HTML page to debug the search in a browser
+ let db_name_cloned = db_name.clone();
let dash_html_route = warp::filters::method::get()
.and(warp::filters::path::end())
- .map(move || IndexTemplate { db_name: db_name.clone(), db_size, docs_count });
+ .map(move || IndexTemplate { db_name: db_name_cloned.clone(), db_size, docs_count });
+
+ let update_store_cloned = update_store.clone();
+ let updates_list_or_html_route = warp::filters::method::get()
+ .and(warp::header("Accept"))
+ .and(warp::path!("updates"))
+ .map(move |header: String| {
+ let update_store = update_store_cloned.clone();
+ let mut updates = update_store.iter_metas(|processed, pending| {
+ let mut updates = Vec::new();
+ for result in processed {
+ let (id, _) = result?;
+ updates.push(format!("update {} processed", id.get()));
+ }
+ for result in pending {
+ let (id, _) = result?;
+ updates.push(format!("update {} pending", id.get()));
+ }
+ Ok(updates)
+ }).unwrap();
+
+ if header.contains("text/html") {
+ updates.reverse();
+ let template = UpdatesTemplate { db_name: db_name.clone(), updates };
+ Box::new(template) as Box
+ } else {
+ Box::new(warp::reply::json(&updates))
+ }
+ });
let dash_bulma_route = warp::filters::method::get()
.and(warp::path!("bulma.min.css"))
@@ -180,6 +216,13 @@ pub fn run(opt: Opt) -> anyhow::Result<()> {
.body(include_str!("../../public/script.js"))
);
+ let updates_script_route = warp::filters::method::get()
+ .and(warp::path!("updates-script.js"))
+ .map(|| Response::builder()
+ .header("content-type", "application/javascript; charset=utf-8")
+ .body(include_str!("../../public/updates-script.js"))
+ );
+
let dash_logo_white_route = warp::filters::method::get()
.and(warp::path!("logo-white.svg"))
.map(|| Response::builder()
@@ -245,7 +288,7 @@ pub fn run(opt: Opt) -> anyhow::Result<()> {
async fn buf_stream(
update_store: Arc>,
- update_status_sender: async_channel::Sender<&'static str>,
+ update_status_sender: async_channel::Sender,
mut stream: impl futures::Stream- > + Unpin,
) -> Result
{
@@ -262,7 +305,7 @@ pub fn run(opt: Opt) -> anyhow::Result<()> {
let meta = String::from("I am the metadata");
let uid = update_store.register_update(&meta, &mmap[..]).unwrap();
- update_status_sender.try_send("registering update").unwrap();
+ update_status_sender.try_send(format!("update {} pending", uid)).unwrap();
eprintln!("Registering update {}", uid);
Ok(warp::reply())
@@ -294,27 +337,8 @@ pub fn run(opt: Opt) -> anyhow::Result<()> {
})
});
- let update_store_cloned = update_store.clone();
- let list_updates_route = warp::filters::method::get()
- .and(warp::path!("updates"))
- .map(move || {
- let update_store = update_store_cloned.clone();
- let updates = update_store.iter_metas(|processed, pending| {
- let mut updates = Vec::new();
- for result in processed {
- let (id, _) = result?;
- updates.push(format!("update {} processed", id.get()));
- }
- for result in pending {
- let (id, _) = result?;
- updates.push(format!("update {} pending", id.get()));
- }
- Ok(updates)
- }).unwrap();
- Ok(warp::reply::json(&updates))
- });
-
let routes = dash_html_route
+ .or(updates_list_or_html_route)
.or(dash_bulma_route)
.or(dash_bulma_dark_route)
.or(dash_style_route)
@@ -322,12 +346,12 @@ pub fn run(opt: Opt) -> anyhow::Result<()> {
.or(dash_papaparse_route)
.or(dash_filesize_route)
.or(dash_script_route)
+ .or(updates_script_route)
.or(dash_logo_white_route)
.or(dash_logo_black_route)
.or(query_route)
.or(indexing_route)
- .or(update_ws_route)
- .or(list_updates_route);
+ .or(update_ws_route);
let addr = SocketAddr::from_str(&opt.http_listen_addr)?;
tokio::runtime::Builder::new()
diff --git a/templates/index.html b/templates/index.html
index 0cb717c92..0fe6034ea 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -89,6 +89,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% for update in updates %}
+ -
+
+ -
+
text
{{ update }}
+
+
+
+ {% endfor %}
+
+
+
+
+
diff --git a/templates/updates.html b/templates/updates.html
new file mode 100644
index 000000000..ec83af4e0
--- /dev/null
+++ b/templates/updates.html
@@ -0,0 +1,48 @@
+
+
+