1use std::{time::Instant, error::Error, fs::create_dir_all};
2use indicatif::{ProgressBar, ProgressStyle};
3use regex::Regex;
4
5const DIRECTORIES: [&str; 5] = ["twitch\\clips", "twitch\\videos", "youtube\\videos", "youtube\\shorts", "tiktok\\videos"];
6const TIMES: [u128; 3] = [1000, 60000, 3600000];
7
8pub fn get_elapsed_time(time: Instant) -> String {
9 let elapsed = time.elapsed().as_millis();
10 let formatted_elapsed = match elapsed {
11 0..=999 => format!("{}ms", elapsed),
12 1000..=59999 => format!("{}s", elapsed / TIMES[0]),
13 60000..=3599999 => format!("{}m {}s", elapsed / TIMES[1], (elapsed % TIMES[1]) / TIMES[0]),
14 _ => format!("{}h {}m", elapsed / TIMES[2], (elapsed % TIMES[2]) / TIMES[1])
15 };
16
17 return formatted_elapsed;
18}
19
20pub fn remove_not_characters(text: &str) -> String {
21 return text.chars().filter(|&c| c.is_alphanumeric() || c.is_whitespace()).collect();
22}
23
24pub async fn setup_files() -> Result<(), Box<dyn Error>> {
25 for directory in DIRECTORIES.iter() {
26 create_dir_all(directory)?;
27 }
28
29 Ok(())
30}
31
32pub fn create_progress_bar(length: u64) -> ProgressBar {
33 let pb = ProgressBar::new(length);
34 pb.set_style(ProgressStyle::default_bar()
35 .template("[{bar:40.blue}] ETA: {eta}")
36 .expect("Failed to set progress bar style")
37 .progress_chars("=> "));
38 return pb;
39}
40
41pub fn get_type(url: &str) -> (bool, &str) {
42 let regex_patterns = [
43 (r"https://www.twitch.tv/[A-Za-z0-9]+/clip/[A-Za-z0-9]+(-[A-Za-z0-9]+)*", "twitch-clip"),
44 (r"https://clips.twitch.tv/[A-Za-z0-9]+(-[A-Za-z0-9]+)*", "twitch-clip"),
45 (r"https://www.twitch.tv/videos/[0-9]+", "twitch-video"),
46 (r"https://www.youtube.com/watch\?v=[A-Za-z0-9_-]+", "youtube-video"),
47 (r"https://www.youtube.com/shorts/[A-Za-z0-9_-]+", "youtube-short"),
48 (r"https://www.tiktok.com/@[A-Za-z0-9_-]+/video/[0-9]+", "tiktok-video")
49 ];
50
51 for (pattern, r#type) in regex_patterns.iter() {
52 let regex = Regex::new(pattern).unwrap();
53 if regex.is_match(url) {
54 return (true, r#type);
55 }
56 }
57
58 return (false, "invalid");
59}
60
61pub async fn check_url(url: &str) -> Result<String, Box<dyn Error>> {
62 let (is_valid, url_type) = get_type(url);
63 if !is_valid {
64 return Err("Url does not match regex pattern".into());
65 }
66
67 Ok(url_type.into())
68}