provider refactors and fixes
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
use async_trait::async_trait;
|
||||
use futures::FutureExt;
|
||||
use once_cell::sync::Lazy;
|
||||
use rustc_hash::FxHashMap as HashMap;
|
||||
use std::future::Future;
|
||||
use std::panic::AssertUnwindSafe;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
DbPool, api::ClientVersion, status::Channel, util::cache::VideoCache, videos::{ServerOptions, VideoItem}
|
||||
DbPool, api::ClientVersion, status::Channel, util::{cache::VideoCache, discord::send_discord_error_report, requester::Requester}, videos::{ServerOptions, VideoItem}
|
||||
};
|
||||
|
||||
pub mod all;
|
||||
@@ -49,6 +52,33 @@ pub type DynProvider = Arc<dyn Provider>;
|
||||
|
||||
pub static ALL_PROVIDERS: Lazy<HashMap<&'static str, DynProvider>> = Lazy::new(|| {
|
||||
let mut m = HashMap::default();
|
||||
m.insert("all", Arc::new(all::AllProvider::new()) as DynProvider);
|
||||
m.insert("perverzija", Arc::new(perverzija::PerverzijaProvider::new()) as DynProvider);
|
||||
m.insert("hanime", Arc::new(hanime::HanimeProvider::new()) as DynProvider);
|
||||
m.insert("pornhub", Arc::new(pornhub::PornhubProvider::new()) as DynProvider);
|
||||
m.insert(
|
||||
"rule34video",
|
||||
Arc::new(rule34video::Rule34videoProvider::new()) as DynProvider,
|
||||
);
|
||||
m.insert("redtube", Arc::new(redtube::RedtubeProvider::new()) as DynProvider);
|
||||
m.insert("okporn", Arc::new(okporn::OkpornProvider::new()) as DynProvider);
|
||||
m.insert("pornhat", Arc::new(pornhat::PornhatProvider::new()) as DynProvider);
|
||||
m.insert(
|
||||
"perfectgirls",
|
||||
Arc::new(perfectgirls::PerfectgirlsProvider::new()) as DynProvider,
|
||||
);
|
||||
m.insert("okxxx", Arc::new(okxxx::OkxxxProvider::new()) as DynProvider);
|
||||
m.insert("homoxxx", Arc::new(homoxxx::HomoxxxProvider::new()) as DynProvider);
|
||||
m.insert("missav", Arc::new(missav::MissavProvider::new()) as DynProvider);
|
||||
m.insert("xxthots", Arc::new(xxthots::XxthotsProvider::new()) as DynProvider);
|
||||
m.insert("sxyprn", Arc::new(sxyprn::SxyprnProvider::new()) as DynProvider);
|
||||
m.insert("porn00", Arc::new(porn00::Porn00Provider::new()) as DynProvider);
|
||||
m.insert("youjizz", Arc::new(youjizz::YoujizzProvider::new()) as DynProvider);
|
||||
m.insert(
|
||||
"paradisehill",
|
||||
Arc::new(paradisehill::ParadisehillProvider::new()) as DynProvider,
|
||||
);
|
||||
m.insert("pornzog", Arc::new(pornzog::PornzogProvider::new()) as DynProvider);
|
||||
m.insert("omgxxx", Arc::new(omgxxx::OmgxxxProvider::new()) as DynProvider);
|
||||
m.insert("beeg", Arc::new(beeg::BeegProvider::new()) as DynProvider);
|
||||
m.insert("tnaflix", Arc::new(tnaflix::TnaflixProvider::new()) as DynProvider);
|
||||
@@ -74,6 +104,75 @@ pub fn init_providers_now() {
|
||||
Lazy::force(&ALL_PROVIDERS);
|
||||
}
|
||||
|
||||
pub fn panic_payload_to_string(payload: Box<dyn std::any::Any + Send>) -> String {
|
||||
if let Some(s) = payload.downcast_ref::<&str>() {
|
||||
return (*s).to_string();
|
||||
}
|
||||
if let Some(s) = payload.downcast_ref::<String>() {
|
||||
return s.clone();
|
||||
}
|
||||
"unknown panic payload".to_string()
|
||||
}
|
||||
|
||||
pub async fn run_provider_guarded<F>(provider_name: &str, context: &str, fut: F) -> Vec<VideoItem>
|
||||
where
|
||||
F: Future<Output = Vec<VideoItem>>,
|
||||
{
|
||||
match AssertUnwindSafe(fut).catch_unwind().await {
|
||||
Ok(videos) => videos,
|
||||
Err(payload) => {
|
||||
let panic_msg = panic_payload_to_string(payload);
|
||||
let _ = send_discord_error_report(
|
||||
format!("Provider panic: {}", provider_name),
|
||||
None,
|
||||
Some("Provider Guard"),
|
||||
Some(&format!("context={}; panic={}", context, panic_msg)),
|
||||
file!(),
|
||||
line!(),
|
||||
module_path!(),
|
||||
)
|
||||
.await;
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn report_provider_error(provider_name: &str, context: &str, msg: &str) {
|
||||
let _ = send_discord_error_report(
|
||||
format!("Provider error: {}", provider_name),
|
||||
None,
|
||||
Some("Provider Guard"),
|
||||
Some(&format!("context={}; error={}", context, msg)),
|
||||
file!(),
|
||||
line!(),
|
||||
module_path!(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub fn report_provider_error_background(provider_name: &str, context: &str, msg: &str) {
|
||||
let provider_name = provider_name.to_string();
|
||||
let context = context.to_string();
|
||||
let msg = msg.to_string();
|
||||
tokio::spawn(async move {
|
||||
report_provider_error(&provider_name, &context, &msg).await;
|
||||
});
|
||||
}
|
||||
|
||||
pub fn requester_or_default(options: &ServerOptions, provider_name: &str, context: &str) -> Requester {
|
||||
match options.requester.clone() {
|
||||
Some(requester) => requester,
|
||||
None => {
|
||||
report_provider_error_background(
|
||||
provider_name,
|
||||
context,
|
||||
"ServerOptions.requester missing; using default Requester",
|
||||
);
|
||||
Requester::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[async_trait]
|
||||
pub trait Provider: Send + Sync {
|
||||
|
||||
Reference in New Issue
Block a user