1use url::Url;
2use dialoguer::console::Term;
3use dialoguer::{theme::ColorfulTheme, Select};
4
5use crate::error::{BlobdlError, BlobResult};
6
7#[derive(Debug, PartialOrd, PartialEq, Clone)]
8pub enum DownloadOption {
9 YtVideo(usize),
11 YtPlaylist,
12}
13
14pub fn analyze_url(command_line_url: &str) -> BlobResult<DownloadOption> {
17 return if let Ok(url) = Url::parse(command_line_url) {
18 if let Some(domain_name) = url.domain() {
19 if domain_name.contains("youtu") {
21 inspect_yt_url(url)
22 } else {
23 Err(BlobdlError::UnsupportedWebsite)
25 }
26 } else {
27 Err(BlobdlError::DomainNotFound)
28 }
29 } else {
30 Err(BlobdlError::UrlParsingError)
31 }
32}
33
34fn inspect_yt_url(yt_url: Url) -> BlobResult<DownloadOption> {
36 if let Some(query) = yt_url.query() {
37 if query.contains("&index=") {
38 let term = Term::buffered_stderr();
40
41 let user_selection = Select::with_theme(&ColorfulTheme::default())
43 .with_prompt("The url refers to a video in a playlist, which do you want to download?")
44 .default(0)
45 .items(&["Only the video", "The whole playlist"])
46 .interact_on(&term)?;
47
48 return match user_selection {
49 0 => {
50 let index = if let Some(index_location) = query.find("&index=") {
51 let slice = &query[index_location + "&index=".len() ..];
52
53 if let Some(second_ampersand_location) = slice.find('&') {
54 &slice[..second_ampersand_location]
56 } else {
57 slice
58 }
59 } else {
60 panic!("url has &index= but doesn't provide a numerical index")
61 };
62
63 if let Ok(parsed) = index.parse() {
64 Ok(DownloadOption::YtVideo(parsed))
65 } else {
66 Err(BlobdlError::UrlIndexParsingError)
67 }
68 }
69
70 _ => Ok(DownloadOption::YtPlaylist),
71 };
72 }
73 if yt_url.path().contains("playlist") || query.contains("list"){
74 return Ok(DownloadOption::YtPlaylist);
75 }
76
77 return Ok(DownloadOption::YtVideo(0));
79 }
80
81 Err(BlobdlError::QueryCouldNotBeParsed)
82}