refactor: using jinja extension for html, adding logger

This commit is contained in:
Gabor Körber 2024-01-09 10:31:43 +01:00
parent fa22be6e0e
commit 35c979e30c
7 changed files with 74 additions and 43 deletions

5
Cargo.lock generated
View File

@ -586,9 +586,9 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.19" version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]] [[package]]
name = "mach" name = "mach"
@ -1142,6 +1142,7 @@ dependencies = [
"axum", "axum",
"axum-template", "axum-template",
"cpal", "cpal",
"log",
"minijinja", "minijinja",
"minimp3", "minimp3",
"regex", "regex",

View File

@ -10,6 +10,7 @@ default-run = "soundboard"
axum = "0.6.18" axum = "0.6.18"
axum-template = { version = "0.19.0", features = ["minijinja"] } axum-template = { version = "0.19.0", features = ["minijinja"] }
cpal = "0.15.2" cpal = "0.15.2"
log = "0.4.20"
minijinja = { version = "1.0.3", features = ["loader"] } minijinja = { version = "1.0.3", features = ["loader"] }
minimp3 = "0.5.1" minimp3 = "0.5.1"
regex = "1.9.0" regex = "1.9.0"

View File

@ -5,6 +5,7 @@ use minijinja::{path_loader, Environment};
use state::{AppState, TemplateEngine}; use state::{AppState, TemplateEngine};
use std::net::SocketAddr; use std::net::SocketAddr;
use log::{debug, info};
use serde::Serialize; use serde::Serialize;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -25,13 +26,13 @@ async fn main() {
let app_state = AppState { let app_state = AppState {
engine: template_engine, engine: template_engine,
clips: soundclips::scan_directory_for_clips("E:/sounds/soundboard", &["mp3"]) clips: soundclips::scan_directory_for_clips("E:/sounds/soundboard/all", &["mp3"])
.expect("No Soundclips found."), .expect("No Soundclips found."),
player: audio, player: audio,
}; };
// Set the address to run our application on // Set the address to run our application on
let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
// Build our application with a route // Build our application with a route
let app = Router::new() let app = Router::new()
@ -57,7 +58,7 @@ struct TemplateContext {
async fn home(engine: TemplateEngine, state: State<AppState>) -> impl axum::response::IntoResponse { async fn home(engine: TemplateEngine, state: State<AppState>) -> impl axum::response::IntoResponse {
let clips = state.0.clone().clips; // this is not ideal. let clips = state.0.clone().clips; // this is not ideal.
let context = TemplateContext { clips: clips }; let context = TemplateContext { clips: clips };
RenderHtml(Key("index.html".to_owned()), engine, context) RenderHtml(Key("index.jinja".to_owned()), engine, context)
} }
async fn play_handler( async fn play_handler(
@ -72,6 +73,7 @@ async fn play_handler(
{ {
let player = state.player.clone(); let player = state.player.clone();
let full_file_name = &clip.full_file_name(); let full_file_name = &clip.full_file_name();
info!("Playing {}", full_file_name);
player player
.lock() .lock()
.unwrap() .unwrap()

View File

@ -1,3 +1,4 @@
use log::error;
use serde::Serialize; use serde::Serialize;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fmt; use std::fmt;
@ -73,11 +74,11 @@ pub fn scan_directory_for_clips(directory: &str, extensions: &[&str]) -> Option<
} }
} }
} else { } else {
println!("Failed to read directory entry: {}", entry.unwrap_err()); error!("Failed to read directory entry: {}", entry.unwrap_err());
} }
} }
} else { } else {
println!( error!(
"Failed to read directory: {}", "Failed to read directory: {}",
fs::read_dir(directory).unwrap_err() fs::read_dir(directory).unwrap_err()
); );

View File

@ -1,5 +1,6 @@
use cpal::traits::{DeviceTrait, HostTrait}; use cpal::traits::{DeviceTrait, HostTrait};
use cpal::{Device, Host}; use cpal::{Device, Host};
use log::{debug, error, info};
use minimp3::{Decoder, Error}; use minimp3::{Decoder, Error};
use regex::Regex; use regex::Regex;
use std::fs::File; use std::fs::File;
@ -13,6 +14,13 @@ pub enum Command {
Stop, Stop,
} }
// todo: implement a device selection with this:
pub enum DeviceSelection {
SelectFirst,
SelectById(usize),
FindByPattern(String),
}
fn list_devices(host: &Host) -> Vec<String> { fn list_devices(host: &Host) -> Vec<String> {
let devices = host.output_devices().unwrap(); let devices = host.output_devices().unwrap();
devices.map(|device| device.name().unwrap()).collect() devices.map(|device| device.name().unwrap()).collect()
@ -30,11 +38,11 @@ fn select_device(host: &Host, i: usize) -> Option<Device> {
fn find_virtual_audio_cable() -> Option<Device> { fn find_virtual_audio_cable() -> Option<Device> {
let host = cpal::default_host(); let host = cpal::default_host();
let devices = list_devices(&host); let devices = list_devices(&host);
println!("Devices: {:?}", devices); info!("Devices: {:?}", devices);
let pattern = ".*VB-Audio Virtual Cable.*"; let pattern = ".*VB-Audio Virtual Cable.*";
if let Some(index) = find_device_index_regex(devices, pattern) { if let Some(index) = find_device_index_regex(devices, pattern) {
println!("Selecting Device: \"{}\" at index {:?}", pattern, index); info!("Selecting Device: \"{}\" at index {:?}", pattern, index);
return select_device(&host, index); return select_device(&host, index);
} }
return None; return None;
@ -84,10 +92,13 @@ fn play_file(sink: &rodio::Sink, file_name: String) {
sink.append(source); sink.append(source);
} }
Err(Error::Eof) => { Err(Error::Eof) => {
println!("EOF"); debug!("EOF");
break;
}
Err(e) => {
error!("{:?}", e);
break; break;
} }
Err(e) => panic!("{:?}", e),
} }
} }
} }

View File

@ -1,32 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Play</title>
<script>
function play(hash) {
fetch("/play/" + hash);
}
function stop() {
fetch("/stop");
}
</script>
</head>
<body>
<div class="container">
<div class="categories">
<span class="category">Category 1</span>
<!-- More categories -->
<button class="more">More</button>
</div>
<div class="soundclips">
{% for clip in clips %}
<button onclick="play('{{clip.hash}}')">{{clip.file_name}}</button>
{% endfor %}
</div>
<div class="player">
<button onclick="stop()">Stop.</button>
</div>
</div>
</body>
</html>

47
templates/index.jinja Normal file
View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.17.11/dist/css/uikit.min.css" />
<!-- UIkit JS -->
<script src="https://cdn.jsdelivr.net/npm/uikit@3.17.11/dist/js/uikit.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/uikit@3.17.11/dist/js/uikit-icons.min.js"></script>
<title>Play</title>
<script>
function play(hash) {
fetch("/play/" + hash);
}
function stop() {
fetch("/stop");
}
</script>
</head>
<body>
<div id="main" class="uk-container">
<div id="categories">
<span class="category">Category 1</span>
<!-- More categories -->
<button class="more">More</button>
</div>
<div class="uk-text-center" uk-grid>
<div id="soundclips">
{% for clip in clips %}
<button class="uk-button uk-button-default" onclick="play('{{clip.hash}}')">{{clip.file_name}}</button>
{% endfor %}
</div>
</div>
<div class="player">
<button onclick="stop()">Stop.</button>
</div>
</div>
</body>
</html>