status upgrade

This commit is contained in:
Simon
2026-03-18 12:13:28 +00:00
parent ce781e2099
commit ce1afd9873
44 changed files with 508 additions and 3 deletions

View File

@@ -1,5 +1,5 @@
use crate::providers::{ 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, run_provider_guarded,
}; };
use crate::util::cache::VideoCache; use crate::util::cache::VideoCache;
@@ -188,7 +188,7 @@ async fn status(req: HttpRequest) -> Result<impl web::Responder, web::Error> {
} }
} }
status.iconUrl = format!("{}/favicon.ico", public_url_base).to_string(); 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( async fn videos_post(

View File

@@ -14,6 +14,12 @@ use futures::stream::FuturesUnordered;
use std::fs; use std::fs;
use std::time::Duration; 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! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -14,6 +14,12 @@ use std::thread;
use std::time::Duration; use std::time::Duration;
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["mainstream", "clips", "mixed"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -8,6 +8,12 @@ use async_trait::async_trait;
use error_chain::error_chain; use error_chain::error_chain;
use htmlentity::entity::{ICodedDataTrait, decode}; 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! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -13,6 +13,12 @@ use std::sync::{Arc, RwLock};
use std::thread; use std::thread;
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "studio-network",
tags: &["tube", "networked", "mixed"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -12,6 +12,12 @@ use crate::status::*;
use crate::util::cache::VideoCache; use crate::util::cache::VideoCache;
use crate::videos::{self, ServerOptions, VideoItem}; 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! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -19,6 +19,12 @@ use std::collections::HashMap;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use std::{thread, vec}; use std::{thread, vec};
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "fetish-kink",
tags: &["fetish", "bdsm", "niche"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -16,6 +16,12 @@ use std::vec;
use titlecase::Titlecase; use titlecase::Titlecase;
use wreq::Version; use wreq::Version;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "hentai-animation",
tags: &["hentai", "anime", "curated"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -14,6 +14,12 @@ use std::vec;
use wreq::Client; use wreq::Client;
use wreq_util::Emulation; use wreq_util::Emulation;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "gay-male",
tags: &["gay", "male", "tube"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -15,6 +15,12 @@ use std::sync::{Arc, RwLock};
use std::{thread, vec}; use std::{thread, vec};
use titlecase::Titlecase; use titlecase::Titlecase;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "studio-network",
tags: &["studio", "hd", "scenes"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -21,6 +21,12 @@ use std::{thread, vec};
use url::Url; use url::Url;
use wreq::Version; use wreq::Version;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "amateur-homemade",
tags: &["amateur", "chinese", "homemade"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -16,6 +16,12 @@ use std::{thread, vec};
use titlecase::Titlecase; use titlecase::Titlecase;
use wreq::Version; use wreq::Version;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "fetish-kink",
tags: &["hypnosis", "fetish", "sissy"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -17,6 +17,12 @@ use std::vec;
use titlecase::Titlecase; use titlecase::Titlecase;
use wreq::Version; use wreq::Version;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "asian-jav",
tags: &["jav", "asian", "streaming"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -16,6 +16,12 @@ use htmlentity::entity::{ICodedDataTrait, decode};
use std::vec; use std::vec;
use wreq::Version; use wreq::Version;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "asian-jav",
tags: &["jav", "asian", "uncensored"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -9,7 +9,7 @@ use std::sync::Arc;
use crate::{ use crate::{
DbPool, DbPool,
api::ClientVersion, api::ClientVersion,
status::Channel, status::{Channel, ChannelGroup, ChannelView, Status, StatusResponse},
util::{cache::VideoCache, discord::send_discord_error_report, requester::Requester}, util::{cache::VideoCache, discord::send_discord_error_report, requester::Requester},
videos::{ServerOptions, VideoItem}, videos::{ServerOptions, VideoItem},
}; };
@@ -62,6 +62,12 @@ pub mod xxdbx;
// convenient alias // convenient alias
pub type DynProvider = Arc<dyn Provider>; pub type DynProvider = Arc<dyn Provider>;
#[derive(Clone, Copy)]
pub struct ProviderChannelMetadata {
pub group_id: &'static str,
pub tags: &'static [&'static str],
}
pub static ALL_PROVIDERS: Lazy<HashMap<&'static str, DynProvider>> = Lazy::new(|| { pub static ALL_PROVIDERS: Lazy<HashMap<&'static str, DynProvider>> = Lazy::new(|| {
let mut m = HashMap::default(); let mut m = HashMap::default();
m.insert("all", Arc::new(all::AllProvider::new()) as DynProvider); 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<ProviderChannelMetadata> {
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<ChannelGroup> {
let mut groups = Vec::new();
let mut group_ids = channels
.iter()
.filter_map(|channel| channel.group.clone())
.collect::<Vec<_>>();
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::<Vec<_>>();
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::<Vec<_>>();
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] #[async_trait]
pub trait Provider: Send + Sync { pub trait Provider: Send + Sync {
async fn get_videos( 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::<ChannelOption>::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");
}
}

View File

@@ -14,6 +14,12 @@ use std::vec;
use titlecase::Titlecase; use titlecase::Titlecase;
use wreq::Version; use wreq::Version;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["search", "mixed", "user-upload"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -14,6 +14,12 @@ use std::vec;
use wreq::Client; use wreq::Client;
use wreq_util::Emulation; use wreq_util::Emulation;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["tube", "hd", "mixed"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -15,6 +15,12 @@ use std::vec;
use wreq::Client; use wreq::Client;
use wreq_util::Emulation; use wreq_util::Emulation;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["tube", "mixed", "search"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -14,6 +14,12 @@ use std::sync::{Arc, RwLock};
use std::thread; use std::thread;
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "studio-network",
tags: &["studio", "networks", "models"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -10,6 +10,12 @@ use async_trait::async_trait;
use error_chain::error_chain; use error_chain::error_chain;
use htmlentity::entity::{ICodedDataTrait, decode}; 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! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -15,6 +15,12 @@ use std::vec;
use wreq::Client; use wreq::Client;
use wreq_util::Emulation; use wreq_util::Emulation;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "studio-network",
tags: &["glamour", "softcore", "solo"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -17,6 +17,12 @@ use wreq::Client;
use wreq::Version; use wreq::Version;
use wreq_util::Emulation; use wreq_util::Emulation;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "amateur-homemade",
tags: &["regional", "amateur", "mixed"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -18,6 +18,12 @@ use titlecase::Titlecase;
use url::Url; use url::Url;
use wreq::Version; use wreq::Version;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "creator-leaks",
tags: &["creator", "onlyfans", "amateur"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -14,6 +14,12 @@ use std::sync::{Arc, RwLock};
use std::vec; use std::vec;
use url::form_urlencoded::Serializer; 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! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -11,6 +11,12 @@ use error_chain::error_chain;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["tube", "hd", "mixed"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -14,6 +14,12 @@ use regex::Regex;
use scraper::{Html, Selector}; use scraper::{Html, Selector};
use std::collections::HashSet; use std::collections::HashSet;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "creator-leaks",
tags: &["creator", "premium", "clips"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -22,6 +22,12 @@ use std::thread;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use url::Url; use url::Url;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "studio-network",
tags: &["mixed", "blog-style", "clips"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -11,6 +11,12 @@ use error_chain::error_chain;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["tube", "hd", "mixed"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -12,6 +12,12 @@ use error_chain::error_chain;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["mainstream", "studio", "general"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -11,6 +11,12 @@ use error_chain::error_chain;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["tube", "clips", "mixed"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -12,6 +12,12 @@ use htmlentity::entity::{ICodedDataTrait, decode};
use serde_json::Value; use serde_json::Value;
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["mainstream", "legacy", "general"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -11,6 +11,12 @@ use error_chain::error_chain;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "hentai-animation",
tags: &["rule34", "ai-generated", "animation"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -13,6 +13,12 @@ use htmlentity::entity::{ICodedDataTrait, decode};
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "hentai-animation",
tags: &["rule34", "animation", "fandom"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -17,6 +17,12 @@ use scraper::{ElementRef, Html, Selector};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use std::{thread, vec}; use std::{thread, vec};
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "creator-leaks",
tags: &["creator", "amateur", "clips"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -12,6 +12,12 @@ use htmlentity::entity::{ICodedDataTrait, decode};
use scraper::{ElementRef, Html, Selector}; use scraper::{ElementRef, Html, Selector};
use url::form_urlencoded::byte_serialize; 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! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -15,6 +15,12 @@ use htmlentity::entity::{ICodedDataTrait, decode};
use scraper::{Html, Selector}; use scraper::{Html, Selector};
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["tube", "community", "mixed"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -12,6 +12,12 @@ use error_chain::error_chain;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["mainstream", "legacy", "studio"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -12,6 +12,12 @@ use htmlentity::entity::{ICodedDataTrait, decode};
use regex::Regex; use regex::Regex;
use url::form_urlencoded::Serializer; 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! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -12,6 +12,12 @@ use htmlentity::entity::{ICodedDataTrait, decode};
use regex::Regex; use regex::Regex;
use std::collections::HashSet; use std::collections::HashSet;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["tube", "viral", "mixed"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -12,6 +12,12 @@ use std::sync::{Arc, RwLock};
use std::vec; use std::vec;
use wreq::Version; use wreq::Version;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["tube", "mixed", "search"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -12,6 +12,12 @@ use regex::Regex;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "creator-leaks",
tags: &["database", "clips", "mixed"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -11,6 +11,12 @@ use error_chain::error_chain;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "creator-leaks",
tags: &["onlyfans", "leaks", "creator"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -11,6 +11,12 @@ use error_chain::error_chain;
use htmlentity::entity::{ICodedDataTrait, decode}; use htmlentity::entity::{ICodedDataTrait, decode};
use std::vec; use std::vec;
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
crate::providers::ProviderChannelMetadata {
group_id: "mainstream-tube",
tags: &["mainstream", "mixed", "search"],
};
error_chain! { error_chain! {
foreign_links { foreign_links {
Io(std::io::Error); Io(std::io::Error);

View File

@@ -22,6 +22,13 @@ pub struct Channel {
pub cacheDuration: Option<u32>, //Some(86400) pub cacheDuration: Option<u32>, //Some(86400)
} }
#[derive(serde::Serialize, Debug, Clone)]
pub struct ChannelGroup {
pub id: String,
pub title: String,
pub channels: Vec<String>,
}
#[derive(serde::Serialize)] #[derive(serde::Serialize)]
pub struct ChannelOption { pub struct ChannelOption {
pub id: String, //"channels", pub id: String, //"channels",
@@ -126,3 +133,41 @@ impl Status {
self.categories.push(category); 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<String>,
pub options: Vec<ChannelOption>,
pub nsfw: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub group: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cacheDuration: Option<u32>,
}
#[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<Notice>,
pub channels: Vec<ChannelView>,
pub channelGroups: Vec<ChannelGroup>,
pub subscription: Subscription,
pub nsfw: bool,
pub categories: Vec<String>,
pub options: Vec<Options>,
pub filtersFooter: String,
}