summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob L. Kreuze <zerodaysfordays@sdf.org>2020-05-26 19:46:20 -0400
committerJakob L. Kreuze <zerodaysfordays@sdf.org>2020-05-26 19:46:20 -0400
commit433c5fa1c56bee5a9032380a3c9a339869a47d16 (patch)
treec6ed8b5722b969abbf3239450466d4933dac039d
parenta932889c9a01537a53e9c587e13e25843744b6f0 (diff)
Implement initial templating.
-rw-r--r--Cargo.lock155
-rw-r--r--Cargo.toml6
-rw-r--r--src/main.rs64
-rw-r--r--static/css/style.css20
-rw-r--r--templates/index.hbs36
5 files changed, 276 insertions, 5 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6178093..1492cbe 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7,6 +7,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
[[package]]
+name = "aho-corasick"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "anyhow"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -119,6 +128,27 @@ dependencies = [
]
[[package]]
+name = "block-buffer"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
+dependencies = [
+ "block-padding",
+ "byte-tools",
+ "byteorder",
+ "generic-array",
+]
+
+[[package]]
+name = "block-padding"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
+dependencies = [
+ "byte-tools",
+]
+
+[[package]]
name = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -318,6 +348,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
[[package]]
+name = "fake-simd"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
+
+[[package]]
name = "fallible-iterator"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -413,6 +449,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
+name = "handlebars"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d82e5750d8027a97b9640e3fefa66bbaf852a35228e1c90790efd13c4b09c166"
+dependencies = [
+ "lazy_static",
+ "log 0.4.8",
+ "pest",
+ "pest_derive",
+ "quick-error",
+ "regex",
+ "serde",
+ "serde_json",
+ "walkdir",
+]
+
+[[package]]
name = "hermit-abi"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -622,6 +675,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
[[package]]
+name = "maplit"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
+
+[[package]]
name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -824,6 +883,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
[[package]]
+name = "pest"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
+dependencies = [
+ "ucd-trie",
+]
+
+[[package]]
+name = "pest_derive"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
+dependencies = [
+ "pest",
+ "pest_generator",
+]
+
+[[package]]
+name = "pest_generator"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
+dependencies = [
+ "pest",
+ "pest_meta",
+ "proc-macro2 1.0.17",
+ "quote 1.0.6",
+ "syn 1.0.25",
+]
+
+[[package]]
+name = "pest_meta"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
+dependencies = [
+ "maplit",
+ "pest",
+ "sha-1",
+]
+
+[[package]]
name = "pkg-config"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -860,6 +962,12 @@ dependencies = [
]
[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
+[[package]]
name = "quote"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -919,6 +1027,24 @@ dependencies = [
]
[[package]]
+name = "regex"
+version = "1.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+ "thread_local",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
+
+[[package]]
name = "ring"
version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -972,6 +1098,8 @@ version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a10e7471279bc2d4a21b6fddd9589016bb119e6fbb547b216dd54ef237f28341"
dependencies = [
+ "glob",
+ "handlebars",
"log 0.4.8",
"notify",
"rocket",
@@ -1085,6 +1213,18 @@ dependencies = [
]
[[package]]
+name = "sha-1"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
+dependencies = [
+ "block-buffer",
+ "digest",
+ "fake-simd",
+ "opaque-debug",
+]
+
+[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1131,6 +1271,15 @@ dependencies = [
]
[[package]]
+name = "thread_local"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
name = "tiff"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1179,6 +1328,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
[[package]]
+name = "ucd-trie"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
+
+[[package]]
name = "unicase"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 9a47e7d..c17f0ef 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,11 +17,15 @@ rusqlite = "0.21.0"
# Until RFC #2887 is merged, image and rocket are deps of the CLI tool as well.
image = "0.23.4"
rocket = "0.4.4"
-rocket_contrib = "0.4.4"
serde = "1.0"
serde_json = "1.0"
serde_derive = "1.0"
+[dependencies.rocket_contrib]
+version = "0.4.4"
+default-features = false
+features = ["handlebars_templates", "json", "serve"]
+
[[bin]]
name = "birka-cli"
path = "src/birka-cli.rs"
diff --git a/src/main.rs b/src/main.rs
index f82f07b..6eb939f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -33,6 +33,9 @@ use database::{hash_file, Query, TagDatabase};
use image::ImageFormat;
use rocket::{Data, State};
use rocket_contrib::json::Json;
+use rocket_contrib::serve::StaticFiles;
+use rocket_contrib::templates::Template;
+use std::collections::HashMap;
use std::env;
use std::fs;
use std::fs::File;
@@ -59,13 +62,48 @@ impl DatabaseConnection {
}
#[get("/")]
-fn index(tb: SiteState) -> &'static str {
- "Hello, world!"
+fn index() -> Template {
+ let context = HashMap::<&str, &str>::new();
+ Template::render("index", &context)
+}
+
+#[get("/posts?<tags>")]
+fn display_posts(conn: SiteState, tags: String) -> Template {
+ #[derive(Serialize)]
+ struct TagResult {
+ name: String,
+ count: i64,
+ }
+
+ #[derive(Serialize)]
+ struct Asdf {
+ tags: Vec<TagResult>,
+ images: Vec<ImageResult>,
+ }
+
+ let tag_results = {
+ let tb = &conn.inner().lock().unwrap().tb;
+ tb.top_tags(20)
+ .unwrap()
+ .iter()
+ .map(|tup| TagResult {
+ name: tup.1.clone(),
+ count: tup.0,
+ })
+ .collect()
+ };
+ let images = get_posts(conn, tags).into_inner();
+ let context = Asdf {
+ tags: tag_results,
+ images,
+ };
+ Template::render("index", context)
}
#[derive(Serialize)]
struct ImageResult {
filename: String,
+ thumb_filename: String,
tags: Vec<String>,
}
@@ -87,6 +125,7 @@ fn get_posts(conn: SiteState, tags: String) -> Json<Vec<ImageResult>> {
.iter()
.map(|image| ImageResult {
filename: image.filename.clone(),
+ thumb_filename: thumb_filename(&image.filename),
tags: tb.tags_for_image(image.id).unwrap(),
})
.collect(),
@@ -105,6 +144,18 @@ fn put_posts(conn: SiteState, filename: String, data: Data) -> Json<&str> {
Json("uploaded!")
}
+fn thumb_filename(filename: &str) -> String {
+ String::from(format!(
+ "{}_thumb.png",
+ // Strip extension.
+ if let Some(n) = filename.rfind('.') {
+ &filename[..n]
+ } else {
+ &filename[..]
+ }
+ ))
+}
+
/// Maybe initialize the directory for storing image symlinks and thumbnails.
fn create_image_directory(conn: &DatabaseConnection) {
fs::create_dir(&conn.image_dir).ok();
@@ -115,7 +166,7 @@ fn create_image_directory(conn: &DatabaseConnection) {
symlink(&src, &dst).ok();
let stem = Path::new(&dst).file_stem().unwrap().to_str().unwrap();
- let thumb_path = format!("{}_thumb.png", stem);
+ let thumb_path = format!("{}/{}", conn.image_dir, thumb_filename(&stem));
let thumb_path = Path::new(&thumb_path);
if !thumb_path.exists() {
@@ -130,9 +181,14 @@ fn create_image_directory(conn: &DatabaseConnection) {
fn main() {
let conn = DatabaseConnection::new().unwrap();
+ let image_dir = conn.image_dir.clone();
create_image_directory(&conn);
rocket::ignite()
+ .attach(Template::fairing())
.manage(Mutex::new(conn))
- .mount("/", routes![index, get_posts])
+ .mount("/public", StaticFiles::from("./static/"))
+ .mount("/image", StaticFiles::from(image_dir))
+ .mount("/", routes![index, display_posts])
+ .mount("/api", routes![get_posts, put_posts])
.launch();
}
diff --git a/static/css/style.css b/static/css/style.css
new file mode 100644
index 0000000..f50fa36
--- /dev/null
+++ b/static/css/style.css
@@ -0,0 +1,20 @@
+body {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ grid-gap: 10px;
+ grid-auto-rows: minmax(50px, auto);
+}
+
+header {
+ grid-column: 1 / 3;
+ grid-row: 1;
+}
+
+aside {
+ grid-column: 1;
+ grid-row: 2;
+}
+
+main {
+ grid-column: 2 /3;
+ grid-row: 2
diff --git a/templates/index.hbs b/templates/index.hbs
new file mode 100644
index 0000000..f0d6d91
--- /dev/null
+++ b/templates/index.hbs
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Hello, world!</title>
+ <link rel="stylesheet" type="text/css" href="/public/css/style.css">
+ <meta charset="UTF-8">
+</head>
+<body>
+ <header>
+ <h1>бирка-тян</h1>
+ </header>
+ <main>
+ {{#each images}}
+ <img src="/image/{{thumb_filename}}">
+ {{/each}}
+ </main>
+ <aside id="tag-view">
+ <section id="search">
+ <h2>Search</h2>
+ <form id="search-box" method="GET" action="/posts">
+ <input id="tags" name="tags" type="text" autocomplete="off">
+ <button id="search-box-submit" type="submit">Search</button>
+ </form>
+ </section>
+
+ <section id="search">
+ <h2>Tags</h2>
+ <ul>
+ {{#each tags}}
+ <li><a href="/posts?tags={{ name }}">{{ name }}</a> {{ count }}</li>
+ {{/each}}
+ </ul>
+ </section>
+ </aside>
+</body>
+</html>