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:
euzu
2024-03-26 01:20:53 +01:00
21 changed files with 423 additions and 384 deletions
+32 -11
View File
@@ -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());
+5 -6
View File
@@ -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);
+2 -2
View File
@@ -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;