masto-rss/src/main.rs

117 lines
4.4 KiB
Rust

extern crate reqwest;
use std::path::Path;
use std::fs::File;
use std::io::Write;
use std::io::copy;
use rss::Channel;
use serde::{Serialize, Deserialize};
use toml;
#[derive(Debug, Serialize, Deserialize)]
struct Config {
url: String,
author: String,
path: String,
version: String,
description: String,
}
impl Config {
pub fn default() -> Config {
Config {
url: "https://mastodon.bofhers.es/tags/micropost.rss".to_string(),
author: "oscarmlage".to_string(),
path: "temp/".to_string(),
version: "0.0.1".to_string(),
description: "Just another tool to convert RSS from Mastodon to Markdown".to_string(),
}
}
pub fn parse(&mut self, config_file: String) -> Config {
let i = std::fs::read_to_string(config_file).expect("Error reading the file");
let myconfig: Self = toml::from_str(&i).unwrap();
myconfig
}
}
#[derive(Debug)]
struct Toot {
title: String,
date: String,
text: String,
author: String,
tags: Vec<String>,
media: Vec<String>,
}
fn download_media(url: String, path: String) {
println!(" - Downloading media images: {:?}", url);
let mut file = reqwest::blocking::get(url.clone()).unwrap();
let filename = Path::new(&url).file_name().unwrap().to_str().unwrap();
let mut out = File::create(format!("{}/{}", path, filename)).unwrap();
copy(&mut file, &mut out).expect("Error copying file");
}
fn write_to_disk(toot: &Toot, path: String, title: String) {
let mut file = File::create(format!("{}{}/index.md", path, title)).expect("Error creating file");
writeln!(&mut file, "---\ntitle: {}\ndate: {}\ndraft: false\ntags: [micropost]\nimage:\n---\n\n{}\n\n", toot.title, toot.date, toot.text).expect("Error appending content to file");
}
fn main() {
// Default config file
let default_config = ".config/masto-rss/masto-rss.ini";
let home = std::env::var("HOME").unwrap();
let cfg = format!("{}/{}", home, default_config);
// Read the config file
let mut default_config = Config::default();
let config = default_config.parse(cfg.to_string());
println!("\n✨ masto-rss v.{} - {}\n", config.version, config.description);
let rss = reqwest::blocking::get(config.url).unwrap().bytes();
let rss2 = rss.unwrap();
let channel = Channel::read_from(&rss2[..]).unwrap();
for item in channel.items.iter() {
// let link_str = item.link.as_ref().unwrap().to_string();
// let (_, title) = link_str.rsplit_once('/').unwrap();
let dt = item.pub_date.as_ref().unwrap();
let datetime = chrono::DateTime::parse_from_rfc2822(dt.as_str()).unwrap();
let title = datetime.format("%Y%m%d-%H%M").to_string();
println!("➡️ {:?}", title);
let mut toot = Toot{
title: title.to_string(),
date: datetime.to_string(),
text: item.description.as_ref().unwrap().to_string(),
author: config.author.to_string(),
tags: vec![],
media: vec![],
};
for tag in item.categories.iter() {
toot.tags.push(tag.name.to_string());
}
// Write the markdown
std::fs::create_dir_all(format!("{}{}", config.path, title))
.expect("Error creating dir");
write_to_disk(&toot, config.path.to_string(), title.to_string());
// Deal with attachments
for media in item.extensions.iter() {
// let () = media.1;
std::fs::create_dir_all(format!("{}{}/gallery", config.path, title))
.expect("Error creating gallery dir");
for image in media.1.get("content").unwrap().iter() {
let img = image.attrs.get("url").unwrap().to_string();
toot.media.push(img.clone());
download_media(img, format!("{}{}/gallery", config.path, title).to_string());
// Add gallery syntax to the markdown
let mut file = std::fs::OpenOptions::new().read(true).write(true)
.append(true).open(format!("{}{}/index.md", config.path, title)).unwrap();
writeln!(&mut file, "{{{{< gallery match=\"gallery/*\" sortOrder=\"asc\"
rowHeight=\"150\" margins=\"5\" thumbnailResizeOptions=\"600x600 q90 Lanczos\"
previewType=\"blur\" embedPreview=\"true\" >}}}}")
.expect("Error appending gallery content to file");
}
}
}
}