feat: downloadable attachments
This commit is contained in:
parent
21301e2bf1
commit
4cb71ccf5e
75
Cargo.lock
generated
75
Cargo.lock
generated
|
@ -49,6 +49,12 @@ dependencies = [
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.22.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
|
@ -125,12 +131,65 @@ version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-io",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-channel"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.30"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-executor"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-macro"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.30"
|
version = "0.3.30"
|
||||||
|
@ -155,11 +214,16 @@ version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"futures-macro",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
|
"memchr",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -521,7 +585,9 @@ dependencies = [
|
||||||
name = "signal-to-blog"
|
name = "signal-to-blog"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"base64",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
|
"futures",
|
||||||
"jsonrpsee",
|
"jsonrpsee",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -531,6 +597,15 @@ dependencies = [
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slab"
|
||||||
|
version = "0.4.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.13.2"
|
version = "1.13.2"
|
||||||
|
|
|
@ -4,7 +4,9 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
base64 = "0.22.1"
|
||||||
color-eyre = "0.6.3"
|
color-eyre = "0.6.3"
|
||||||
|
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"
|
||||||
|
|
68
src/main.rs
68
src/main.rs
|
@ -1,7 +1,13 @@
|
||||||
|
use std::fs::{create_dir, write};
|
||||||
|
use std::path::Path;
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
|
|
||||||
|
use base64::prelude::BASE64_STANDARD;
|
||||||
|
use base64::Engine;
|
||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
use jsonrpsee::async_client::ClientBuilder;
|
use futures::future::join_all;
|
||||||
|
use jsonrpsee::async_client::{Client, ClientBuilder};
|
||||||
|
use serde_json::Value;
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
use tokio_util::codec::{FramedRead, LinesCodec};
|
use tokio_util::codec::{FramedRead, LinesCodec};
|
||||||
|
|
||||||
|
@ -26,13 +32,69 @@ async fn main() -> Result<()> {
|
||||||
inner: FramedRead::new(cmd.stdout.take().unwrap(), LinesCodec::new()),
|
inner: FramedRead::new(cmd.stdout.take().unwrap(), LinesCodec::new()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let client = ClientBuilder::default().build_with_tokio(sender, receiver);
|
let mut client = ClientBuilder::default().build_with_tokio(sender, receiver);
|
||||||
let mut stream = client.subscribe_receive(None).await?;
|
let mut stream = client.subscribe_receive(None).await?;
|
||||||
{
|
loop {
|
||||||
let v = stream.next().await.unwrap()?;
|
let v = stream.next().await.unwrap()?;
|
||||||
println!("{v}");
|
println!("{v}");
|
||||||
|
println!("{:?}", get_msg_text(&v));
|
||||||
|
println!("{:?}", get_msg_sender(&v));
|
||||||
|
let at = get_msg_attachments(&mut client, &v).await;
|
||||||
|
if let Some(i) = at {
|
||||||
|
for (id, content) in i {
|
||||||
|
save_picture(id, &content)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stream.unsubscribe().await?;
|
stream.unsubscribe().await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn save_picture(name: &str, content: &str) -> Result<()> {
|
||||||
|
if !Path::new("./data/").exists() {
|
||||||
|
create_dir("./data/")?
|
||||||
|
}
|
||||||
|
write(format!("./data/{}", name), BASE64_STANDARD.decode(content)?)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_msg_attachments<'a>(
|
||||||
|
client: &mut Client,
|
||||||
|
val: &'a Value,
|
||||||
|
) -> Option<Vec<(&'a str, String)>> {
|
||||||
|
let account = val.get("account")?.as_str()?;
|
||||||
|
let attachments = val
|
||||||
|
.pointer("/envelope/dataMessage/attachments")?
|
||||||
|
.as_array()?;
|
||||||
|
let recipient = val.pointer("/envelope/source")?.as_str()?;
|
||||||
|
join_all(attachments.into_iter().map(|i| async {
|
||||||
|
let id = i.get("id")?.as_str()?;
|
||||||
|
let val = client
|
||||||
|
.get_attachment(
|
||||||
|
Some(account.to_string()),
|
||||||
|
id.to_string(),
|
||||||
|
Some(recipient.to_string()),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
val.and_then(|x| {
|
||||||
|
x.get("data")
|
||||||
|
.and_then(|x| x.as_str().map(|x| x.to_string()))
|
||||||
|
})
|
||||||
|
.and_then(|x| Some((id, x)))
|
||||||
|
}))
|
||||||
|
.await
|
||||||
|
.into_iter()
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_msg_sender(val: &Value) -> Option<&str> {
|
||||||
|
val.pointer("/envelope/source").and_then(|x| x.as_str())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_msg_text(val: &Value) -> Option<&str> {
|
||||||
|
val.pointer("/envelope/dataMessage/message")
|
||||||
|
.and_then(|x| x.as_str())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue