diff options
author | Vincent Ambo <mail@tazj.in> | 2022-05-14T23·35+0200 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-05-14T23·50+0000 |
commit | b308361a73778c2921e7f657af434261a91c5a53 (patch) | |
tree | 6187b3c2c1cd0fb4a8cb5ca0bd3c6c1fd3ef84f8 | |
parent | f200b1265f62a1d4c91dbeeb7100dd79afb261fa (diff) |
feat(tazjin/tgsa): add stable redirects to telegram images r/4077
telegram occasionally changes the upstream urls at which images are served, with old/new partially overlapping in time afaict. with this commit, a new endpoint is added to tgsa at /img/$user/$post_id/$img_idx which serves a redirect to the actual image url that telegram had returned within the last hour (i.e. as per the cache). next step is to use these image urls in the bbcode itself. Change-Id: I9aa5cb56bc444cbe796868346c67f2e1e1b79413 Reviewed-on: https://cl.tvl.fyi/c/depot/+/5610 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su>
Diffstat (limited to '')
-rw-r--r-- | users/tazjin/tgsa/src/main.rs | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/users/tazjin/tgsa/src/main.rs b/users/tazjin/tgsa/src/main.rs index 0d323bb5be4a..1069dd83b232 100644 --- a/users/tazjin/tgsa/src/main.rs +++ b/users/tazjin/tgsa/src/main.rs @@ -192,6 +192,7 @@ const CACHE_EXPIRY: Duration = Duration::from_secs(60 * 60); struct TgPost { bbcode: String, at: Instant, + media: Vec<String>, } type Cache = RwLock<HashMap<TgLink, TgPost>>; @@ -209,10 +210,16 @@ fn fetch_with_cache(cache: &Cache, link: &TgLink) -> Result<TgPost> { let mut writer = cache.write().unwrap(); let embed = fetch_embed(&link)?; - let msg = parse_tgmessage(&embed)?; + let mut msg = parse_tgmessage(&embed)?; + let bbcode = to_bbcode(&link, &msg); + + let mut media = vec![]; + media.append(&mut msg.photos); + media.append(&mut msg.videos); let post = TgPost { - bbcode: to_bbcode(&link, &msg), + bbcode, + media, at: Instant::now(), }; @@ -221,6 +228,43 @@ fn fetch_with_cache(cache: &Cache, link: &TgLink) -> Result<TgPost> { Ok(post) } +fn handle_img_redirect(cache: &Cache, img_path: &str) -> Result<rouille::Response> { + // img_path: + // + // RWApodcast/113/1 + // ^ ^ ^ + // | | | + // | | image (0-indexed) + // | post ID + // username + + let img_parts: Vec<&str> = img_path.split("/").collect(); + + if img_parts.len() != 3 { + println!("invalid image link: {}", img_path); + return Err(anyhow!("not a valid image link: {}", img_path)); + } + + let link = TgLink { + username: img_parts[0].into(), + message_id: img_parts[1].parse().context("failed to parse message_id")?, + }; + + let img_idx: usize = img_parts[2].parse().context("failed to parse img_idx")?; + let post = fetch_with_cache(cache, &link)?; + + if img_idx >= post.media.len() { + return Err(anyhow!( + "there is no {}. image in {}/{}", + img_idx, + link.username, + link.message_id + )); + } + + Ok(rouille::Response::redirect_303(post.media[img_idx].clone())) +} + fn handle_tg_link(cache: &Cache, link: &TgLink) -> Result<rouille::Response> { let post = fetch_with_cache(cache, link)?; Ok(rouille::Response::text(post.bbcode)) @@ -232,8 +276,12 @@ fn main() { let cache: Cache = RwLock::new(HashMap::new()); rouille::start_server("0.0.0.0:8472", move |request| { - let response = { - match TgLink::parse(request.raw_url()) { + let response = loop { + if request.raw_url().starts_with("/img/") { + break handle_img_redirect(&cache, &request.raw_url()[5..]); + } + + break match TgLink::parse(request.raw_url()) { None => Ok(rouille::Response::text( r#"tgsa ---- @@ -258,7 +306,7 @@ pm me on the forums if this makes you mad or something. "#, )), Some(link) => handle_tg_link(&cache, &link), - } + }; }; match response { |