Skip to content
431 changes: 5 additions & 426 deletions src/anime/anime.rs

Large diffs are not rendered by default.

32 changes: 22 additions & 10 deletions src/anime/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,28 @@ use rust_cast::{
};
use std::str::FromStr;

pub fn open_video(link: (String, String)) {
let title = link.1;
let title = title.replace("-", " ");
let arg: String = format!("--force-media-title={}", title);
let _ = std::process::Command::new("mpv")
.arg(link.0)
.arg(arg)
.output()
.expect("failed to open mpv");

pub fn open_video(link: (String, String, String)) {
if link.2 == "null" {
let title = link.1;
let title = title.replace("-", " ");
let arg: String = format!("--force-media-title={}", title);
let _ = std::process::Command::new("mpv")
.arg(link.0)
.arg(arg)
.output()
.expect("failed to open mpv");
} else {
let title = link.1;
let title = title.replace("-", " ");
let arg1: String = format!("--force-media-title={}", title);
let arg2: String = format!("--sub-files={}", link.2);
let _ = std::process::Command::new("mpv")
.arg(link.0)
.arg(arg1)
.arg(arg2)
.output()
.expect("failed to open mpv");
}
// clear terminal
}

Expand Down
158 changes: 93 additions & 65 deletions src/anime/scraper.rs
Original file line number Diff line number Diff line change
@@ -1,89 +1,117 @@
use isahc::config::Configurable;
use isahc::{ReadResponseExt, Request, RequestExt};
use regex::Regex;
use std::fs::File;
use std::io::prelude::*;

//use serde_json::json;

pub fn get_anime_html(url: &str) -> String {
pub fn search_anime(query: String) -> (Vec<String>, Vec<String>, Vec<String>) {
let req = Request::builder()
.uri(url)
.uri(format!(
"https://api.consumet.org/meta/anilist/{}",
query
.replace(" ", "%20")
.replace(":", "%3A")
.replace("!", "%21")
.replace("?", "%3F")
.replace("'", "%27")
))
.redirect_policy(isahc::config::RedirectPolicy::Follow)
.header(
"user-agent",
"Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/100.0",
)
.body(())
.unwrap();
req.send().unwrap().text().unwrap()
}

pub fn get_post(id: &str) -> String {
let resp = Request::builder()
.method("POST")
.uri("https://yugen.to/api/embed/")
.header("x-requested-with", "XMLHttpRequest")
.body(id)
.unwrap()
.send()
.unwrap()
.text();
let resp: String = resp.as_ref().unwrap().to_string();
resp
}
let json = req.send().unwrap().text().unwrap();
let json: serde_json::Value = serde_json::from_str(&json).unwrap();
let mut titles = Vec::new();
let mut ids = Vec::new();
let mut images = Vec::new();
for i in 0..json["results"].as_array().unwrap().len() {
titles.push(
json["results"][i]["title"]["userPreferred"]
.as_str()
.unwrap()
.to_string(),
);

pub fn get_animes(query: String) -> (Vec<String>, Vec<String>, Vec<String>) {
let query = query.replace(" ", "+");
let html = get_anime_html(&format!("https://yugen.to/search/?q={}", query));
let re = Regex::new(r#"href="(/anime[^"]*)""#).unwrap();
let mut animes_links = Vec::new();
for cap in re.captures_iter(&html) {
animes_links.push(cap[1].to_string());
ids.push(json["results"][i]["id"].as_str().unwrap().to_string());
//convert ids to i32
images.push(json["results"][i]["image"].as_str().unwrap().to_string());
}
let re = Regex::new(r#"/" title="([^"]*)""#).unwrap();
let mut animes_names = Vec::new();
for cap in re.captures_iter(&html) {
animes_names.push(cap[1].to_string());
}
let re = Regex::new(r#"data-src="([^"]*)"#).unwrap();
let mut animes_images = Vec::new();
for cap in re.captures_iter(&html) {
animes_images.push(cap[1].to_string());
}
(animes_links, animes_names, animes_images)
(ids, titles, images)
}

pub fn get_anime_info(url: &str) -> (i32, u16) {
let url = format!("https://yugen.to{}watch", url);
let html = get_anime_html(&url);
//print html and exit
let re = Regex::new(r#""mal_id":(\d*)"#).unwrap();
let mal_id = re.captures(&html).unwrap()[1].parse().unwrap();
let re =
Regex::new(r#"Episodes</div><span class="description" style="font-size: \d*px;">(\d*)"#)
.unwrap();
let episodes = re.captures(&html).unwrap()[1].parse().unwrap();
(mal_id, episodes)
pub fn get_episodes(id: &i32, provider: &str) -> (Vec<String>, Vec<String>) {
let req = Request::builder()
.uri(format!(
"https://api.consumet.org/meta/anilist/info/{}?provider={}",
id, provider
))
.redirect_policy(isahc::config::RedirectPolicy::Follow)
.header(
"user-agent",
"Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/100.0",
)
.body(())
.unwrap();
let json = req.send().unwrap().text().unwrap();
let json: serde_json::Value = serde_json::from_str(&json).unwrap();
let mut titles = Vec::new();
let mut ids = Vec::new();
for i in 0..json["episodes"].as_array().unwrap().len() {
titles.push(json["episodes"][i]["title"].as_str().unwrap().to_string());
ids.push(json["episodes"][i]["id"].as_str().unwrap().to_string());
}
(titles, ids)
}

pub fn get_anime_link(url: &str, episode: u64) -> String {
let url = &format!(
"https://yugen.to/watch{}{}/",
url.replace("/anime", ""),
episode
);
let html = get_anime_html(url);
let re = Regex::new(r#"/e/([^/]*)"#).unwrap();
let capture = re.captures(&html).unwrap();
let id = &capture[1];
let id = format!("id={}%3D&ac=0", id);
let json = get_post(&id);
let re = Regex::new(r#"hls": \["(.*)","#).unwrap();
let capture = re.captures(&json).unwrap();
let link = &capture[1];
//return the link
link.to_string()
pub fn get_episode_link(ep_id: &str, provider: &str) -> (String, String) {
let req = Request::builder()
.uri(format!(
"https://api.consumet.org/meta/anilist/watch/{}?provider={}",
ep_id, provider
))
.redirect_policy(isahc::config::RedirectPolicy::Follow)
.header(
"user-agent",
"Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/100.0",
)
.body(())
.unwrap();
let json = req.send().unwrap().text().unwrap();
let json: serde_json::Value = serde_json::from_str(&json).unwrap();
let mut url = String::new();
std::fs::write("test.json", json.to_string()).unwrap();
let mut subtitle = String::new();
let _error_vec = Vec::new();
let sub_array = json["subtitles"].as_array().unwrap_or(&_error_vec);
for i in 0..sub_array.len() {
//set subtitle to lang = English
if json["subtitles"][i]["lang"].as_str().unwrap_or("null") == "English" {
subtitle = json["subtitles"][i]["url"]
.as_str()
.unwrap_or("null")
.to_string();
// add \ before the first : in the url
subtitle = subtitle.replace(":", "\\:");
}
}
let mut highest_quality = 0;
for i in 0..json["sources"].as_array().unwrap().len() {
let quality = json["sources"][i]["quality"]
.as_str()
.unwrap()
.replace("p", "")
.parse::<i32>()
.unwrap_or(0);
if quality > highest_quality {
highest_quality = quality;
url = json["sources"][i]["url"].as_str().unwrap().to_string();
}
}
(url.to_string(), subtitle)
}

pub fn get_image(url: &str, path: &str) {
Expand Down
48 changes: 0 additions & 48 deletions src/anime/trackers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,54 +40,6 @@ pub fn get_token() -> String {
token
}

pub fn get_anime_id(mal_id: i32) -> i32 {
const QUERY: &str = "
query ($id: Int, $search: Int) {
Media (id: $id, idMal: $search, type: ANIME) {
id
title {
native
romaji
english
}
}
}
";
let json = json!({
"query": QUERY,
"variables": {
"search": mal_id
}
});
let resp = Request::builder()
.method("POST")
.uri("https://graphql.anilist.co/")
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.body(json.to_string())
.unwrap()
.send()
.unwrap()
.text();
let regex = regex::Regex::new(r#"id":(.*?),"#).unwrap();
let resp: String = resp.as_ref().unwrap().to_string();
//if error let id = 0
let id = match regex.captures(&resp) {
Some(captures) => captures[1].parse::<i32>().unwrap(),
None => 0,
};

// let id = regex
// .captures(&resp)
// .unwrap()
// .get(1)
// .unwrap()
// .as_str()
// .parse::<i32>()
// .unwrap();
id
}

//get the user id from the token
fn get_user_id(token: &str) -> i32 {
const QUERY: &str = "query {
Expand Down
Loading