rudimentary command parsing
This commit is contained in:
parent
94f99e9f84
commit
65e42c2f2a
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2380,6 +2380,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"libmpv",
|
"libmpv",
|
||||||
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tubest-common",
|
"tubest-common",
|
||||||
|
|
|
@ -1 +1,47 @@
|
||||||
|
use std::time::Duration;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub const PROG_NAME: &str = "tubest";
|
pub const PROG_NAME: &str = "tubest";
|
||||||
|
const DEFAULT_SEEK: Duration = Duration::from_secs(30);
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub enum Action {
|
||||||
|
Media(MediaAction),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub enum MediaAction {
|
||||||
|
Enqueue {
|
||||||
|
path: String,
|
||||||
|
replace: bool,
|
||||||
|
},
|
||||||
|
Pause,
|
||||||
|
Unpause,
|
||||||
|
FastForward(Duration),
|
||||||
|
Rewind(Duration),
|
||||||
|
Next,
|
||||||
|
Stop,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Action {
|
||||||
|
pub fn from_line(line: &str) -> Self {
|
||||||
|
let split: Vec<&str> = line.split_whitespace().collect();
|
||||||
|
match &split[..] {
|
||||||
|
["pause", ..] => Action::Media(MediaAction::Pause),
|
||||||
|
["unpause", ..] => Action::Media(MediaAction::Unpause),
|
||||||
|
["rewind", ..] => {
|
||||||
|
if split.len() > 1 {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
Action::Media(MediaAction::Rewind(DEFAULT_SEEK))
|
||||||
|
},
|
||||||
|
["forward", ..] => {
|
||||||
|
// TODO: as above
|
||||||
|
Action::Media(MediaAction::FastForward(DEFAULT_SEEK))
|
||||||
|
},
|
||||||
|
["next" | "skip", ..] => Action::Media(MediaAction::Next),
|
||||||
|
["stop", ..] => Action::Media(MediaAction::Stop),
|
||||||
|
_ => Action::Media(MediaAction::Enqueue { path: line.to_string(), replace: true }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,5 +7,6 @@ edition = "2021"
|
||||||
tubest-common.workspace = true
|
tubest-common.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
libmpv.workspace = true
|
libmpv.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
tokio-stream.workspace = true
|
tokio-stream.workspace = true
|
||||||
|
|
|
@ -4,6 +4,7 @@ use std::process::Stdio;
|
||||||
use tokio::io::{AsyncBufReadExt, AsyncRead, BufReader};
|
use tokio::io::{AsyncBufReadExt, AsyncRead, BufReader};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
use tokio_stream::wrappers::LinesStream;
|
use tokio_stream::wrappers::LinesStream;
|
||||||
|
use tubest_common::*;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
|
@ -33,9 +34,45 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
mpv.load_config(home.join(".config/mpv/mpv.conf").to_str().unwrap())
|
mpv.load_config(home.join(".config/mpv/mpv.conf").to_str().unwrap())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// TODO: handle other cases of combined.next().await appropriately
|
||||||
while let Some(Ok(line)) = combined.next().await {
|
while let Some(Ok(line)) = combined.next().await {
|
||||||
mpv.playlist_load_files(&[(&line, FileState::AppendPlay, None)])
|
// TODO: remove ? and unwrap so stuff is nonfatal
|
||||||
.expect("couldn't load path");
|
let cmd: Action = serde_json::from_str(line.trim())?;
|
||||||
|
do_action(&mpv, cmd).unwrap();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_action(mpv: &Mpv, cmd: Action) -> Result<(), libmpv::Error> {
|
||||||
|
match cmd {
|
||||||
|
Action::Media(mcmd) => match mcmd {
|
||||||
|
MediaAction::Enqueue { path, replace } => {
|
||||||
|
let action = if replace {
|
||||||
|
FileState::Replace
|
||||||
|
} else {
|
||||||
|
FileState::AppendPlay
|
||||||
|
};
|
||||||
|
mpv.playlist_load_files(&[(&path, action, None)])?;
|
||||||
|
}
|
||||||
|
MediaAction::Pause => {
|
||||||
|
mpv.pause()?;
|
||||||
|
}
|
||||||
|
MediaAction::Unpause => {
|
||||||
|
mpv.unpause()?;
|
||||||
|
}
|
||||||
|
MediaAction::FastForward(duration) => {
|
||||||
|
mpv.seek_forward(duration.as_secs_f64())?;
|
||||||
|
}
|
||||||
|
MediaAction::Rewind(duration) => {
|
||||||
|
mpv.seek_backward(duration.as_secs_f64())?;
|
||||||
|
}
|
||||||
|
MediaAction::Next => {
|
||||||
|
mpv.playlist_next_weak()?;
|
||||||
|
}
|
||||||
|
MediaAction::Stop => {
|
||||||
|
mpv.playlist_clear()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use matrix_sdk::{
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tubest_common::PROG_NAME;
|
use tubest_common::{Action, PROG_NAME};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Config {
|
struct Config {
|
||||||
|
@ -114,7 +114,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
SyncRoomMessageEvent::Original(orig) => {
|
SyncRoomMessageEvent::Original(orig) => {
|
||||||
let body = orig.content.body();
|
let body = orig.content.body();
|
||||||
// TODO: my own IPC wrapper
|
// TODO: my own IPC wrapper
|
||||||
println!("{}", body);
|
println!("{}", serde_json::to_string(&Action::from_line(body)).unwrap());
|
||||||
eprintln!("{}", body);
|
eprintln!("{}", body);
|
||||||
}
|
}
|
||||||
SyncRoomMessageEvent::Redacted(_) => {}
|
SyncRoomMessageEvent::Redacted(_) => {}
|
||||||
|
|
Loading…
Reference in a new issue