about summary refs log tree commit diff
path: root/users/tazjin/tgsa/src/main.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-05-14T23·35+0200
committertazjin <tazjin@tvl.su>2022-05-14T23·50+0000
commitb308361a73778c2921e7f657af434261a91c5a53 (patch)
tree6187b3c2c1cd0fb4a8cb5ca0bd3c6c1fd3ef84f8 /users/tazjin/tgsa/src/main.rs
parentf200b1265f62a1d4c91dbeeb7100dd79afb261fa (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 'users/tazjin/tgsa/src/main.rs')
-rw-r--r--users/tazjin/tgsa/src/main.rs58
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 {