status upgrade
This commit is contained in:
@@ -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(
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user