mirror of
https://github.com/euzu/tuliprox.git
synced 2026-10-08 00:42:32 +02:00
Merge branch 'bugfi/m3u_missing_id' into bugfix/multi_xtream_input
# Conflicts: # src/api/v1_api.rs # src/api/xmltv_api.rs # src/api/xtream_api.rs # src/main.rs # src/processing/playlist_processor.rs # src/repository/xtream_repository.rs # src/util/config_reader.rs # src/util/utils.rs # src/utils.rs # src/utils/request_utils.rs
This commit is contained in:
@@ -4,6 +4,7 @@ use std::rc::Rc;
|
||||
use crate::model::config::Config;
|
||||
use crate::model::model_config::default_as_empty_rc_str;
|
||||
use crate::model::model_playlist::{default_playlist_item_type, default_stream_cluster, PlaylistGroup, PlaylistItem, PlaylistItemHeader, PlaylistItemType, XtreamCluster};
|
||||
use crate::utils::string_utils;
|
||||
|
||||
fn token_value(it: &mut std::str::Chars) -> String {
|
||||
if let Some(oc) = it.next() {
|
||||
@@ -117,8 +118,10 @@ fn process_header(video_suffixes: &Vec<&str>, content: &String, url: String) ->
|
||||
}
|
||||
c = it.next();
|
||||
}
|
||||
if plih.group.is_empty() {
|
||||
plih.group = Rc::new(String::from("Unknown"));
|
||||
if plih.id.is_empty() {
|
||||
if let Some(chanid) = extract_id_from_url(url.as_str()) {
|
||||
plih.id = Rc::new(chanid);
|
||||
}
|
||||
}
|
||||
plih.stream_id = Rc::clone(&plih.id);
|
||||
plih.epg_channel_id = Some(Rc::clone(&plih.id));
|
||||
@@ -145,6 +148,12 @@ fn process_header(video_suffixes: &Vec<&str>, content: &String, url: String) ->
|
||||
plih
|
||||
}
|
||||
|
||||
fn extract_id_from_url(url: &str) -> Option<String> {
|
||||
if let Some(filename) = url.split('/').last() {
|
||||
return filename.rsplit('.').next().map(|stem| stem.to_string());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn parse_m3u(cfg: &Config, lines: &Vec<String>) -> Vec<PlaylistGroup> {
|
||||
let mut groups: std::collections::HashMap<Rc<String>, Vec<PlaylistItem>> = std::collections::HashMap::new();
|
||||
@@ -152,6 +161,7 @@ pub(crate) fn parse_m3u(cfg: &Config, lines: &Vec<String>) -> Vec<PlaylistGroup>
|
||||
let mut header: Option<String> = None;
|
||||
let mut group: Option<String> = None;
|
||||
|
||||
let mut playlist = Vec::new();
|
||||
let video_suffixes = cfg.video.as_ref().unwrap().extensions.iter().map(|ext| ext.as_str()).collect();
|
||||
for line in lines {
|
||||
if line.starts_with("#EXTINF") {
|
||||
@@ -172,20 +182,31 @@ pub(crate) fn parse_m3u(cfg: &Config, lines: &Vec<String>) -> Vec<PlaylistGroup>
|
||||
item.header.borrow_mut().group = Rc::new(group_value);
|
||||
}
|
||||
}
|
||||
let key = Rc::clone(&item.header.borrow().group);
|
||||
// let key2 = String::from(&item.header.group);
|
||||
match groups.entry(Rc::clone(&key)) {
|
||||
std::collections::hash_map::Entry::Vacant(e) => {
|
||||
e.insert(vec![item]);
|
||||
sort_order.push(Rc::clone(&key));
|
||||
}
|
||||
std::collections::hash_map::Entry::Occupied(mut e) => { e.get_mut().push(item); }
|
||||
}
|
||||
playlist.push(item);
|
||||
}
|
||||
header = None;
|
||||
group = None;
|
||||
}
|
||||
|
||||
for item in &playlist {
|
||||
if item.header.borrow().group.is_empty() {
|
||||
let current_title = item.header.borrow().title.to_owned();
|
||||
item.header.borrow_mut().group = Rc::new(string_utils::get_title_group(current_title.as_str()));
|
||||
}
|
||||
}
|
||||
|
||||
playlist.drain(..).for_each(|item| {
|
||||
let key = Rc::clone(&item.header.borrow().group);
|
||||
// let key2 = String::from(&item.header.group);
|
||||
match groups.entry(Rc::clone(&key)) {
|
||||
std::collections::hash_map::Entry::Vacant(e) => {
|
||||
e.insert(vec![item]);
|
||||
sort_order.push(Rc::clone(&key));
|
||||
}
|
||||
std::collections::hash_map::Entry::Occupied(mut e) => { e.get_mut().push(item); }
|
||||
}
|
||||
});
|
||||
|
||||
let mut result: Vec<PlaylistGroup> = vec![];
|
||||
for (grp_id, (key, channels)) in (1_u32..).zip(groups.into_iter()) {
|
||||
let cluster = channels.first().map(|pli| pli.header.borrow().xtream_cluster.clone());
|
||||
|
||||
@@ -11,7 +11,6 @@ use log::{debug, error, info};
|
||||
use unidecode::unidecode;
|
||||
|
||||
use crate::{Config, get_errors_notify_message, model::config, valid_property};
|
||||
use crate::download::{get_m3u_playlist, get_xmltv, get_xtream_playlist, get_xtream_playlist_series};
|
||||
use crate::filter::{get_field_value, MockValueProcessor, set_field_value, ValueProvider};
|
||||
use crate::m3u_filter_error::{M3uFilterError, M3uFilterErrorKind};
|
||||
use crate::messaging::{MsgKind, send_message};
|
||||
@@ -27,6 +26,7 @@ use crate::processing::xmltv_parser::flatten_tvguide;
|
||||
use crate::repository::epg_repository::write_epg;
|
||||
use crate::repository::m3u_repository::{write_m3u_playlist, write_strm_playlist};
|
||||
use crate::repository::xtream_repository::{write_xtream_mapping, write_xtream_playlist};
|
||||
use crate::utils::download;
|
||||
|
||||
fn filter_playlist(playlist: &mut [PlaylistGroup], target: &ConfigTarget) -> Option<Vec<PlaylistGroup>> {
|
||||
debug!("Filtering {} groups", playlist.len());
|
||||
@@ -282,11 +282,11 @@ async fn process_source(cfg: Arc<Config>, source_idx: usize, user_targets: Arc<P
|
||||
let input_id = input.id;
|
||||
if is_input_enabled(enabled_inputs, input.enabled, input_id, &user_targets) {
|
||||
let (playlist, mut error_list) = match input.input_type {
|
||||
InputType::M3u => get_m3u_playlist(&cfg, input, &cfg.working_dir).await,
|
||||
InputType::Xtream => get_xtream_playlist(input, &cfg.working_dir).await,
|
||||
InputType::M3u => download::get_m3u_playlist(&cfg, input, &cfg.working_dir).await,
|
||||
InputType::Xtream => download::get_xtream_playlist(input, &cfg.working_dir).await,
|
||||
};
|
||||
let (tvguide, mut tvguide_errors) = if error_list.is_empty() {
|
||||
get_xmltv(&cfg, input, &cfg.working_dir).await
|
||||
download::get_xmltv(&cfg, input, &cfg.working_dir).await
|
||||
} else {
|
||||
(None, vec![])
|
||||
};
|
||||
@@ -425,7 +425,6 @@ pub(crate) async fn process_playlist<'a>(playlists: &mut [FetchedPlaylist<'a>],
|
||||
}
|
||||
}
|
||||
playlist_resolve_series(target, errors, &pipe, fpl, &mut new_fpl).await;
|
||||
|
||||
// stats
|
||||
let input_stats = stats.get_mut(&new_fpl.input.id);
|
||||
if let Some(stat) = input_stats {
|
||||
@@ -528,7 +527,7 @@ async fn playlist_resolve_series<'a>(target: &ConfigTarget, errors: &mut Vec<M3u
|
||||
(false, 0)
|
||||
};
|
||||
if resolve_series {
|
||||
let mut series_playlist = get_xtream_playlist_series(fpl, errors, resolve_series_delay).await;
|
||||
let mut series_playlist = download::get_xtream_playlist_series(fpl, errors, resolve_series_delay).await;
|
||||
// original content saved into original list
|
||||
for plg in &series_playlist {
|
||||
fpl.update_playlist(plg);
|
||||
|
||||
@@ -5,7 +5,7 @@ use regex::Regex;
|
||||
use crate::messaging::{MsgKind, send_message};
|
||||
use crate::model::config::Config;
|
||||
use crate::model::model_playlist::PlaylistGroup;
|
||||
use crate::utils;
|
||||
use crate::utils::file_utils;
|
||||
|
||||
pub(crate) fn process_group_watch(cfg: &Config, target_name: &str, pl: &PlaylistGroup) {
|
||||
let mut new_tree = BTreeSet::new();
|
||||
@@ -18,7 +18,7 @@ pub(crate) fn process_group_watch(cfg: &Config, target_name: &str, pl: &Playlist
|
||||
let filename_re = Regex::new(r"[^A-Za-z0-9_-]").unwrap();
|
||||
let file_name = format!("watch_{}_{}", target_name, &pl.title);
|
||||
let watch_filename = format!("{}.bin", filename_re.replace_all(&file_name, "_")).to_string();
|
||||
match utils::get_file_path(&cfg.working_dir, Some(std::path::PathBuf::from(&watch_filename))) {
|
||||
match file_utils::get_file_path(&cfg.working_dir, Some(std::path::PathBuf::from(&watch_filename))) {
|
||||
Some(path) => {
|
||||
let save_path = path.clone();
|
||||
let mut changed = false;
|
||||
|
||||
Reference in New Issue
Block a user