Fixed invalid epg text content parsing

This commit is contained in:
euzu
2025-10-01 17:06:41 +02:00
parent 38b1cd6d31
commit 4e549f6603
9 changed files with 25 additions and 21 deletions
+2 -1
View File
@@ -3,7 +3,7 @@
- Added Dark/Bright theme switch
- Resource proxy retries failed requests up to three times and respects the `Retry-After` header (falls back to 100 ms wait)
to reduce transient HTTP errors (400, 408, 425, 429, 5xx)
- Added `accept_unsecure_ssl_certificate` option in `config.yml` (for serving images over HTTPS without a valid SSL certificate)
- Added `accept_insecure_ssl_certificates` option in `config.yml` (for serving images over HTTPS without a valid SSL certificate)
- VOD streams now use tmdbid from `get_vod_streams` if available, removing the need for `resolve_vod` in STRM generation
- Fixed file length issue in STRM generation
- Fixed empty parentheses issue in series names
@@ -11,6 +11,7 @@ to reduce transient HTTP errors (400, 408, 425, 429, 5xx)
- WebSocket now reconnects on disconnect; added WebSocket connection status icon in Web UI
- Added Playlist EPG view with timeline, channels, `now` line, and program details
- EPG data can now be fetched from selected targets and custom URLs
- Faster, more reliable EPG loading via streaming and asynchronous processing, with reduced memory usage and better support for large or compressed guides.
- Invalid EPG text data fix
- Added new sidebar entry and icon for quick EPG access
- Added CBOR (binary JSON) support for large API data
+8 -6
View File
@@ -159,16 +159,18 @@ fn serve_epg_with_timeshift(
}
// Write the modified start event
xml_writer
.write_event_async(Event::Start(elem)).await
.expect("Failed to write event");
if let Err(e) = xml_writer.write_event_async(Event::Start(elem)).await {
error!("Failed to write Start event: {e}");
break;
}
}
Ok(Event::Eof) => break, // End of file
Ok(event) => {
// Write any other event as is
xml_writer
.write_event_async(event).await
.expect("Failed to write event");
if let Err(e) = xml_writer.write_event_async(event).await {
error!("Failed to write event: {e}");
break;
}
}
Err(e) => {
error!("Error: {e}");
+2 -2
View File
@@ -58,7 +58,7 @@ pub struct Config {
pub sleep_timer_mins: Option<u32>,
pub update_on_boot: bool,
pub config_hot_reload: bool,
pub accept_unsecure_ssl_certificates: bool,
pub accept_insecure_ssl_certificates: bool,
pub web_ui: Option<WebUiConfig>,
pub messaging: Option<MessagingConfig>,
pub reverse_proxy: Option<ReverseProxyConfig>,
@@ -139,7 +139,7 @@ impl From<&ConfigDto> for Config {
sleep_timer_mins: dto.sleep_timer_mins,
update_on_boot: dto.update_on_boot,
config_hot_reload: dto.config_hot_reload,
accept_unsecure_ssl_certificates: dto.accept_unsecure_ssl_certificates,
accept_insecure_ssl_certificates: dto.accept_insecure_ssl_certificates,
web_ui: dto.web_ui.as_ref().map(Into::into),
messaging: dto.messaging.as_ref().map(Into::into),
reverse_proxy: dto.reverse_proxy.as_ref().map(Into::into),
+1 -1
View File
@@ -63,7 +63,7 @@ fn name_prefix<'a>(name: &'a str, smart_config: &EpgSmartMatchConfig) -> (&'a st
fn combine(join: &str, left: &str, right: &str) -> String {
let mut combined = String::with_capacity(left.len() + join.len() + right.len());
combined.push_str(left);
combined.push('.');
combined.push_str(join);
combined.push_str(right);
combined
}
@@ -45,6 +45,7 @@ impl AsyncRead for CompressedFileReaderAsync {
Pin::new(&mut self.reader).poll_read(cx, buf)
}
}
//
// impl AsyncBufRead for CompressedFileReaderAsync {
// fn poll_fill_buf(
+1 -1
View File
@@ -387,7 +387,7 @@ pub fn create_client(cfg: &AppConfig) -> reqwest::ClientBuilder {
.redirect(reqwest::redirect::Policy::limited(10))
.pool_idle_timeout(Duration::from_secs(30))
.pool_max_idle_per_host(10)
.danger_accept_invalid_certs(config.accept_unsecure_ssl_certificates);
.danger_accept_invalid_certs(config.accept_insecure_ssl_certificates);
if let Some(proxy_cfg) = config.proxy.as_ref() {
+1 -1
View File
@@ -207,7 +207,7 @@
"SLEEP_TIMER_MINS": "Sleep Timer (mins)",
"CONNECT_TIMEOUT_SECS": "Connect Timeout (secs)",
"CONFIG_HOT_RELOAD": "Config Hot Reload",
"ACCEPT_UNSECURE_SSL_CERTIFICATES": "Accept Unsecure SSL Certificates",
"ACCEPT_INSECURE_SSL_CERTIFICATES": "Accept Insecure SSL Certificates",
"CUSTOM_STREAM_RESPONSE_PATH": "Custom Stream Response dir",
"REVERSE_PROXY": "Reverse Proxy",
"WEB_SEARCH": "Web Search",
@@ -18,7 +18,7 @@ const LABEL_USER_CONFIG_DIR: &str = "LABEL.USER_CONFIG_DIR";
const LABEL_SLEEP_TIMER_MINS: &str = "LABEL.SLEEP_TIMER_MINS";
const LABEL_CONNECT_TIMEOUT_SECS: &str = "LABEL.CONNECT_TIMEOUT_SECS";
const LABEL_CUSTOM_STREAM_RESPONSE_PATH: &str = "LABEL.CUSTOM_STREAM_RESPONSE_PATH";
const LABEL_ACCEPT_UNSECURE_SSL_CERTIFICATES: &str = "LABEL.ACCEPT_UNSECURE_SSL_CERTIFICATES";
const LABEL_ACCEPT_INSECURE_SSL_CERTIFICATES: &str = "LABEL.ACCEPT_INSECURE_SSL_CERTIFICATES";
generate_form_reducer!(
state: MainConfigFormState { form: MainConfigDto },
@@ -27,7 +27,7 @@ generate_form_reducer!(
UpdateOnBoot => update_on_boot: bool,
ConfigHotReload => config_hot_reload: bool,
UserAccessControl => user_access_control: bool,
AcceptUnsecureSslCertificates => accept_unsecure_ssl_certificates: bool,
AcceptInsecureSslCertificates => accept_insecure_ssl_certificates: bool,
Threads => threads: u8,
WorkingDir => working_dir: String,
MappingPath => mapping_path: Option<String>,
@@ -77,7 +77,7 @@ pub fn MainConfigView() -> Html {
{ config_field_bool!(form_state.form, translate.t(LABEL_UPDATE_ON_BOOT), update_on_boot) }
{ config_field_bool!(form_state.form, translate.t(LABEL_CONFIG_HOT_RELOAD), config_hot_reload) }
{ config_field_bool!(form_state.form, translate.t(LABEL_USER_ACCESS_CONTROL), user_access_control) }
{ config_field_bool!(form_state.form, translate.t(LABEL_ACCEPT_UNSECURE_SSL_CERTIFICATES), accept_unsecure_ssl_certificates) }
{ config_field_bool!(form_state.form, translate.t(LABEL_ACCEPT_INSECURE_SSL_CERTIFICATES), accept_insecure_ssl_certificates) }
{ config_field!(form_state.form, translate.t(LABEL_THREADS), threads) }
{ config_field!(form_state.form, translate.t(LABEL_WORKING_DIR), working_dir) }
{ config_field_optional!(form_state.form, translate.t(LABEL_MAPPING_PATH), mapping_path) }
@@ -95,7 +95,7 @@ pub fn MainConfigView() -> Html {
{ edit_field_bool!(form_state, translate.t(LABEL_UPDATE_ON_BOOT), update_on_boot, MainConfigFormAction::UpdateOnBoot) }
{ edit_field_bool!(form_state, translate.t(LABEL_CONFIG_HOT_RELOAD), config_hot_reload, MainConfigFormAction::ConfigHotReload) }
{ edit_field_bool!(form_state, translate.t(LABEL_USER_ACCESS_CONTROL), user_access_control, MainConfigFormAction::UserAccessControl) }
{ edit_field_bool!(form_state, translate.t(LABEL_ACCEPT_UNSECURE_SSL_CERTIFICATES), user_access_control, MainConfigFormAction::AcceptUnsecureSslCertificates) }
{ edit_field_bool!(form_state, translate.t(LABEL_ACCEPT_INSECURE_SSL_CERTIFICATES), user_access_control, MainConfigFormAction::AcceptInsecureSslCertificates) }
{ edit_field_number_u8!(form_state, translate.t(LABEL_THREADS), threads, MainConfigFormAction::Threads) }
{ edit_field_text!(form_state, translate.t(LABEL_WORKING_DIR), working_dir, MainConfigFormAction::WorkingDir) }
{ edit_field_text_option!(form_state, translate.t(LABEL_MAPPING_PATH), mapping_path, MainConfigFormAction::MappingPath) }
+5 -5
View File
@@ -37,7 +37,7 @@ pub struct ConfigDto {
#[serde(default)]
pub config_hot_reload: bool,
#[serde(default)]
pub accept_unsecure_ssl_certificates: bool,
pub accept_insecure_ssl_certificates: bool,
#[serde(default)]
pub web_ui: Option<WebUiConfigDto>,
#[serde(default, skip_serializing_if = "Option::is_none")]
@@ -78,7 +78,7 @@ pub struct MainConfigDto {
#[serde(default)]
pub config_hot_reload: bool,
#[serde(default)]
pub accept_unsecure_ssl_certificates: bool,
pub accept_insecure_ssl_certificates: bool,
}
impl Default for MainConfigDto {
@@ -95,7 +95,7 @@ impl Default for MainConfigDto {
sleep_timer_mins: None,
update_on_boot: false,
config_hot_reload: false,
accept_unsecure_ssl_certificates: false,
accept_insecure_ssl_certificates: false,
}
}
}
@@ -114,7 +114,7 @@ impl From<&ConfigDto> for MainConfigDto {
sleep_timer_mins: config.sleep_timer_mins,
update_on_boot: config.update_on_boot,
config_hot_reload: config.config_hot_reload,
accept_unsecure_ssl_certificates: config.accept_unsecure_ssl_certificates,
accept_insecure_ssl_certificates: config.accept_insecure_ssl_certificates,
}
}
}
@@ -248,7 +248,7 @@ impl ConfigDto {
self.sleep_timer_mins = main_config.sleep_timer_mins;
self.update_on_boot = main_config.update_on_boot;
self.config_hot_reload = main_config.config_hot_reload;
self.accept_unsecure_ssl_certificates = main_config.accept_unsecure_ssl_certificates;
self.accept_insecure_ssl_certificates = main_config.accept_insecure_ssl_certificates;
}
}