diff --git a/Cargo.lock b/Cargo.lock index df09983..4d21120 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -446,9 +446,9 @@ dependencies = [ [[package]] name = "async-signal" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" +checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" dependencies = [ "async-io", "async-lock", @@ -1254,7 +1254,7 @@ dependencies = [ [[package]] name = "collections" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "indexmap", "rustc-hash 2.1.2", @@ -1307,6 +1307,7 @@ dependencies = [ "nostr", "nostr-sdk", "qrcode", + "regex", "smallvec", "smol", ] @@ -1806,7 +1807,7 @@ dependencies = [ [[package]] name = "derive_refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "proc-macro2", "quote", @@ -2882,7 +2883,7 @@ dependencies = [ [[package]] name = "gpui" version = "0.2.2" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "async-channel 2.5.0", @@ -2909,6 +2910,7 @@ dependencies = [ "futures-concurrency", "getrandom 0.3.4", "gpui_macros 0.1.0 (git+https://github.com/zed-industries/zed)", + "gpui_shared_string", "gpui_util 0.1.0 (git+https://github.com/zed-industries/zed)", "http_client 0.1.0 (git+https://github.com/zed-industries/zed)", "image", @@ -2994,7 +2996,7 @@ dependencies = [ [[package]] name = "gpui_linux" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "as-raw-xcb-connection", @@ -3042,7 +3044,7 @@ dependencies = [ [[package]] name = "gpui_macos" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "async-task", @@ -3096,7 +3098,7 @@ dependencies = [ [[package]] name = "gpui_macros" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -3107,7 +3109,7 @@ dependencies = [ [[package]] name = "gpui_platform" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "console_error_panic_hook", "gpui 0.2.2 (git+https://github.com/zed-industries/zed)", @@ -3117,10 +3119,21 @@ dependencies = [ "gpui_windows", ] +[[package]] +name = "gpui_shared_string" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" +dependencies = [ + "derive_more", + "gpui_util 0.1.0 (git+https://github.com/zed-industries/zed)", + "schemars", + "serde", +] + [[package]] name = "gpui_tokio" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "gpui 0.2.2 (git+https://github.com/zed-industries/zed)", @@ -3140,7 +3153,7 @@ dependencies = [ [[package]] name = "gpui_util" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "log", @@ -3149,7 +3162,7 @@ dependencies = [ [[package]] name = "gpui_web" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "console_error_panic_hook", @@ -3201,7 +3214,7 @@ dependencies = [ [[package]] name = "gpui_wgpu" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "bytemuck", @@ -3229,7 +3242,7 @@ dependencies = [ [[package]] name = "gpui_windows" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "collections 0.1.0 (git+https://github.com/zed-industries/zed)", @@ -3526,7 +3539,7 @@ dependencies = [ [[package]] name = "http_client" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "async-compression", @@ -3551,7 +3564,7 @@ dependencies = [ [[package]] name = "http_client_tls" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "rustls", "rustls-platform-verifier", @@ -4221,9 +4234,9 @@ checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "lmdb-master-sys" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864808e0b19fb6dd3b70ba94ee671b82fce17554cf80aeb0a155c65bb08027df" +checksum = "aaeb9bd22e73bd1babffff614994b341e9b2008de7bb73bf1f7e9154f1978f8b" dependencies = [ "cc", "doxygen-rs", @@ -4406,7 +4419,7 @@ dependencies = [ [[package]] name = "media" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "bindgen", @@ -4672,7 +4685,7 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" [[package]] name = "nostr" version = "0.44.1" -source = "git+https://github.com/rust-nostr/nostr#fd25803fbc9b3fb3207ead372336208c1c60b37b" +source = "git+https://github.com/rust-nostr/nostr#2be7983065ec3af8a1f699869a125a49bc23fd22" dependencies = [ "aes", "base64", @@ -4696,7 +4709,7 @@ dependencies = [ [[package]] name = "nostr-blossom" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#fd25803fbc9b3fb3207ead372336208c1c60b37b" +source = "git+https://github.com/rust-nostr/nostr#2be7983065ec3af8a1f699869a125a49bc23fd22" dependencies = [ "base64", "nostr", @@ -4707,7 +4720,7 @@ dependencies = [ [[package]] name = "nostr-connect" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#fd25803fbc9b3fb3207ead372336208c1c60b37b" +source = "git+https://github.com/rust-nostr/nostr#2be7983065ec3af8a1f699869a125a49bc23fd22" dependencies = [ "async-utility", "futures-core", @@ -4720,7 +4733,7 @@ dependencies = [ [[package]] name = "nostr-database" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#fd25803fbc9b3fb3207ead372336208c1c60b37b" +source = "git+https://github.com/rust-nostr/nostr#2be7983065ec3af8a1f699869a125a49bc23fd22" dependencies = [ "btreecap", "flatbuffers", @@ -4730,7 +4743,7 @@ dependencies = [ [[package]] name = "nostr-gossip" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#fd25803fbc9b3fb3207ead372336208c1c60b37b" +source = "git+https://github.com/rust-nostr/nostr#2be7983065ec3af8a1f699869a125a49bc23fd22" dependencies = [ "nostr", ] @@ -4738,7 +4751,7 @@ dependencies = [ [[package]] name = "nostr-gossip-memory" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#fd25803fbc9b3fb3207ead372336208c1c60b37b" +source = "git+https://github.com/rust-nostr/nostr#2be7983065ec3af8a1f699869a125a49bc23fd22" dependencies = [ "indexmap", "lru", @@ -4750,7 +4763,7 @@ dependencies = [ [[package]] name = "nostr-lmdb" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#fd25803fbc9b3fb3207ead372336208c1c60b37b" +source = "git+https://github.com/rust-nostr/nostr#2be7983065ec3af8a1f699869a125a49bc23fd22" dependencies = [ "async-utility", "flume 0.12.0", @@ -4764,7 +4777,7 @@ dependencies = [ [[package]] name = "nostr-sdk" version = "0.44.1" -source = "git+https://github.com/rust-nostr/nostr#fd25803fbc9b3fb3207ead372336208c1c60b37b" +source = "git+https://github.com/rust-nostr/nostr#2be7983065ec3af8a1f699869a125a49bc23fd22" dependencies = [ "async-utility", "async-wsocket", @@ -5280,7 +5293,7 @@ dependencies = [ [[package]] name = "perf" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "collections 0.1.0 (git+https://github.com/zed-industries/zed)", "serde", @@ -5555,7 +5568,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.10+spec-1.1.0", + "toml_edit 0.25.11+spec-1.1.0", ] [[package]] @@ -6000,7 +6013,7 @@ dependencies = [ [[package]] name = "refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "derive_refineable 0.1.0 (git+https://github.com/zed-industries/zed)", ] @@ -6099,7 +6112,7 @@ dependencies = [ [[package]] name = "reqwest_client" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "bytes", @@ -6157,7 +6170,7 @@ dependencies = [ [[package]] name = "rope" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "heapless 0.9.2", "log", @@ -6434,7 +6447,7 @@ dependencies = [ [[package]] name = "scheduler" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "async-task", "backtrace", @@ -7047,7 +7060,7 @@ dependencies = [ [[package]] name = "sum_tree" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "heapless 0.9.2", "log", @@ -7464,9 +7477,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.51.0" +version = "1.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" +checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" dependencies = [ "bytes", "libc", @@ -7621,9 +7634,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.10+spec-1.1.0" +version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82418ca169e235e6c399a84e395ab6debeb3bc90edc959bf0f48647c6a32d1b" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ "indexmap", "toml_datetime 1.1.1+spec-1.1.0", @@ -8059,7 +8072,7 @@ dependencies = [ [[package]] name = "util" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "async-fs", @@ -8108,7 +8121,7 @@ dependencies = [ [[package]] name = "util_macros" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "perf 0.1.0 (git+https://github.com/zed-industries/zed)", "quote", @@ -9936,7 +9949,7 @@ dependencies = [ [[package]] name = "zlog" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "anyhow", "chrono", @@ -9964,7 +9977,7 @@ dependencies = [ [[package]] name = "ztracing" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" dependencies = [ "tracing", "tracing-subscriber", @@ -9980,7 +9993,7 @@ source = "git+https://github.com/zed-industries/zed?rev=56104fb17e6c5849900a4c28 [[package]] name = "ztracing_macro" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#3a5dc8ef6aaed33f7c57f9eeab36bbc71a19bc59" +source = "git+https://github.com/zed-industries/zed#5be9dc1781ef6d2cbfbdbcd417edd0935cbb83a8" [[package]] name = "zune-core" diff --git a/crates/chat/src/message.rs b/crates/chat/src/message.rs index de91023..3234226 100644 --- a/crates/chat/src/message.rs +++ b/crates/chat/src/message.rs @@ -1,8 +1,8 @@ use std::hash::Hash; use std::ops::Range; -use common::{EventExt, NostrParser}; -use gpui::SharedString; +use common::{EventExt, NostrParser, extract_and_remove_media_urls}; +use gpui::{SharedString, SharedUri}; use nostr_sdk::prelude::*; /// New message. @@ -132,6 +132,8 @@ pub struct RenderedMessage { pub author: PublicKey, /// The content/text of the message pub content: String, + /// List of media URLs in the message + pub media: Vec, /// Message created time as unix timestamp pub created_at: Timestamp, /// List of mentioned public keys in the message @@ -144,11 +146,13 @@ impl From<&Event> for RenderedMessage { fn from(val: &Event) -> Self { let mentions = extract_mentions(&val.content); let replies_to = extract_reply_ids(&val.tags); + let (media, string) = extract_and_remove_media_urls(&val.content); Self { id: val.id, author: val.pubkey, - content: val.content.clone(), + content: string, + media, created_at: val.created_at, mentions, replies_to, @@ -160,12 +164,14 @@ impl From<&UnsignedEvent> for RenderedMessage { fn from(val: &UnsignedEvent) -> Self { let mentions = extract_mentions(&val.content); let replies_to = extract_reply_ids(&val.tags); + let (media, string) = extract_and_remove_media_urls(&val.content); Self { // Event ID must be known id: val.id.unwrap(), author: val.pubkey, - content: val.content.clone(), + content: string, + media, created_at: val.created_at, mentions, replies_to, @@ -177,12 +183,14 @@ impl From<&NewMessage> for RenderedMessage { fn from(val: &NewMessage) -> Self { let mentions = extract_mentions(&val.rumor.content); let replies_to = extract_reply_ids(&val.rumor.tags); + let (media, string) = extract_and_remove_media_urls(&val.rumor.content); Self { // Event ID must be known id: val.rumor.id.unwrap(), author: val.rumor.pubkey, - content: val.rumor.content.clone(), + content: string, + media, created_at: val.rumor.created_at, mentions, replies_to, diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index 2bac890..670e635 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -20,3 +20,4 @@ log.workspace = true dirs = "5.0" qrcode = "0.14.1" bech32 = "0.11.1" +regex = "1.10" diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index 0318b82..7d7720e 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -1,6 +1,7 @@ pub use debounced_delay::*; pub use display::*; pub use event::*; +pub use media_extractor::*; pub use parser::*; pub use paths::*; pub use range::*; @@ -8,6 +9,7 @@ pub use range::*; mod debounced_delay; mod display; mod event; +mod media_extractor; mod parser; mod paths; mod range; diff --git a/crates/common/src/media_extractor.rs b/crates/common/src/media_extractor.rs new file mode 100644 index 0000000..ffe7f55 --- /dev/null +++ b/crates/common/src/media_extractor.rs @@ -0,0 +1,117 @@ +use gpui::SharedUri; +use regex::Regex; + +/// Extracts media URLs from a string and returns both the extracted URLs +/// and the string with media URLs removed +pub struct MediaExtractor { + image_regex: Regex, + video_regex: Regex, +} + +impl MediaExtractor { + /// Creates a new MediaExtractor with compiled regex patterns + pub fn new() -> Self { + MediaExtractor { + // Match common image extensions + image_regex: Regex::new( + r#"(?i)\bhttps?://[^\s<>"']+\.(?:jpg|jpeg|png|gif|bmp|webp|svg|ico)(?:\?[^\s<>"']*)?\b"#, + ).unwrap(), + // Match common video extensions + video_regex: Regex::new( + r#"(?i)\bhttps?://[^\s<>"']+\.(?:mp4|mov|avi|mkv|webm|flv|wmv|m4v|3gp)(?:\?[^\s<>"']*)?\b"#, + ).unwrap(), + } + } + + /// Extracts all media URLs from a string + pub fn extract_media_urls(&self, text: &str) -> Vec { + let mut urls = Vec::new(); + + // Extract image URLs + for capture in self.image_regex.find_iter(text) { + urls.push(capture.as_str().to_string().into()); + } + + // Extract video URLs + for capture in self.video_regex.find_iter(text) { + urls.push(capture.as_str().to_string().into()); + } + + urls + } + + /// Removes all media URLs from a string and returns the cleaned text + pub fn remove_media_urls(&self, text: &str) -> String { + let mut result = text.to_string(); + + // Remove image URLs + result = self.image_regex.replace_all(&result, "").to_string(); + + // Remove video URLs + result = self.video_regex.replace_all(&result, "").to_string(); + + // Clean up extra whitespace that might result from removal + self.cleanup_text(&result) + } + + /// Extracts media URLs and removes them from the string, returning both + pub fn extract_and_remove(&self, text: &str) -> (Vec, String) { + let urls = self.extract_media_urls(text); + let cleaned_text = self.remove_media_urls(text); + (urls, cleaned_text) + } + + /// Helper function to clean up text after URL removal + fn cleanup_text(&self, text: &str) -> String { + let text = text.trim(); + + // Remove multiple consecutive spaces + let re = Regex::new(r"\s+").unwrap(); + re.replace_all(text, " ").to_string() + } + + /// Validates if a URL is a valid media URL + pub fn is_media_url(&self, url: &str) -> bool { + self.image_regex.is_match(url) || self.video_regex.is_match(url) + } + + /// Categorizes extracted URLs into images and videos + pub fn categorize_urls(&self, urls: &[SharedUri]) -> (Vec, Vec) { + let mut images = Vec::new(); + let mut videos = Vec::new(); + + for url in urls { + if self.image_regex.is_match(url) { + images.push(url.clone()); + } else if self.video_regex.is_match(url) { + videos.push(url.clone()); + } + } + + (images, videos) + } +} + +impl Default for MediaExtractor { + fn default() -> Self { + Self::new() + } +} + +/// Convenience function for one-time extraction and removal +pub fn extract_and_remove_media_urls(text: &str) -> (Vec, String) { + let extractor = MediaExtractor::new(); + extractor.extract_and_remove(text) +} + +/// Convenience function for just extracting media URLs +pub fn extract_media_urls(text: &str) -> Vec { + let extractor = MediaExtractor::new(); + extractor.extract_media_urls(text) +} + +/// Convenience function for just removing media URLs +pub fn remove_media_urls(text: &str) -> String { + let extractor = MediaExtractor::new(); + extractor.remove_media_urls(text) +}