about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2025-01-01 05:59:30 +0300
committerVika <vika@fireburn.ru>2025-01-01 23:24:13 +0300
commit3785e3e590127be63a698ad94eb0cdf3a92eff0a (patch)
treec618aa3525113ebbb9f8e8975703aa217fc336c2
parentd10710326da703f69eaa06723dc66e330fd32745 (diff)
downloadkittybox-feature/html-view-caching.tar.zst
Gather touched channels when inserting new posts feature/html-view-caching
This is useful for cache-busting feeds. In addition, it could also be
used for things like WebSub.

Change-Id: I8061f66c2bf233ed330dfd7b1debfe9372e81b1f
-rw-r--r--src/micropub/mod.rs35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/micropub/mod.rs b/src/micropub/mod.rs
index 719fbf0..2f99592 100644
--- a/src/micropub/mod.rs
+++ b/src/micropub/mod.rs
@@ -278,7 +278,7 @@ pub(crate) async fn _post<D: 'static + Storage>(
     tracing::debug!("Saving post to database...");
     db.put_post(&mf2, &user.me).await?;
 
-    let mut channels = mf2["properties"]["channel"]
+    let channels_iter = mf2["properties"]["channel"]
         .as_array()
         .unwrap()
         .iter()
@@ -297,17 +297,30 @@ pub(crate) async fn _post<D: 'static + Storage>(
     let food_channel = user.me.join(util::FOOD_CHANNEL_PATH).unwrap().to_string();
     let default_channels = [default_channel, vcards_channel, food_channel];
 
-    for chan in &mut channels {
-        debug!("Adding post {} to channel {}", uid, chan);
-        if db.post_exists(chan).await? {
-            db.add_to_feed(chan, &uid).await?;
-        } else if default_channels.iter().any(|i| chan == i) {
-            util::create_feed(&db, &uid, chan, user).await?;
-        } else {
-            warn!("Ignoring non-existent channel: {}", chan);
+    {
+        // Borrowing iterators are actually cheap to clone!
+        let mut channels_iter = channels_iter.clone();
+
+        for chan in &mut channels_iter {
+            debug!("Adding post {} to channel {}", uid, chan);
+            if db.post_exists(chan).await? {
+                db.add_to_feed(chan, &uid).await?;
+            } else if default_channels.iter().any(|i| chan == i) {
+                // Fallback for channels that are created by default:
+                // recreate them if they're missing
+                util::create_feed(&db, &uid, chan, user).await?;
+            } else {
+                warn!("Ignoring non-existent channel: {}", chan);
+            }
         }
     }
 
+    // TODO: send the signal to frontend to purge caches for these posts
+    let cache_purge = std::iter::once(uid.as_str())
+        .chain(channels_iter)
+        .filter_map(|s| url::Url::parse(s).ok())
+        .collect::<Vec<url::Url>>();
+
     let reply =
         IntoResponse::into_response((StatusCode::ACCEPTED, [("Location", uid.as_str())]));
 
@@ -508,6 +521,10 @@ async fn post_action<D: Storage, A: AuthBackend>(
 
             update.check_validity()?;
             db.update_post(&action.url, update).await?;
+
+            // TODO: send the signal to frontend to purge caches for these posts
+            let cache_purge = std::iter::once(action.url.clone())
+                .collect::<Vec<_>>();
         }
     }