diff --git a/.gitignore b/.gitignore index e44cad5..29d5f07 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ target/ # Added by cargo /target + +.envrc diff --git a/Cargo.lock b/Cargo.lock index 7f1d35a..b4ed9da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,19 +92,19 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "async-trait" -version = "0.1.71" +version = "0.1.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.27", ] [[package]] @@ -228,9 +228,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.12" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eab9e8ceb9afdade1ab3f0fd8dbce5b1b2f468ad653baf10e771781b2b67b73" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" dependencies = [ "clap_builder", "clap_derive", @@ -239,9 +239,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.12" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f2763db829349bf00cfc06251268865ed4363b93a943174f638daf3ecdba2cd" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" dependencies = [ "anstream", "anstyle", @@ -258,7 +258,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.27", ] [[package]] @@ -481,12 +481,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "fd-lock" @@ -495,7 +492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5" dependencies = [ "cfg-if", - "rustix 0.38.4", + "rustix", "windows-sys", ] @@ -568,7 +565,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.27", ] [[package]] @@ -849,26 +846,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys", -] - [[package]] name = "ipnet" version = "2.8.0" @@ -882,15 +859,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.4", + "rustix", "windows-sys", ] [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jni" @@ -953,12 +930,6 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - [[package]] name = "linux-raw-sys" version = "0.4.3" @@ -1015,9 +986,9 @@ dependencies = [ [[package]] name = "megalodon" -version = "0.8.7" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6715f17d5f0686ebf32cbf0731139d2abd068e0502fd1c7d20688044176f0839" +checksum = "8041cc58b39d60da6d92aa9f255a80a20a39d6cb528a2b01b60fbc25357aa244" dependencies = [ "async-trait", "chrono", @@ -1133,9 +1104,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] @@ -1208,7 +1179,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.27", ] [[package]] @@ -1328,9 +1299,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -1347,9 +1318,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.29" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -1510,20 +1481,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustix" -version = "0.37.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys", -] - [[package]] name = "rustix" version = "0.38.4" @@ -1533,7 +1490,7 @@ dependencies = [ "bitflags 2.3.3", "errno", "libc", - "linux-raw-sys 0.4.3", + "linux-raw-sys", "windows-sys", ] @@ -1593,9 +1550,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -1617,9 +1574,9 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" @@ -1633,9 +1590,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -1646,9 +1603,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -1656,29 +1613,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.171" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.27", ] [[package]] name = "serde_json" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed" +checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" dependencies = [ "itoa", "ryu", @@ -1687,9 +1644,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc4422959dd87a76cb117c191dcbffc20467f06c9100b76721dab370f24d3a" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" dependencies = [ "itoa", "serde", @@ -1832,9 +1789,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.25" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", @@ -1843,15 +1800,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" dependencies = [ - "autocfg", "cfg-if", "fastrand", "redox_syscall", - "rustix 0.37.23", + "rustix", "windows-sys", ] @@ -1877,22 +1833,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.27", ] [[package]] @@ -1949,7 +1905,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.27", ] [[package]] @@ -1985,9 +1941,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c" +checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" dependencies = [ "futures-util", "log", @@ -2045,9 +2001,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" +checksum = "e862a1c4128df0112ab625f55cd5c934bcb4312ba80b39ae4b4835a3fd58e649" dependencies = [ "byteorder", "bytes", @@ -2086,9 +2042,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -2141,9 +2097,9 @@ dependencies = [ [[package]] name = "urlencoding" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "utf-8" @@ -2221,7 +2177,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.27", "wasm-bindgen-shared", ] @@ -2255,7 +2211,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.27", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/src/format.rs b/src/format.rs index 1e9f4d4..4ff619c 100644 --- a/src/format.rs +++ b/src/format.rs @@ -13,17 +13,23 @@ use url_open::UrlOpen; pub(super) async fn format_status( client: &Box, + depth: usize, account: &Account, status: &Status, ) -> Result { + let time_prefix = quote_prefix(0); + let ancestor_prefix = quote_prefix(depth); let ancestor = format!( - "{} -> {}{}", - status.created_at.with_timezone(&Local).format("%H:%M"), - apply_block_quote(1, (&status.content).trim()), - format_attachments(1, &status.media_attachments) + "{time_prefix}{timestamp} +{ancestor_prefix}{status}{attachments}", + time_prefix = time_prefix, + timestamp = status.created_at.with_timezone(&Local).format("%H:%M"), + ancestor_prefix = ancestor_prefix, + status = apply_block_quote(depth, (&status.content).trim()), + attachments = format_attachments(depth, &status.media_attachments) ); let Response { json, .. } = client.get_status_context(status.id.clone(), None).await?; + let descendant_prefix = quote_prefix(depth + 1); let thread = json .descendants .into_iter() @@ -32,12 +38,14 @@ pub(super) async fn format_status( }) .map(|status| { format!( - "> -> {} ->> {}{}", - status.created_at.with_timezone(&Local).format("%H:%M"), - apply_block_quote(2, parse_html(&status.content).trim()), - format_attachments(2, &status.media_attachments) + "{ancestor_prefix} +{ancestor_prefix}{timestamp} +{descendant_prefix}{status}{attachments}", + ancestor_prefix = ancestor_prefix, + timestamp = status.created_at.with_timezone(&Local).format("%H:%M"), + descendant_prefix = descendant_prefix, + status = apply_block_quote(depth + 1, parse_html(&status.content).trim()), + attachments = format_attachments(depth + 1, &status.media_attachments) ) }) .collect::>() @@ -54,7 +62,11 @@ pub(super) async fn format_status( } fn quote_prefix(depth: usize) -> String { - vec![">"; depth].join("") + if depth == 0 { + String::default() + } else { + format!("{} ", vec![">"; depth].join("")) + } } fn format_attachments(depth: usize, attachments: &[Attachment]) -> String { @@ -94,9 +106,9 @@ fn apply_block_quote>(depth: usize, content: S) -> String { let content = content.replace("

