testing and fixing

This commit is contained in:
Simon
2025-08-09 12:21:43 +00:00
parent 6b4b0be522
commit 3feeb02251
12 changed files with 204 additions and 96 deletions

View File

@@ -357,40 +357,39 @@ async fn status(req: HttpRequest) -> Result<impl web::Responder, web::Error> {
}], }],
nsfw: true, nsfw: true,
}); });
status.add_channel(Channel { // status.add_channel(Channel {
id: "spankbang".to_string(), // id: "spankbang".to_string(),
name: "SpankBang".to_string(), // name: "SpankBang".to_string(),
description: "Popular Porn Videos - SpankBang".to_string(), // description: "Popular Porn Videos - SpankBang".to_string(),
premium: false, // premium: false,
favicon: "https://www.google.com/s2/favicons?sz=64&domain=spankbang.com".to_string(), // favicon: "https://www.google.com/s2/favicons?sz=64&domain=spankbang.com".to_string(),
status: "active".to_string(), // status: "active".to_string(),
categories: vec![], // categories: vec![],
options: vec![ChannelOption { // options: vec![ChannelOption {
id: "sort".to_string(), // id: "sort".to_string(),
title: "Sort".to_string(), // title: "Sort".to_string(),
description: "Sort the Videos".to_string(), //"Sort the videos by Date or Name.".to_string(), // description: "Sort the Videos".to_string(), //"Sort the videos by Date or Name.".to_string(),
systemImage: "list.number".to_string(), // systemImage: "list.number".to_string(),
colorName: "blue".to_string(), // colorName: "blue".to_string(),
options: vec![ // options: vec![
FilterOption { // FilterOption {
id: "trending_videos".to_string(), // id: "trending_videos".to_string(),
title: "Trending".to_string(), // title: "Trending".to_string(),
}, // },
FilterOption { // FilterOption {
id: "new_videos".to_string(), // id: "new_videos".to_string(),
title: "New".to_string(), // title: "New".to_string(),
}, // },
FilterOption { // FilterOption {
id: "most_popular".to_string(), // id: "most_popular".to_string(),
title: "Popular".to_string(), // title: "Popular".to_string(),
}, // },
], // ],
multiSelect: false, // multiSelect: false,
}], // }],
nsfw: true, // nsfw: true,
}); // });
// pronhub
status.add_channel(Channel { status.add_channel(Channel {
id: "rule34video".to_string(), id: "rule34video".to_string(),
name: "Rule34Video".to_string(), name: "Rule34Video".to_string(),
@@ -431,6 +430,52 @@ async fn status(req: HttpRequest) -> Result<impl web::Responder, web::Error> {
}], }],
nsfw: true, nsfw: true,
}); });
status.add_channel(Channel {
id: "all".to_string(),
name: "All".to_string(),
description: "Query from all sites of this Server".to_string(),
premium: false,
favicon: "https://hottub.spacemoehre.de/favicon".to_string(),
status: "active".to_string(),
categories: vec![],
options: vec![ChannelOption {
id: "sites".to_string(),
title: "Sites".to_string(),
description: "What Sites to use".to_string(), //"Sort the videos by Date or Name.".to_string(),
systemImage: "list.number".to_string(),
colorName: "green".to_string(),
options: vec![
FilterOption {
id: "hanime".to_string(),
title: "Hanime".to_string(),
},
FilterOption {
id: "perverzija".to_string(),
title: "Perverzija".to_string(),
},
FilterOption {
id: "pmvhaven".to_string(),
title: "PMVHaven".to_string(),
},
FilterOption {
id: "pornhub".to_string(),
title: "Pornhub".to_string(),
},
FilterOption {
id: "redtube".to_string(),
title: "Redtube".to_string(),
},
FilterOption {
id: "rule34video".to_string(),
title: "Rule34Video".to_string(),
},
],
multiSelect: true,
}],
nsfw: true,
});
status.add_channel(Channel { status.add_channel(Channel {
id: "redtube".to_string(), id: "redtube".to_string(),
name: "Redtube".to_string(), name: "Redtube".to_string(),
@@ -494,7 +539,12 @@ async fn videos_post(
.as_deref() .as_deref()
.unwrap_or("all") .unwrap_or("all")
.to_string(); .to_string();
let sites = video_request
.sites
.as_deref()
.unwrap_or("")
.to_string();
let options = ServerOptions { featured: Some(featured), category: Some(category), sites: Some(sites) };
let video_items = provider let video_items = provider
.get_videos( .get_videos(
cache.get_ref().clone(), cache.get_ref().clone(),
@@ -504,8 +554,7 @@ async fn videos_post(
query.clone(), query.clone(),
page.to_string(), page.to_string(),
perPage.to_string(), perPage.to_string(),
featured.clone(), options.clone()
category.clone(),
) )
.await; .await;
videos.items = video_items.clone(); videos.items = video_items.clone();
@@ -524,8 +573,7 @@ async fn videos_post(
let sort_clone = sort.clone(); let sort_clone = sort.clone();
let query_clone = query.clone(); let query_clone = query.clone();
let per_page_clone = perPage.to_string(); let per_page_clone = perPage.to_string();
let featured_clone = featured.clone(); let options_clone = options.clone();
let category_clone = category.clone();
task::spawn_local(async move { task::spawn_local(async move {
// if let AnyProvider::Spankbang(_) = provider_clone { // if let AnyProvider::Spankbang(_) = provider_clone {
// // Spankbang has a delay for the next page // // Spankbang has a delay for the next page
@@ -540,8 +588,7 @@ async fn videos_post(
query_clone, query_clone,
next_page.to_string(), next_page.to_string(),
per_page_clone, per_page_clone,
featured_clone, options_clone
category_clone,
) )
.await; .await;
}); });

44
src/providers/all.rs Normal file
View File

@@ -0,0 +1,44 @@
use std::vec;
use error_chain::error_chain;
use futures::future::join_all;
use serde_json::error::Category;
use wreq::Client;
use wreq_util::Emulation;
use crate::db;
use crate::providers::Provider;
use crate::util::cache::VideoCache;
use crate::videos::{self, ServerOptions, VideoItem};
use crate::DbPool;
error_chain! {
foreign_links {
Io(std::io::Error);
HttpRequest(wreq::Error);
}
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct AllProvider {
}
impl Provider for AllProvider {
async fn get_videos(
&self,
cache: VideoCache,
pool: DbPool,
_channel: String,
sort: String,
query: Option<String>,
page: String,
per_page: String,
options: ServerOptions,
) -> Vec<VideoItem> {
let sites = options.sites.unwrap();
println!("{:?}", sites);
return vec![];
}
}

View File

@@ -7,7 +7,7 @@ use wreq_util::Emulation;
use crate::db; use crate::db;
use crate::providers::Provider; use crate::providers::Provider;
use crate::util::cache::VideoCache; use crate::util::cache::VideoCache;
use crate::videos::{self, VideoItem}; use crate::videos::{self, ServerOptions, VideoItem};
use crate::DbPool; use crate::DbPool;
error_chain! { error_chain! {
@@ -264,11 +264,9 @@ impl Provider for HanimeProvider {
query: Option<String>, query: Option<String>,
page: String, page: String,
per_page: String, per_page: String,
featured: String, options: ServerOptions,
category: String,
) -> Vec<VideoItem> { ) -> Vec<VideoItem> {
let _ = category; let _ = options;
let _ = featured;
let _ = per_page; let _ = per_page;
let _ = sort; let _ = sort;
let videos: std::result::Result<Vec<VideoItem>, Error> = match query { let videos: std::result::Result<Vec<VideoItem>, Error> = match query {

View File

@@ -1,9 +1,10 @@
use crate::{ use crate::{
providers::{ providers::{
hanime::HanimeProvider, perverzija::PerverzijaProvider, pmvhaven::PmvhavenProvider, pornhub::PornhubProvider, rule34video::Rule34videoProvider, spankbang::SpankbangProvider, redtube::RedtubeProvider, all::AllProvider, hanime::HanimeProvider, perverzija::PerverzijaProvider, pmvhaven::PmvhavenProvider, pornhub::PornhubProvider, redtube::RedtubeProvider, rule34video::Rule34videoProvider, spankbang::SpankbangProvider
}, util::cache::VideoCache, videos::VideoItem, DbPool }, util::cache::VideoCache, videos::{ServerOptions, VideoItem}, DbPool
}; };
pub mod all;
pub mod hanime; pub mod hanime;
pub mod perverzija; pub mod perverzija;
pub mod pmvhaven; pub mod pmvhaven;
@@ -22,13 +23,13 @@ pub trait Provider {
query: Option<String>, query: Option<String>,
page: String, page: String,
per_page: String, per_page: String,
featured: String, options: ServerOptions,
category: String,
) -> Vec<VideoItem>; ) -> Vec<VideoItem>;
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum AnyProvider { pub enum AnyProvider {
All(AllProvider),
Perverzija(PerverzijaProvider), Perverzija(PerverzijaProvider),
Hanime(HanimeProvider), Hanime(HanimeProvider),
Spankbang(SpankbangProvider), Spankbang(SpankbangProvider),
@@ -37,6 +38,7 @@ pub enum AnyProvider {
Rule34video(Rule34videoProvider), Rule34video(Rule34videoProvider),
Redtube(RedtubeProvider), // Assuming Redtube is similar to Rule34video Redtube(RedtubeProvider), // Assuming Redtube is similar to Rule34video
} }
impl Provider for AnyProvider { impl Provider for AnyProvider {
async fn get_videos( async fn get_videos(
&self, &self,
@@ -47,12 +49,11 @@ impl Provider for AnyProvider {
query: Option<String>, query: Option<String>,
page: String, page: String,
per_page: String, per_page: String,
featured: String, options: ServerOptions
category: String,
) -> Vec<VideoItem> { ) -> Vec<VideoItem> {
println!( println!(
"/api/videos: channel={:?}, sort={:?}, query={:?}, page={:?}, per_page={:?}, featured={:?}", "/api/videos: channel={:?}, sort={:?}, query={:?}, page={:?}",
channel, sort, query, page, per_page, featured channel, sort, query, page
); );
match self { match self {
AnyProvider::Perverzija(p) => { AnyProvider::Perverzija(p) => {
@@ -64,39 +65,36 @@ impl Provider for AnyProvider {
query.clone(), query.clone(),
page.clone(), page.clone(),
per_page.clone(), per_page.clone(),
featured.clone(), options,
category.clone(),
) )
.await .await
} }
AnyProvider::Hanime(p) => { AnyProvider::Hanime(p) => {
p.get_videos(cache, pool, channel, sort, query, page, per_page, featured, p.get_videos(cache, pool, channel, sort, query, page, per_page, options,)
category.clone(),)
.await .await
} }
AnyProvider::Spankbang(p) => { AnyProvider::Spankbang(p) => {
p.get_videos(cache, pool, channel, sort, query, page, per_page, featured, p.get_videos(cache, pool, channel, sort, query, page, per_page, options,)
category.clone(),)
.await .await
} }
AnyProvider::Pornhub(p) => { AnyProvider::Pornhub(p) => {
p.get_videos(cache, pool, channel, sort, query, page, per_page, featured, p.get_videos(cache, pool, channel, sort, query, page, per_page, options,)
category.clone(),)
.await .await
} }
AnyProvider::Pmvhaven(p) => { AnyProvider::Pmvhaven(p) => {
p.get_videos(cache, pool, channel, sort, query, page, per_page, featured, p.get_videos(cache, pool, channel, sort, query, page, per_page, options,)
category.clone(),)
.await .await
} }
AnyProvider::Rule34video(p) => { AnyProvider::Rule34video(p) => {
p.get_videos(cache, pool, channel, sort, query, page, per_page, featured, p.get_videos(cache, pool, channel, sort, query, page, per_page, options,)
category.clone(),)
.await .await
} }
AnyProvider::Redtube(p) => { AnyProvider::Redtube(p) => {
p.get_videos(cache, pool, channel, sort, query, page, per_page, featured, p.get_videos(cache, pool, channel, sort, query, page, per_page, options,)
category.clone(),) .await
}
AnyProvider::All(p) => {
p.get_videos(cache, pool, channel, sort, query, page, per_page, options,)
.await .await
} }
} }

View File

@@ -14,6 +14,7 @@ use crate::schema::videos::url;
use crate::util::cache::VideoCache; use crate::util::cache::VideoCache;
use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr}; use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr};
use crate::util::time::parse_time_to_seconds; use crate::util::time::parse_time_to_seconds;
use crate::videos::ServerOptions;
use crate::videos::{self, VideoEmbed, VideoItem}; use crate::videos::{self, VideoEmbed, VideoItem};
use crate::DbPool; use crate::DbPool;
@@ -550,15 +551,13 @@ impl Provider for PerverzijaProvider {
query: Option<String>, query: Option<String>,
page: String, page: String,
per_page: String, per_page: String,
featured: String, options: ServerOptions,
category: String,
) -> Vec<VideoItem> { ) -> Vec<VideoItem> {
let _ = category;
let _ = per_page; let _ = per_page;
let _ = sort; let _ = sort;
let videos: std::result::Result<Vec<VideoItem>, Error> = match query { let videos: std::result::Result<Vec<VideoItem>, Error> = match query {
Some(q) => self.query(cache, pool, page.parse::<u8>().unwrap_or(1), &q).await, Some(q) => self.query(cache, pool, page.parse::<u8>().unwrap_or(1), &q).await,
None => self.get(cache, pool, page.parse::<u8>().unwrap_or(1), featured).await, None => self.get(cache, pool, page.parse::<u8>().unwrap_or(1), options.featured.unwrap()).await,
}; };
match videos { match videos {
Ok(v) => v, Ok(v) => v,

View File

@@ -5,7 +5,7 @@ use crate::util::cache::VideoCache;
use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr}; use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr};
use crate::util::parse_abbreviated_number; use crate::util::parse_abbreviated_number;
use crate::util::time::parse_time_to_seconds; use crate::util::time::parse_time_to_seconds;
use crate::videos::{VideoFormat, VideoItem}; use crate::videos::{ServerOptions, VideoFormat, VideoItem};
use cute::c; use cute::c;
use error_chain::error_chain; use error_chain::error_chain;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
@@ -424,16 +424,14 @@ impl Provider for PmvhavenProvider {
query: Option<String>, query: Option<String>,
page: String, page: String,
per_page: String, per_page: String,
featured: String, options: ServerOptions,
category: String,
) -> Vec<VideoItem> { ) -> Vec<VideoItem> {
let _ = per_page; let _ = per_page;
let _ = featured; // Ignored in this implementation
let _ = pool; // Ignored in this implementation let _ = pool; // Ignored in this implementation
let videos: std::result::Result<Vec<VideoItem>, Error> = match query { let videos: std::result::Result<Vec<VideoItem>, Error> = match query {
Some(q) => self.query(cache, page.parse::<u8>().unwrap_or(1), &q).await, Some(q) => self.query(cache, page.parse::<u8>().unwrap_or(1), &q).await,
None => { None => {
self.get(cache, page.parse::<u8>().unwrap_or(1), category, sort) self.get(cache, page.parse::<u8>().unwrap_or(1), options.category.unwrap(), sort)
.await .await
} }
}; };

View File

@@ -5,7 +5,7 @@ use crate::providers::Provider;
use crate::util::cache::VideoCache; use crate::util::cache::VideoCache;
use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr}; use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr};
use crate::util::time::parse_time_to_seconds; use crate::util::time::parse_time_to_seconds;
use crate::videos::{VideoItem}; use crate::videos::{ServerOptions, VideoItem};
use error_chain::error_chain; use error_chain::error_chain;
use futures::stream::SplitSink; use futures::stream::SplitSink;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
@@ -331,12 +331,10 @@ impl Provider for PornhubProvider {
query: Option<String>, query: Option<String>,
page: String, page: String,
per_page: String, per_page: String,
featured: String, options: ServerOptions,
category: String,
) -> Vec<VideoItem> { ) -> Vec<VideoItem> {
let _ = category; let _ = options;
let _ = per_page; let _ = per_page;
let _ = featured; // Ignored in this implementation
let _ = pool; // Ignored in this implementation let _ = pool; // Ignored in this implementation
let mut sort = sort.to_lowercase(); let mut sort = sort.to_lowercase();
if sort.contains("date"){ if sort.contains("date"){

View File

@@ -5,7 +5,7 @@ use crate::providers::Provider;
use crate::util::cache::VideoCache; use crate::util::cache::VideoCache;
use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr}; use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr};
use crate::util::time::parse_time_to_seconds; use crate::util::time::parse_time_to_seconds;
use crate::videos::{VideoItem}; use crate::videos::{ServerOptions, VideoItem};
use error_chain::error_chain; use error_chain::error_chain;
use futures::stream::SplitSink; use futures::stream::SplitSink;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
@@ -266,13 +266,11 @@ impl Provider for RedtubeProvider {
query: Option<String>, query: Option<String>,
page: String, page: String,
per_page: String, per_page: String,
featured: String, options: ServerOptions,
category: String,
) -> Vec<VideoItem> { ) -> Vec<VideoItem> {
let _ = category; let _ = options;
let _ = per_page; let _ = per_page;
let _ = featured; // Ignored in this implementation let _ = pool;
let _ = pool; // Ignored in this implementation
let mut sort = sort.to_lowercase(); let mut sort = sort.to_lowercase();
if sort.contains("date"){ if sort.contains("date"){
sort = "mr".to_string(); sort = "mr".to_string();

View File

@@ -4,7 +4,7 @@ use crate::providers::Provider;
use crate::util::cache::VideoCache; use crate::util::cache::VideoCache;
use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr}; use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr};
use crate::util::time::parse_time_to_seconds; use crate::util::time::parse_time_to_seconds;
use crate::videos::{VideoItem}; use crate::videos::{ServerOptions, VideoItem};
use error_chain::error_chain; use error_chain::error_chain;
use futures::stream::SplitSink; use futures::stream::SplitSink;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
@@ -292,12 +292,10 @@ impl Provider for Rule34videoProvider {
query: Option<String>, query: Option<String>,
page: String, page: String,
per_page: String, per_page: String,
featured: String, options: ServerOptions,
category: String,
) -> Vec<VideoItem> { ) -> Vec<VideoItem> {
let _ = category; let _ = options;
let _ = per_page; let _ = per_page;
let _ = featured; // Ignored in this implementation
let _ = pool; // Ignored in this implementation let _ = pool; // Ignored in this implementation
let videos: std::result::Result<Vec<VideoItem>, Error> = match query { let videos: std::result::Result<Vec<VideoItem>, Error> = match query {
Some(q) => { Some(q) => {

View File

@@ -7,6 +7,7 @@ use crate::db;
use crate::providers::Provider; use crate::providers::Provider;
use crate::util::cache::VideoCache; use crate::util::cache::VideoCache;
use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr}; use crate::util::flaresolverr::{FlareSolverrRequest, Flaresolverr};
use crate::videos::ServerOptions;
use crate::videos::{VideoItem}; use crate::videos::{VideoItem};
use crate::DbPool; use crate::DbPool;
use std::collections::HashMap; use std::collections::HashMap;
@@ -357,12 +358,10 @@ impl Provider for SpankbangProvider {
query: Option<String>, query: Option<String>,
page: String, page: String,
per_page: String, per_page: String,
featured: String, options: ServerOptions,
category: String,
) -> Vec<VideoItem> { ) -> Vec<VideoItem> {
let _ = category; let _ = options;
let _ = per_page; let _ = per_page;
let _ = featured;
let _ = pool; let _ = pool;
if sort == "date"{ if sort == "date"{

View File

@@ -19,3 +19,25 @@ pub fn parse_abbreviated_number(s: &str) -> Option<u32> {
}; };
num_part.parse::<f64>().ok().map(|n| (n * multiplier) as u32) num_part.parse::<f64>().ok().map(|n| (n * multiplier) as u32)
} }
pub fn interleave<T: Clone>(lists: &[Vec<T>]) -> Vec<T> {
let mut result = Vec::new();
if lists.is_empty() {
return result;
}
// Find the maximum length among the lists
let max_len = lists.iter().map(|l| l.len()).max().unwrap_or(0);
// Interleave elements
for i in 0..max_len {
for list in lists {
if let Some(item) = list.get(i) {
result.push(item.clone());
}
}
}
result
}

View File

@@ -27,7 +27,16 @@ pub struct VideosRequest {
// pub flavor: "mint chocolate chip" // pub flavor: "mint chocolate chip"
pub featured: Option<String>, // "featured", pub featured: Option<String>, // "featured",
pub category: Option<String>, // "pmv" pub category: Option<String>, // "pmv"
pub sites: Option<String>, //
} }
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct ServerOptions{
pub featured: Option<String>, // "featured",
pub category: Option<String>, // "pmv"
pub sites: Option<String>, //
}
#[derive(serde::Serialize, Debug)] #[derive(serde::Serialize, Debug)]
pub struct PageInfo { pub struct PageInfo {
pub hasNextPage: bool, // true, pub hasNextPage: bool, // true,