database support

This commit is contained in:
Simon
2025-06-05 18:50:28 +00:00
parent 6d08362937
commit 175c9b748f
15 changed files with 333 additions and 140 deletions

View File

@@ -6,11 +6,13 @@ use htmlentity::entity::{decode, ICodedDataTrait};
use reqwest::{Proxy};
use futures::future::join_all;
use crate::db;
use crate::providers::Provider;
use crate::util::cache::VideoCache;
use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr};
use crate::util::time::parse_time_to_seconds;
use crate::videos::{self, Video_Embed, Video_Item}; // Make sure Provider trait is imported
use crate::videos::{self, Video_Embed, Video_Item};
use crate::DbPool; // Make sure Provider trait is imported
error_chain! {
foreign_links {
@@ -125,12 +127,30 @@ impl HanimeProvider {
}
}
async fn get_video_item(&self, hit: HanimeSearchResult) -> Result<(u64,Video_Item)> {
async fn get_video_item(&self, hit: HanimeSearchResult, pool: DbPool) -> Result<Video_Item> {
let mut conn = pool.get().expect("couldn't get db connection from pool");
let db_result = db::get_video(&mut conn,format!("https://h.freeanimehentai.net/api/v8/video?id={}&", hit.slug.clone()));
drop(conn);
let id = hit.id.to_string();
let title = hit.name;
let thumb = hit.poster_url;
let duration = (hit.duration_in_ms / 1000) as u32; // Convert ms to seconds
let channel = "hanime".to_string(); // Placeholder, adjust as needed
match db_result {
Ok(Some(video_url)) => {
return Ok(Video_Item::new(id, title, video_url.clone(), channel, thumb, duration)
.tags(hit.tags)
.uploader(hit.brand)
.views(hit.views as u32)
.rating((hit.likes as f32 / (hit.likes + hit.dislikes)as f32) * 100 as f32)
.formats(vec![videos::Video_Format::new(video_url.clone(), "1080".to_string(), "m3u8".to_string())]));
}
Ok(None) => (),
Err(e) => {
println!("Error fetching video from database: {}", e);
// return Err(format!("Error fetching video from database: {}", e).into());
}
}
let client = match env::var("BURP_URL").as_deref() {
Ok(burp_url) =>
@@ -149,11 +169,14 @@ impl HanimeProvider {
let text = match response.status().is_success() {
true => {
response.text().await?},
response.text().await?
},
false => {
print!("Failed to fetch video item: {}\n\n", response.status());
return Err(format!("Failed to fetch video item: {}", response.status()).into());
} };
}
};
let urls = text.split("\"servers\"").collect::<Vec<&str>>()[1];
let mut url_vec = vec![];
@@ -163,16 +186,19 @@ impl HanimeProvider {
url_vec.push(url.to_string());
}
}
Ok((hit.created_at, Video_Item::new(id, title, url_vec[0].clone(), channel, thumb, duration)
let mut conn = pool.get().expect("couldn't get db connection from pool");
let _ = db::insert_video(&mut conn, &format!("https://h.freeanimehentai.net/api/v8/video?id={}&", hit.slug.clone()), &url_vec[0].clone());
drop(conn);
Ok(Video_Item::new(id, title, url_vec[0].clone(), channel, thumb, duration)
.tags(hit.tags)
.uploader(hit.brand)
.views(hit.views as u32)
.rating((hit.likes as f32 / (hit.likes + hit.dislikes)as f32) * 100 as f32)
.formats(vec![videos::Video_Format::new(url_vec[0].clone(), "1080".to_string(), "m3u8".to_string())])))
.formats(vec![videos::Video_Format::new(url_vec[0].clone(), "1080".to_string(), "m3u8".to_string())]))
}
async fn get(&self, cache: VideoCache, page: u8, query: String) -> Result<Vec<Video_Item>> {
async fn get(&self, cache: VideoCache, pool: DbPool, page: u8, query: String) -> Result<Vec<Video_Item>> {
let index = format!("{}:{}", query, page);
let old_items = match cache.get(&index) {
@@ -219,13 +245,12 @@ impl HanimeProvider {
let hits_json: Vec<HanimeSearchResult> = serde_json::from_str(hits.as_str())
.map_err(|e| format!("Failed to parse hits JSON: {}", e))?;
// let timeout_duration = Duration::from_secs(120);
let futures = hits_json.into_iter().map(|el| self.get_video_item(el.clone()));
let results: Vec<Result<(u64,Video_Item)>> = join_all(futures).await;
let mut items: Vec<(u64, Video_Item)> = results
let futures = hits_json.into_iter().map(|el| self.get_video_item(el.clone(), pool.clone()));
let results: Vec<Result<Video_Item>> = join_all(futures).await;
let video_items: Vec<Video_Item> = results
.into_iter()
.filter_map(Result::ok)
.collect();
let video_items: Vec<Video_Item> = items.into_iter().map(|(_, item)| item).collect();
.collect();
if !video_items.is_empty() {
cache.remove(&index);
cache.insert(index.clone(), video_items.clone());
@@ -241,6 +266,7 @@ impl Provider for HanimeProvider {
async fn get_videos(
&self,
cache: VideoCache,
pool: DbPool,
_channel: String,
sort: String,
query: Option<String>,
@@ -252,8 +278,8 @@ impl Provider for HanimeProvider {
let _ = per_page;
let _ = sort;
let videos: std::result::Result<Vec<Video_Item>, Error> = match query {
Some(q) => self.get(cache, page.parse::<u8>().unwrap_or(1), q).await,
None => self.get(cache, page.parse::<u8>().unwrap_or(1), "".to_string()).await,
Some(q) => self.get(cache, pool, page.parse::<u8>().unwrap_or(1), q).await,
None => self.get(cache, pool, page.parse::<u8>().unwrap_or(1), "".to_string()).await,
};
match videos {
Ok(v) => v,