feat: better command handling
This commit is contained in:
parent
2fb8f1dbbf
commit
4760406224
68
Cargo.lock
generated
68
Cargo.lock
generated
|
@ -68,7 +68,7 @@ version = "1.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
|
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -78,7 +78,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
|
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstyle",
|
"anstyle",
|
||||||
"windows-sys",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -304,6 +304,16 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "eyre"
|
name = "eyre"
|
||||||
version = "0.6.12"
|
version = "0.6.12"
|
||||||
|
@ -314,6 +324,12 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "2.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
@ -594,6 +610,12 @@ version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
|
@ -656,7 +678,7 @@ dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi",
|
||||||
"windows-sys",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -808,6 +830,19 @@ version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
|
checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "0.38.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
|
@ -889,6 +924,7 @@ dependencies = [
|
||||||
"jsonrpsee",
|
"jsonrpsee",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
|
@ -917,7 +953,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
|
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -937,6 +973,19 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"fastrand",
|
||||||
|
"once_cell",
|
||||||
|
"rustix",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.63"
|
version = "1.0.63"
|
||||||
|
@ -982,7 +1031,7 @@ dependencies = [
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"windows-sys",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1202,6 +1251,15 @@ dependencies = [
|
||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.59.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "windows-targets"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
|
|
|
@ -13,6 +13,7 @@ futures = "0.3.30"
|
||||||
jsonrpsee = { version = "0.24.3", features = ["macros", "async-client"] }
|
jsonrpsee = { version = "0.24.3", features = ["macros", "async-client"] }
|
||||||
serde = { version = "1.0.209", features = ["derive"] }
|
serde = { version = "1.0.209", features = ["derive"] }
|
||||||
serde_json = "1.0.127"
|
serde_json = "1.0.127"
|
||||||
|
tempfile = "3.12.0"
|
||||||
thiserror = "1.0.63"
|
thiserror = "1.0.63"
|
||||||
tokio = { version = "1.40.0", features = ["full"] }
|
tokio = { version = "1.40.0", features = ["full"] }
|
||||||
tokio-stream = "0.1.15"
|
tokio-stream = "0.1.15"
|
||||||
|
|
174
src/main.rs
174
src/main.rs
|
@ -1,18 +1,21 @@
|
||||||
use std::fs::{create_dir_all, write, File, OpenOptions};
|
use std::fs::{create_dir_all, remove_file, rename, write, File, OpenOptions};
|
||||||
use std::io::{BufRead, BufReader, Write};
|
use std::io::{BufRead, BufReader, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use base64::prelude::BASE64_STANDARD;
|
use base64::prelude::BASE64_STANDARD;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use chrono::{DateTime, Local, Timelike};
|
use chrono::{DateTime, Local};
|
||||||
use clap::{command, Parser};
|
use clap::{command, Parser};
|
||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::{eyre, Result};
|
||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use jsonrpsee::async_client::{Client, ClientBuilder};
|
use jsonrpsee::async_client::{Client, ClientBuilder};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
use tempfile::tempdir;
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tokio::task::yield_now;
|
||||||
use tokio_util::codec::{FramedRead, LinesCodec};
|
use tokio_util::codec::{FramedRead, LinesCodec};
|
||||||
|
|
||||||
use crate::jsonrpc::RpcClient;
|
use crate::jsonrpc::RpcClient;
|
||||||
|
@ -37,9 +40,9 @@ struct Config {
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
output_folder: String,
|
output_folder: String,
|
||||||
|
|
||||||
///The time of day when generate the post
|
///The used as the journal
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
time: String,
|
url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Template)]
|
#[derive(Debug, Default, Template)]
|
||||||
|
@ -57,14 +60,12 @@ struct Message {
|
||||||
time: String,
|
time: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn generate_post(config: &Config, client: &mut Client) -> Result<()> {
|
async fn generate_post(config: &Config, client: &mut Client) -> Result<String> {
|
||||||
let day: DateTime<Local> = Local::now();
|
let day: DateTime<Local> = Local::now();
|
||||||
let _hour = day.hour();
|
let file = PathBuf::from(format!("{}/texts.json", config.data_folder));
|
||||||
let folder: PathBuf = [config.output_folder.clone(), day.to_rfc3339()]
|
let tempdir = tempdir()?;
|
||||||
.iter()
|
if !file.exists() {
|
||||||
.collect();
|
return Err(eyre!("No content to post"));
|
||||||
if !folder.exists() {
|
|
||||||
create_dir_all(&folder)?;
|
|
||||||
}
|
}
|
||||||
let mut template = PostTemplate {
|
let mut template = PostTemplate {
|
||||||
date: day.to_rfc3339(),
|
date: day.to_rfc3339(),
|
||||||
|
@ -72,14 +73,15 @@ async fn generate_post(config: &Config, client: &mut Client) -> Result<()> {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let mut msgs = Vec::new();
|
let mut msgs = Vec::new();
|
||||||
let file = File::open(format!("{}/texts.json", config.data_folder))?;
|
{
|
||||||
let reader = BufReader::new(file);
|
let file = File::open(file.clone())?;
|
||||||
|
let reader = BufReader::new(file.try_clone()?);
|
||||||
for line in reader.lines() {
|
for line in reader.lines() {
|
||||||
let v = serde_json::from_str(&line?)?;
|
let v = serde_json::from_str(&line?)?;
|
||||||
let mut attachments = Vec::new();
|
let mut attachments = Vec::new();
|
||||||
if let Some(i) = get_msg_attachments(client, &v).await {
|
if let Some(i) = get_msg_attachments(client, &v).await {
|
||||||
for (id, content) in i {
|
for (id, content) in i {
|
||||||
let path = folder.join(id);
|
let path = tempdir.path().join(id);
|
||||||
save_picture(&path, &content)?;
|
save_picture(&path, &content)?;
|
||||||
attachments.push(id.to_string());
|
attachments.push(id.to_string());
|
||||||
}
|
}
|
||||||
|
@ -91,10 +93,24 @@ async fn generate_post(config: &Config, client: &mut Client) -> Result<()> {
|
||||||
time: get_msg_time(&v).unwrap(),
|
time: get_msg_time(&v).unwrap(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if msgs.is_empty() {
|
||||||
|
return Err(eyre!("No content to post"));
|
||||||
|
};
|
||||||
template.messages = msgs;
|
template.messages = msgs;
|
||||||
|
|
||||||
println!("{}", template.render()?);
|
println!("{}", template.render()?);
|
||||||
Ok(())
|
write(tempdir.path().join("index.md"), template.render()?)?;
|
||||||
|
}
|
||||||
|
let folder: PathBuf = [config.output_folder.clone(), day.to_rfc3339()]
|
||||||
|
.iter()
|
||||||
|
.collect();
|
||||||
|
if folder.exists() {
|
||||||
|
return Err(eyre!("Blog folder already exists"));
|
||||||
|
}
|
||||||
|
rename(tempdir, folder)?;
|
||||||
|
// Delete messages after we're finished with writing
|
||||||
|
remove_file(file)?;
|
||||||
|
Ok(day.to_rfc3339())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -120,17 +136,18 @@ async fn main() -> Result<()> {
|
||||||
let mut stream = client.subscribe_receive(None).await?;
|
let mut stream = client.subscribe_receive(None).await?;
|
||||||
loop {
|
loop {
|
||||||
let v = stream.next().await.unwrap()?;
|
let v = stream.next().await.unwrap()?;
|
||||||
let sender = get_msg_sender(&v);
|
// which message doesn't have a sender?
|
||||||
|
let sender = get_msg_sender(&v).expect("which message doesn't have a sender?");
|
||||||
let text = get_msg_text(&v);
|
let text = get_msg_text(&v);
|
||||||
let at = get_msg_attachments(&mut client, &v).await;
|
let at = get_msg_attachments(&mut client, &v).await;
|
||||||
if text.is_none() && at.is_none() {
|
if text.is_none() && at.is_none() {
|
||||||
continue;
|
continue;
|
||||||
} else if sender != Some(&config.allowed_sender) {
|
} else if sender != &config.allowed_sender {
|
||||||
println!("{:?}", sender);
|
println!("{:?}", sender);
|
||||||
if let Some(x) = sender {
|
client
|
||||||
client.send(
|
.send(
|
||||||
None,
|
None,
|
||||||
vec![x.to_string()],
|
vec![sender.to_string()],
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -153,33 +170,116 @@ async fn main() -> Result<()> {
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
).await?;
|
)
|
||||||
}
|
.await?;
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
println!("{v}");
|
println!("{v}");
|
||||||
println!("{:?}", text);
|
println!("{:?}", text);
|
||||||
if text == Some("post") {
|
if let Some(text) = text {
|
||||||
generate_post(&config, &mut client).await?;
|
// ©ontrol character
|
||||||
|
if let Some(text) = text.strip_prefix("©").and_then(|x| Some(x.trim())) {
|
||||||
|
match text {
|
||||||
|
"post" => {
|
||||||
|
let res = generate_post(&config, &mut client).await;
|
||||||
|
if let Ok(res) = res {
|
||||||
|
client
|
||||||
|
.send(
|
||||||
|
None,
|
||||||
|
vec![sender.to_string()],
|
||||||
|
Vec::new(),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
format!("Generated blog post at: {}/{}", config.url, res)
|
||||||
|
.to_string(),
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
} else {
|
} else {
|
||||||
|
client
|
||||||
|
.send(
|
||||||
|
None,
|
||||||
|
vec![sender.to_string()],
|
||||||
|
Vec::new(),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
format!("Error generating blog post:\n{:?}", res).to_string(),
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
client
|
||||||
|
.send(
|
||||||
|
None,
|
||||||
|
vec![sender.to_string()],
|
||||||
|
Vec::new(),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
format!("Unknown command: {}", text).to_string(),
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
let mut file = OpenOptions::new()
|
let mut file = OpenOptions::new()
|
||||||
.append(true)
|
.append(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
.open(format!("{}/texts.json", config.data_folder))?;
|
.open(format!("{}/texts.json", config.data_folder))?;
|
||||||
writeln!(file, "{}", v.to_string())?;
|
writeln!(file, "{}", v.to_string())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
//let at = get_msg_attachments(&mut client, &v).await;
|
|
||||||
//if let Some(i) = at {
|
|
||||||
// for (id, content) in i {
|
|
||||||
// let path = format!("{}/{}", &config.data_folder, id);
|
|
||||||
// save_picture(&path, &content)?;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
//stream.unsubscribe().await?;
|
|
||||||
|
|
||||||
//Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// make sure the directory exists before trying to save into it
|
/// make sure the directory exists before trying to save into it
|
||||||
|
|
Loading…
Reference in a new issue