diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fb69d7d0..8bc2c8eed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/backend/src/api/endpoints/xmltv_api.rs b/backend/src/api/endpoints/xmltv_api.rs index 66e5af570..a06cb8361 100644 --- a/backend/src/api/endpoints/xmltv_api.rs +++ b/backend/src/api/endpoints/xmltv_api.rs @@ -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}"); diff --git a/backend/src/model/config/base.rs b/backend/src/model/config/base.rs index 502a05dbd..b9f60aeec 100644 --- a/backend/src/model/config/base.rs +++ b/backend/src/model/config/base.rs @@ -58,7 +58,7 @@ pub struct Config { pub sleep_timer_mins: Option, 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, pub messaging: Option, pub reverse_proxy: Option, @@ -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), diff --git a/backend/src/processing/parser/xmltv.rs b/backend/src/processing/parser/xmltv.rs index 07336b838..01c1e8770 100644 --- a/backend/src/processing/parser/xmltv.rs +++ b/backend/src/processing/parser/xmltv.rs @@ -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 } diff --git a/backend/src/utils/compression/compressed_file_reader_async.rs b/backend/src/utils/compression/compressed_file_reader_async.rs index cb695f4af..9ea2b60bd 100644 --- a/backend/src/utils/compression/compressed_file_reader_async.rs +++ b/backend/src/utils/compression/compressed_file_reader_async.rs @@ -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( diff --git a/backend/src/utils/network/request.rs b/backend/src/utils/network/request.rs index 40a751d07..2dea82e7a 100644 --- a/backend/src/utils/network/request.rs +++ b/backend/src/utils/network/request.rs @@ -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() { diff --git a/frontend/public/assets/i18n/en.json b/frontend/public/assets/i18n/en.json index 815e50f08..a8ea4cf9e 100644 --- a/frontend/public/assets/i18n/en.json +++ b/frontend/public/assets/i18n/en.json @@ -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", diff --git a/frontend/src/app/components/config/main_config_view.rs b/frontend/src/app/components/config/main_config_view.rs index 807c2558d..5cd232c34 100644 --- a/frontend/src/app/components/config/main_config_view.rs +++ b/frontend/src/app/components/config/main_config_view.rs @@ -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, @@ -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) } diff --git a/shared/src/model/config/base.rs b/shared/src/model/config/base.rs index 42214be2a..07b790220 100644 --- a/shared/src/model/config/base.rs +++ b/shared/src/model/config/base.rs @@ -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, #[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; } } \ No newline at end of file