From 0bbbf3594f3c1f212cf79ac7f31df3d5219191f3 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 10 Apr 2021 22:37:33 +0200 Subject: [PATCH] Reimplement is_image and is_video in coreutils Signed-off-by: trivernis --- Cargo.lock | 1 + bot-coreutils/Cargo.lock | 32 +++++++++++++++++++++++++ bot-coreutils/Cargo.toml | 3 ++- bot-coreutils/src/tests/url_tests.rs | 18 ++++++++++++++ bot-coreutils/src/url.rs | 28 ++++++++++++++++++++++ src/commands/misc/sauce.rs | 7 +++--- src/utils/mod.rs | 36 ---------------------------- 7 files changed, 85 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c4181bd..972a1eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,6 +183,7 @@ name = "bot-coreutils" version = "0.1.0" dependencies = [ "log 0.4.14", + "mime_guess", "tokio", "url", ] diff --git a/bot-coreutils/Cargo.lock b/bot-coreutils/Cargo.lock index 39d41b4..b92d663 100644 --- a/bot-coreutils/Cargo.lock +++ b/bot-coreutils/Cargo.lock @@ -11,6 +11,7 @@ name = "bot-coreutils" version = "0.1.0" dependencies = [ "log", + "mime_guess", "tokio", "url", ] @@ -57,6 +58,22 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mime_guess" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -94,6 +111,15 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.5" @@ -123,3 +149,9 @@ dependencies = [ "matches", "percent-encoding", ] + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" diff --git a/bot-coreutils/Cargo.toml b/bot-coreutils/Cargo.toml index 3444171..96c3128 100644 --- a/bot-coreutils/Cargo.toml +++ b/bot-coreutils/Cargo.toml @@ -9,4 +9,5 @@ edition = "2018" [dependencies] tokio = "1.4.0" log = "0.4.14" -url = "2.2.1" \ No newline at end of file +url = "2.2.1" +mime_guess = "2.0.3" \ No newline at end of file diff --git a/bot-coreutils/src/tests/url_tests.rs b/bot-coreutils/src/tests/url_tests.rs index 2f3cac4..c9264fa 100644 --- a/bot-coreutils/src/tests/url_tests.rs +++ b/bot-coreutils/src/tests/url_tests.rs @@ -17,3 +17,21 @@ fn it_returns_the_domain_name() { Some("domain.com".to_string()) ); } + +#[test] +fn it_checks_for_image() { + assert!(is_image("domain.com/image.png")); + assert!(is_image("https://domain.com/image.jpeg?yo=someparam")); + assert!(!is_image("https://domain.com")); + assert!(!is_image("https://domain.com/file.pdf")); + assert!(!is_image("not an url")); +} + +#[test] +fn it_checks_for_video() { + assert!(is_video("domain.com/video.mp4")); + assert!(is_video("https://domain.com/video.webm?yo=someparam")); + assert!(!is_video("https://domain.com")); + assert!(!is_video("https://domain.com/file.pdf")); + assert!(!is_video("not an url")); +} diff --git a/bot-coreutils/src/url.rs b/bot-coreutils/src/url.rs index 6c9f23b..f145dff 100644 --- a/bot-coreutils/src/url.rs +++ b/bot-coreutils/src/url.rs @@ -1,3 +1,5 @@ +use mime_guess::{mime, Mime}; + pub use url::*; static PROTOCOL_HTTP: &str = "http://"; @@ -41,3 +43,29 @@ pub fn get_domain_for_url(url_str: &str) -> Option { Some(domain.trim_start_matches("www.").to_string()) } + +/// Guesses the mime for a given url string +#[inline] +fn guess_mime_for_url(url_str: &str) -> Option { + parse_url(url_str) + .ok() + .and_then(|u| mime_guess::from_path(u.path()).first()) +} + +/// Returns if a given url could be an image +pub fn is_image(url_str: &str) -> bool { + if let Some(guess) = guess_mime_for_url(url_str) { + guess.type_() == mime::IMAGE + } else { + false + } +} + +/// Returns if a given url could be a video +pub fn is_video(url_str: &str) -> bool { + if let Some(guess) = guess_mime_for_url(url_str) { + guess.type_() == mime::VIDEO + } else { + false + } +} diff --git a/src/commands/misc/sauce.rs b/src/commands/misc/sauce.rs index d1058ee..800542d 100644 --- a/src/commands/misc/sauce.rs +++ b/src/commands/misc/sauce.rs @@ -1,5 +1,6 @@ use crate::messages::sauce::show_sauce_menu; -use crate::utils::{get_previous_message_or_reply, is_image, is_video}; +use crate::utils::get_previous_message_or_reply; +use bot_coreutils::url; use sauce_api::Sauce; @@ -29,7 +30,7 @@ async fn sauce(ctx: &Context, msg: &Message) -> CommandResult { .attachments .into_iter() .map(|a| a.url) - .filter(|url| is_image(url) || is_video(url)) + .filter(|url| url::is_image(url) || url::is_video(url)) .collect(); log::debug!("Getting embedded images..."); @@ -37,7 +38,7 @@ async fn sauce(ctx: &Context, msg: &Message) -> CommandResult { .embeds .into_iter() .filter_map(|e| e.thumbnail.map(|t| t.url).or(e.image.map(|i| i.url))) - .filter(|url| is_image(url) || is_video(url)) + .filter(|url| url::is_image(url) || url::is_video(url)) .collect::>(); attachment_urls.append(&mut embed_images); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 683bac3..bf53d26 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,6 +1,5 @@ use crate::utils::error::BotResult; use rand::Rng; -use regex::Regex; use serenity::client::Context; use serenity::model::channel::Message; use std::collections::VecDeque; @@ -38,38 +37,3 @@ pub async fn get_previous_message_or_reply( Ok(referenced) } - -/// Returns the file for a given domain -pub fn get_file_name_for_domain(url: &str) -> Option { - lazy_static::lazy_static! { - static ref FILE_REGEX: Regex = Regex::new(r"^(https?://)?(www\.)?(\w+\.)+\w+([^/]*/)*([^/]+)$").unwrap(); - } - - let captures = FILE_REGEX.captures(url)?; - - captures.get(3).map(|c| c.as_str().to_string()) -} - -/// Returns if the given file is an image -#[inline] -pub fn is_image(url: &str) -> bool { - static IMAGE_EXTENSIONS: &[&str] = &["png", "webp", "jpg", "jpeg", "ico", "gif"]; - for ext in IMAGE_EXTENSIONS { - if url.ends_with(ext) { - return true; - } - } - return false; -} - -/// Returns if the given file is an image -#[inline] -pub fn is_video(url: &str) -> bool { - static IMAGE_EXTENSIONS: &[&str] = &["mp4", "flv", "mkv", "webm"]; - for ext in IMAGE_EXTENSIONS { - if url.ends_with(ext) { - return true; - } - } - return false; -}