From ce1afd9873097b5146179b17489158602ca69c82 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 18 Mar 2026 12:13:28 +0000 Subject: [PATCH] status upgrade --- src/api.rs | 4 +- src/providers/all.rs | 6 + src/providers/beeg.rs | 6 + src/providers/chaturbate.rs | 6 + src/providers/freepornvideosxxx.rs | 6 + src/providers/hanime.rs | 6 + src/providers/heavyfetish.rs | 6 + src/providers/hentaihaven.rs | 6 + src/providers/homoxxx.rs | 6 + src/providers/hqporner.rs | 6 + src/providers/hsex.rs | 6 + src/providers/hypnotube.rs | 6 + src/providers/javtiful.rs | 6 + src/providers/missav.rs | 6 + src/providers/mod.rs | 216 ++++++++++++++++++++++++++++- src/providers/noodlemagazine.rs | 6 + src/providers/okporn.rs | 6 + src/providers/okxxx.rs | 6 + src/providers/omgxxx.rs | 6 + src/providers/paradisehill.rs | 6 + src/providers/perfectgirls.rs | 6 + src/providers/perverzija.rs | 6 + src/providers/pimpbunny.rs | 6 + src/providers/pmvhaven.rs | 6 + src/providers/porn00.rs | 6 + src/providers/porn4fans.rs | 6 + src/providers/porndish.rs | 6 + src/providers/pornhat.rs | 6 + src/providers/pornhub.rs | 6 + src/providers/pornzog.rs | 6 + src/providers/redtube.rs | 6 + src/providers/rule34gen.rs | 6 + src/providers/rule34video.rs | 6 + src/providers/shooshtime.rs | 6 + src/providers/spankbang.rs | 6 + src/providers/sxyprn.rs | 6 + src/providers/tnaflix.rs | 6 + src/providers/tokyomotion.rs | 6 + src/providers/viralxxxporn.rs | 6 + src/providers/xfree.rs | 6 + src/providers/xxdbx.rs | 6 + src/providers/xxthots.rs | 6 + src/providers/youjizz.rs | 6 + src/status.rs | 45 ++++++ 44 files changed, 508 insertions(+), 3 deletions(-) diff --git a/src/api.rs b/src/api.rs index 3f1aefb..1ee9423 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,5 +1,5 @@ use crate::providers::{ - ALL_PROVIDERS, DynProvider, panic_payload_to_string, report_provider_error, + ALL_PROVIDERS, DynProvider, build_status_response, panic_payload_to_string, report_provider_error, run_provider_guarded, }; use crate::util::cache::VideoCache; @@ -188,7 +188,7 @@ async fn status(req: HttpRequest) -> Result { } } status.iconUrl = format!("{}/favicon.ico", public_url_base).to_string(); - Ok(web::HttpResponse::Ok().json(&status)) + Ok(web::HttpResponse::Ok().json(&build_status_response(status))) } async fn videos_post( diff --git a/src/providers/all.rs b/src/providers/all.rs index 68c13c3..74cf4d4 100644 --- a/src/providers/all.rs +++ b/src/providers/all.rs @@ -14,6 +14,12 @@ use futures::stream::FuturesUnordered; use std::fs; use std::time::Duration; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "meta-search", + tags: &["aggregator", "multi-site", "search"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/beeg.rs b/src/providers/beeg.rs index 05684f8..90ad723 100644 --- a/src/providers/beeg.rs +++ b/src/providers/beeg.rs @@ -14,6 +14,12 @@ use std::thread; use std::time::Duration; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["mainstream", "clips", "mixed"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/chaturbate.rs b/src/providers/chaturbate.rs index d2f72f1..e1798f6 100644 --- a/src/providers/chaturbate.rs +++ b/src/providers/chaturbate.rs @@ -8,6 +8,12 @@ use async_trait::async_trait; use error_chain::error_chain; use htmlentity::entity::{ICodedDataTrait, decode}; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "live-cams", + tags: &["live", "cams", "amateur"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/freepornvideosxxx.rs b/src/providers/freepornvideosxxx.rs index f2c98e3..1ae5895 100644 --- a/src/providers/freepornvideosxxx.rs +++ b/src/providers/freepornvideosxxx.rs @@ -13,6 +13,12 @@ use std::sync::{Arc, RwLock}; use std::thread; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "studio-network", + tags: &["tube", "networked", "mixed"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/hanime.rs b/src/providers/hanime.rs index f352aff..1ec68a6 100644 --- a/src/providers/hanime.rs +++ b/src/providers/hanime.rs @@ -12,6 +12,12 @@ use crate::status::*; use crate::util::cache::VideoCache; use crate::videos::{self, ServerOptions, VideoItem}; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "hentai-animation", + tags: &["hentai", "anime", "premium"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/heavyfetish.rs b/src/providers/heavyfetish.rs index c409481..a98eac3 100644 --- a/src/providers/heavyfetish.rs +++ b/src/providers/heavyfetish.rs @@ -19,6 +19,12 @@ use std::collections::HashMap; use std::sync::{Arc, RwLock}; use std::{thread, vec}; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "fetish-kink", + tags: &["fetish", "bdsm", "niche"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/hentaihaven.rs b/src/providers/hentaihaven.rs index 890eb9a..00242b4 100644 --- a/src/providers/hentaihaven.rs +++ b/src/providers/hentaihaven.rs @@ -16,6 +16,12 @@ use std::vec; use titlecase::Titlecase; use wreq::Version; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "hentai-animation", + tags: &["hentai", "anime", "curated"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/homoxxx.rs b/src/providers/homoxxx.rs index d4146a8..e15e3b7 100644 --- a/src/providers/homoxxx.rs +++ b/src/providers/homoxxx.rs @@ -14,6 +14,12 @@ use std::vec; use wreq::Client; use wreq_util::Emulation; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "gay-male", + tags: &["gay", "male", "tube"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/hqporner.rs b/src/providers/hqporner.rs index 9bebcc6..fc0cca4 100644 --- a/src/providers/hqporner.rs +++ b/src/providers/hqporner.rs @@ -15,6 +15,12 @@ use std::sync::{Arc, RwLock}; use std::{thread, vec}; use titlecase::Titlecase; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "studio-network", + tags: &["studio", "hd", "scenes"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/hsex.rs b/src/providers/hsex.rs index c1dc8ae..6f44525 100644 --- a/src/providers/hsex.rs +++ b/src/providers/hsex.rs @@ -21,6 +21,12 @@ use std::{thread, vec}; use url::Url; use wreq::Version; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "amateur-homemade", + tags: &["amateur", "chinese", "homemade"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/hypnotube.rs b/src/providers/hypnotube.rs index 7c4f01c..c449b62 100644 --- a/src/providers/hypnotube.rs +++ b/src/providers/hypnotube.rs @@ -16,6 +16,12 @@ use std::{thread, vec}; use titlecase::Titlecase; use wreq::Version; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "fetish-kink", + tags: &["hypnosis", "fetish", "sissy"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/javtiful.rs b/src/providers/javtiful.rs index 185b9df..c0dc350 100644 --- a/src/providers/javtiful.rs +++ b/src/providers/javtiful.rs @@ -17,6 +17,12 @@ use std::vec; use titlecase::Titlecase; use wreq::Version; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "asian-jav", + tags: &["jav", "asian", "streaming"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/missav.rs b/src/providers/missav.rs index a057c26..847eac9 100644 --- a/src/providers/missav.rs +++ b/src/providers/missav.rs @@ -16,6 +16,12 @@ use htmlentity::entity::{ICodedDataTrait, decode}; use std::vec; use wreq::Version; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "asian-jav", + tags: &["jav", "asian", "uncensored"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/mod.rs b/src/providers/mod.rs index 7a54de1..568ebd0 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -9,7 +9,7 @@ use std::sync::Arc; use crate::{ DbPool, api::ClientVersion, - status::Channel, + status::{Channel, ChannelGroup, ChannelView, Status, StatusResponse}, util::{cache::VideoCache, discord::send_discord_error_report, requester::Requester}, videos::{ServerOptions, VideoItem}, }; @@ -62,6 +62,12 @@ pub mod xxdbx; // convenient alias pub type DynProvider = Arc; +#[derive(Clone, Copy)] +pub struct ProviderChannelMetadata { + pub group_id: &'static str, + pub tags: &'static [&'static str], +} + pub static ALL_PROVIDERS: Lazy> = Lazy::new(|| { let mut m = HashMap::default(); m.insert("all", Arc::new(all::AllProvider::new()) as DynProvider); @@ -326,6 +332,166 @@ pub fn build_proxy_url(options: &ServerOptions, proxy: &str, target: &str) -> St } } +fn channel_metadata_for(id: &str) -> Option { + match id { + "all" | "hottub" => Some(all::CHANNEL_METADATA), + "pornhub" => Some(pornhub::CHANNEL_METADATA), + "spankbang" => Some(spankbang::CHANNEL_METADATA), + "rule34video" => Some(rule34video::CHANNEL_METADATA), + "redtube" => Some(redtube::CHANNEL_METADATA), + "okporn" => Some(okporn::CHANNEL_METADATA), + "pornhat" => Some(pornhat::CHANNEL_METADATA), + "perfectgirls" => Some(perfectgirls::CHANNEL_METADATA), + "okxxx" => Some(okxxx::CHANNEL_METADATA), + "homoxxx" => Some(homoxxx::CHANNEL_METADATA), + "missav" => Some(missav::CHANNEL_METADATA), + "xxthots" => Some(xxthots::CHANNEL_METADATA), + "sxyprn" => Some(sxyprn::CHANNEL_METADATA), + "porn00" => Some(porn00::CHANNEL_METADATA), + "youjizz" => Some(youjizz::CHANNEL_METADATA), + "paradisehill" => Some(paradisehill::CHANNEL_METADATA), + "porn4fans" => Some(porn4fans::CHANNEL_METADATA), + "porndish" => Some(porndish::CHANNEL_METADATA), + "shooshtime" => Some(shooshtime::CHANNEL_METADATA), + "pornzog" => Some(pornzog::CHANNEL_METADATA), + "omgxxx" => Some(omgxxx::CHANNEL_METADATA), + "beeg" => Some(beeg::CHANNEL_METADATA), + "tnaflix" => Some(tnaflix::CHANNEL_METADATA), + "tokyomotion" => Some(tokyomotion::CHANNEL_METADATA), + "viralxxxporn" => Some(viralxxxporn::CHANNEL_METADATA), + "rule34gen" => Some(rule34gen::CHANNEL_METADATA), + "xxdbx" => Some(xxdbx::CHANNEL_METADATA), + "xfree" => Some(xfree::CHANNEL_METADATA), + "hqporner" => Some(hqporner::CHANNEL_METADATA), + "pmvhaven" => Some(pmvhaven::CHANNEL_METADATA), + "noodlemagazine" => Some(noodlemagazine::CHANNEL_METADATA), + "pimpbunny" => Some(pimpbunny::CHANNEL_METADATA), + "javtiful" => Some(javtiful::CHANNEL_METADATA), + "hypnotube" => Some(hypnotube::CHANNEL_METADATA), + "freepornvideosxxx" => Some(freepornvideosxxx::CHANNEL_METADATA), + "heavyfetish" => Some(heavyfetish::CHANNEL_METADATA), + "hsex" => Some(hsex::CHANNEL_METADATA), + "hentaihaven" => Some(hentaihaven::CHANNEL_METADATA), + "hanime" => Some(hanime::CHANNEL_METADATA), + "perverzija" => Some(perverzija::CHANNEL_METADATA), + "chaturbate" => Some(chaturbate::CHANNEL_METADATA), + _ => None, + } +} + +fn channel_group_title(group_id: &str) -> &'static str { + match group_id { + "meta-search" => "Meta Search", + "mainstream-tube" => "Mainstream Tube", + "studio-network" => "Studio & Network", + "amateur-homemade" => "Amateur & Homemade", + "creator-leaks" => "Creator & Leaks", + "asian-jav" => "Asian & JAV", + "fetish-kink" => "Fetish & Kink", + "hentai-animation" => "Hentai & Animation", + "gay-male" => "Gay & Male", + "live-cams" => "Live Cams", + "pmv-compilation" => "PMV & Compilation", + _ => "Other", + } +} + +fn channel_group_order(group_id: &str) -> usize { + match group_id { + "meta-search" => 0, + "mainstream-tube" => 1, + "studio-network" => 2, + "amateur-homemade" => 3, + "creator-leaks" => 4, + "asian-jav" => 5, + "fetish-kink" => 6, + "hentai-animation" => 7, + "gay-male" => 8, + "live-cams" => 9, + "pmv-compilation" => 10, + _ => 99, + } +} + +pub fn decorate_channel(channel: Channel) -> ChannelView { + let metadata = channel_metadata_for(&channel.id); + ChannelView { + id: channel.id, + name: channel.name, + description: channel.description, + premium: channel.premium, + favicon: channel.favicon, + status: channel.status, + categories: channel.categories, + options: channel.options, + nsfw: channel.nsfw, + group: metadata.map(|value| value.group_id.to_string()), + tags: metadata.map(|value| { + value + .tags + .iter() + .take(3) + .map(|tag| (*tag).to_string()) + .collect() + }), + cacheDuration: channel.cacheDuration, + } +} + +pub fn build_channel_groups(channels: &[ChannelView]) -> Vec { + let mut groups = Vec::new(); + + let mut group_ids = channels + .iter() + .filter_map(|channel| channel.group.clone()) + .collect::>(); + group_ids.sort_by_key(|group_id| (channel_group_order(group_id), group_id.clone())); + group_ids.dedup(); + + for group_id in group_ids { + let mut channel_ids = channels + .iter() + .filter(|channel| channel.group.as_deref() == Some(group_id.as_str())) + .map(|channel| channel.id.clone()) + .collect::>(); + channel_ids.sort(); + groups.push(ChannelGroup { + id: group_id.clone(), + title: channel_group_title(&group_id).to_string(), + channels: channel_ids, + }); + } + + groups +} + +pub fn build_status_response(status: Status) -> StatusResponse { + let channels = status + .channels + .into_iter() + .map(decorate_channel) + .collect::>(); + let channelGroups = build_channel_groups(&channels); + + StatusResponse { + id: status.id, + name: status.name, + subtitle: status.subtitle, + description: status.description, + iconUrl: status.iconUrl, + color: status.color, + status: status.status, + notices: status.notices, + channels, + channelGroups, + subscription: status.subscription, + nsfw: status.nsfw, + categories: status.categories, + options: status.options, + filtersFooter: status.filtersFooter, + } +} + #[async_trait] pub trait Provider: Send + Sync { async fn get_videos( @@ -359,3 +525,51 @@ pub trait Provider: Send + Sync { }) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::status::ChannelOption; + + fn base_channel(id: &str) -> Channel { + Channel { + id: id.to_string(), + name: id.to_string(), + description: String::new(), + premium: false, + favicon: String::new(), + status: "active".to_string(), + categories: vec![], + options: Vec::::new(), + nsfw: true, + cacheDuration: None, + } + } + + #[test] + fn decorates_channel_with_group_and_tags() { + let channel = decorate_channel(base_channel("hsex")); + assert_eq!(channel.group.as_deref(), Some("amateur-homemade")); + assert_eq!( + channel.tags.as_deref(), + Some(&[ + "amateur".to_string(), + "chinese".to_string(), + "homemade".to_string(), + ][..]) + ); + } + + #[test] + fn builds_group_index() { + let channels = vec![ + decorate_channel(base_channel("all")), + decorate_channel(base_channel("hsex")), + decorate_channel(base_channel("missav")), + ]; + let groups = build_channel_groups(&channels); + assert_eq!(groups[0].id, "meta-search"); + assert_eq!(groups[1].id, "amateur-homemade"); + assert_eq!(groups[2].id, "asian-jav"); + } +} diff --git a/src/providers/noodlemagazine.rs b/src/providers/noodlemagazine.rs index 031ce5b..30df8ec 100644 --- a/src/providers/noodlemagazine.rs +++ b/src/providers/noodlemagazine.rs @@ -14,6 +14,12 @@ use std::vec; use titlecase::Titlecase; use wreq::Version; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["search", "mixed", "user-upload"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/okporn.rs b/src/providers/okporn.rs index 5e45a22..5f0c8cc 100644 --- a/src/providers/okporn.rs +++ b/src/providers/okporn.rs @@ -14,6 +14,12 @@ use std::vec; use wreq::Client; use wreq_util::Emulation; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["tube", "hd", "mixed"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/okxxx.rs b/src/providers/okxxx.rs index ec55ef3..c3a77eb 100644 --- a/src/providers/okxxx.rs +++ b/src/providers/okxxx.rs @@ -15,6 +15,12 @@ use std::vec; use wreq::Client; use wreq_util::Emulation; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["tube", "mixed", "search"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/omgxxx.rs b/src/providers/omgxxx.rs index 181031b..982f663 100644 --- a/src/providers/omgxxx.rs +++ b/src/providers/omgxxx.rs @@ -14,6 +14,12 @@ use std::sync::{Arc, RwLock}; use std::thread; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "studio-network", + tags: &["studio", "networks", "models"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/paradisehill.rs b/src/providers/paradisehill.rs index 3bbc49c..909923a 100644 --- a/src/providers/paradisehill.rs +++ b/src/providers/paradisehill.rs @@ -10,6 +10,12 @@ use async_trait::async_trait; use error_chain::error_chain; use htmlentity::entity::{ICodedDataTrait, decode}; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["tube", "mixed", "movies"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/perfectgirls.rs b/src/providers/perfectgirls.rs index 565c584..2eb8b71 100644 --- a/src/providers/perfectgirls.rs +++ b/src/providers/perfectgirls.rs @@ -15,6 +15,12 @@ use std::vec; use wreq::Client; use wreq_util::Emulation; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "studio-network", + tags: &["glamour", "softcore", "solo"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/perverzija.rs b/src/providers/perverzija.rs index 528cfba..a4e017e 100644 --- a/src/providers/perverzija.rs +++ b/src/providers/perverzija.rs @@ -17,6 +17,12 @@ use wreq::Client; use wreq::Version; use wreq_util::Emulation; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "amateur-homemade", + tags: &["regional", "amateur", "mixed"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/pimpbunny.rs b/src/providers/pimpbunny.rs index 90602ba..01e5f47 100644 --- a/src/providers/pimpbunny.rs +++ b/src/providers/pimpbunny.rs @@ -18,6 +18,12 @@ use titlecase::Titlecase; use url::Url; use wreq::Version; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "creator-leaks", + tags: &["creator", "onlyfans", "amateur"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/pmvhaven.rs b/src/providers/pmvhaven.rs index 3b59cd2..5529c88 100644 --- a/src/providers/pmvhaven.rs +++ b/src/providers/pmvhaven.rs @@ -14,6 +14,12 @@ use std::sync::{Arc, RwLock}; use std::vec; use url::form_urlencoded::Serializer; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "pmv-compilation", + tags: &["pmv", "music", "compilation"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/porn00.rs b/src/providers/porn00.rs index 4b258bd..d9ca84c 100644 --- a/src/providers/porn00.rs +++ b/src/providers/porn00.rs @@ -11,6 +11,12 @@ use error_chain::error_chain; use htmlentity::entity::{ICodedDataTrait, decode}; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["tube", "hd", "mixed"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/porn4fans.rs b/src/providers/porn4fans.rs index f33916c..15b6ab7 100644 --- a/src/providers/porn4fans.rs +++ b/src/providers/porn4fans.rs @@ -14,6 +14,12 @@ use regex::Regex; use scraper::{Html, Selector}; use std::collections::HashSet; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "creator-leaks", + tags: &["creator", "premium", "clips"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/porndish.rs b/src/providers/porndish.rs index e8b6c46..6aa6c83 100644 --- a/src/providers/porndish.rs +++ b/src/providers/porndish.rs @@ -22,6 +22,12 @@ use std::thread; use std::time::{SystemTime, UNIX_EPOCH}; use url::Url; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "studio-network", + tags: &["mixed", "blog-style", "clips"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/pornhat.rs b/src/providers/pornhat.rs index 9149931..7b9f164 100644 --- a/src/providers/pornhat.rs +++ b/src/providers/pornhat.rs @@ -11,6 +11,12 @@ use error_chain::error_chain; use htmlentity::entity::{ICodedDataTrait, decode}; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["tube", "hd", "mixed"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/pornhub.rs b/src/providers/pornhub.rs index 5521e48..d433ebc 100644 --- a/src/providers/pornhub.rs +++ b/src/providers/pornhub.rs @@ -12,6 +12,12 @@ use error_chain::error_chain; use htmlentity::entity::{ICodedDataTrait, decode}; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["mainstream", "studio", "general"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/pornzog.rs b/src/providers/pornzog.rs index ac52f70..92def24 100644 --- a/src/providers/pornzog.rs +++ b/src/providers/pornzog.rs @@ -11,6 +11,12 @@ use error_chain::error_chain; use htmlentity::entity::{ICodedDataTrait, decode}; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["tube", "clips", "mixed"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/redtube.rs b/src/providers/redtube.rs index 90fec35..0e04f2a 100644 --- a/src/providers/redtube.rs +++ b/src/providers/redtube.rs @@ -12,6 +12,12 @@ use htmlentity::entity::{ICodedDataTrait, decode}; use serde_json::Value; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["mainstream", "legacy", "general"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/rule34gen.rs b/src/providers/rule34gen.rs index a6b2562..04239ab 100644 --- a/src/providers/rule34gen.rs +++ b/src/providers/rule34gen.rs @@ -11,6 +11,12 @@ use error_chain::error_chain; use htmlentity::entity::{ICodedDataTrait, decode}; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "hentai-animation", + tags: &["rule34", "ai-generated", "animation"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/rule34video.rs b/src/providers/rule34video.rs index 0d58abb..1bb33eb 100644 --- a/src/providers/rule34video.rs +++ b/src/providers/rule34video.rs @@ -13,6 +13,12 @@ use htmlentity::entity::{ICodedDataTrait, decode}; use std::time::{SystemTime, UNIX_EPOCH}; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "hentai-animation", + tags: &["rule34", "animation", "fandom"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/shooshtime.rs b/src/providers/shooshtime.rs index f8a57dd..462f836 100644 --- a/src/providers/shooshtime.rs +++ b/src/providers/shooshtime.rs @@ -17,6 +17,12 @@ use scraper::{ElementRef, Html, Selector}; use std::sync::{Arc, RwLock}; use std::{thread, vec}; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "creator-leaks", + tags: &["creator", "amateur", "clips"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/spankbang.rs b/src/providers/spankbang.rs index 1d210e8..1c1c93c 100644 --- a/src/providers/spankbang.rs +++ b/src/providers/spankbang.rs @@ -12,6 +12,12 @@ use htmlentity::entity::{ICodedDataTrait, decode}; use scraper::{ElementRef, Html, Selector}; use url::form_urlencoded::byte_serialize; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["mainstream", "mixed", "search"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/sxyprn.rs b/src/providers/sxyprn.rs index 7cc1b56..d981fa4 100644 --- a/src/providers/sxyprn.rs +++ b/src/providers/sxyprn.rs @@ -15,6 +15,12 @@ use htmlentity::entity::{ICodedDataTrait, decode}; use scraper::{Html, Selector}; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["tube", "community", "mixed"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/tnaflix.rs b/src/providers/tnaflix.rs index 1ec205e..ebc8eb6 100644 --- a/src/providers/tnaflix.rs +++ b/src/providers/tnaflix.rs @@ -12,6 +12,12 @@ use error_chain::error_chain; use htmlentity::entity::{ICodedDataTrait, decode}; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["mainstream", "legacy", "studio"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/tokyomotion.rs b/src/providers/tokyomotion.rs index 93836bb..2f45d61 100644 --- a/src/providers/tokyomotion.rs +++ b/src/providers/tokyomotion.rs @@ -12,6 +12,12 @@ use htmlentity::entity::{ICodedDataTrait, decode}; use regex::Regex; use url::form_urlencoded::Serializer; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "asian-jav", + tags: &["japanese", "amateur", "jav"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/viralxxxporn.rs b/src/providers/viralxxxporn.rs index 291fc5f..ccb94e9 100644 --- a/src/providers/viralxxxporn.rs +++ b/src/providers/viralxxxporn.rs @@ -12,6 +12,12 @@ use htmlentity::entity::{ICodedDataTrait, decode}; use regex::Regex; use std::collections::HashSet; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["tube", "viral", "mixed"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/xfree.rs b/src/providers/xfree.rs index 822614d..2d0801a 100644 --- a/src/providers/xfree.rs +++ b/src/providers/xfree.rs @@ -12,6 +12,12 @@ use std::sync::{Arc, RwLock}; use std::vec; use wreq::Version; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["tube", "mixed", "search"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/xxdbx.rs b/src/providers/xxdbx.rs index 656b4f4..2a14c1c 100644 --- a/src/providers/xxdbx.rs +++ b/src/providers/xxdbx.rs @@ -12,6 +12,12 @@ use regex::Regex; use std::sync::{Arc, RwLock}; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "creator-leaks", + tags: &["database", "clips", "mixed"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/xxthots.rs b/src/providers/xxthots.rs index c4d4f9a..b519302 100644 --- a/src/providers/xxthots.rs +++ b/src/providers/xxthots.rs @@ -11,6 +11,12 @@ use error_chain::error_chain; use htmlentity::entity::{ICodedDataTrait, decode}; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "creator-leaks", + tags: &["onlyfans", "leaks", "creator"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/providers/youjizz.rs b/src/providers/youjizz.rs index 29a08b3..9d3de74 100644 --- a/src/providers/youjizz.rs +++ b/src/providers/youjizz.rs @@ -11,6 +11,12 @@ use error_chain::error_chain; use htmlentity::entity::{ICodedDataTrait, decode}; use std::vec; +pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata = + crate::providers::ProviderChannelMetadata { + group_id: "mainstream-tube", + tags: &["mainstream", "mixed", "search"], + }; + error_chain! { foreign_links { Io(std::io::Error); diff --git a/src/status.rs b/src/status.rs index 9abf0c5..1c7ae28 100644 --- a/src/status.rs +++ b/src/status.rs @@ -22,6 +22,13 @@ pub struct Channel { pub cacheDuration: Option, //Some(86400) } +#[derive(serde::Serialize, Debug, Clone)] +pub struct ChannelGroup { + pub id: String, + pub title: String, + pub channels: Vec, +} + #[derive(serde::Serialize)] pub struct ChannelOption { pub id: String, //"channels", @@ -126,3 +133,41 @@ impl Status { self.categories.push(category); } } + +#[derive(serde::Serialize)] +pub struct ChannelView { + pub id: String, + pub name: String, + pub description: String, + pub premium: bool, + pub favicon: String, + pub status: String, + pub categories: Vec, + pub options: Vec, + pub nsfw: bool, + #[serde(skip_serializing_if = "Option::is_none")] + pub group: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub tags: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub cacheDuration: Option, +} + +#[derive(serde::Serialize)] +pub struct StatusResponse { + pub id: String, + pub name: String, + pub subtitle: String, + pub description: String, + pub iconUrl: String, + pub color: String, + pub status: String, + pub notices: Vec, + pub channels: Vec, + pub channelGroups: Vec, + pub subscription: Subscription, + pub nsfw: bool, + pub categories: Vec, + pub options: Vec, + pub filtersFooter: String, +}