updates
This commit is contained in:
@@ -651,7 +651,7 @@ async fn status(req: HttpRequest) -> Result<impl web::Responder, web::Error> {
|
|||||||
status.add_channel(Channel {
|
status.add_channel(Channel {
|
||||||
id: "hentaihaven".to_string(),
|
id: "hentaihaven".to_string(),
|
||||||
name: "Hentaihaven".to_string(),
|
name: "Hentaihaven".to_string(),
|
||||||
description: "Watch free hentai video stream in English subtitles".to_string(),
|
description: "(Work in Progress) Watch free hentai video stream in English subtitles".to_string(),
|
||||||
premium: false,
|
premium: false,
|
||||||
favicon: "https://www.google.com/s2/favicons?sz=64&domain=hentaihaven.xxx".to_string(),
|
favicon: "https://www.google.com/s2/favicons?sz=64&domain=hentaihaven.xxx".to_string(),
|
||||||
status: "active".to_string(),
|
status: "active".to_string(),
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::schema::videos::url;
|
||||||
use crate::util::parse_abbreviated_number;
|
use crate::util::parse_abbreviated_number;
|
||||||
use crate::DbPool;
|
use crate::DbPool;
|
||||||
use crate::providers::Provider;
|
use crate::providers::Provider;
|
||||||
@@ -192,10 +193,10 @@ impl HentaihavenProvider {
|
|||||||
.to_vec()
|
.to_vec()
|
||||||
;
|
;
|
||||||
for video_segment in &raw_videos {
|
for video_segment in &raw_videos {
|
||||||
// let vid = video_segment.split("\n").collect::<Vec<&str>>();
|
let vid = video_segment.split("\n").collect::<Vec<&str>>();
|
||||||
// for (index, line) in vid.iter().enumerate() {
|
for (index, line) in vid.iter().enumerate() {
|
||||||
// println!("Line {}: {}", index, line);
|
println!("Line {}: {}", index, line);
|
||||||
// }
|
}
|
||||||
|
|
||||||
let episode_count = video_segment.split("chapter font-meta").collect::<Vec<&str>>()[1]
|
let episode_count = video_segment.split("chapter font-meta").collect::<Vec<&str>>()[1]
|
||||||
.split("class=\"btn-link\">").collect::<Vec<&str>>()[1]
|
.split("class=\"btn-link\">").collect::<Vec<&str>>()[1]
|
||||||
@@ -206,12 +207,24 @@ impl HentaihavenProvider {
|
|||||||
.split("class=\"btn-link\">").collect::<Vec<&str>>()[1]
|
.split("class=\"btn-link\">").collect::<Vec<&str>>()[1]
|
||||||
.split("<").collect::<Vec<&str>>()[0]
|
.split("<").collect::<Vec<&str>>()[0]
|
||||||
.split(" ").collect::<Vec<&str>>()[1] == "Season" ;
|
.split(" ").collect::<Vec<&str>>()[1] == "Season" ;
|
||||||
|
println!("{:?}",video_segment.split("chapter font-meta").collect::<Vec<&str>>()[1]
|
||||||
let url_part = video_segment.split("chapter font-meta").collect::<Vec<&str>>()[1]
|
|
||||||
.split("href=\"").collect::<Vec<&str>>()[1]
|
.split("href=\"").collect::<Vec<&str>>()[1]
|
||||||
.split("\"").collect::<Vec<&str>>()[0]
|
.split("\"").collect::<Vec<&str>>()[0]
|
||||||
.split("/").collect::<Vec<&str>>()[4];
|
.split("/").collect::<Vec<&str>>()[4]);
|
||||||
|
let mut url_part_list = video_segment.split("chapter font-meta").collect::<Vec<&str>>()[1]
|
||||||
|
.split("href=\"").collect::<Vec<&str>>()[1]
|
||||||
|
.split("\"").collect::<Vec<&str>>()[0]
|
||||||
|
.split("/").collect::<Vec<&str>>()[4]
|
||||||
|
.split("-").collect::<Vec<&str>>();
|
||||||
|
if url_part_list.len() > 5 {
|
||||||
|
if let Some(pos) = url_part_list.iter().rposition(|x| *x == "no") {
|
||||||
|
url_part_list.remove(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url_part_list.truncate(5);
|
||||||
|
let url_part = url_part_list.join("-");
|
||||||
for i in 1..=episode_count {
|
for i in 1..=episode_count {
|
||||||
|
|
||||||
let mut video_url = format!("https://master-lengs.org/api/v3/hh/{}-{}-eng/master.m3u8", url_part, i);
|
let mut video_url = format!("https://master-lengs.org/api/v3/hh/{}-{}-eng/master.m3u8", url_part, i);
|
||||||
if season {
|
if season {
|
||||||
video_url = format!("https://master-lengs.org/api/v3/hh/{}-season-eng/master.m3u8", url_part);
|
video_url = format!("https://master-lengs.org/api/v3/hh/{}-season-eng/master.m3u8", url_part);
|
||||||
@@ -220,10 +233,18 @@ impl HentaihavenProvider {
|
|||||||
.split("\"").collect::<Vec<&str>>()[0]
|
.split("\"").collect::<Vec<&str>>()[0]
|
||||||
.to_string(), i);
|
.to_string(), i);
|
||||||
let id = format!("{}-{}", url_part, i);
|
let id = format!("{}-{}", url_part, i);
|
||||||
let mut thumb = format!("https://himg.nl/images/hh/{}-{}-eng/poster.jpg", url_part, i);
|
|
||||||
if season {
|
let thumb = match video_segment.split("<img").collect::<Vec<&str>>()[1]
|
||||||
thumb = format!("https://himg.nl/images/hh/{}-season-eng/poster.jpg", url_part);
|
.split("").collect::<Vec<&str>>()[0].contains("data-src=\"") {
|
||||||
}
|
true => video_segment.split("<img ").collect::<Vec<&str>>()[1]
|
||||||
|
.split("data-src=\"").collect::<Vec<&str>>()[1]
|
||||||
|
.split("\"").collect::<Vec<&str>>()[0]
|
||||||
|
.to_string(),
|
||||||
|
false =>video_segment.split("<img ").collect::<Vec<&str>>()[1]
|
||||||
|
.split("src=\"").collect::<Vec<&str>>()[1]
|
||||||
|
.split("\"").collect::<Vec<&str>>()[0]
|
||||||
|
.to_string()
|
||||||
|
};
|
||||||
items.push(VideoItem::new(
|
items.push(VideoItem::new(
|
||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
@@ -231,8 +252,9 @@ impl HentaihavenProvider {
|
|||||||
"hentaihaven".to_string(),
|
"hentaihaven".to_string(),
|
||||||
thumb,
|
thumb,
|
||||||
0, // duration is not available
|
0, // duration is not available
|
||||||
))
|
)
|
||||||
;
|
.aspect_ratio(0.73)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
|
|||||||
@@ -60,21 +60,33 @@ impl VideoEmbed {
|
|||||||
#[derive(serde::Serialize, Debug, Clone)]
|
#[derive(serde::Serialize, Debug, Clone)]
|
||||||
pub struct VideoItem {
|
pub struct VideoItem {
|
||||||
pub duration: u32, // 110,
|
pub duration: u32, // 110,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub views: Option<u32>, // 14622653,
|
pub views: Option<u32>, // 14622653,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub rating: Option<f32>, // 0.0,
|
pub rating: Option<f32>, // 0.0,
|
||||||
pub id: String, // "c85017ca87477168d648727753c4ded8a35f173e22ef93743e707b296becb299",
|
pub id: String, // "c85017ca87477168d648727753c4ded8a35f173e22ef93743e707b296becb299",
|
||||||
pub title: String, // "20 Minutes of Adorable Kittens BEST Compilation",
|
pub title: String, // "20 Minutes of Adorable Kittens BEST Compilation",
|
||||||
pub url: String, // "https://www.youtube.com/watch?v=y0sF5xhGreA",
|
pub url: String, // "https://www.youtube.com/watch?v=y0sF5xhGreA",
|
||||||
pub channel: String, // "youtube",
|
pub channel: String, // "youtube",
|
||||||
pub thumb: String, // "https://i.ytimg.com/vi/y0sF5xhGreA/hqdefault.jpg",
|
pub thumb: String, // "https://i.ytimg.com/vi/y0sF5xhGreA/hqdefault.jpg",
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub uploader: Option<String>, // "The Pet Collective",
|
pub uploader: Option<String>, // "The Pet Collective",
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub uploaderUrl: Option<String>, // "https://www.youtube.com/@petcollective",
|
pub uploaderUrl: Option<String>, // "https://www.youtube.com/@petcollective",
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub verified: Option<bool>, // false,
|
pub verified: Option<bool>, // false,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub tags: Option<Vec<String>>, // [],
|
pub tags: Option<Vec<String>>, // [],
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub uploadedAt: Option<u64>, // 1741142954
|
pub uploadedAt: Option<u64>, // 1741142954
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub formats: Option<Vec<VideoFormat>>, // Additional HTTP headers if needed
|
pub formats: Option<Vec<VideoFormat>>, // Additional HTTP headers if needed
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub embed: Option<VideoEmbed>, // Optional embed information
|
pub embed: Option<VideoEmbed>, // Optional embed information
|
||||||
pub preview: Option<String>
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub preview: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub aspectRation: Option<f32>
|
||||||
}
|
}
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl VideoItem {
|
impl VideoItem {
|
||||||
@@ -102,7 +114,8 @@ impl VideoItem {
|
|||||||
uploadedAt: None,
|
uploadedAt: None,
|
||||||
formats: None, // Placeholder for formats
|
formats: None, // Placeholder for formats
|
||||||
embed: None, // Placeholder for embed information
|
embed: None, // Placeholder for embed information
|
||||||
preview: None
|
preview: None,
|
||||||
|
aspectRation: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn tags(mut self, tags: Vec<String>) -> Self {
|
pub fn tags(mut self, tags: Vec<String>) -> Self {
|
||||||
@@ -152,6 +165,11 @@ impl VideoItem {
|
|||||||
self.preview = Some(preview);
|
self.preview = Some(preview);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn aspect_ratio(mut self, aspect_ratio: f32) -> Self {
|
||||||
|
self.aspectRation = Some(aspect_ratio);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, Debug, Clone)]
|
#[derive(serde::Serialize, Debug, Clone)]
|
||||||
@@ -159,27 +177,49 @@ pub struct VideoFormat {
|
|||||||
url: String,
|
url: String,
|
||||||
quality: String,
|
quality: String,
|
||||||
format: String,
|
format: String,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
format_id: Option<String>,
|
format_id: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
format_note: Option<String>,
|
format_note: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
filesize: Option<u32>,
|
filesize: Option<u32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
asr: Option<u32>,
|
asr: Option<u32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
fps: Option<u32>,
|
fps: Option<u32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
width: Option<u32>,
|
width: Option<u32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
height: Option<u32>,
|
height: Option<u32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
tbr: Option<u32>,
|
tbr: Option<u32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
language: Option<String>,
|
language: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
language_preference: Option<u32>,
|
language_preference: Option<u32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
ext: Option<String>,
|
ext: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
vcodec: Option<String>,
|
vcodec: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
acodec: Option<String>,
|
acodec: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
dynamic_range: Option<String>,
|
dynamic_range: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
abr: Option<u32>,
|
abr: Option<u32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
vbr: Option<u32>,
|
vbr: Option<u32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
container: Option<String>,
|
container: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
protocol: Option<String>,
|
protocol: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
audio_ext: Option<String>,
|
audio_ext: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
video_ext: Option<String>,
|
video_ext: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
resolution: Option<String>,
|
resolution: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
http_headers: Option<HashMap<String, String>>,
|
http_headers: Option<HashMap<String, String>>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user