From d38429390c43f7d586660571c587d974fc684db4 Mon Sep 17 00:00:00 2001 From: Leonora Tindall Date: Mon, 18 Oct 2021 20:22:26 -0500 Subject: [PATCH] Polish and publish sigweb --- README.md | 8 ++++++- sigweb.png | Bin 0 -> 31270 bytes sigweb/sigweb.service | 12 ++++++++++ sigweb/src/main.rs | 52 +++++++++++++++++++++++----------------- sigweb/src/templates.rs | 20 ++++++++-------- 5 files changed, 59 insertions(+), 33 deletions(-) create mode 100644 sigweb.png create mode 100644 sigweb/sigweb.service diff --git a/README.md b/README.md index de80a92..088c4db 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ Consisting of a Rust library for generating song ideas `libsig`, a command line tool for calling `libsig`, and a web interface with a JSON API for getting structured results from `libsig`. +![an example of sigweb in use](sigweb.png) + ## Usage The primary type of `libsig` is the `SongIdea`. You can generate human-readable representations with `Display` (so, `println!("{}", my_song_idea)`). @@ -19,4 +21,8 @@ buzzy pad, glassy vocals, plonky kick, plucky snare, and dry tom at 63 bpm, with surfy lead, blownout pad, light vocals, acidic snare, sonorous hat, and digital tom at 33 bpm, with no swing, through lofi ``` -It also takes a parameter `--ambient` to avoid suggesting percussion parts. \ No newline at end of file +It also takes a parameter `--ambient` to avoid suggesting percussion parts. + +`sigweb` is a very basic Rocket app. I suggest building it with `x86_64-unknown-linux-musl`. Once built take the `sigweb` binary and put it in a folder with an appropriate `Rocket.toml`. You can set a base URL with the environment variable `SIGWEB_BASE_URL`. See the provided `sigweb.service` for a sample SystemD unit. + +It provides a JSON API with the endpoints `/api/v1/{generate, generate_ambient}`. \ No newline at end of file diff --git a/sigweb.png b/sigweb.png new file mode 100644 index 0000000000000000000000000000000000000000..d8bd630e1d420b8b3c285b15121578f7cc3adf89 GIT binary patch literal 31270 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 K7fXEl_J0A4dVEs= literal 0 HcmV?d00001 diff --git a/sigweb/sigweb.service b/sigweb/sigweb.service new file mode 100644 index 0000000..d424c3a --- /dev/null +++ b/sigweb/sigweb.service @@ -0,0 +1,12 @@ +[Unit] +Description=Song Idea Generator Web Service + +[Service] +Type=simple +User=nora +WorkingDirectory=/home/nora/sigweb +ExecStart=/home/nora/sigweb/sigweb +Environment=SIGWEB_BASE_URL="https://nora.codes/sigweb/" + +[Install] +WantedBy=multi-user.target diff --git a/sigweb/src/main.rs b/sigweb/src/main.rs index 76f84b4..ec162fe 100644 --- a/sigweb/src/main.rs +++ b/sigweb/src/main.rs @@ -1,13 +1,17 @@ #[macro_use] extern crate rocket; use libsig; -use rocket::fs::NamedFile; use rocket::response::content::{Css, Html}; use rocket::serde::json::Json; +use rocket::State; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; mod templates; +struct BaseUrl { + url: String, +} + #[get("/api")] fn api_version_available() -> Json { Json(json! ({ @@ -47,42 +51,46 @@ fn api_v1_generate_ambient() -> Json { } #[get("/")] -fn index() -> Html { - Html(templates::main_page_template(None)) +fn index(base: &State) -> Html { + Html(templates::main_page_template(None, &base.url)) } #[get("/generate")] -fn generate() -> Html { +fn generate(base: &State) -> Html { Html(templates::main_page_template(Some( libsig::SongIdea::generate(), - ))) + ), &base.url)) } #[get("/generate_ambient")] -fn generate_ambient() -> Html { +fn generate_ambient(base: &State) -> Html { Html(templates::main_page_template(Some( libsig::SongIdea::generate_ambient(), - ))) + ), &base.url)) } #[get("/style.css")] -async fn style_css() -> Css> { - Css(NamedFile::open("static/style.css").await.ok()) +async fn style_css() -> Css { + Css(include_str!("../static/style.css").into()) } #[launch] fn rocket() -> _ { - rocket::build().mount( - "/", - routes![ - api_version_available, - api_v1_index, - api_v1_generate, - api_v1_generate_ambient, - generate, - generate_ambient, - index, - style_css, - ], - ) + rocket::build() + .manage(BaseUrl { + url: std::env::var("SIGWEB_BASE_URL").unwrap_or("/".to_string()), + }) + .mount( + "/", + routes![ + api_version_available, + api_v1_index, + api_v1_generate, + api_v1_generate_ambient, + generate, + generate_ambient, + index, + style_css, + ], + ) } diff --git a/sigweb/src/templates.rs b/sigweb/src/templates.rs index cfcdf0a..b261055 100644 --- a/sigweb/src/templates.rs +++ b/sigweb/src/templates.rs @@ -1,22 +1,22 @@ use maud::{html, DOCTYPE}; use libsig::SongIdea; -pub fn main_page_template(idea: Option) -> String { - let content = match idea { - Some(idea) => { idea.to_string() }, - None => { "Generate a new idea with the links below!".to_string() } - }; +pub fn main_page_template(idea: Option, base_url: &str) -> String { let html = html! { (DOCTYPE) head { link rel="stylesheet" href="style.css"; + base href=(base_url); } body { - h1 { "Song Idea Generator" } - p{ "Why don't you make a song like this: " } - p.content { - (content) - } + h1 { "Song Idea Generator" } + (match idea { + Some(idea) => html!{ + p { "Why don't you make a song like this: " } + p.content { (idea) } + }, + None => html! { p { "Generate a new idea with the links below!" } p.content {} } + }) footer { p { a href="./generate" { "generate new" }