From b21b48fcb30eaac7cf5deff36b14720849489cca Mon Sep 17 00:00:00 2001 From: npub128x7j3pwgm4vs8yra3c42fcgcwcvh94g3luwzkqa376du2q6l0esqcrwch <51cde9442e46eac81c83ec71552708c3b0cb96a88ff8e1581d8fb4de281afbf3@buzz.block.builderlab.xyz> Date: Mon, 3 Aug 2026 11:36:51 -0400 Subject: [PATCH] fix(media): use explicit media key prefix Co-authored-by: npub128x7j3pwgm4vs8yra3c42fcgcwcvh94g3luwzkqa376du2q6l0esqcrwch <51cde9442e46eac81c83ec71552708c3b0cb96a88ff8e1581d8fb4de281afbf3@buzz.block.builderlab.xyz> Signed-off-by: npub128x7j3pwgm4vs8yra3c42fcgcwcvh94g3luwzkqa376du2q6l0esqcrwch <51cde9442e46eac81c83ec71552708c3b0cb96a88ff8e1581d8fb4de281afbf3@buzz.block.builderlab.xyz> --- crates/buzz-media/src/bucket_index.rs | 32 +++++++++++++-------------- crates/buzz-media/src/keys.rs | 16 +++++++------- crates/buzz-media/src/migration.rs | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/crates/buzz-media/src/bucket_index.rs b/crates/buzz-media/src/bucket_index.rs index 38d8614f0..2807371fd 100644 --- a/crates/buzz-media/src/bucket_index.rs +++ b/crates/buzz-media/src/bucket_index.rs @@ -13,8 +13,8 @@ //! //! | Class | Shape | //! |---|---| -//! | thumb | `{sha256}.thumb.jpg` or `m/{hh}/{hh}/{community-uuid}/{sha256}.thumb.jpg` | -//! | blob | `{sha256}.{ext}` or `m/{hh}/{hh}/{community-uuid}/{sha256}.{ext}` (ext: 1-8 mixed-case alphanumeric) | +//! | thumb | `{sha256}.thumb.jpg` or `media/{hh}/{hh}/{community-uuid}/{sha256}.thumb.jpg` | +//! | blob | `{sha256}.{ext}` or `media/{hh}/{hh}/{community-uuid}/{sha256}.{ext}` (ext: 1-8 mixed-case alphanumeric) | //! | sidecar | `_meta/{community-uuid}/{sha256}.json` | //! | auxiliary | `_uploads/{community-uuid}/{sha256}/{ulid}.json` | //! | unknown | everything else | @@ -155,11 +155,11 @@ fn parse_canonical_uuid(s: &str) -> Option { Uuid::parse_str(s).ok() } -/// `m/{sha[0:2]}/{sha[2:4]}/{community}/{filename}`. The filename's digest +/// `media/{sha[0:2]}/{sha[2:4]}/{community}/{filename}`. The filename's digest /// must agree with both shard segments; malformed migration keys stay unknown. fn parse_sharded_prefix(key: &str) -> Option<(Uuid, &str)> { let mut segments = key.split('/'); - if segments.next()? != "m" { + if segments.next()? != "media" { return None; } let shard_1 = segments.next()?; @@ -586,7 +586,7 @@ mod tests { let s = sha(0xab); let c = community(10); assert_eq!( - classify_key(&format!("m/ab/ab/{c}/{s}.png")), + classify_key(&format!("media/ab/ab/{c}/{s}.png")), KeyClass::Blob { community: Some(c), sha256: s.clone(), @@ -594,7 +594,7 @@ mod tests { } ); assert_eq!( - classify_key(&format!("m/ab/ab/{c}/{s}.thumb.jpg")), + classify_key(&format!("media/ab/ab/{c}/{s}.thumb.jpg")), KeyClass::Thumb { community: Some(c), sha256: s, @@ -607,13 +607,13 @@ mod tests { let s = sha(0xab); let c = community(11); for key in [ - format!("m/ff/ab/{c}/{s}.png"), - format!("m/ab/ff/{c}/{s}.png"), - format!("m/a/ab/{c}/{s}.png"), - format!("m/ab/ab/not-a-uuid/{s}.png"), - format!("m/ab/ab/{c}/{s}.png/extra"), - format!("m/ab/ab/{c}/{}.png", s.to_uppercase()), - format!("m/ab/ab/{c}/{s}.tar.gz"), + format!("media/ff/ab/{c}/{s}.png"), + format!("media/ab/ff/{c}/{s}.png"), + format!("media/a/ab/{c}/{s}.png"), + format!("media/ab/ab/not-a-uuid/{s}.png"), + format!("media/ab/ab/{c}/{s}.png/extra"), + format!("media/ab/ab/{c}/{}.png", s.to_uppercase()), + format!("media/ab/ab/{c}/{s}.tar.gz"), ] { assert_eq!(classify_key(&key), KeyClass::Unknown, "key: {key}"); } @@ -725,9 +725,9 @@ mod tests { let c = community(12); let mut agg = BucketAggregate::default(); agg.fold(&format!("{s}.jpg"), 100); - agg.fold(&format!("m/ab/ab/{c}/{s}.jpg"), 100); + agg.fold(&format!("media/ab/ab/{c}/{s}.jpg"), 100); agg.fold(&format!("{s}.thumb.jpg"), 20); - agg.fold(&format!("m/ab/ab/{c}/{s}.thumb.jpg"), 20); + agg.fold(&format!("media/ab/ab/{c}/{s}.thumb.jpg"), 20); agg.fold(&format!("_meta/{c}/{s}.json"), 10); let snap = agg.finish(); @@ -748,7 +748,7 @@ mod tests { let sharded_community = community(13); let other_community = community(14); let mut agg = BucketAggregate::default(); - agg.fold(&format!("m/cd/cd/{sharded_community}/{s}.jpg"), 200); + agg.fold(&format!("media/cd/cd/{sharded_community}/{s}.jpg"), 200); agg.fold(&format!("_meta/{sharded_community}/{s}.json"), 10); agg.fold(&format!("_meta/{other_community}/{s}.json"), 10); diff --git a/crates/buzz-media/src/keys.rs b/crates/buzz-media/src/keys.rs index 695d818ce..de604684a 100644 --- a/crates/buzz-media/src/keys.rs +++ b/crates/buzz-media/src/keys.rs @@ -60,7 +60,7 @@ pub fn legacy_blob_key(sha256: &str, ext: &str) -> Result Ok(format!("{sha256}.{ext}")) } -/// Hash-leading blob key: `m/<2>/<2>//.`. +/// Hash-leading blob key: `media/<2>/<2>//.`. pub fn sharded_blob_key( community: CommunityId, sha256: &str, @@ -68,7 +68,7 @@ pub fn sharded_blob_key( ) -> Result { let filename = legacy_blob_key(sha256, ext)?; Ok(format!( - "m/{}/{}/{community}/{filename}", + "media/{}/{}/{community}/{filename}", &sha256[..2], &sha256[2..4] )) @@ -80,11 +80,11 @@ pub fn legacy_thumb_key(sha256: &str) -> Result { Ok(format!("{sha256}.thumb.jpg")) } -/// Hash-leading thumbnail key: `m/<2>/<2>//.thumb.jpg`. +/// Hash-leading thumbnail key: `media/<2>/<2>//.thumb.jpg`. pub fn sharded_thumb_key(community: CommunityId, sha256: &str) -> Result { let filename = legacy_thumb_key(sha256)?; Ok(format!( - "m/{}/{}/{community}/{filename}", + "media/{}/{}/{community}/{filename}", &sha256[..2], &sha256[2..4] )) @@ -135,11 +135,11 @@ mod tests { assert_eq!( sharded_blob_key(community, SHA, "jpg").unwrap(), - format!("m/ab/cd/{community}/{SHA}.jpg") + format!("media/ab/cd/{community}/{SHA}.jpg") ); assert_eq!( sharded_thumb_key(community, SHA).unwrap(), - format!("m/ab/cd/{community}/{SHA}.thumb.jpg") + format!("media/ab/cd/{community}/{SHA}.thumb.jpg") ); assert_ne!( sharded_blob_key(community, SHA, "jpg").unwrap(), @@ -155,14 +155,14 @@ mod tests { assert_eq!( read_candidates(&ctx, &format!("{SHA}.png")).unwrap(), MediaReadCandidates { - sharded: format!("m/ab/cd/{community}/{SHA}.png"), + sharded: format!("media/ab/cd/{community}/{SHA}.png"), legacy: format!("{SHA}.png"), } ); assert_eq!( read_candidates(&ctx, &format!("{SHA}.thumb.jpg")).unwrap(), MediaReadCandidates { - sharded: format!("m/ab/cd/{community}/{SHA}.thumb.jpg"), + sharded: format!("media/ab/cd/{community}/{SHA}.thumb.jpg"), legacy: format!("{SHA}.thumb.jpg"), } ); diff --git a/crates/buzz-media/src/migration.rs b/crates/buzz-media/src/migration.rs index 7cc8a7bf3..a47b8be0c 100644 --- a/crates/buzz-media/src/migration.rs +++ b/crates/buzz-media/src/migration.rs @@ -91,7 +91,7 @@ mod tests { format!("_meta/{community}/{SHA}.json/extra"), format!("_meta/{}/{SHA}.json", community.simple()), format!("_meta/{community}/ABC.json"), - format!("m/{community}/{SHA}.json"), + format!("media/{community}/{SHA}.json"), ] { assert_eq!(parse_sidecar_key(&invalid), None, "{invalid}"); }