Merge branch 'master' into feture/template_optimization

This commit is contained in:
euzu
2025-05-19 15:51:45 +02:00
3 changed files with 27 additions and 20 deletions
+6 -6
View File
@@ -69,9 +69,9 @@ pub struct KodiStyle {
}
pub struct Constants {
pub re_username: Regex,
pub re_password: Regex,
pub re_token: Regex,
pub re_credentials: Regex,
pub re_ipv4: Regex,
pub re_ipv6: Regex,
pub re_stream_url: Regex,
pub re_url: Regex,
pub re_base_href: Regex,
@@ -93,9 +93,9 @@ pub struct Constants {
pub static CONSTANTS: LazyLock<Constants> = LazyLock::new(||
Constants {
re_username: Regex::new(r"(username=)[^&]*").unwrap(),
re_password: Regex::new(r"(password=)[^&]*").unwrap(),
re_token: Regex::new(r"(token=)[^&]*").unwrap(),
re_credentials: Regex::new(r"((username|password|token)=)[^&]*").unwrap(),
re_ipv4: Regex::new(r"\b((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\b").unwrap(),
re_ipv6: Regex::new(r"\b([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b|\b::([0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}\b|\b([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}\b|\b::ffff:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b").unwrap(),
re_stream_url: Regex::new(r"(?i)^(?P<scheme>https?://)[^/]+/(?P<ctx>live|video|movie|series|m3u-stream|resource)/[^/]+/[^/]+/").unwrap(),
re_url: Regex::new(r"(.*://).*?/(.*)").unwrap(),
re_base_href: Regex::new(r#"(href|src)="/([^"]*)""#).unwrap(),
+1 -1
View File
@@ -15,7 +15,7 @@ async fn download_epg_file(url: &str, client: &Arc<reqwest::Client>, input: &Con
let persist_file_path = prepare_file_path(input.persist.as_deref(), working_dir, "")
.map(|path| add_prefix_to_filename(&path, format!("{file_prefix}_epg_").as_str(), Some("xml")));
request::get_input_text_content_as_file(Arc::clone(client), input, working_dir, url, persist_file_path).await
request::get_input_epg_content_as_file(Arc::clone(client), input, working_dir, url, persist_file_path).await
}
pub async fn get_xmltv(client: Arc<reqwest::Client>, _cfg: &Config, input: &ConfigInput, working_dir: &str) -> (Option<TVGuide>, Vec<TuliproxError>) {
+20 -13
View File
@@ -29,10 +29,10 @@ pub const fn bytes_to_megabytes(bytes: u64) -> u64 {
bytes / 1_048_576
}
pub async fn get_input_text_content_as_file(client: Arc<reqwest::Client>, input: &ConfigInput, working_dir: &str, url_str: &str, persist_filepath: Option<PathBuf>) -> Result<PathBuf, TuliproxError> {
pub async fn get_input_epg_content_as_file(client: Arc<reqwest::Client>, input: &ConfigInput, working_dir: &str, url_str: &str, persist_filepath: Option<PathBuf>) -> Result<PathBuf, TuliproxError> {
debug_if_enabled!("getting input text content working_dir: {}, url: {}", working_dir, sanitize_sensitive_info(url_str));
if url_str.parse::<url::Url>().is_ok() {
match download_text_content_as_file(client, input, url_str, working_dir, persist_filepath).await {
match download_epg_content_as_file(client, input, url_str, working_dir, persist_filepath).await {
Ok(content) => Ok(content),
Err(e) => {
error!("cant download input url: {} => {}", sanitize_sensitive_info(url_str), sanitize_sensitive_info(e.to_string().as_str()));
@@ -298,7 +298,7 @@ async fn get_remote_content(client: Arc<reqwest::Client>, input: &ConfigInput, u
}
}
pub async fn download_text_content_as_file(client: Arc<reqwest::Client>, input: &ConfigInput, url_str: &str, working_dir: &str, persist_filepath: Option<PathBuf>) -> Result<PathBuf, Error> {
async fn download_epg_content_as_file(client: Arc<reqwest::Client>, input: &ConfigInput, url_str: &str, working_dir: &str, persist_filepath: Option<PathBuf>) -> Result<PathBuf, Error> {
if let Ok(url) = url_str.parse::<url::Url>() {
if url.scheme() == "file" {
url.to_file_path().map_or_else(|()| Err(Error::new(ErrorKind::Unsupported, format!("Unknown file {}", sanitize_sensitive_info(url_str)))), |file_path| if file_path.exists() {
@@ -371,19 +371,26 @@ pub fn set_sanitize_sensitive_info(value: bool) {
CONSTANTS.sanitize.store(value, Ordering::SeqCst);
}
pub fn sanitize_sensitive_info(query: &str) -> String {
if CONSTANTS.sanitize.load(Ordering::SeqCst) {
// Replace with "***"
let masked_query = CONSTANTS.re_username.replace_all(query, "$1***");
let masked_query = CONSTANTS.re_password.replace_all(&masked_query, "$1***");
let masked_query = CONSTANTS.re_token.replace_all(&masked_query, "$1***");
let masked_query = CONSTANTS.re_stream_url.replace_all(&masked_query, "$1***/$2/***");
let masked_query = CONSTANTS.re_url.replace_all(&masked_query, "$1***/$2");
masked_query.to_string()
} else {
query.to_string()
if !CONSTANTS.sanitize.load(Ordering::SeqCst) {
return query.to_string();
}
let mut result = query.to_owned();
for (re, replacement) in &[
(&CONSTANTS.re_credentials, "$1***"),
(&CONSTANTS.re_ipv4, "$1***"),
(&CONSTANTS.re_ipv6, "$1***"),
(&CONSTANTS.re_stream_url, "$1***/$2/***"),
(&CONSTANTS.re_url, "$1***/$2"),
] {
result = re.replace_all(&result, *replacement).into_owned();
}
result
}
pub fn extract_extension_from_url(url: &str) -> Option<&str> {
if let Some(protocol_pos) = url.find("://") {
if let Some(last_slash_pos) = url[protocol_pos + 3..].rfind('/') {