status updated

This commit is contained in:
Simon
2026-03-21 19:15:35 +00:00
parent 75b7241803
commit cecc1f994b
2 changed files with 91 additions and 16 deletions

View File

@@ -50,9 +50,9 @@ pub mod youjizz;
pub mod chaturbate; pub mod chaturbate;
pub mod freepornvideosxxx; pub mod freepornvideosxxx;
pub mod heavyfetish; pub mod heavyfetish;
pub mod hsex;
pub mod hentaihaven; pub mod hentaihaven;
pub mod hqporner; pub mod hqporner;
pub mod hsex;
pub mod hypnotube; pub mod hypnotube;
pub mod javtiful; pub mod javtiful;
pub mod noodlemagazine; pub mod noodlemagazine;
@@ -437,7 +437,8 @@ pub fn decorate_channel(channel: Channel) -> ChannelView {
categories: channel.categories, categories: channel.categories,
options: channel.options, options: channel.options,
nsfw: channel.nsfw, nsfw: channel.nsfw,
group: metadata.map(|value| value.group_id.to_string()), groupKey: metadata.map(|value| value.group_id.to_string()),
sortOrder: None,
tags: metadata.map(|value| { tags: metadata.map(|value| {
value value
.tags .tags
@@ -455,34 +456,74 @@ pub fn build_channel_groups(channels: &[ChannelView]) -> Vec<ChannelGroup> {
let mut group_ids = channels let mut group_ids = channels
.iter() .iter()
.filter_map(|channel| channel.group.clone()) .filter_map(|channel| channel.groupKey.clone())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
group_ids.sort_by_key(|group_id| (channel_group_order(group_id), group_id.clone())); group_ids.sort_by_key(|group_id| (channel_group_order(group_id), group_id.clone()));
group_ids.dedup(); group_ids.dedup();
for group_id in group_ids { for group_id in group_ids {
let mut channel_ids = channels let mut grouped_channels = channels
.iter() .iter()
.filter(|channel| channel.group.as_deref() == Some(group_id.as_str())) .filter(|channel| channel.groupKey.as_deref() == Some(group_id.as_str()))
.collect::<Vec<_>>();
grouped_channels.sort_by(|a, b| {
(a.sortOrder.unwrap_or(u32::MAX), &a.name, &a.id).cmp(&(
b.sortOrder.unwrap_or(u32::MAX),
&b.name,
&b.id,
))
});
let channel_ids = grouped_channels
.into_iter()
.map(|channel| channel.id.clone()) .map(|channel| channel.id.clone())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
channel_ids.sort();
groups.push(ChannelGroup { groups.push(ChannelGroup {
id: group_id.clone(), id: group_id.clone(),
title: channel_group_title(&group_id).to_string(), title: channel_group_title(&group_id).to_string(),
channels: channel_ids, channelIds: channel_ids,
}); });
} }
groups groups
} }
fn assign_channel_sort_order(channels: &mut [ChannelView]) {
let mut ordered = channels
.iter()
.enumerate()
.map(|(index, channel)| {
(
index,
channel.groupKey.clone(),
channel.name.to_ascii_lowercase(),
channel.id.to_ascii_lowercase(),
)
})
.collect::<Vec<_>>();
ordered.sort_by(|a, b| {
let a_group = a.1.as_deref().unwrap_or("");
let b_group = b.1.as_deref().unwrap_or("");
(channel_group_order(a_group), a_group, &a.2, &a.3).cmp(&(
channel_group_order(b_group),
b_group,
&b.2,
&b.3,
))
});
for (sort_index, (channel_index, _, _, _)) in ordered.into_iter().enumerate() {
channels[channel_index].sortOrder = Some((sort_index + 1) as u32);
}
}
pub fn build_status_response(status: Status) -> StatusResponse { pub fn build_status_response(status: Status) -> StatusResponse {
let channels = status let mut channels = status
.channels .channels
.into_iter() .into_iter()
.map(decorate_channel) .map(decorate_channel)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assign_channel_sort_order(&mut channels);
let channelGroups = build_channel_groups(&channels); let channelGroups = build_channel_groups(&channels);
StatusResponse { StatusResponse {
@@ -561,14 +602,17 @@ mod tests {
#[test] #[test]
fn decorates_channel_with_group_and_tags() { fn decorates_channel_with_group_and_tags() {
let channel = decorate_channel(base_channel("hsex")); let channel = decorate_channel(base_channel("hsex"));
assert_eq!(channel.group.as_deref(), Some("amateur-homemade")); assert_eq!(channel.groupKey.as_deref(), Some("amateur-homemade"));
assert_eq!(channel.sortOrder, None);
assert_eq!( assert_eq!(
channel.tags.as_deref(), channel.tags.as_deref(),
Some(&[ Some(
"amateur".to_string(), &[
"chinese".to_string(), "amateur".to_string(),
"homemade".to_string(), "chinese".to_string(),
][..]) "homemade".to_string(),
][..]
)
); );
} }
@@ -584,4 +628,33 @@ mod tests {
assert_eq!(groups[1].id, "amateur-homemade"); assert_eq!(groups[1].id, "amateur-homemade");
assert_eq!(groups[2].id, "asian-jav"); assert_eq!(groups[2].id, "asian-jav");
} }
#[test]
fn status_response_uses_documented_group_keys() {
let mut status = Status::new();
status.channels = vec![
base_channel("missav"),
base_channel("hsex"),
base_channel("all"),
];
let json = serde_json::to_value(build_status_response(status)).expect("valid status json");
let channels = json["channels"].as_array().expect("channels array");
let all_channel = channels
.iter()
.find(|channel| channel["id"] == "all")
.expect("all channel present");
assert_eq!(all_channel["groupKey"], "meta-search");
assert!(all_channel.get("group").is_none());
assert!(all_channel["sortOrder"].is_number());
let groups = json["channelGroups"].as_array().expect("group array");
let meta_group = groups
.iter()
.find(|group| group["id"] == "meta-search")
.expect("meta group present");
assert_eq!(meta_group["channelIds"], serde_json::json!(["all"]));
assert!(meta_group.get("channels").is_none());
}
} }

View File

@@ -26,7 +26,7 @@ pub struct Channel {
pub struct ChannelGroup { pub struct ChannelGroup {
pub id: String, pub id: String,
pub title: String, pub title: String,
pub channels: Vec<String>, pub channelIds: Vec<String>,
} }
#[derive(serde::Serialize)] #[derive(serde::Serialize)]
@@ -146,7 +146,9 @@ pub struct ChannelView {
pub options: Vec<ChannelOption>, pub options: Vec<ChannelOption>,
pub nsfw: bool, pub nsfw: bool,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub group: Option<String>, pub groupKey: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sortOrder: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<Vec<String>>, pub tags: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]