From 3305fa412d495da6e58631197200e96d88e58e12 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 27 Jan 2018 15:02:49 +1100 Subject: [PATCH] Implement file selection --- Cargo.lock | 16 ++++++++++++ Cargo.toml | 2 ++ src/main.rs | 2 ++ src/rest.rs | 49 +++++++++++++++++++++++++++++++--- static/index.html | 28 ++++++++++++++++---- static/js/helpers.js | 62 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 151 insertions(+), 8 deletions(-) create mode 100644 static/js/helpers.js diff --git a/Cargo.lock b/Cargo.lock index bf9bcf8..8b78932 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,6 +122,11 @@ name = "fuchsia-zircon-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "gcc" +version = "0.3.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "includedir" version = "0.2.2" @@ -190,6 +195,14 @@ dependencies = [ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "nfd" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num" version = "0.1.41" @@ -453,6 +466,7 @@ version = "0.1.0" dependencies = [ "includedir 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "includedir_codegen 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", @@ -481,6 +495,7 @@ dependencies = [ "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum includedir 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ed470a2a5c0afe4587796a886aa185fcef159feaefd8c4f40d85423aeeec4a3a" "checksum includedir_codegen 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4cb2bb86e79496ab481fc7865ce8c2960cf1eb40cc1411524ce67fce54f3c95e" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" @@ -490,6 +505,7 @@ dependencies = [ "checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" +"checksum nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98" "checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" "checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" diff --git a/Cargo.toml b/Cargo.toml index 474ee98..4b0e734 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,5 +16,7 @@ serde_json = "1.0.9" toml = "0.4" +nfd = "0.0.4" + [build-dependencies] includedir_codegen = "0.2.0" diff --git a/src/main.rs b/src/main.rs index 049b6c5..a96501f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,8 @@ extern crate serde_derive; extern crate serde_json; extern crate toml; +extern crate nfd; + mod assets; mod rest; mod config; diff --git a/src/rest.rs b/src/rest.rs index 4e8547f..76eaa80 100644 --- a/src/rest.rs +++ b/src/rest.rs @@ -5,6 +5,11 @@ use tiny_http::{Server, Request, Response, Header}; +use nfd; +use nfd::Response as NfdResponse; + +use serde_json; + use std::error::Error; use std::net::{SocketAddr, IpAddr, Ipv4Addr}; use std::thread::{self, JoinHandle}; @@ -14,6 +19,11 @@ use assets; use installer::InstallerFramework; +#[derive(Serialize)] +struct FileSelection { + path : Option +} + /// Encapsulates tiny_http's state. pub struct WebServer { server : Server, @@ -34,7 +44,9 @@ impl WebServer { let call_response = self.rest_call(api_url); match call_response { - Some(response) => request.respond(Response::from_string(response)), + Some(response) => request.respond(Response::from_data(response.into_bytes()) + .with_header(Header::from_str("Content-Type: application/json") + .unwrap())), None => request.respond(Response::empty(404)) }.unwrap(); return; @@ -51,7 +63,7 @@ impl WebServer { let mut response = Response::from_data(file); if let Some(content_type) = content_type { response.add_header(Header::from_str( - &format!("Content-Type:{}", content_type)).unwrap()) + &format!("Content-Type: {}", content_type)).unwrap()) } request.respond(response) @@ -62,10 +74,41 @@ impl WebServer { /// Makes a call to a REST endpoint. fn rest_call(&self, path : &str) -> Option { - match path { + let mut path = path.to_owned(); + + // Strip off query params + let query = match path.rfind("?") { + Some(pos) => { + let ext = path[pos + 1 ..].to_owned(); + path = path[0 .. pos].to_owned(); + + println!("Got query string: {}", ext); + + Some(ext) + }, + None => None + }; + + match path.as_str() { // This endpoint should be usable directly from a + diff --git a/static/js/helpers.js b/static/js/helpers.js new file mode 100644 index 0000000..6e5c80c --- /dev/null +++ b/static/js/helpers.js @@ -0,0 +1,62 @@ +/** + * helpers.js + * + * Additional state-less helper methods. + */ + +var request_id = 0; + +/** + * Makes a AJAX request. + * + * @param path The path to connect to. + * @param successCallback A callback with a JSON payload. + * @param failCallback A fail callback. Optional. + * @param data POST data. Optional. + */ +function ajax(path, successCallback, failCallback, data) { + if (failCallback === undefined) { + failCallback = defaultFailHandler; + } + + var req = new XMLHttpRequest(); + + req.addEventListener("load", function() { + // The server can sometimes return a string error. Make sure we handle this. + if (this.status === 200 && this.getResponseHeader('Content-Type').indexOf("application/json") !== -1) { + successCallback(JSON.parse(this.responseText)); + } else { + failCallback(); + } + }); + req.addEventListener("error", failCallback); + + req.open(data == null ? "GET" : "POST", path + "?nocache=" + request_id++, true); + // Rocket only currently supports URL encoded forms. + req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + + if (data != null) { + var form = ""; + + for (var key in data) { + if (form !== "") { + form += "&"; + } + form += encodeURIComponent(key) + "=" + encodeURIComponent(data[key]); + } + + req.send(form); + } else { + req.send(); + } +} + +/** + * The default handler if a AJAX request fails. Not to be used directly. + * + * @param e The XMLHttpRequest that failed. + */ +function defaultFailHandler(e) { + console.error("A AJAX request failed, and was not caught:"); + console.error(e); +}