use std::io::{Error, ErrorKind}; use anyhow::Result; use regex::Regex; pub fn is_zippyshare_url(url: &str) -> bool { Regex::new(r"^https?://(?:www\d*\.)?zippyshare\.com/v/[0-9a-zA-Z]+/file\.html$") .unwrap() .is_match(url) } pub async fn resolve_link(url: &str) -> Result { // Regex to check if the provided url is a zippyshare download url let re = Regex::new(r"^(https?://(?:www\d*\.)?zippyshare\.com)/v/[0-9a-zA-Z]+/file\.html$")?; if !re.is_match(url) { return Err(Error::new(ErrorKind::Other, "URL is not a zippyshare url").into()); } // Extract the hostname (with https:// prefix) for later let host = &re.captures(url).unwrap()[1]; // Download the html body for the download page let body = reqwest::get(url).await?.text().await?; // Try to extract the link using the latest extractor let link = extract_dl_link_2022_08_16(&host, &body).await; // Try the previous extractors as fallback if it didn't work let link = match link { Err(_) => extract_dl_link_2022_07_24(&host, &body).await, ok => ok, }; let link = match link { Err(_) => extract_dl_link_2022_07_17(&host, &body).await, ok => ok, }; let link = match link { Err(_) => extract_dl_link_2022_03_07(&host, &body).await, ok => ok, }; link } /* Updated: 16.08.2022 Link generation code: - `a` and `b` are random - `omg` is always `f` - the number used in the middle part `XXX%b` seems to be always the same as `a` ``` var a = 634851; var b = 958673; document.getElementById('dlbutton').omg = "f"; if (document.getElementById('dlbutton').omg != 'f') { a = Math.ceil(a/3); } else { a = Math.floor(a/3); } document.getElementById('dlbutton').href = "/d/gue47sk7/"+(a + 634851%b)+"/some-file-name.part1.rar"; ``` */ pub async fn extract_dl_link_2022_08_16(host: &str, body: &str) -> Result { let re_a = Regex::new(r#"var a = (\d+);"#)?; let re_b = Regex::new(r#"var b = (\d+);"#)?; let re_link = Regex::new( r#"document\.getElementById\('dlbutton'\)\.href = "(/d/.+/)"\+\(a \+ (\d+)%b\)\+"(.+)";"#, )?; if !body.contains( r#"document.getElementById('dlbutton').omg = "f"; if (document.getElementById('dlbutton').omg != 'f') { a = Math.ceil(a/3); } else { a = Math.floor(a/3); }"#, ) { return Err(Error::new(ErrorKind::Other, "omg part of the link-gen not found").into()); } let cap_a = match re_a.captures(body) { Some(cap) => cap, None => return Err(Error::new(ErrorKind::Other, "Link not found").into()), }; let cap_b = match re_b.captures(body) { Some(cap) => cap, None => return Err(Error::new(ErrorKind::Other, "Link not found").into()), }; let cap_link = match re_link.captures(body) { Some(cap) => cap, None => return Err(Error::new(ErrorKind::Other, "Link not found").into()), }; let a: i64 = cap_a[1].parse()?; let b: i64 = cap_b[1].parse()?; let url_start = &cap_link[1]; let n1: i64 = cap_link[2].parse()?; let url_end = &cap_link[3]; let middle = (a / 3) + n1 % b; let dl_url = format!("{}{}{}{}", &host, url_start, middle, url_end); Ok(dl_url) } /* Updated: 24.07.2022 Link generation code: ```