master
Pietro Brenna 2021-04-24 08:35:48 +02:00
commit 0012585992
5 changed files with 1952 additions and 0 deletions

1
.gitignore vendored 100644
View File

@ -0,0 +1 @@
/target

1771
Cargo.lock generated 100644

File diff suppressed because it is too large Load Diff

17
Cargo.toml 100644
View File

@ -0,0 +1,17 @@
[package]
name = "volume"
version = "0.1.0"
authors = ["Pietro Brenna <pietro.brenna@briq.it>"]
edition = "2018"
[dependencies]
actix-web = { version = "3.3.2", default-features = false }
ipconfig = "0.2.2"
qr2term = "0.2.2"
#autopilot = {version = "0.4.0", default-featuers = false }
win_key_codes = "0.1.2"
winapi = { version = "*", features = ["winuser"] }
[profile.release]
panic = "abort"
opt-level = "z"

94
src/index.html 100644
View File

@ -0,0 +1,94 @@
<!DOCTYPE html>
<html>
<head>
<title>Controlla volume</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<style type="text/css">
body {
margin: 0;
padding: 0;
font-size: 0;
height: 100vh;
}
.row1, .row2 {
display: flex;
justify-content: space-between;
height: 50vh;
width: 100vw;
}
html {
margin: 0;
padding: 0;
}
button {
border: none;
font-size: calc(min(20vh, 20vw));
outline: 0;
margin: 0;
flex-grow:2;
padding: 0;
color: #ddd;
}
.down {
background: #000;
}
.up {
background: #444;
}
.play_pause {
background: #222;
}
.prev {
background: #444;
}
.next {
background: #000;
}
button:active {
background: #888;
}
</style>
</head>
<body>
<div class="row1">
<button onmousedown="md('down')" onmouseup="mu('down')" class="down">-</button>
<button onmousedown="md('up')" onmouseup="mu('up')" class="up">+</button>
</div>
<div class="row1">
<button onmousedown="md('prev')" onmouseup="mu('prev')" class="prev"></button>
<button onclick="vol('play_pause')" class="play_pause"></button>
<button onmousedown="md('next')" onmouseup="mu('next')" class="next"></button>
</div>
</body>
<script type="text/javascript">
var premuto = null;
var interval = null;
function md(direz) {
premuto = direz;
vol(premuto);
interval = setInterval(function () {
vol(premuto);
}, 100);
}
function mu(direz) {
clearInterval(interval);
}
async function vol(direz) {
let f = await fetch("/a/" + direz);
}
</script>
</html>

69
src/main.rs 100644
View File

@ -0,0 +1,69 @@
use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer};
use win_key_codes;
type WinKeyCode = i32;
fn win_send_key_event(keycode: WinKeyCode, down: bool, delay_ms: u64) {
use winapi::um::winuser::{keybd_event, KEYEVENTF_KEYUP};
let flags = if down { 0 } else { KEYEVENTF_KEYUP };
unsafe { keybd_event(keycode as u8, 0, flags, 0) };
std::thread::sleep(std::time::Duration::from_millis(delay_ms));
}
async fn index(_req: HttpRequest) -> HttpResponse {
HttpResponse::Ok()
.content_type("text/html")
.body(include_str!("index.html"))
}
async fn action(req: HttpRequest) -> HttpResponse {
match req.match_info().get("action") {
Some(action) => {
let key_code = match action {
"up" => win_key_codes::VK_VOLUME_UP,
"down" => win_key_codes::VK_VOLUME_DOWN,
"play_pause" => win_key_codes::VK_MEDIA_PLAY_PAUSE,
"prev" => win_key_codes::VK_LEFT,
"next" => win_key_codes::VK_RIGHT,
_ => return HttpResponse::BadRequest().body("Bad request"),
};
win_send_key_event(key_code, true, 10);
win_send_key_event(key_code, false, 10);
HttpResponse::NoContent().body("")
}
None => HttpResponse::BadRequest().body("Bad request"),
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let port = 8030;
println!("Chiudi questa finestra per terminare il programma. Collegati alla porta {} per controllare il volume.", port);
let mut candidates = vec![];
if let Ok(adapters) = ipconfig::get_adapters() {
for adapter in adapters {
if adapter.oper_status() == ipconfig::OperStatus::IfOperStatusUp {
let desc = adapter.description().to_lowercase().to_string();
if !desc.contains("virtual") && !desc.contains("loopback") {
for addr in adapter.ip_addresses() {
match addr {
std::net::IpAddr::V4(v4addr) if v4addr.is_private() => {
candidates.push(v4addr.clone());
}
_ => {}
}
}
}
}
}
}
if let Some(addr) = candidates.first() {
qr2term::print_qr(format!("http://{}:{}/", addr, port)).unwrap();
}
HttpServer::new(|| {
App::new()
.route("/", web::get().to(index))
.route("/a/{action}", web::get().to(action))
})
.bind(("0.0.0.0", port))?
.run()
.await
}