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 0000000..d8bd630 Binary files /dev/null and b/sigweb.png differ 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" }