link_preview/profiles/
youtube.rs

1use scraper::Html;
2use url::Url;
3
4use crate::profiles::ProfileExt;
5use crate::LinkPreview;
6
7const YOUTUBE_IMAGE_STORAGE_DOMAIN: &str = "https://i.ytimg.com";
8
9pub struct YouTubeProfile {}
10
11impl ProfileExt for YouTubeProfile {
12    fn extract(html: &Html) -> Option<LinkPreview> {
13        let mut link_preview = LinkPreview::from(html);
14
15        if let Some(image_url) = link_preview.image_url {
16            let mut url = Url::parse(YOUTUBE_IMAGE_STORAGE_DOMAIN).ok()?;
17            url.set_path(image_url.path());
18            link_preview.image_url = Some(url);
19        }
20
21        Some(link_preview)
22    }
23
24    fn fits(url: &Url) -> bool {
25        url.host_str()
26            .is_some_and(|host| host.contains("youtube.com") || host.contains("youtu.be"))
27    }
28}
29
30#[cfg(test)]
31mod tests {
32    use std::str::from_utf8;
33
34    use scraper::Html;
35
36    use crate::tests::YOUTUBE_VIDEO_HTML;
37
38    use super::*;
39
40    #[test]
41    fn test_youtube_profile() {
42        let html = from_utf8(YOUTUBE_VIDEO_HTML).expect("Failed to parse YouTube HTML");
43        let html = Html::parse_document(html);
44
45        let url = Url::parse("https://youtu.be/61JHONRXhjs").expect("Failed to parse URL");
46        assert!(YouTubeProfile::fits(&url));
47
48        let link_preview = YouTubeProfile::extract(&html);
49        assert!(link_preview.is_some());
50
51        let preview = link_preview.unwrap();
52
53        assert_eq!(
54            preview.title,
55            Some("Google — Year in Search 2024".to_string())
56        );
57
58        assert_eq!(
59            preview.description,
60            Some("This year, we're celebrating the Breakout Searches of 2024. From iconic performances, to history-making breakthroughs, see the moments that shaped our year i...".to_string())
61        );
62
63        assert_eq!(
64            preview.image_url.map(|u| u.to_string()),
65            Some("https://i.ytimg.com/vi/61JHONRXhjs/maxresdefault.jpg".to_string())
66        );
67
68        assert_eq!(preview.domain, Some("www.youtube.com".to_string()));
69    }
70}