initial commit
This commit is contained in:
commit
bd92493910
2129
Cargo.lock
generated
Normal file
2129
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
Cargo.toml
Normal file
14
Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "mastui"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
chrono = "0.4.31"
|
||||||
|
env_logger = "0.10.1"
|
||||||
|
megalodon = "0.11.6"
|
||||||
|
scraper = "0.18.1"
|
||||||
|
serde_json = "1.0.108"
|
||||||
|
tokio = "1.34.0"
|
131
src/main.rs
Normal file
131
src/main.rs
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
use megalodon::{generator, streaming::Message};
|
||||||
|
use std::env;
|
||||||
|
use scraper::{Html,Selector};
|
||||||
|
use megalodon::entities::Status;
|
||||||
|
use megalodon::entities::notification::NotificationType;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
let url = env::var("MASTODON_STREAMING_URL").unwrap_or_else(|_| {
|
||||||
|
String::from("https://mamot.fr/")
|
||||||
|
});
|
||||||
|
|
||||||
|
let Ok(token) = env::var("MASTODON_ACCESS_TOKEN") else {
|
||||||
|
println!("Specify MASTODON_ACCESS_TOKEN!!");
|
||||||
|
return
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let client = megalodon::generator(
|
||||||
|
megalodon::SNS::Mastodon,
|
||||||
|
url.clone(),
|
||||||
|
Some(token.clone()),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let res = client.verify_account_credentials().await.unwrap();
|
||||||
|
println!("Creds: {:#?}", res.json());
|
||||||
|
|
||||||
|
let res = client.get_instance().await.unwrap();
|
||||||
|
//println!("Instance: {:#?}", res.json());
|
||||||
|
|
||||||
|
let mut res2 = client.get_home_timeline(None).await.unwrap().json();
|
||||||
|
res2.reverse();
|
||||||
|
for status in &res2 {
|
||||||
|
print_status(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
let url_ws = res.json().urls.unwrap().streaming_api;
|
||||||
|
streaming(url_ws.as_str(), token).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn print_status(status: &Status) {
|
||||||
|
let now = chrono::offset::Utc::now();
|
||||||
|
let date_diff = duration_to_string(&(now - status.created_at));
|
||||||
|
|
||||||
|
if let Some(retoot) = &status.reblog {
|
||||||
|
println!("From: {}, {date_diff} ago [retoot by: {}]",
|
||||||
|
retoot.account.acct,
|
||||||
|
status.account.acct);
|
||||||
|
print_content(&retoot.content);
|
||||||
|
} else {
|
||||||
|
println!("From: {}, {date_diff} ago", status.account.acct);
|
||||||
|
print_content(&status.content);
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn duration_to_string(d: &chrono::Duration) -> String {
|
||||||
|
match d.num_seconds() {
|
||||||
|
s if s < 60 => format!("{} secs.", s),
|
||||||
|
s if s < 60*60 => format!("{} mins.", s/60),
|
||||||
|
s if s < 60*60*24 => format!("{} hours.", s/(60*60)),
|
||||||
|
s => format!("{}days", s/(60*60*24))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_content(content: &str) {
|
||||||
|
let fragment = Html::parse_fragment(content);
|
||||||
|
let sel = Selector::parse("p").unwrap();
|
||||||
|
if let Some(p) = fragment.select(&sel).next() {
|
||||||
|
let text = p.text().collect::<Vec<_>>();
|
||||||
|
let text2 = text.join(" ");
|
||||||
|
println!("Content: {}", text2);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
println!("Content: {:?}", content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn streaming(url: &str, access_token: String) {
|
||||||
|
let client = generator(
|
||||||
|
megalodon::SNS::Mastodon,
|
||||||
|
url.to_string(),
|
||||||
|
Some(access_token),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let streaming = client.user_streaming(url.to_string());
|
||||||
|
|
||||||
|
streaming
|
||||||
|
.listen(Box::new(|message| match message {
|
||||||
|
Message::Update(status) => print_status(&status),
|
||||||
|
Message::Notification(mes) => {
|
||||||
|
|
||||||
|
let from = mes.account.map(| u | u.acct)
|
||||||
|
.unwrap_or_else(|| String::from("(unknown)"));
|
||||||
|
|
||||||
|
match mes.r#type {
|
||||||
|
NotificationType::Favourite => {
|
||||||
|
println!("*** {from} favorited one of your toots.");
|
||||||
|
},
|
||||||
|
NotificationType::Reblog => {
|
||||||
|
println!("*** {from} boosted one of your toots.");
|
||||||
|
},
|
||||||
|
NotificationType::Follow => {
|
||||||
|
println!("*** {from} follows you.");
|
||||||
|
},
|
||||||
|
NotificationType::FollowRequest => {
|
||||||
|
println!("*** {from} sent you a follow request.");
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
println!("Notification: {:?}", mes.r#type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Message::Conversation(mes) => {
|
||||||
|
println!("Conversation: {:#?}", mes);
|
||||||
|
}
|
||||||
|
Message::Delete(mes) => {
|
||||||
|
println!("message is deleted: {}", mes);
|
||||||
|
}
|
||||||
|
Message::StatusUpdate(mes) => {
|
||||||
|
println!("updated: {:#?}", mes)
|
||||||
|
}
|
||||||
|
Message::Heartbeat() => {
|
||||||
|
//println!("heartbeat");
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.await;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user