01/04/26_00.35
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use reqwest::get;
|
||||
use scraper::{Html, Selector};
|
||||
use tokio::io::split;
|
||||
|
||||
use crate::source::{Chapter, EpisodeListItem, MangaSource, SourceType};
|
||||
|
||||
pub struct Mangaworld {
|
||||
url: String,
|
||||
hostname:String,
|
||||
sourcetype: SourceType
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MangaSource for Mangaworld {
|
||||
fn get_hostname(&self)->String {
|
||||
self.hostname.clone()
|
||||
}
|
||||
fn get_url(&self) -> String {
|
||||
self.url.clone()
|
||||
}
|
||||
|
||||
fn new(hostname: String, url: String) -> Self {
|
||||
Self {
|
||||
url,
|
||||
hostname,
|
||||
sourcetype: crate::source::SourceType::Manga
|
||||
}
|
||||
}
|
||||
async fn listupdated(&self, page: usize) -> Result<Vec<crate::source::Chapter>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let body = self.fetch_updated_page(page).await?;
|
||||
self.extract_episode_from_updated(body)
|
||||
}
|
||||
//https://www.mangaworld.mx/archive?keyword=
|
||||
fn extract_episode_from_search(&self, body: String) -> Result<Vec<crate::source::Chapter>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let document = Html::parse_document(&body);
|
||||
let sel_inner = Selector::parse("div.entry").unwrap();
|
||||
// let sel_episode_number = Selector::parse("a.xanh").unwrap();
|
||||
let sel_anime_name = Selector::parse("a.manga-title").unwrap();
|
||||
let cards = document.select(&sel_inner)
|
||||
.filter_map(|card| {
|
||||
// let carde = card.select(&sel_episode_number).next()?;
|
||||
// let index = carde.inner_html().trim().split(" ").last().unwrap().parse::<usize>().unwrap_or(0);
|
||||
// log!("index: {}", index);
|
||||
let carda = card.select(&sel_anime_name).next()?;
|
||||
|
||||
// log!("Card a found");
|
||||
let url = carda.value().attr("href").unwrap_or("").trim().to_owned();
|
||||
// log!("Card url: {}",url);
|
||||
let title = carda.inner_html().trim().to_owned();
|
||||
// log!("Card title: {}", title);
|
||||
Some(Chapter {
|
||||
title,
|
||||
index: 0,
|
||||
url,
|
||||
section: 0
|
||||
})
|
||||
});
|
||||
Ok(cards.collect::<Vec<Chapter>>())
|
||||
}
|
||||
//https://www.mangaworld.ac/
|
||||
fn extract_episode_from_updated(&self, body: String) -> Result<Vec<crate::source::Chapter>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let document = Html::parse_document(&body);
|
||||
let sel_inner = Selector::parse("div.entry").unwrap();
|
||||
let sel_episode_number = Selector::parse("a.xanh").unwrap();
|
||||
let sel_anime_name = Selector::parse("a.manga-title").unwrap();
|
||||
let cards = document.select(&sel_inner)
|
||||
.filter_map(|card| {
|
||||
let carde = card.select(&sel_episode_number).next()?;
|
||||
let index = carde.inner_html().trim().split(" ").last().unwrap().parse::<usize>().unwrap_or(0);
|
||||
// log!("index: {}", index);
|
||||
let carda = card.select(&sel_anime_name).next()?;
|
||||
|
||||
// log!("Card a found");
|
||||
let url = carda.value().attr("href").unwrap_or("").trim().to_owned();
|
||||
// log!("Card url: {}",url);
|
||||
let title = carda.inner_html().trim().to_owned();
|
||||
// log!("Card title: {}", title);
|
||||
Some(Chapter {
|
||||
title,
|
||||
index,
|
||||
url,
|
||||
section: 0
|
||||
})
|
||||
});
|
||||
Ok(cards.collect::<Vec<Chapter>>())
|
||||
}
|
||||
// async fn episode_openable_link(&self, card: Chapter) -> Result<String, Box<dyn std::error::Error>> {
|
||||
// let id= Self::id_extract(&card.url).unwrap();
|
||||
// let u = format!("{}/api/episode/serverPlayerAnimeWorld?id={}", self.url, id);
|
||||
// let r = get(u).await?.error_for_status()?.text().await?;
|
||||
// let b = Html::parse_document(&r);
|
||||
// let select_source = Selector::parse("source").unwrap();
|
||||
// Ok(b.select(&select_source).next().unwrap().value().attr("src").unwrap_or("").to_owned())
|
||||
// }
|
||||
async fn fetch_search_page(&self, query: String, page: usize) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
|
||||
// if page < 1 { page = 1};
|
||||
let u = format!("{}?keyword={}&page={}",self.get_url(), query, page);
|
||||
let r = reqwest::get(u).await?.error_for_status()?.text().await?;
|
||||
return Ok(r);
|
||||
}
|
||||
|
||||
// async fn search(&self, query: String, page: usize) -> Result<Vec<crate::source::Episode>, Box<dyn std::error::Error + Send + Sync>>{
|
||||
// let body = self.fetch_search_page(query, page).await?;
|
||||
// self.extract_episode_from_search(body)
|
||||
// }
|
||||
|
||||
async fn fetch_updated_page(&self, page: usize)-> Result<String, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let p = std::cmp::max(1, page);
|
||||
let u = format!("{}",self.get_url());
|
||||
let a = get(u).await?.error_for_status()?.text().await?;
|
||||
return Ok(a);
|
||||
}
|
||||
async fn lib_url_parse(&self, url: String) -> Result<HashMap<String, EpisodeListItem>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let mut hs = HashMap::<String, EpisodeListItem>::new();
|
||||
if let Ok(a) = get(url).await?.error_for_status()?.text().await {
|
||||
let b = Html::parse_document(&a);
|
||||
// let select_chapters_wrapper = Selector::parse("").unwrap();
|
||||
let select_volume_element = Selector::parse(".chapters-wrapper .volume-element").unwrap();
|
||||
let select_volume_name = Selector::parse(".volume .volume-name").unwrap();
|
||||
let select_episodes = Selector::parse("div.chapter a.chap").unwrap();
|
||||
let select_span = Selector::parse("span").unwrap();
|
||||
// for ep in b.select(&select_episodes) {
|
||||
// // let alink = ep.value();
|
||||
// if let Some(span) = ep.select(&select_span).next() {
|
||||
// hs.insert(span.inner_html(), EpisodeListItem {
|
||||
// title: format!("Volume {:>4} Capitolo {:>4}",,span.inner_html()),
|
||||
// url: alink.attr("href").unwrap_or("").trim().to_owned()
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
for vol in b.select(&select_volume_element) {
|
||||
if let Some(volname) = vol.select(&select_volume_name).next() {
|
||||
let volume = volname.text().next();
|
||||
for ep in vol.select(&select_episodes) {
|
||||
if let Some(span) = ep.select(&select_span).next() {
|
||||
let alink = ep.value();
|
||||
let chapter = span.inner_html();
|
||||
let x = volume
|
||||
.and_then(|s| s.split_whitespace().nth(1))
|
||||
.and_then(|second| second.split_once('.'));
|
||||
let y = chapter.split_whitespace().nth(1)
|
||||
.and_then(|second| second.split_once('.'));
|
||||
|
||||
let title_vol = match x {
|
||||
Some((vola,volb)) => {
|
||||
if volb.is_empty() {
|
||||
format!("Volume {:>4}", vola)
|
||||
} else {
|
||||
format!("Volume {:>4}.{}", vola,volb)
|
||||
}
|
||||
},
|
||||
_ => "".to_owned()
|
||||
};
|
||||
let title_cha = match y {
|
||||
Some((cha,chb)) => {
|
||||
if chb.is_empty() {
|
||||
format!("Capitolo {:>4}", cha)
|
||||
} else {
|
||||
format!("Capitolo {:>4}.{}", cha,chb)
|
||||
}
|
||||
},
|
||||
_ => "".to_owned()
|
||||
};
|
||||
let title_sep = if !title_vol.is_empty() && !title_cha.is_empty() {" "} else {""};
|
||||
hs.insert(span.inner_html(), EpisodeListItem {
|
||||
title: format!("{}{}{}", title_vol,title_sep, title_cha),
|
||||
url: alink.attr("href").unwrap_or("").trim().to_owned()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ok(hs);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user