diff --git a/Cargo.lock b/Cargo.lock index 23d38ca62..0d8bb0378 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1156,7 +1156,7 @@ dependencies = [ [[package]] name = "frontend" -version = "3.2.39" +version = "3.2.40" dependencies = [ "anyhow", "base64", @@ -3983,7 +3983,7 @@ dependencies = [ [[package]] name = "shared" -version = "3.2.39" +version = "3.2.40" dependencies = [ "base64", "bitflags 2.10.0", @@ -4557,7 +4557,7 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tuliprox" -version = "3.2.39" +version = "3.2.40" dependencies = [ "arc-swap", "async-compression", diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 66e32f00e..7059cdff0 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tuliprox" -version = "3.2.39" +version = "3.2.40" edition = "2021" rust-version = "1.89.0" diff --git a/backend/src/api/endpoints/xtream_api.rs b/backend/src/api/endpoints/xtream_api.rs index 3543123a2..e7308cd72 100644 --- a/backend/src/api/endpoints/xtream_api.rs +++ b/backend/src/api/endpoints/xtream_api.rs @@ -353,7 +353,7 @@ async fn xtream_player_api_stream( return response.into_response(); } - let (query_path, extension) = get_query_path(stream_req.action_path, stream_ext.as_ref(), &pli); + let (query_path, extension) = get_query_path(stream_req.action_path, stream_ext.as_ref(), &pli, app_state); let stream_url = try_option_bad_request!( get_xtream_player_api_stream_url(&input, stream_req.context, &query_path, session_url), @@ -402,11 +402,12 @@ async fn xtream_player_api_stream( .into_response() } -fn get_query_path(action_path: &str, stream_ext: Option<&String>, pli: &XtreamPlaylistItem) -> (String, String) { - let provider_id = pli.provider_id.to_string(); +fn get_query_path(action_path: &str, stream_ext: Option<&String>, pli: &XtreamPlaylistItem, app_state: &Arc) -> (String, String) { + + let discard_extension = pli.item_type.is_live() && app_state.app_config.sources.load().get_input_by_name(&pli.input_name).as_ref().and_then(|i| i.options.as_ref()).is_some_and(|o| o.xtream_live_stream_without_extension); let extracted_ext; - let extension: &str = if pli.item_type.is_live() { + let extension: &str = if discard_extension { "" } else if let Some(ext) = stream_ext { ext @@ -415,6 +416,8 @@ fn get_query_path(action_path: &str, stream_ext: Option<&String>, pli: &XtreamPl extracted_ext.unwrap_or("") }; + let provider_id = pli.provider_id.to_string(); + let query_path = if action_path.is_empty() { concat_string!(&provider_id, extension) } else { @@ -522,7 +525,7 @@ async fn xtream_player_api_stream_with_token( .into_response(); } - let (query_path, _extension) = get_query_path(stream_req.action_path, stream_ext.as_ref(), &pli); + let (query_path, _extension) = get_query_path(stream_req.action_path, stream_ext.as_ref(), &pli, app_state); let stream_url = try_option_bad_request!( get_xtream_player_api_stream_url( diff --git a/backend/src/processing/processor/sort.rs b/backend/src/processing/processor/sort.rs index c837ff678..e5c84e517 100644 --- a/backend/src/processing/processor/sort.rs +++ b/backend/src/processing/processor/sort.rs @@ -5,8 +5,7 @@ use std::cmp::Ordering; fn direction(order: SortOrder, ordering: Ordering) -> Ordering { match (order, ordering) { - (SortOrder::None, _) - | (_, Ordering::Equal) => Ordering::Equal, + (SortOrder::None, _) | (_, Ordering::Equal) => Ordering::Equal, (SortOrder::Asc, o) => o, (SortOrder::Desc, o) => o.reverse(), } @@ -108,7 +107,10 @@ fn playlist_comparator( } } -pub(in crate::processing::processor) fn sort_playlist(target: &ConfigTarget, playlist: &mut [PlaylistGroup]) -> bool { +pub(in crate::processing::processor) fn sort_playlist( + target: &ConfigTarget, + playlist: &mut [PlaylistGroup], +) -> bool { let Some(sort) = &target.sort else { return false; }; @@ -121,11 +123,7 @@ pub(in crate::processing::processor) fn sort_playlist(target: &ConfigTarget, pla true } -fn sort_groups( - groups: &mut [PlaylistGroup], - rules: &[ConfigSortRule], - match_as_ascii: bool, -) { +fn sort_groups(groups: &mut [PlaylistGroup], rules: &[ConfigSortRule], match_as_ascii: bool) { let group_rules: Vec<_> = rules .iter() .filter(|r| matches!(r.target, SortTarget::Group)) @@ -147,14 +145,24 @@ fn sort_groups( (Some(a), Some(b)) => (a, b), }; - let provider_a = ValueProvider { pli: a_chan, match_as_ascii }; - let provider_b = ValueProvider { pli: b_chan, match_as_ascii }; + let provider_a = ValueProvider { + pli: a_chan, + match_as_ascii, + }; + let provider_b = ValueProvider { + pli: b_chan, + match_as_ascii, + }; - match (rule.filter.filter(&provider_a), rule.filter.filter(&provider_b)) { - (false, false) => return Ordering::Equal, - (true, false) => return direction(rule.order, Ordering::Less), - (false, true) => return direction(rule.order, Ordering::Greater), + match ( + rule.filter.filter(&provider_a), + rule.filter.filter(&provider_b), + ) { + // (false, false) => return Ordering::Equal, + // (true, false) => return direction(rule.order, Ordering::Less), + // (false, true) => return direction(rule.order, Ordering::Greater), (true, true) => { /* fallthrough */ } + _ => return Ordering::Equal, } let va = provider_a.get(rule.field.as_str()); @@ -164,12 +172,7 @@ fn sort_groups( (Some(_), None) => return direction(rule.order, Ordering::Less), (None, Some(_)) => return direction(rule.order, Ordering::Greater), (Some(va), Some(vb)) => { - let ord = playlist_comparator( - rule.sequence.as_ref(), - rule.order, - &va, - &vb, - ); + let ord = playlist_comparator(rule.sequence.as_ref(), rule.order, &va, &vb); if ord != Ordering::Equal { return ord; @@ -198,42 +201,44 @@ fn sort_channels_in_groups( for rule in channel_rules { for group in &mut *groups { if rule.order == SortOrder::None { - group.channels.sort_by(|a, b| - a.header.source_ordinal.cmp(&b.header.source_ordinal)); - } else { - group.channels.sort_by(|a, b| { - let provider_a = ValueProvider { pli: a, match_as_ascii }; - let provider_b = ValueProvider { pli: b, match_as_ascii }; - - match (rule.filter.filter(&provider_a), rule.filter.filter(&provider_b)) { - (false, false) => return Ordering::Equal, - (true, false) => return direction(rule.order, Ordering::Less), - (false, true) => return direction(rule.order, Ordering::Greater), - (true, true) => { /* fallthrough */ } - } - - let va = provider_a.get(rule.field.as_str()); - let vb = provider_b.get(rule.field.as_str()); - match (va, vb) { - (None, None) => Ordering::Equal, - (Some(_), None) => direction(rule.order, Ordering::Less), - (None, Some(_)) => direction(rule.order, Ordering::Greater), - (Some(va), Some(vb)) => { - playlist_comparator( - rule.sequence.as_ref(), - rule.order, - &va, - &vb, - ) - } - } - }); + continue; } + group.channels.sort_by(|a, b| { + let provider_a = ValueProvider { + pli: a, + match_as_ascii, + }; + let provider_b = ValueProvider { + pli: b, + match_as_ascii, + }; + + match ( + rule.filter.filter(&provider_a), + rule.filter.filter(&provider_b), + ) { + // (false, false) => return Ordering::Equal, + // (true, false) => return direction(rule.order, Ordering::Less), + // (false, true) => return direction(rule.order, Ordering::Greater), + (true, true) => { /* fallthrough */ } + _ => return Ordering::Equal, + } + + let va = provider_a.get(rule.field.as_str()); + let vb = provider_b.get(rule.field.as_str()); + match (va, vb) { + (None, None) => Ordering::Equal, + (Some(_), None) => direction(rule.order, Ordering::Less), + (None, Some(_)) => direction(rule.order, Ordering::Greater), + (Some(va), Some(vb)) => { + playlist_comparator(rule.sequence.as_ref(), rule.order, &va, &vb) + } + } + }); } } } - #[cfg(test)] mod tests { use crate::model::ConfigSortRule; @@ -246,19 +251,29 @@ mod tests { #[test] fn test_sort() { let mut channels: Vec = vec![ - ("D", "HD"), ("A", "FHD"), ("Z", "HD"), ("K", "HD"), ("B", "HD"), ("A", "HD"), - ("K", "UHD"), ("C", "HD"), ("L", "FHD"), ("R", "UHD"), ("T", "SD"), ("A", "FHD"), + ("D", "HD"), + ("A", "FHD"), + ("Z", "HD"), + ("K", "HD"), + ("B", "HD"), + ("A", "HD"), + ("K", "UHD"), + ("C", "HD"), + ("L", "FHD"), + ("R", "UHD"), + ("T", "SD"), + ("A", "FHD"), ] - .into_iter() - .enumerate() - .map(|(i, (name, quality))| PlaylistItem { - header: PlaylistItemHeader { - title: format!("Chanel {name} [{quality}]"), - source_ordinal: i as u32, - ..Default::default() - }, - }) - .collect(); + .into_iter() + .enumerate() + .map(|(i, (name, quality))| PlaylistItem { + header: PlaylistItemHeader { + title: format!("Chanel {name} [{quality}]"), + source_ordinal: i as u32, + ..Default::default() + }, + }) + .collect(); let channel_sort = ConfigSortRule { target: SortTarget::Channel, @@ -276,12 +291,8 @@ mod tests { let va = &a.header.title; let vb = &b.header.title; - let ord = playlist_comparator( - channel_sort.sequence.as_ref(), - channel_sort.order, - va, - vb, - ); + let ord = + playlist_comparator(channel_sort.sequence.as_ref(), channel_sort.order, va, vb); if ord != Ordering::Equal { ord @@ -341,16 +352,16 @@ mod tests { "US| West e", "US| West f", ] - .into_iter() - .enumerate() - .map(|(i, name)| PlaylistItem { - header: PlaylistItemHeader { - title: name.to_string(), - source_ordinal: i as u32, - ..Default::default() - }, - }) - .collect(); + .into_iter() + .enumerate() + .map(|(i, name)| PlaylistItem { + header: PlaylistItemHeader { + title: name.to_string(), + source_ordinal: i as u32, + ..Default::default() + }, + }) + .collect(); let channel_sort = ConfigSortRule { target: SortTarget::Channel, diff --git a/frontend/Cargo.toml b/frontend/Cargo.toml index 0ddb807c1..fb4726151 100644 --- a/frontend/Cargo.toml +++ b/frontend/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "frontend" -version = "3.2.39" +version = "3.2.40" edition = "2021" rust-version = "1.89.0" [dependencies] -shared = { version = "3.2.39", path = "../shared" } +shared = { version = "3.2.40", path = "../shared" } chrono = "0" yew = "0.21" yew-router = "0.18" diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 31bc6f658..565b84537 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shared" -version = "3.2.39" +version = "3.2.40" edition = "2021" rust-version = "1.89.0"