diff --git a/src/api/xmltv_api.rs b/src/api/xmltv_api.rs index 6b0791669..777321a00 100644 --- a/src/api/xmltv_api.rs +++ b/src/api/xmltv_api.rs @@ -2,9 +2,8 @@ use std::fs::File; use std::path::{Path, PathBuf}; use actix_web::{HttpRequest, HttpResponse, web, http::header}; -use log::{debug, info}; +use log::{info}; use quick_xml::{Reader, Writer}; -use url::{ParseError}; use flate2::write::GzEncoder; use flate2::Compression; use quick_xml::events::{BytesStart, Event}; @@ -13,13 +12,13 @@ use chrono::{Duration, NaiveDateTime, TimeDelta}; use crate::api::api_model::{AppState, UserApiRequest}; use crate::api::api_utils::{get_user_target, serve_file}; -use crate::model::api_proxy::{ProxyType, ProxyUserCredentials}; -use crate::model::config::{Config, ConfigInput, ConfigTarget}; +use crate::model::api_proxy::{ProxyUserCredentials}; +use crate::model::config::{Config, ConfigTarget}; use crate::model::config::TargetType; use crate::repository::m3u_repository::m3u_get_epg_file_path; use crate::repository::storage::get_target_storage_path; use crate::repository::xtream_repository::{xtream_get_epg_file_path, xtream_get_storage_path}; -use crate::utils::{file_utils, request_utils}; +use crate::utils::{file_utils}; fn time_correct(date_time: &str, correction: &TimeDelta) -> String { // Split the dateTime string into date and time parts @@ -194,11 +193,8 @@ async fn xmltv_api( if let Some((user, target)) = get_user_target(&api_req, &app_state) { match get_epg_path_for_target(&app_state.config, target) { None => { - // No epg configured, we try to figure out an epg url and redirect. - // No processing or timeshift - if let Some(value) = get_xmltv_raw_epg(&app_state.config, &user, &target.name).await { - return value; - } + // No epg configured, No processing or timeshift, epg can't be mapped to the channels. + // we do not deliver epg } Some(epg_path) => return serve_epg(&epg_path, &req, &user).await } @@ -207,53 +203,6 @@ async fn xmltv_api( r#""#) } -fn get_xmltv_epg_url(input: &ConfigInput) -> Result { - let epg_url = input.epg_url.as_ref().map_or(String::new(), std::borrow::ToOwned::to_owned); - if epg_url.is_empty() { - if let Some(user_info) = input.get_user_info() { - let url = user_info.base_url.as_str(); - let username = user_info.username.as_str(); - let password = user_info.password.as_str(); - Ok(format!("{url}/xmltv.php?username={username}&password={password}")) - } else { - Err(ParseError::EmptyHost) - } - } else { - Ok(epg_url) - } -} - -async fn get_xmltv_raw_epg(config: &Config, user: &ProxyUserCredentials, target_name: &str) -> Option { - // If no epg_url is provided for input, we did not process the xmltv for our channels. - // We are now delivering the original untouched xmltv. - // If you want to use xmltv then provide the url in the config to filter unnecessary content. - // If you have multiple xtream sources, no response because of mapped ids - // if you want epg for multi xtream input, then provide epg_url. - if let Some(inputs) = config.get_inputs_for_target(target_name) { - if inputs.len() == 1 { - if let Some(&input) = inputs.first() { - if let Ok(url) = get_xmltv_epg_url(input) { - if user.proxy == ProxyType::Redirect { - debug!("Redirecting epg request to {}", url.as_str()); - return Some(HttpResponse::Found().insert_header(("Location", url.as_str())).finish()); - } - match request_utils::download_text_content(input, url.as_str(), None).await { - Ok(content) => return Some(HttpResponse::Ok().content_type(mime::TEXT_XML).body(content)), - Err(err) => { - debug!("Could not generate epg url for {target_name} {err}"); - } - } - } else { - debug!("Could not generate epg url for {target_name}"); - } - } - } else { - debug!("No epg_url is provided for target {target_name}, multi input requires epg_url"); - } - } - None -} - pub(crate) fn xmltv_api_register(cfg: &mut web::ServiceConfig) { cfg.service(web::resource("/xmltv.php").route(web::get().to(xmltv_api))) .service(web::resource("/epg").route(web::get().to(xmltv_api))); diff --git a/src/model/config.rs b/src/model/config.rs index d4b9ae64f..fb543ff62 100644 --- a/src/model/config.rs +++ b/src/model/config.rs @@ -437,17 +437,17 @@ impl ConfigSource { Ok(index + (self.inputs.len() as u16)) } - pub(crate) fn get_inputs_for_target(&self, target_name: &str) -> Option> { - for target in &self.targets { - if target.name.eq(target_name) { - let inputs = self.inputs.iter().filter(|&i| i.enabled).collect::>(); - if !inputs.is_empty() { - return Some(inputs); - } - } - } - None - } + // pub(crate) fn get_inputs_for_target(&self, target_name: &str) -> Option> { + // for target in &self.targets { + // if target.name.eq(target_name) { + // let inputs = self.inputs.iter().filter(|&i| i.enabled).collect::>(); + // if !inputs.is_empty() { + // return Some(inputs); + // } + // } + // } + // None + // } } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] @@ -840,14 +840,14 @@ impl Config { } } - pub(crate) fn get_inputs_for_target(&self, target_name: &str) -> Option> { - for source in &self.sources { - if let Some(cfg) = source.get_inputs_for_target(target_name) { - return Some(cfg); - } - } - None - } + // pub(crate) fn get_inputs_for_target(&self, target_name: &str) -> Option> { + // for source in &self.sources { + // if let Some(cfg) = source.get_inputs_for_target(target_name) { + // return Some(cfg); + // } + // } + // None + // } pub fn get_target_for_user(&self, username: &str, password: &str) -> Option<(ProxyUserCredentials, &ConfigTarget)> { match self.t_api_proxy.read().unwrap().as_ref() { diff --git a/src/utils/request_utils.rs b/src/utils/request_utils.rs index ee12ed3d7..ed3e9c25a 100644 --- a/src/utils/request_utils.rs +++ b/src/utils/request_utils.rs @@ -14,6 +14,9 @@ use crate::m3u_filter_error::{M3uFilterError, M3uFilterErrorKind}; use crate::model::config::ConfigInput; use crate::utils::file_utils::{get_file_path, persist_file}; +const ENCODING_GZIP: &str = "gzip"; +const ENCODING_DEFLATE: &str = "deflate"; + fn is_gzip(bytes: &[u8]) -> bool { // Gzip files start with the bytes 0x1F 0x8B bytes.len() >= 2 && bytes[0] == 0x1F && bytes[1] == 0x8B @@ -144,19 +147,19 @@ async fn get_remote_content(input: &ConfigInput, url: &Url) -> Result { if bytes.len() >= 2 && is_gzip(&bytes[0..2]) { - encoding = Some("gzip".to_string()); + encoding = Some(ENCODING_GZIP.to_string()); } let mut decode_buffer = String::new(); if let Some(encoding_type) = encoding { match encoding_type.as_str() { - "gzip" => { + ENCODING_GZIP => { let mut decoder = GzDecoder::new(&bytes[..]); match decoder.read_to_string(&mut decode_buffer) { Ok(_) => {} Err(err) => return Err(std::io::Error::new(ErrorKind::Other, format!("failed to decode gzip content {err}"))) }; } - "deflate" => { + ENCODING_DEFLATE => { let mut decoder = ZlibDecoder::new(&bytes[..]); match decoder.read_to_string(&mut decode_buffer) { Ok(_) => {}