overhault to fix warnings etc

This commit is contained in:
Simon
2025-10-04 14:28:29 +00:00
parent d84cc715a8
commit 28a4c57616
29 changed files with 889 additions and 1338 deletions

View File

@@ -2,15 +2,11 @@ use crate::DbPool;
use crate::providers::Provider;
use crate::util::cache::VideoCache;
use crate::videos::{ServerOptions, VideoItem};
use async_trait::async_trait;
use cute::c;
use error_chain::error_chain;
use htmlentity::entity::ICodedDataTrait;
use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
// use percent_encoding::{AsciiSet, CONTROLS, utf8_percent_encode};
use std::vec;
use wreq::{Client, Proxy};
use wreq_util::Emulation;
#[macro_use(c)]
error_chain! {
foreign_links {
@@ -157,50 +153,55 @@ impl PmvhavenSearch {
#[derive(serde::Deserialize)]
struct PmvhavenVideo {
title: String, //JAV Addiction Therapy",
uploader: Option<String>, //itonlygetsworse",
duration: f32, //259.093333,
width: Option<String>, //3840",
height: Option<String>, //2160",
ratio: Option<u32>, //50,
title: String, //JAV Addiction Therapy",
_uploader: Option<String>, //itonlygetsworse",
duration: f32, //259.093333,
_width: Option<String>, //3840",
_height: Option<String>, //2160",
_ratio: Option<u32>, //50,
thumbnails: Vec<Option<String>>, //[
// "placeholder",
// "https://storage.pmvhaven.com/686f24e96f7124f3dfbe90ab/thumbnail/JAV Addiction Therapy_686f24e96f7124f3dfbe90ab.png",
// "https://storage.pmvhaven.com/686f24e96f7124f3dfbe90ab/thumbnail/webp320_686f24e96f7124f3dfbe90ab.webp"
// ],
views: u32, //1971,
url: Option<String>, //https://storage.pmvhaven.com/686f24e96f7124f3dfbe90ab/JAV Addiction Therapy_686f24e96f7124f3dfbe90ab.mp4",
views: u32, //1971,
_url: Option<String>, //https://storage.pmvhaven.com/686f24e96f7124f3dfbe90ab/JAV Addiction Therapy_686f24e96f7124f3dfbe90ab.mp4",
previewUrlCompressed: Option<String>, //https://storage.pmvhaven.com/686f24e96f7124f3dfbe90ab/videoPreview/comus_686f24e96f7124f3dfbe90ab.mp4",
seizureWarning: Option<bool>, //false,
isoDate: Option<String>, //2025-07-10T02:52:26.000Z",
gayContent: Option<bool>, //false,
transContent: Option<bool>, //false,
_seizureWarning: Option<bool>, //false,
_isoDate: Option<String>, //2025-07-10T02:52:26.000Z",
_gayContent: Option<bool>, //false,
_transContent: Option<bool>, //false,
creator: Option<String>, //itonlygetsworse",
_id: String, //686f2aeade2062f93d72931f",
totalRaters: Option<u32>, //42,
rating: Option<u32>, //164
_id: String, //686f2aeade2062f93d72931f",
_totalRaters: Option<u32>, //42,
_rating: Option<u32>, //164
}
impl PmvhavenVideo {
fn to_videoitem(self) -> VideoItem {
let encoded_title = percent_encode_emojis(&self.title);
let thumbnail = self.thumbnails[self.thumbnails.len()-1].clone().unwrap_or("".to_string());
let video_id = thumbnail.split("_").collect::<Vec<&str>>().last().unwrap_or(&"").to_string().split('.').next().unwrap_or("").to_string();
// let encoded_title = percent_encode_emojis(&self.title);
let thumbnail = self.thumbnails[self.thumbnails.len() - 1]
.clone()
.unwrap_or("".to_string());
// let video_id = thumbnail.split("_").collect::<Vec<&str>>().last().unwrap_or(&"").to_string().split('.').next().unwrap_or("").to_string();
let mut item = VideoItem::new(
self._id.clone(),
self.title.clone(),
format!("https://pmvhaven.com/video/{}_{}", self.title.replace(" ","-"), self._id),
format!(
"https://pmvhaven.com/video/{}_{}",
self.title.replace(" ", "-"),
self._id
),
"pmvhaven".to_string(),
thumbnail,
self.duration as u32,
)
.views(self.views);
item = match self.creator{
item = match self.creator {
Some(c) => item.uploader(c),
_ => item,
};
item = match self.previewUrlCompressed{
item = match self.previewUrlCompressed {
Some(u) => item.preview(u),
_ => item,
};
@@ -210,18 +211,33 @@ impl PmvhavenVideo {
}
// Define a percent-encoding set that encodes all non-ASCII characters
const EMOJI_ENCODE_SET: &AsciiSet = &CONTROLS.add(b' ').add(b'"').add(b'#').add(b'%').add(b'<').add(b'>').add(b'?').add(b'[').add(b'\\').add(b']').add(b'^').add(b'`').add(b'{').add(b'|').add(b'}');
// const EMOJI_ENCODE_SET: &AsciiSet = &CONTROLS
// .add(b' ')
// .add(b'"')
// .add(b'#')
// .add(b'%')
// .add(b'<')
// .add(b'>')
// .add(b'?')
// .add(b'[')
// .add(b'\\')
// .add(b']')
// .add(b'^')
// .add(b'`')
// .add(b'{')
// .add(b'|')
// .add(b'}');
//
// Helper function to percent-encode emojis and other non-ASCII chars
fn percent_encode_emojis(s: &str) -> String {
utf8_percent_encode(s, EMOJI_ENCODE_SET).to_string()
}
// fn percent_encode_emojis(s: &str) -> String {
// utf8_percent_encode(s, EMOJI_ENCODE_SET).to_string()
// }
#[derive(serde::Deserialize)]
struct PmvhavenResponse {
httpStatusCode: Option<u32>,
_httpStatusCode: Option<u32>,
data: Vec<PmvhavenVideo>,
count: Option<u32>,
_count: Option<u32>,
}
impl PmvhavenResponse {
@@ -240,22 +256,46 @@ impl PmvhavenProvider {
url: "https://pmvhaven.com".to_string(),
}
}
async fn get(&self, cache: VideoCache, page: u8, category: String, sort:String) -> Result<Vec<VideoItem>> {
async fn get(
&self,
cache: VideoCache,
page: u8,
sort: String,
options: ServerOptions,
) -> Result<Vec<VideoItem>> {
let category = options.category.unwrap_or("".to_string());
let index = format!("pmvhaven:{}:{}", page, category);
let url = format!("{}/api/getmorevideos", self.url);
let mut request = PmvhavenRequest::new(page as u32);
request.activeView = sort;
println!("Category: {}", category);
request = match category.as_str() {
"hypno" => { request.hypno(); request },
"pmv" => { request.pmv(); request },
"hmv" => { request.hmv(); request },
"tiktok" => { request.tiktok(); request },
"koreanbj" => { request.koreanbj(); request },
"other" => { request.other(); request },
"hypno" => {
request.hypno();
request
}
"pmv" => {
request.pmv();
request
}
"hmv" => {
request.hmv();
request
}
"tiktok" => {
request.tiktok();
request
}
"koreanbj" => {
request.koreanbj();
request
}
"other" => {
request.other();
request
}
_ => request,
};
let old_items = match cache.get(&index) {
Some((time, items)) => {
if time.elapsed().unwrap_or_default().as_secs() < 60 * 5 {
@@ -270,42 +310,35 @@ impl PmvhavenProvider {
}
};
// let proxy = Proxy::all("http://192.168.0.103:8081").unwrap();
let client = Client::builder()
.cert_verification(false)
.emulation(Emulation::Firefox136)
.build()?;
let response = client
.post(url.clone())
// .proxy(proxy.clone())
.json(&request)
.header("Content-Type", "text/plain;charset=UTF-8")
.send()
.await?;
if response.status().is_success() {
let videos = match response.json::<PmvhavenResponse>().await {
Ok(resp) => resp,
Err(e) => {
println!("Failed to parse PmvhavenResponse: {}", e);
return Ok(old_items);
}
};
let video_items: Vec<VideoItem> = videos.to_videoitems();
if !video_items.is_empty() {
cache.remove(&url);
cache.insert(url.clone(), video_items.clone());
} else {
let mut requester = options.requester.clone().unwrap();
let response = requester.post(&url, &request).await.unwrap();
let videos = match response.json::<PmvhavenResponse>().await {
Ok(resp) => resp,
Err(e) => {
println!("Failed to parse PmvhavenResponse: {}", e);
return Ok(old_items);
}
return Ok(video_items);
};
let video_items: Vec<VideoItem> = videos.to_videoitems();
if !video_items.is_empty() {
cache.remove(&url);
cache.insert(url.clone(), video_items.clone());
} else {
return Ok(old_items);
}
Err("Failed to get Videos".into())
return Ok(video_items);
}
async fn query(&self, cache: VideoCache, page: u8, query: &str) -> Result<Vec<VideoItem>> {
async fn query(
&self,
cache: VideoCache,
page: u8,
query: &str,
options: ServerOptions,
) -> Result<Vec<VideoItem>> {
let index = format!("pmvhaven:{}:{}", query, page);
let url = format!("{}/api/v2/search", self.url);
let request = PmvhavenSearch::new(query.to_string(),page as u32);
let request = PmvhavenSearch::new(query.to_string(), page as u32);
// Check our Video Cache. If the result is younger than 1 hour, we return it.
let old_items = match cache.get(&index) {
Some((time, items)) => {
@@ -321,66 +354,27 @@ impl PmvhavenProvider {
}
};
// let proxy = Proxy::all("http://192.168.0.103:8081").unwrap();
let client = Client::builder()
.cert_verification(false)
.emulation(Emulation::Firefox136)
.build()?;
let response = client
.post(url.clone())
// .proxy(proxy.clone())
.json(&request)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.send()
.await?;
if response.status().is_success() {
let videos = match response.json::<PmvhavenResponse>().await {
Ok(resp) => resp,
Err(e) => {
println!("Failed to parse PmvhavenResponse: {}", e);
return Ok(old_items);
}
};
let video_items: Vec<VideoItem> = videos.to_videoitems();
if !video_items.is_empty() {
cache.remove(&url);
cache.insert(url.clone(), video_items.clone());
} else {
let mut requester = options.requester.clone().unwrap();
let response = requester.post(&url, &request).await.unwrap();
let videos = match response.json::<PmvhavenResponse>().await {
Ok(resp) => resp,
Err(e) => {
println!("Failed to parse PmvhavenResponse: {}", e);
return Ok(old_items);
}
return Ok(video_items);
};
let video_items: Vec<VideoItem> = videos.to_videoitems();
if !video_items.is_empty() {
cache.remove(&url);
cache.insert(url.clone(), video_items.clone());
} else {
return Ok(old_items);
}
// else {
// let flare_url = env::var("FLARE_URL").expect("FLARE_URL not set");
// let flare = Flaresolverr::new(flare_url);
// let result = flare
// .solve(FlareSolverrRequest {
// cmd: "request.get".to_string(),
// url: url.clone(),
// maxTimeout: 60000,
// })
// .await;
// let video_items = match result {
// Ok(res) => self.get_video_items_from_html(res.solution.response),
// Err(e) => {
// println!("Error solving FlareSolverr: {}", e);
// return Err("Failed to solve FlareSolverr".into());
// }
// };
// if !video_items.is_empty() {
// cache.remove(&url);
// cache.insert(url.clone(), video_items.clone());
// } else {
// return Ok(old_items);
// }
// Ok(video_items)
// }
Err("Failed to query Videos".into())
return Ok(video_items);
}
}
#[async_trait]
impl Provider for PmvhavenProvider {
async fn get_videos(
&self,
@@ -395,11 +389,19 @@ impl Provider for PmvhavenProvider {
let _ = per_page;
let _ = pool; // Ignored in this implementation
let videos: std::result::Result<Vec<VideoItem>, Error> = match query {
Some(q) => self.query(cache, page.parse::<u8>().unwrap_or(1), &q).await,
None => {
self.get(cache, page.parse::<u8>().unwrap_or(1), options.category.unwrap(), sort)
Some(q) => {
self.query(cache, page.parse::<u8>().unwrap_or(1), &q, options)
.await
}
None => {
self.get(
cache,
page.parse::<u8>().unwrap_or(1),
sort,
options,
)
.await
}
};
match videos {
Ok(v) => v,