caveman/hunter/src/feed.rs
2022-11-03 20:59:36 +01:00

95 lines
2.1 KiB
Rust

use chrono::{DateTime, FixedOffset};
#[derive(Debug, serde::Deserialize)]
pub struct Account {
pub username: String,
pub display_name: String,
pub url: String,
pub bot: bool,
pub avatar: String,
pub header: String,
}
impl Account {
pub fn host(&self) -> Option<String> {
reqwest::Url::parse(&self.url)
.ok()
.and_then(|url| url.domain()
.map(|s| s.to_lowercase())
)
}
}
#[derive(Debug, serde::Deserialize)]
pub struct Tag {
pub name: String,
}
#[derive(Debug, serde::Deserialize)]
pub struct Application {
pub name: String,
pub website: Option<String>,
}
#[derive(Debug, serde::Deserialize)]
pub struct Mention {
pub username: Option<String>,
pub url: String,
pub acct: Option<String>,
}
impl Mention {
pub fn user_host(&self) -> Option<String> {
reqwest::Url::parse(&self.url)
.ok()
.and_then(|url| url.domain()
.map(|host| host.to_lowercase())
)
}
}
#[derive(Debug, serde::Deserialize)]
pub struct Post {
pub created_at: String,
pub url: String,
pub content: String,
pub account: Account,
pub tags: Vec<Tag>,
pub application: Option<Application>,
pub sensitive: Option<bool>,
pub mentions: Vec<Mention>,
pub language: Option<String>,
}
impl Post {
pub fn url_host(&self) -> Option<String> {
reqwest::Url::parse(&self.url)
.ok()
.and_then(|url| url.domain()
.map(|host| host.to_owned())
)
}
pub fn timestamp(&self) -> Option<DateTime<FixedOffset>> {
DateTime::parse_from_rfc3339(&self.created_at)
.ok()
}
}
#[derive(Debug)]
pub struct Feed {
pub posts: Vec<Post>,
}
impl Feed {
pub async fn fetch(client: &reqwest::Client, url: &str) -> Result<Self, reqwest::Error> {
let posts: Vec<Post> = client.get(url)
.send()
.await?
.json()
.await?;
log::trace!("{} {} posts", url, posts.len());
Ok(Feed { posts })
}
}