feat: use nhentai.xxx

This commit is contained in:
ihciah 2022-11-18 01:09:25 +08:00
parent 2e90a912ed
commit 956129abee
No known key found for this signature in database
GPG Key ID: 97CE6E121061F3BA
13 changed files with 35 additions and 82 deletions

52
Cargo.lock generated
View File

@ -91,7 +91,7 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bot"
version = "0.1.4"
version = "0.1.5"
dependencies = [
"anyhow",
"chrono",
@ -128,9 +128,6 @@ name = "cc"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
dependencies = [
"jobserver",
]
[[package]]
name = "cfg-if"
@ -535,19 +532,6 @@ dependencies = [
"syn",
]
[[package]]
name = "git2"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0155506aab710a86160ddb504a480d2964d7ab5b9e62419be69e0032bc5931c"
dependencies = [
"bitflags",
"libc",
"libgit2-sys",
"log",
"url",
]
[[package]]
name = "h2"
version = "0.3.13"
@ -759,15 +743,6 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
name = "jobserver"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
dependencies = [
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.58"
@ -789,30 +764,6 @@ version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "libgit2-sys"
version = "0.13.4+1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0fa6563431ede25f5cc7f6d803c6afbc1c5d3ad3d4925d12c882bf2b526f5d1"
dependencies = [
"cc",
"libc",
"libz-sys",
"pkg-config",
]
[[package]]
name = "libz-sys"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "linked-hash-map"
version = "0.5.4"
@ -1985,7 +1936,6 @@ dependencies = [
"cfg-if",
"enum-iterator",
"getset",
"git2",
"rustc_version",
"rustversion",
"thiserror",

View File

@ -1,7 +1,7 @@
[package]
edition = "2021"
name = "bot"
version = "0.1.4"
version = "0.1.5"
[dependencies]
eh2telegraph = {path = "../eh2telegraph"}
@ -22,4 +22,4 @@ tracing = "0.1"
tracing-subscriber = {version = "0.3", features = ["local-time", "parking_lot", "time"]}
[build-dependencies]
vergen = {version = "7", default_features = false, features = ["build", "cargo", "rustc", "git"]}
vergen = {version = "7", default_features = false, features = ["build", "cargo", "rustc"]}

View File

@ -6,12 +6,6 @@ pub(crate) static VERSION: &str = concat!(
"Package Version:\t",
env!("VERGEN_BUILD_SEMVER"),
"\n",
"Git Commit SHA: \t",
env!("VERGEN_GIT_SHA"),
"\n",
"Git Commit Date:\t",
env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
"\n",
"rustc Version: \t",
env!("VERGEN_RUSTC_SEMVER"),
"\n",

View File

@ -71,7 +71,7 @@ impl EHCollector {
impl Collector for EHCollector {
type FetchError = anyhow::Error;
type FetchFuture<'a> =
impl std::future::Future<Output = anyhow::Result<(AlbumMeta, Self::ImageStream)>>;
impl std::future::Future<Output = anyhow::Result<(AlbumMeta, Self::ImageStream)>> + 'a;
type StreamError = anyhow::Error;
type ImageStream = EHImageStream;

View File

@ -83,7 +83,7 @@ impl EXCollector {
impl Collector for EXCollector {
type FetchError = anyhow::Error;
type FetchFuture<'a> =
impl std::future::Future<Output = anyhow::Result<(AlbumMeta, Self::ImageStream)>>;
impl std::future::Future<Output = anyhow::Result<(AlbumMeta, Self::ImageStream)>> + 'a;
type StreamError = anyhow::Error;
type ImageStream = EXImageStream;

View File

@ -39,9 +39,8 @@ pub struct AlbumMeta {
/// memory VM, it will keep only a small amount in memory.
pub trait Collector {
type FetchError;
type FetchFuture<'a>: std::future::Future<
Output = Result<(AlbumMeta, Self::ImageStream), Self::FetchError>,
>
type FetchFuture<'a>: std::future::Future<Output = Result<(AlbumMeta, Self::ImageStream), Self::FetchError>>
+ 'a
where
Self: 'a;

View File

@ -1,5 +1,8 @@
/// nhentai collector.
/// Host matching: nhentai.to or nhentai.net
///
/// Since nhentai.net always enable CloudFlare Firewall, so we will
/// use nhentai.xxx(but there is about 1~2 days syncing latency).
use again::RetryPolicy;
use ipnet::Ipv6Net;
use regex::Regex;
@ -17,14 +20,15 @@ use super::{AlbumMeta, Collector, ImageData, ImageMeta};
lazy_static::lazy_static! {
static ref TITLE_RE: Regex = Regex::new(r#"<span class="pretty">(.*?)</span>"#).unwrap();
static ref PAGE_RE: Regex = Regex::new(r#"<noscript><img src="(https://t\d?\.nhentai\.net/galleries/\d+/\d+t\.\w+)"#).unwrap();
// static ref PAGE_RE: Regex = Regex::new(r#"<noscript><img src="(https://t\d?\.nhentai\.net/galleries/\d+/\d+t\.\w+)"#).unwrap();
static ref PAGE_RE: Regex = Regex::new(r#"<noscript><img src="(https://cdn.nhentai.xxx/g/\d+/\d+t\.\w+)"#).unwrap();
static ref RETRY_POLICY: RetryPolicy = RetryPolicy::fixed(Duration::from_millis(200))
.with_max_retries(5)
.with_jitter(true);
}
const DOMAIN_LIST: [&str; 10] = [
const DOMAIN_LIST: [&str; 12] = [
"nhentai.net",
"i.nhentai.net",
"i2.nhentai.net",
@ -35,6 +39,8 @@ const DOMAIN_LIST: [&str; 10] = [
"i7.nhentai.net",
"i8.nhentai.net",
"i9.nhentai.net",
"nhentai.xxx",
"cdn.nhentai.xxx",
];
#[derive(Debug, Clone, Default)]
@ -63,7 +69,7 @@ impl NHCollector {
impl Collector for NHCollector {
type FetchError = anyhow::Error;
type FetchFuture<'a> =
impl std::future::Future<Output = anyhow::Result<(AlbumMeta, Self::ImageStream)>>;
impl std::future::Future<Output = anyhow::Result<(AlbumMeta, Self::ImageStream)>> + 'a;
type StreamError = anyhow::Error;
type ImageStream = NHImageStream;
@ -85,7 +91,8 @@ impl Collector for NHCollector {
return Err(anyhow::anyhow!("invalid input path({path}), gallery url is expected(like https://nhentai.net/g/333678)"));
}
};
let url = format!("https://nhentai.net/g/{album_id}");
// let url = format!("https://nhentai.net/g/{album_id}");
let url = format!("https://nhentai.xxx/g/{album_id}");
tracing::info!("[nhentai] process {url}");
// clone client to force changing ip

View File

@ -159,7 +159,7 @@ impl GhostClient {
// apply resolve
for (domain, addr) in mapping {
builder = builder.resolve(*domain, *addr);
builder = builder.resolve(domain, *addr);
}
// not add preconfigured tls

View File

@ -1,4 +1,3 @@
#![feature(generic_associated_types)]
#![feature(type_alias_impl_trait)]
pub mod buffer;

View File

@ -1,12 +1,12 @@
pub mod f_hash;
pub mod saucenao;
pub trait ImageSearcher {
pub trait ImageSearcher<T> {
type SeacheError;
type SearchOutput;
type FetchFuture<T>: std::future::Future<Output = Result<Self::SearchOutput, Self::SeacheError>>;
type FetchFuture: std::future::Future<Output = Result<Self::SearchOutput, Self::SeacheError>>;
fn search<T: Into<std::borrow::Cow<'static, [u8]>>>(&self, data: T) -> Self::FetchFuture<T>;
fn search(&self, data: T) -> Self::FetchFuture;
}
#[cfg(test)]

View File

@ -67,7 +67,7 @@ impl SaucenaoSearcher {
}
}
async fn search(client: &reqwest::Client, file: Part) -> anyhow::Result<SaucenaoOutput> {
async fn do_search(client: &reqwest::Client, file: Part) -> anyhow::Result<SaucenaoOutput> {
let response = client
.post("https://saucenao.com/search.php")
.multipart(multipart::Form::new().part("file", file))
@ -115,15 +115,18 @@ impl IntoIterator for SaucenaoOutput {
}
}
impl ImageSearcher for SaucenaoSearcher {
impl<T> ImageSearcher<T> for SaucenaoSearcher
where
T: Into<Cow<'static, [u8]>>,
{
type SeacheError = anyhow::Error;
type SearchOutput = SaucenaoOutput;
type FetchFuture<T> = impl Future<Output = Result<Self::SearchOutput, Self::SeacheError>>;
type FetchFuture = impl Future<Output = Result<Self::SearchOutput, Self::SeacheError>>;
fn search<T: Into<Cow<'static, [u8]>>>(&self, data: T) -> Self::FetchFuture<T> {
fn search(&self, data: T) -> Self::FetchFuture {
let file_part = Part::bytes(data).file_name("image.jpg");
let client = self.client.clone();
async move { Self::search(&client, file_part).await }
async move { Self::do_search(&client, file_part).await }
}
}

View File

@ -50,7 +50,7 @@ impl<T> KVStorage<T> for CFStorage
where
T: DeserializeOwned + Serialize + Send + Sync,
{
type GetFuture<'a> = impl Future<Output = anyhow::Result<Option<T>>> where Self: 'a;
type GetFuture<'a> = impl Future<Output = anyhow::Result<Option<T>>> + 'a where Self: 'a;
fn get<'a>(&'a self, key: &'a str) -> Self::GetFuture<'_> {
async move {
self.0
@ -61,12 +61,12 @@ where
}
}
type SetFuture<'a> = impl Future<Output = anyhow::Result<()>> where Self: 'a;
type SetFuture<'a> = impl Future<Output = anyhow::Result<()>> + 'a where Self: 'a, T: 'a;
fn set<'a>(&self, key: String, value: T, _expire_ttl: Option<usize>) -> Self::SetFuture<'_> {
async move { self.0.put(&key, &value).await.map_err(Into::into) }
}
type DeleteFuture<'a> = impl Future<Output = anyhow::Result<()>> where Self: 'a;
type DeleteFuture<'a> = impl Future<Output = anyhow::Result<()>> + 'a where Self: 'a;
fn delete<'a>(&'a self, key: &'a str) -> Self::DeleteFuture<'_> {
async move { self.0.delete(key).await.map_err(Into::into) }
}

View File

@ -13,7 +13,8 @@ pub trait KVStorage<V> {
type SetFuture<'a>: Future<Output = anyhow::Result<()>> + Send
where
Self: 'a;
Self: 'a,
V: 'a;
fn set(&self, key: String, value: V, expire_ttl: Option<usize>) -> Self::SetFuture<'_>;
type DeleteFuture<'a>: Future<Output = anyhow::Result<()>> + Send