First commit
commit
a7de875f12
|
@ -0,0 +1,14 @@
|
|||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
debug/
|
||||
target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "masto-rss"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
reqwest = { version = "0.11.12", features = ["blocking"] }
|
||||
rss = "2.0.1"
|
||||
chrono = "0.4.23"
|
|
@ -0,0 +1,8 @@
|
|||
bash:
|
||||
docker-compose run --rm dev
|
||||
|
||||
build:
|
||||
cargo build
|
||||
|
||||
run:
|
||||
cargo run
|
|
@ -0,0 +1,3 @@
|
|||
# masto-rss
|
||||
|
||||
A rust utility used to convert some RSS information (toots mainly) from Mastodon to Markdown. The destination directory is able to be imported into Hugo (The world’s fastest framework for building websites).
|
|
@ -0,0 +1,8 @@
|
|||
version: "3.8"
|
||||
|
||||
services:
|
||||
|
||||
dev:
|
||||
image: "rust:1.65"
|
||||
volumes:
|
||||
- .:/app
|
|
@ -0,0 +1,93 @@
|
|||
extern crate reqwest;
|
||||
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::io::copy;
|
||||
use rss::Channel;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Config {
|
||||
url: String,
|
||||
author: String,
|
||||
path: String,
|
||||
}
|
||||
|
||||
#[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) {
|
||||
print!("Downloading media images: {:?}", url);
|
||||
let mut file = reqwest::blocking::get(url.clone()).unwrap();
|
||||
let filename = Path::new(&url).file_name().unwrap().to_str().unwrap();
|
||||
println!("file: {:?}", file);
|
||||
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() {
|
||||
// Configure RSS url, author and path where the .md will be stored
|
||||
let config = Config {
|
||||
// url: "https://mastodon.bofhers.es/@oscarmlage.rss",
|
||||
url: "https://mastodon.bofhers.es/tags/micropost.rss".to_string(),
|
||||
author: "oscarmlage".to_string(),
|
||||
path: "temp/".to_string(),
|
||||
};
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue