diff --git a/app/src/main/rust/src/lib.rs b/app/src/main/rust/src/lib.rs index 711057bb1..b98187ed5 100644 --- a/app/src/main/rust/src/lib.rs +++ b/app/src/main/rust/src/lib.rs @@ -19,9 +19,10 @@ use jnix::jni::sys::{jint, jintArray, jobject, jobjectArray, JavaVM, JNI_VERSION use jnix::jni::JNIEnv; use jnix::{IntoJava, JnixEnv}; use jnix_macros::IntoJava; +use log::{error, LevelFilter}; use quick_xml::escape::unescape; use std::ffi::c_void; -use tl::{Parser, VDom}; +use tl::{Node, Parser, VDom}; macro_rules! regex { ($re:literal $(,)?) => {{ @@ -30,6 +31,20 @@ macro_rules! regex { }}; } +const EHGT_PREFIX: &str = "https://ehgt.org/"; +const EX_PREFIX: &str = "https://s.exhentai.org/"; + +trait Anon { + fn get_first_element_by_class_name(&self, name: &str) -> Option<&Node>; +} + +impl<'a> Anon for VDom<'a> { + fn get_first_element_by_class_name(&self, name: &str) -> Option<&Node> { + let handle = self.get_elements_by_class_name(name).next()?; + Some(handle.get(self.parser())?) + } +} + #[derive(Default, IntoJava)] #[jnix(package = "com.hippo.ehviewer.client.parser")] pub struct Torrent { @@ -42,6 +57,33 @@ pub struct Torrent { name: String, } +#[derive(Default, IntoJava)] +#[allow(non_snake_case)] +#[jnix(package = "com.hippo.ehviewer.client.data")] +pub struct BaseGalleryInfo { + gid: i64, + token: String, + title: String, + titleJpn: Option, + thumbKey: String, + category: i32, + posted: String, + uploader: Option, + disowned: bool, + rating: f32, + rated: bool, + simpleTags: Vec, + pages: i32, + thumbWidth: i32, + thumbHeight: i32, + spanSize: i32, + spanIndex: i32, + spanGroupIndex: i32, + simpleLanguage: String, + favoriteSlot: i32, + favoriteName: Option, +} + #[derive(Default, IntoJava)] #[jnix(package = "com.hippo.ehviewer.client.parser")] pub struct TorrentResult { @@ -96,7 +138,7 @@ pub fn parseLimit(env: JNIEnv, _class: JClass, input: JString) -> jobject { #[catch_panic(default = "std::ptr::null_mut()")] #[allow(non_snake_case)] #[jni_fn("com.hippo.ehviewer.client.parser.FavoritesParserKt")] -pub fn parseFav(mut env: JNIEnv, _class: JClass, input: JString, str: jobjectArray) -> jintArray { +pub fn parseFav(env: JNIEnv, _class: JClass, input: JString, str: jobjectArray) -> jintArray { let mut env = JnixEnv { env }; let vec = parse_jni_string(&mut env, &input, |dom, parser, env| { let fp = dom.get_elements_by_class_name("fp"); @@ -146,14 +188,83 @@ pub fn parseTorrent(env: JNIEnv, _class: JClass, input: JString) -> jobject { let reg = regex!(" ([0-9-]+) [0-9:]+[\\s\\S]+ ([0-9.]+ [KMGT]B)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+([^<]+)[\\s\\S]+onclick=\"document.location='([^\"]+)'[^<]+>([^<]+)"); let grp = reg.captures(&html)?; let name = unescape(&grp[8]).ok()?; - Some(Torrent { posted: grp[1].to_string(), size: grp[2].to_string(), seeds: grp[3].parse().ok()?, peers: grp[4].parse().ok()?, downloads: grp[5].parse().ok()?, url: grp[7].to_string(), name: name.to_string() }) + Some(Torrent { + posted: grp[1].to_string(), + size: grp[2].to_string(), + seeds: grp[3].parse().ok()?, + peers: grp[4].parse().ok()?, + downloads: grp[5].parse().ok()?, + url: grp[7].to_string(), + name: name.to_string() + }) }).collect() }) }).unwrap().into_java(&env).forget().into_raw() } +#[no_mangle] +#[catch_panic(default = "std::ptr::null_mut()")] +#[allow(non_snake_case)] +#[jni_fn("com.hippo.ehviewer.client.parser.GalleryListParserKt")] +pub fn parseGalleryInfo(env: JNIEnv, _class: JClass, input: JString) -> jobject { + let mut env = JnixEnv { env }; + parse_jni_string(&mut env, &input, |dom, parser, _env| { + let title = dom + .get_first_element_by_class_name("glink")? + .inner_text(parser) + .into_owned(); + let thumb = dom + .get_first_element_by_class_name("glthumb")? + .children()? + .top() + .get(1)? + .get(parser)? + .as_tag()? + .children() + .top() + .get(1)? + .get(parser)? + .as_tag()? + .attributes() + .get("data-src")?? + .try_as_utf8_str()?; + error!("{}", thumb); + Some(BaseGalleryInfo { + gid: 0, + token: "".to_string(), + title: title.to_string(), + titleJpn: None, + thumbKey: thumb + .trim_start_matches(EHGT_PREFIX) + .trim_start_matches(EX_PREFIX) + .trim_start_matches("t/") + .to_string(), + category: 0, + posted: "".to_string(), + uploader: None, + disowned: false, + rating: 0.0, + rated: false, + simpleTags: vec![], + pages: 0, + thumbWidth: 0, + thumbHeight: 0, + spanSize: 0, + spanIndex: 0, + spanGroupIndex: 0, + simpleLanguage: "".to_string(), + favoriteSlot: 0, + favoriteName: None, + }) + }) + .unwrap() + .into_java(&env) + .forget() + .into_raw() +} + #[no_mangle] pub extern "system" fn JNI_OnLoad(_: JavaVM, _: *mut c_void) -> jint { - android_logger::init_once(Config::default()); + android_logger::init_once(Config::default().with_max_level(LevelFilter::Trace)); JNI_VERSION_1_6 }