", ""); let content = content.replace("

", ""); // 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)); + 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"].to_string()) }); content.to_string() } diff --git a/src/main.rs b/src/main.rs index dc7e35d..e0b8d59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,9 +3,9 @@ use chrono::{DateTime, Local, Utc}; use clap::{arg, command, Parser}; use log::{debug, trace}; use megalodon::{ - entities::{Account, Status}, + entities::{Account, Status, StatusVisibility}, generator, - megalodon::GetLocalTimelineInputOptions, + megalodon::{GetAccountStatusesInputOptions, GetLocalTimelineInputOptions}, response::Response, Megalodon, }; @@ -80,38 +80,46 @@ async fn main() -> Result<()> { trace!("Page bounds {:?}", page); - // this age comparison only applies after the first page is fetched; the rest of the loop - // body handles if the requested date is newer than any statuses on the first page - if last_id_on_page.is_some() && page_start_older_than(&page, &day) { + let (last_id, next_iter, mut formatted) = + process_page(&client, &account, &statuses, &last_id_on_page, &day, 1).await?; + reversed.append(&mut formatted); + if let Some(NextIter::Stop) = next_iter { break; } - - // fetching returns 20 at a time, in reverse chronological order so may require skipping - // pages after the requested date - if let Some(oldest_id) = page_newer_than(&page, &day) { - last_id_on_page.replace(oldest_id); + if let Some(last_id) = last_id { + last_id_on_page.replace(last_id); + } + if let Some(NextIter::Skip) = next_iter { continue; } - - // mapping the vector runs into thorny ownership issues and only produces futures, not - // resolved values; a for in loop works with await but also runs into thorny ownership - // issues; a stream resolves both because the stream takes ownership of the statuses and - // can be iterated in a simple way that allows the use of await in the body - let mut stream = iter(filter_statuses(&account, &day, &statuses)); - while let Some(status) = stream.next().await { - reversed.push(format_status(&client, &account, status).await?); - } - - if page_end_older_than(&page, &day) { - debug!("No more posts in range."); + } + last_id_on_page = None; + loop { + let statuses = fetch_dm_page(&client, &account, &last_id_on_page).await?; + if statuses.is_empty() { + debug!("No more DMs in range."); break; } + let page = bounds_from(&statuses); - if let Some(id) = page.oldest_id { - last_id_on_page.replace(id.clone()); + trace!("Page bounds {:?}", page); + + let (last_id, next_iter, mut formatted) = + process_page(&client, &account, &statuses, &last_id_on_page, &day, 0).await?; + reversed.append(&mut formatted); + if let Some(NextIter::Stop) = next_iter { + break; + } + if let Some(last_id) = last_id { + last_id_on_page.replace(last_id); + } + if let Some(NextIter::Skip) = next_iter { + continue; } } + reversed.reverse(); + if let Some(output_dir) = output_dir { let output = format!("{}{}.md", output_dir, date); let mut f = File::options().append(true).open(&output)?; @@ -123,6 +131,57 @@ async fn main() -> Result<()> { Ok(()) } +enum NextIter { + Skip, + Stop, +} + +async fn process_page( + client: &Box, + account: &Account, + statuses: &Vec, + last_id_on_page: &Option, + day: &Range, + depth: usize, +) -> Result<(Option, Option, Vec)> { + let page = bounds_from(&statuses); + + trace!("Page bounds {:?}", page); + + // this age comparison only applies after the first page is fetched; the rest of the loop + // body handles if the requested date is newer than any statuses on the first page + if last_id_on_page.is_some() && page_start_older_than(&page, day) { + return Ok((None, Some(NextIter::Stop), Vec::new())); + } + + // fetching returns 20 at a time, in reverse chronological order so may require skipping + // pages after the requested date + if let Some(oldest_id) = page_newer_than(&page, &day) { + return Ok((Some(oldest_id), Some(NextIter::Skip), Vec::new())); + } + + // mapping the vector runs into thorny ownership issues and only produces futures, not + // resolved values; a for in loop works with await but also runs into thorny ownership + // issues; a stream resolves both because the stream takes ownership of the statuses and + // can be iterated in a simple way that allows the use of await in the body + let mut stream = iter(filter_statuses(account, &day, &statuses)); + let mut formatted = Vec::new(); + while let Some(status) = stream.next().await { + formatted.push(format_status(client, depth, &account, status).await?); + } + + if page_end_older_than(&page, &day) { + debug!("No more posts in range."); + return Ok((None, Some(NextIter::Stop), formatted)); + } + + if let Some(id) = page.oldest_id { + return Ok((Some(id.clone()), None, formatted)); + } else { + return 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) -> Vec<&'a Status> { json.iter() @@ -143,8 +202,9 @@ async fn fetch_page( client: &Box, last_id_on_page: &Option, ) -> Result> { + trace!("Fetching page of local timeline"); let Response { json, .. } = if let Some(max_id) = last_id_on_page.as_ref() { - debug!("Fetching next page"); + trace!("Fetching next page"); client .get_local_timeline(Some(&GetLocalTimelineInputOptions { max_id: Some(max_id.clone()), @@ -152,12 +212,53 @@ async fn fetch_page( })) .await? } else { - debug!("Fetching first page"); + trace!("Fetching first page"); client.get_local_timeline(None).await? }; Ok(json) } +async fn fetch_dm_page( + client: &Box, + account: &Account, + last_id_on_page: &Option, +) -> Result> { + trace!("Fetching page of DMs"); + let Response { json, .. } = if let Some(max_id) = last_id_on_page.as_ref() { + trace!("Fetching next page"); + client + .get_account_statuses( + account.id.clone(), + Some(&GetAccountStatusesInputOptions { + max_id: Some(max_id.clone()), + ..GetAccountStatusesInputOptions::default() + }), + ) + .await? + } else { + trace!("Fetching first page"); + client + .get_account_statuses(account.id.clone(), None) + .await? + }; + let json: Vec = json + .into_iter() + .filter(|s| { + if let StatusVisibility::Direct = s.visibility { + (s.in_reply_to_account_id.is_none() + || s.in_reply_to_account_id + .as_ref() + .map(|r| r == &account.id) + .unwrap_or_default()) + && s.mentions.is_empty() + } else { + false + } + }) + .collect(); + Ok(json) +} + fn page_newer_than(page: &Page, range: &Range) -> Option { page.oldest .filter(|oldest| *oldest > &range.end)