Polish and publish sigweb

This commit is contained in:
Leonora Tindall 2021-10-18 20:22:26 -05:00
parent a9acc17c79
commit d38429390c
Signed by: nora
GPG Key ID: 7A8B52EC67E09AAF
5 changed files with 59 additions and 33 deletions

View File

@ -4,6 +4,8 @@ Consisting of a Rust library for generating song ideas `libsig`,
a command line tool for calling `libsig`, a command line tool for calling `libsig`,
and a web interface with a JSON API for getting structured results from `libsig`. and a web interface with a JSON API for getting structured results from `libsig`.
![an example of sigweb in use](sigweb.png)
## Usage ## Usage
The primary type of `libsig` is the `SongIdea`. You can generate human-readable representations with `Display` (so, `println!("{}", my_song_idea)`). The primary type of `libsig` is the `SongIdea`. You can generate human-readable representations with `Display` (so, `println!("{}", my_song_idea)`).
@ -20,3 +22,7 @@ surfy lead, blownout pad, light vocals, acidic snare, sonorous hat, and digital
``` ```
It also takes a parameter `--ambient` to avoid suggesting percussion parts. 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}`.

BIN
sigweb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

12
sigweb/sigweb.service Normal file
View File

@ -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

View File

@ -1,13 +1,17 @@
#[macro_use] #[macro_use]
extern crate rocket; extern crate rocket;
use libsig; use libsig;
use rocket::fs::NamedFile;
use rocket::response::content::{Css, Html}; use rocket::response::content::{Css, Html};
use rocket::serde::json::Json; use rocket::serde::json::Json;
use rocket::State;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::{json, Value}; use serde_json::{json, Value};
mod templates; mod templates;
struct BaseUrl {
url: String,
}
#[get("/api")] #[get("/api")]
fn api_version_available() -> Json<Value> { fn api_version_available() -> Json<Value> {
Json(json! ({ Json(json! ({
@ -47,42 +51,46 @@ fn api_v1_generate_ambient() -> Json<Output> {
} }
#[get("/")] #[get("/")]
fn index() -> Html<String> { fn index(base: &State<BaseUrl>) -> Html<String> {
Html(templates::main_page_template(None)) Html(templates::main_page_template(None, &base.url))
} }
#[get("/generate")] #[get("/generate")]
fn generate() -> Html<String> { fn generate(base: &State<BaseUrl>) -> Html<String> {
Html(templates::main_page_template(Some( Html(templates::main_page_template(Some(
libsig::SongIdea::generate(), libsig::SongIdea::generate(),
))) ), &base.url))
} }
#[get("/generate_ambient")] #[get("/generate_ambient")]
fn generate_ambient() -> Html<String> { fn generate_ambient(base: &State<BaseUrl>) -> Html<String> {
Html(templates::main_page_template(Some( Html(templates::main_page_template(Some(
libsig::SongIdea::generate_ambient(), libsig::SongIdea::generate_ambient(),
))) ), &base.url))
} }
#[get("/style.css")] #[get("/style.css")]
async fn style_css() -> Css<Option<NamedFile>> { async fn style_css() -> Css<String> {
Css(NamedFile::open("static/style.css").await.ok()) Css(include_str!("../static/style.css").into())
} }
#[launch] #[launch]
fn rocket() -> _ { fn rocket() -> _ {
rocket::build().mount( rocket::build()
"/", .manage(BaseUrl {
routes![ url: std::env::var("SIGWEB_BASE_URL").unwrap_or("/".to_string()),
api_version_available, })
api_v1_index, .mount(
api_v1_generate, "/",
api_v1_generate_ambient, routes![
generate, api_version_available,
generate_ambient, api_v1_index,
index, api_v1_generate,
style_css, api_v1_generate_ambient,
], generate,
) generate_ambient,
index,
style_css,
],
)
} }

View File

@ -1,22 +1,22 @@
use maud::{html, DOCTYPE}; use maud::{html, DOCTYPE};
use libsig::SongIdea; use libsig::SongIdea;
pub fn main_page_template(idea: Option<SongIdea>) -> String { pub fn main_page_template(idea: Option<SongIdea>, base_url: &str) -> String {
let content = match idea {
Some(idea) => { idea.to_string() },
None => { "Generate a new idea with the links below!".to_string() }
};
let html = html! { let html = html! {
(DOCTYPE) (DOCTYPE)
head { head {
link rel="stylesheet" href="style.css"; link rel="stylesheet" href="style.css";
base href=(base_url);
} }
body { body {
h1 { "Song Idea Generator" } h1 { "Song Idea Generator" }
p{ "Why don't you make a song like this: " } (match idea {
p.content { Some(idea) => html!{
(content) 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 { footer {
p { p {
a href="./generate" { "generate new" } a href="./generate" { "generate new" }