1
0
mirror of https://gitlab.com/Anson-Projects/zine.git synced 2025-06-16 05:26:40 +00:00
zine/src/web_fetchers.rs
2025-01-10 12:26:35 -07:00

53 lines
1.5 KiB
Rust

use feed_rs::model::Entry;
use feed_rs::parser;
use reqwest::blocking::get;
use scraper::{Html, Selector};
use std::error::Error;
pub fn fetch_feed(url: &str) -> Result<Vec<Entry>, Box<dyn Error>> {
let content = get(url)?.text()?;
let feed = parser::parse(content.as_bytes())?;
if feed.entries.is_empty() {
log::warn!("Feed {url} returned no items!");
} else {
log::info!("Feed {} returned {} items", url, feed.entries.len());
}
Ok(feed.entries)
}
pub fn fetch_social_image(url: String) -> Result<String, Box<dyn std::error::Error>> {
let html = reqwest::blocking::get(url)?.text()?;
let document = Html::parse_document(&html);
let selector = Selector::parse("meta[property=\"og:image\"]").unwrap();
let image_url = document
.select(&selector)
.next()
.and_then(|element| element.value().attr("content"));
if let Some(url) = image_url {
Ok(url.to_string())
} else {
Err("No social image found".into())
}
}
pub fn is_valid_image_url(url: &str) -> Result<bool, Box<dyn std::error::Error>> {
let client = reqwest::blocking::Client::new();
let response = client.head(url).send()?;
let status = response.status();
let content_type = response.headers().get(reqwest::header::CONTENT_TYPE);
Ok(status.is_success()
&& content_type.is_some_and(|ct| ct.to_str().is_ok_and(|s| s.starts_with("image/"))))
}
pub fn is_valid_url(url: &str) -> bool {
let client = reqwest::blocking::Client::new();
client.get(url).send().is_ok()
}