mirror of
https://github.com/euzu/tuliprox.git
synced 2026-10-04 23:12:27 +02:00
@@ -27,9 +27,8 @@ use crate::processing::processor::sort::sort_playlist;
|
||||
use crate::processing::processor::trakt::process_trakt_categories_for_target;
|
||||
use crate::processing::processor::xtream_series::playlist_resolve_series;
|
||||
use crate::processing::processor::xtream_vod::playlist_resolve_vod;
|
||||
use crate::repository::playlist_repository::{load_input_playlist, persist_input_playlist, persist_playlist};
|
||||
use crate::repository::xtream_repository::CategoryKey;
|
||||
use crate::repository::{MemoryPlaylistSource, PlaylistSource};
|
||||
use crate::repository::{load_input_playlist, persist_input_playlist, persist_playlist};
|
||||
use crate::repository::{CategoryKey, MemoryPlaylistSource, PlaylistSource};
|
||||
use crate::utils::StepMeasure;
|
||||
use crate::utils::{debug_if_enabled, trace_if_enabled};
|
||||
use futures::StreamExt;
|
||||
|
||||
@@ -45,7 +45,6 @@ fn playlist_comparator(
|
||||
|
||||
match (match_a, match_b) {
|
||||
(Some((idx_a, caps_a)), Some((idx_b, caps_b))) => {
|
||||
// Different regex indices → sort by their sequence order.
|
||||
if idx_a != idx_b {
|
||||
return match order {
|
||||
SortOrder::Asc => idx_a.cmp(&idx_b),
|
||||
@@ -66,15 +65,19 @@ fn playlist_comparator(
|
||||
for name in named {
|
||||
let va = caps_a.name(name).map(|m| m.as_str());
|
||||
let vb = caps_b.name(name).map(|m| m.as_str());
|
||||
if let (Some(va), Some(vb)) = (va, vb) {
|
||||
let o = va.cmp(vb);
|
||||
if !matches!(o, Ordering::Equal) {
|
||||
return match order {
|
||||
SortOrder::Asc => o,
|
||||
SortOrder::Desc => o.reverse(),
|
||||
SortOrder::None => Ordering::Equal,
|
||||
};
|
||||
}
|
||||
let o = match (va, vb) {
|
||||
(Some(a), Some(b)) => a.cmp(b),
|
||||
(Some(_), None) => Ordering::Greater,
|
||||
(None, Some(_)) => Ordering::Less,
|
||||
_ => Ordering::Equal,
|
||||
};
|
||||
|
||||
if o != Ordering::Equal {
|
||||
return match order {
|
||||
SortOrder::Asc => o,
|
||||
SortOrder::Desc => o.reverse(),
|
||||
SortOrder::None => Ordering::Equal,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,15 +208,24 @@ fn sort_channels_in_groups(
|
||||
let va = vp_a.get(rule.field.as_str());
|
||||
let vb = vp_b.get(rule.field.as_str());
|
||||
|
||||
let ord = match (va, vb) {
|
||||
let ord = 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)
|
||||
playlist_comparator(rule.sequence.as_ref(), rule.order, va, vb)
|
||||
}
|
||||
};
|
||||
|
||||
if ord == Ordering::Equal {
|
||||
if let (Some(va), Some(vb)) = (&va, &vb) {
|
||||
let fallback = direction(rule.order, va.cmp(vb));
|
||||
if fallback != Ordering::Equal {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ord != Ordering::Equal {
|
||||
return ord;
|
||||
}
|
||||
|
||||
@@ -4,12 +4,20 @@ use crate::model::{ConfigInput, InputSource};
|
||||
use shared::model::{PlaylistEntry, PlaylistItem, XtreamCluster};
|
||||
use crate::utils::xtream;
|
||||
|
||||
pub(in crate::processing) async fn playlist_resolve_download_playlist_item(client: &reqwest::Client, pli: &PlaylistItem, input: &ConfigInput, errors: &mut Vec<TuliproxError>, resolve_delay: u16, cluster: XtreamCluster) -> Option<String> {
|
||||
pub(in crate::processing) async fn playlist_resolve_download_playlist_item(
|
||||
client: &reqwest::Client,
|
||||
pli: &PlaylistItem,
|
||||
input: &ConfigInput,
|
||||
errors: &mut Vec<TuliproxError>,
|
||||
resolve_delay: u16,
|
||||
cluster: XtreamCluster,
|
||||
default_user_agent: Option<&str>,
|
||||
) -> Option<String> {
|
||||
let mut result = None;
|
||||
let provider_id = pli.get_provider_id()?;
|
||||
if let Some(info_url) = xtream::get_xtream_player_api_info_url(input, cluster, provider_id) {
|
||||
let input_source = InputSource::from(input).with_url(info_url);
|
||||
result = match xtream::get_xtream_stream_info_content(client, &input_source, true).await {
|
||||
result = match xtream::get_xtream_stream_info_content(client, &input_source, true, default_user_agent).await {
|
||||
Ok(content) => Some(content),
|
||||
Err(err) => {
|
||||
errors.push(info_err!("{err}"));
|
||||
|
||||
@@ -4,9 +4,7 @@ use crate::processing::parser::xtream::parse_xtream_series_info;
|
||||
use crate::processing::processor::create_resolve_options_function_for_xtream_target;
|
||||
use crate::processing::processor::playlist::ProcessingPipe;
|
||||
use crate::processing::processor::xtream::playlist_resolve_download_playlist_item;
|
||||
use crate::repository::storage::get_input_storage_path;
|
||||
use crate::repository::xtream_repository::persist_input_series_info_batch;
|
||||
use crate::repository::{MemoryPlaylistSource, PlaylistSource};
|
||||
use crate::repository::{get_input_storage_path, persist_input_series_info_batch, MemoryPlaylistSource, PlaylistSource};
|
||||
use log::{error, info, log_enabled, Level};
|
||||
use shared::error::TuliproxError;
|
||||
use shared::model::{InputType, PlaylistEntry, SeriesStreamProperties, StreamProperties, XtreamSeriesInfo};
|
||||
@@ -50,6 +48,7 @@ async fn playlist_resolve_series_info(app_config: &Arc<AppConfig>, client: &reqw
|
||||
let mut processed_series_info_count = 0;
|
||||
let mut group_series: HashMap<u32, PlaylistGroup> = HashMap::new();
|
||||
let mut batch = Vec::with_capacity(BATCH_SIZE);
|
||||
let default_user_agent = app_config.config.load().default_user_agent.clone();
|
||||
|
||||
let input = fpl.input;
|
||||
for pli in fpl.items_mut() {
|
||||
@@ -66,7 +65,17 @@ async fn playlist_resolve_series_info(app_config: &Arc<AppConfig>, client: &reqw
|
||||
let should_download = resolve_series && !pli.has_details();
|
||||
if should_download {
|
||||
processed_series_info_count += 1;
|
||||
if let Some(content) = playlist_resolve_download_playlist_item(client, pli, input, errors, resolve_delay, XtreamCluster::Series).await {
|
||||
if let Some(content) = playlist_resolve_download_playlist_item(
|
||||
client,
|
||||
pli,
|
||||
input,
|
||||
errors,
|
||||
resolve_delay,
|
||||
XtreamCluster::Series,
|
||||
default_user_agent.as_deref(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
if !content.is_empty() {
|
||||
match serde_json::from_str::<XtreamSeriesInfo>(&content) {
|
||||
Ok(info) => {
|
||||
|
||||
@@ -2,8 +2,8 @@ use crate::model::FetchedPlaylist;
|
||||
use crate::model::{AppConfig, ConfigTarget};
|
||||
use crate::processing::processor::create_resolve_options_function_for_xtream_target;
|
||||
use crate::processing::processor::xtream::playlist_resolve_download_playlist_item;
|
||||
use crate::repository::storage::get_input_storage_path;
|
||||
use crate::repository::xtream_repository::persist_input_vod_info_batch;
|
||||
use crate::repository::get_input_storage_path;
|
||||
use crate::repository::persist_input_vod_info_batch;
|
||||
use log::{error, info, log_enabled, Level};
|
||||
use shared::error::TuliproxError;
|
||||
use shared::model::{InputType, PlaylistEntry, StreamProperties, VideoStreamProperties, XtreamVideoInfo};
|
||||
@@ -41,6 +41,7 @@ pub async fn playlist_resolve_vod(app_config: &Arc<AppConfig>,
|
||||
let mut last_log_time = Instant::now();
|
||||
let mut processed_vod_info_count = 0;
|
||||
let mut batch = Vec::with_capacity(BATCH_SIZE);
|
||||
let default_user_agent = app_config.config.load().default_user_agent.clone();
|
||||
|
||||
provider_fpl.source.release_resources(XtreamCluster::Video);
|
||||
|
||||
@@ -54,7 +55,17 @@ pub async fn playlist_resolve_vod(app_config: &Arc<AppConfig>,
|
||||
let Some(provider_id) = pli.get_provider_id() else { continue; };
|
||||
processed_vod_info_count += 1;
|
||||
if provider_id != 0 {
|
||||
if let Some(content) = playlist_resolve_download_playlist_item(client, pli, input, errors, resolve_delay, XtreamCluster::Video).await {
|
||||
if let Some(content) = playlist_resolve_download_playlist_item(
|
||||
client,
|
||||
pli,
|
||||
input,
|
||||
errors,
|
||||
resolve_delay,
|
||||
XtreamCluster::Video,
|
||||
default_user_agent.as_deref(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
if content.is_empty() { continue; }
|
||||
match serde_json::from_str::<XtreamVideoInfo>(&content) {
|
||||
Ok(info) => {
|
||||
|
||||
Reference in New Issue
Block a user