Skip to content

Commit

Permalink
Support v.redd.it, imgur, streamable, dubz
Browse files Browse the repository at this point in the history
  • Loading branch information
evanc577 committed Apr 29, 2024
1 parent b0c4dcd commit fff102e
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 24 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ RUN cargo install cargo-chef
###########
FROM chef AS planner

COPY src/ ./src
COPY Cargo.toml .
COPY Cargo.lock .
COPY src/ ./src
RUN cargo chef prepare --recipe-path recipe.json


Expand All @@ -37,9 +37,9 @@ FROM chef AS builder

COPY --from=planner /insomnia_bot/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json
COPY src/ ./src
COPY Cargo.toml .
COPY Cargo.lock .
COPY src/ ./src
RUN cargo build --release


Expand Down
18 changes: 18 additions & 0 deletions src/link_embed/media/dubz.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use once_cell::sync::Lazy;
use regex::Regex;

use super::MediaLinkResolver;

pub struct DubzMediaResolver;

impl MediaLinkResolver for DubzMediaResolver {
async fn resolve(url: &reqwest::Url) -> Option<Box<str>> {
static PATH_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"^/c/(?P<id>\w+)").unwrap());
PATH_RE
.captures(url.path())
.map(|cap| cap.name("id").unwrap())
.map(|id| {
format!("https://dubzalt.com/storage/videos/{}.mp4", id.as_str()).into_boxed_str()
})
}
}
18 changes: 18 additions & 0 deletions src/link_embed/media/imgur.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use once_cell::sync::Lazy;
use regex::Regex;

use super::MediaLinkResolver;

pub struct ImgurMediaResolver;

impl MediaLinkResolver for ImgurMediaResolver {
async fn resolve(url: &reqwest::Url) -> Option<Box<str>> {
static PATH_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"^/(?P<id>\w+)").unwrap());
PATH_RE
.captures(url.path())
.map(|cap| cap.name("id").unwrap())
.map(|id| {
format!("https://i.imgur.com/{}.mp4", id.as_str()).into_boxed_str()
})
}
}
20 changes: 20 additions & 0 deletions src/link_embed/media/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use self::dubz::DubzMediaResolver;
use self::imgur::ImgurMediaResolver;
use self::streamable::StreamableMediaResolver;

mod dubz;
mod streamable;
mod imgur;

pub trait MediaLinkResolver {
async fn resolve(url: &reqwest::Url) -> Option<Box<str>>;
}

pub(crate) async fn resolve_media_link(url: &reqwest::Url) -> Option<Box<str>> {
match url.domain() {
Some("streamable.com") => StreamableMediaResolver::resolve(url).await,
Some("dubz.link") => DubzMediaResolver::resolve(url).await,
Some("imgur.com") | Some("i.imgur.com") => ImgurMediaResolver::resolve(url).await,
_ => None,
}
}
18 changes: 18 additions & 0 deletions src/link_embed/media/streamable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use once_cell::sync::Lazy;
use regex::Regex;

use super::MediaLinkResolver;

pub struct StreamableMediaResolver;

impl MediaLinkResolver for StreamableMediaResolver {
async fn resolve(url: &reqwest::Url) -> Option<Box<str>> {
static PATH_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"^/(?P<id>\w+)").unwrap());
PATH_RE
.captures(url.path())
.map(|cap| cap.name("id").unwrap())
.map(|id| {
format!("https://streamable.com/{}", id.as_str()).into_boxed_str()
})
}
}
1 change: 1 addition & 0 deletions src/link_embed/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod reddit;
mod tweet;
mod media;

use std::sync::Arc;

Expand Down
37 changes: 15 additions & 22 deletions src/link_embed/reddit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ use time::{Duration, OffsetDateTime};
use tokio::sync::Mutex;

use super::ReplacedLink;
use crate::link_embed::media::resolve_media_link;
use crate::CLIENT;

static REDDIT_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"\bhttps?://(?:(?:www|old|new)\.)?reddit\.com/r/(?P<subreddit>\w+)\b(?:/comments/(?P<submission>\w+\b)(?:/[^/]+/(?P<comment>\w+\b))?)").unwrap()
Regex::new(r"\bhttps?://(?:(?:www|old|new)\.)?reddit\.com(/r/\w+)?\b(?:/comments/(?P<submission>\w+\b)(?:/[^/]+/(?P<comment>\w+\b))?)").unwrap()
});
static REDDIT_SHARE_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"\bhttps?://(?:(?:www|old|new)\.)?reddit\.com/r/(?P<subreddit>\w+)\b/s/(?P<id>\w+)")
.unwrap()
let share_re = r"\bhttps?://(?:(?:www|old|new)\.)?reddit\.com/r/\w+/s/\w+";
let vreddit_re = r"\bhttps?://v\.redd\.it/\w+";
Regex::new(&format!("{}|{}", share_re, vreddit_re)).unwrap()
});

static REDDIT_ACCESS_TOKEN: Lazy<AccessToken> = Lazy::new(AccessToken::default);
Expand All @@ -28,7 +30,6 @@ enum RedditLink {
media: Option<Box<str>>,
},
Comment {
subreddit: Box<str>,
submission_id: Box<str>,
comment_id: Box<str>,
},
Expand All @@ -41,13 +42,10 @@ impl RedditLink {
format!("https://rxddit.com/{id}").into_boxed_str()
}
RedditLink::Comment {
subreddit,
submission_id,
comment_id,
} => {
format!("https://rxddit.com/r/{subreddit}/comments/{submission_id}/_/{comment_id}")
.into_boxed_str()
}
} => format!("https://rxddit.com/comments/{submission_id}/_/{comment_id}")
.into_boxed_str(),
}
}

Expand Down Expand Up @@ -125,13 +123,12 @@ async fn reddit_share_links(text: &str) -> Vec<ReplacedLink> {
}

async fn match_reddit_link(m: Captures<'_>) -> Option<RedditLink> {
match (m.name("subreddit"), m.name("submission"), m.name("comment")) {
(Some(subreddit), Some(submission_id), Some(comment_id)) => Some(RedditLink::Comment {
subreddit: subreddit.as_str().into(),
match (m.name("submission"), m.name("comment")) {
(Some(submission_id), Some(comment_id)) => Some(RedditLink::Comment {
submission_id: submission_id.as_str().into(),
comment_id: comment_id.as_str().into(),
}),
(_, Some(submission_id), _) => Some(RedditLink::Submission {
(Some(submission_id), _) => Some(RedditLink::Submission {
id: submission_id.as_str().into(),
media: reddit_post_media(submission_id.as_str()).await,
}),
Expand Down Expand Up @@ -188,16 +185,12 @@ async fn reddit_post_media(submission_id: &str) -> Option<Box<str>> {
.first()
.and_then(|r| r.data.children.first())
.and_then(|c| c.data.url.clone())
.and_then(|url| reqwest::Url::parse(&url).ok())
.and_then(|url| media_url(&url));

media_url
}
.and_then(|url| reqwest::Url::parse(&url).ok());

fn media_url(url: &reqwest::Url) -> Option<Box<str>> {
match url.domain() {
Some("streamable.com") => Some(url.as_str().into()),
_ => None,
if let Some(media_url) = media_url {
resolve_media_link(&media_url).await
} else {
None
}
}

Expand Down

0 comments on commit fff102e

Please sign in to comment.