Enhance back links
- Use directory listing to ensure linked entries exist. - Use a filter array for within the past year. - Read the first line summary of each entry to include in link text.
This commit is contained in:
parent
709033f5cc
commit
927a0c3257
4 changed files with 95 additions and 24 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -1101,6 +1101,7 @@ dependencies = [
|
|||
"log",
|
||||
"megalodon",
|
||||
"regex",
|
||||
"relativetime",
|
||||
"rss",
|
||||
"rustyline",
|
||||
"tokio",
|
||||
|
@ -1560,6 +1561,16 @@ version = "0.8.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||
|
||||
[[package]]
|
||||
name = "relativetime"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87b093e81f7b2ee8db5253e1343a98c8334bd5e7214e507e188d2450084e1c8d"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"humantime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.27"
|
||||
|
|
|
@ -23,6 +23,7 @@ html2md = "0.2.14"
|
|||
log = "0.4.19"
|
||||
megalodon = "0.13.3"
|
||||
regex = "1.9.1"
|
||||
relativetime = { version = "0.1.4", features = ["chrono"] }
|
||||
rss = "2.0.4"
|
||||
rustyline = "14.0.0"
|
||||
tokio = { version = "1.28.2", features = ["default", "full"] }
|
||||
|
|
|
@ -113,7 +113,7 @@ fn apply_block_quote<S: AsRef<str>>(depth: usize, content: S) -> String {
|
|||
// replace separately to avoid trailing spaces when replacing empty lines with the prefix
|
||||
let content = empty.replace_all(content.as_ref(), format!("\n{}\n", prefix.trim()));
|
||||
let content = non_empty.replace_all(&content, |c: &Captures| {
|
||||
format!("\n{}{}", prefix, c["initial"].to_string())
|
||||
format!("\n{}{}", prefix, &c["initial"])
|
||||
});
|
||||
content.to_string()
|
||||
}
|
||||
|
|
105
src/main.rs
105
src/main.rs
|
@ -9,10 +9,15 @@ use megalodon::{
|
|||
response::Response,
|
||||
Megalodon,
|
||||
};
|
||||
use relativetime::RelativeTime;
|
||||
use tokio::fs::try_exists;
|
||||
use tokio_stream::{iter, StreamExt};
|
||||
|
||||
use std::{env, fs::File, io::prelude::*};
|
||||
use std::{
|
||||
env,
|
||||
fs::{read_dir, File},
|
||||
io::{prelude::*, BufReader},
|
||||
};
|
||||
|
||||
use self::{
|
||||
format::format_status,
|
||||
|
@ -127,7 +132,7 @@ async fn main() -> Result<()> {
|
|||
Ok(exists) if exists => {
|
||||
debug!("Appending {}", output);
|
||||
let mut file = File::options().append(true).open(&output)?;
|
||||
file.write("\n\n".as_bytes())?;
|
||||
file.write_all("\n".as_bytes())?;
|
||||
file
|
||||
}
|
||||
_ => {
|
||||
|
@ -137,21 +142,18 @@ async fn main() -> Result<()> {
|
|||
.append(true)
|
||||
.open(&output)
|
||||
.with_context(|| format!("Failed to create {}", output))?;
|
||||
file.write(format!("# {}\n\n", day.end.format("%Y-%m-%d")).as_bytes())?;
|
||||
file.write_all(format!("# {}\n\n", day.end.format("%Y-%m-%d")).as_bytes())?;
|
||||
|
||||
// TODO move to separate function
|
||||
file.write(create_back_link(&day.end, "One week ago", 7).as_bytes())?;
|
||||
file.write(create_back_link(&day.end, "One month ago", 30).as_bytes())?;
|
||||
file.write(create_back_link(&day.end, "Six months ago", 6 * 30).as_bytes())?;
|
||||
file.write(create_back_link(&day.end, "One year ago", 365).as_bytes())?;
|
||||
file.write(create_back_link(&day.end, "Two years ago", 365 * 2).as_bytes())?;
|
||||
file.write(create_back_link(&day.end, "Three years ago", 365 * 3).as_bytes())?;
|
||||
let back_links = create_back_links(&output_dir, &day.end).await?;
|
||||
debug!("Created {back_links:?}");
|
||||
file.write_all(back_links.join("\n").as_bytes())
|
||||
.with_context(|| "Failed to write back links!")?;
|
||||
|
||||
file.write(b"\n")?;
|
||||
file.write_all(b"\n")?;
|
||||
file
|
||||
}
|
||||
};
|
||||
f.write_all(&reversed.join("\n\n").as_bytes())
|
||||
f.write_all(reversed.join("\n\n").as_bytes())
|
||||
.with_context(|| format!("Failed to write all to {}", output))?;
|
||||
println!("Appended matching posts to {}.", output);
|
||||
} else {
|
||||
|
@ -160,14 +162,71 @@ async fn main() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn create_back_link(day_end: &DateTime<Local>, anchor_text: &str, ago: i64) -> String {
|
||||
let prior_date = *day_end - Duration::days(ago);
|
||||
// TODO check if the file exists
|
||||
format!(
|
||||
"[{}](diary:{})\n",
|
||||
anchor_text,
|
||||
prior_date.format("%Y-%m-%d")
|
||||
)
|
||||
async fn create_back_links(output_dir: &str, this_day: &DateTime<Local>) -> Result<Vec<String>> {
|
||||
//file.write_all(create_back_link_old(&day.end, "One week ago", 7).as_bytes())?;
|
||||
//file.write_all(create_back_link_old(&day.end, "One month ago", 30).as_bytes())?;
|
||||
//file.write_all(
|
||||
// create_back_link_old(&day.end, "Six months ago", 6 * 30).as_bytes(),
|
||||
//)?;
|
||||
let within_year = [
|
||||
(*this_day - Duration::days(7))
|
||||
.format("%Y-%m-%d.md")
|
||||
.to_string(),
|
||||
(*this_day - Duration::days(30))
|
||||
.format("%Y-%m-%d.md")
|
||||
.to_string(),
|
||||
(*this_day - Duration::days(6 * 30))
|
||||
.format("%Y-%m-%d.md")
|
||||
.to_string(),
|
||||
];
|
||||
let mut years_past: Vec<String> = read_dir(output_dir)?
|
||||
.filter_map(|d| {
|
||||
d.ok().and_then(|d| {
|
||||
let d = d.file_name().to_owned();
|
||||
let d = d.to_string_lossy().to_string();
|
||||
if within_year.contains(&d)
|
||||
|| (!d.starts_with(&this_day.format("%Y-").to_string())
|
||||
&& d.ends_with(&this_day.format("-%m-%d.md").to_string()))
|
||||
{
|
||||
Some(d)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
years_past.sort();
|
||||
years_past.reverse();
|
||||
debug!("Found {years_past:?}");
|
||||
|
||||
let years_past = years_past
|
||||
.into_iter()
|
||||
.map(|b| {
|
||||
let f = format!("{}/{}", output_dir.trim_end_matches("/"), b);
|
||||
trace!("Building link for {f}");
|
||||
let mut f =
|
||||
BufReader::new(File::open(&f).with_context(|| format!("Could not open {f}"))?);
|
||||
let mut first = String::default();
|
||||
f.read_line(&mut first)
|
||||
.with_context(|| format!("Failed to read first line of {b}"))?;
|
||||
trace!("Read {first}");
|
||||
let day = b.to_string();
|
||||
let day = day.trim_end_matches(".md");
|
||||
let day: DateTime<Local> = format!("{day}T00:00:00-04:00")
|
||||
.parse()
|
||||
.with_context(|| format!("Could not parse {day} as date!"))?;
|
||||
let first = first.trim_start_matches(&format!("# {} - ", day.format("%Y-%m-%d")));
|
||||
let link = format!(
|
||||
"[{} - {}](diary:{})",
|
||||
(day - *this_day).to_relative(),
|
||||
first.trim(),
|
||||
b
|
||||
);
|
||||
debug!("Link {link}");
|
||||
Ok(link)
|
||||
})
|
||||
.collect::<Result<Vec<String>>>()?;
|
||||
Ok(years_past)
|
||||
}
|
||||
|
||||
enum NextIter {
|
||||
|
@ -215,14 +274,14 @@ async fn process_page(
|
|||
}
|
||||
|
||||
if let Some(id) = page.oldest_id {
|
||||
return Ok((Some(id.clone()), None, formatted));
|
||||
Ok((Some(id.clone()), None, formatted))
|
||||
} else {
|
||||
return Ok((None, None, formatted));
|
||||
Ok((None, None, formatted))
|
||||
}
|
||||
}
|
||||
|
||||
// Only ones authored by the user, on the date requested, that aren't a reply to any other status
|
||||
fn filter_statuses<'a>(account: &Account, day: &Range, json: &'a Vec<Status>) -> Vec<&'a Status> {
|
||||
fn filter_statuses<'a>(account: &Account, day: &Range, json: &'a [Status]) -> Vec<&'a Status> {
|
||||
json.iter()
|
||||
.filter(|status| {
|
||||
status.account.id == account.id
|
||||
|
|
Loading…
Reference in a new issue