fix: Modified the Sonarr DownloadRecord so that the episode_id is optional to prevent crashes for weird downloads
This commit is contained in:
@@ -191,7 +191,7 @@ pub(in crate::handlers::sonarr_handlers) mod utils {
|
|||||||
title: "Test Download Title".to_owned(),
|
title: "Test Download Title".to_owned(),
|
||||||
status: DownloadStatus::Downloading,
|
status: DownloadStatus::Downloading,
|
||||||
id: 1,
|
id: 1,
|
||||||
episode_id: 1,
|
episode_id: Some(Number::from(1i64)),
|
||||||
size: 3543348019f64,
|
size: 3543348019f64,
|
||||||
sizeleft: 1771674009f64,
|
sizeleft: 1771674009f64,
|
||||||
output_path: Some(HorizontallyScrollableText::from(
|
output_path: Some(HorizontallyScrollableText::from(
|
||||||
|
|||||||
@@ -112,8 +112,7 @@ pub struct DownloadRecord {
|
|||||||
pub status: DownloadStatus,
|
pub status: DownloadStatus,
|
||||||
#[serde(deserialize_with = "super::from_i64")]
|
#[serde(deserialize_with = "super::from_i64")]
|
||||||
pub id: i64,
|
pub id: i64,
|
||||||
#[serde(deserialize_with = "super::from_i64")]
|
pub episode_id: Option<Number>,
|
||||||
pub episode_id: i64,
|
|
||||||
#[serde(deserialize_with = "super::from_f64")]
|
#[serde(deserialize_with = "super::from_f64")]
|
||||||
pub size: f64,
|
pub size: f64,
|
||||||
#[serde(deserialize_with = "super::from_f64")]
|
#[serde(deserialize_with = "super::from_f64")]
|
||||||
|
|||||||
+1
-1
@@ -133,7 +133,7 @@ impl<'a, 'b> Network<'a, 'b> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let status = response.status();
|
let status = response.status();
|
||||||
let whitespace_regex = Regex::new(r"\s+").unwrap();
|
let whitespace_regex = Regex::new(r"\s+")?;
|
||||||
let response_body = response.text().await.unwrap_or_default();
|
let response_body = response.text().await.unwrap_or_default();
|
||||||
let error_body = whitespace_regex
|
let error_body = whitespace_regex
|
||||||
.replace_all(&response_body.replace('\n', " "), " ")
|
.replace_all(&response_body.replace('\n', " "), " ")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use indoc::formatdoc;
|
use indoc::formatdoc;
|
||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Number, Value};
|
||||||
use urlencoding::encode;
|
use urlencoding::encode;
|
||||||
|
|
||||||
use super::{Network, NetworkEvent, NetworkResource};
|
use super::{Network, NetworkEvent, NetworkResource};
|
||||||
@@ -2321,10 +2321,16 @@ impl Network<'_, '_> {
|
|||||||
|
|
||||||
fn get_episode_status(has_file: bool, downloads_vec: &[DownloadRecord], episode_id: i64) -> String {
|
fn get_episode_status(has_file: bool, downloads_vec: &[DownloadRecord], episode_id: i64) -> String {
|
||||||
if !has_file {
|
if !has_file {
|
||||||
if let Some(download) = downloads_vec
|
let default_episode_id = Number::from(-1i64);
|
||||||
.iter()
|
if let Some(download) = downloads_vec.iter().find(|&download| {
|
||||||
.find(|&download| download.episode_id == episode_id)
|
download
|
||||||
{
|
.episode_id
|
||||||
|
.as_ref()
|
||||||
|
.unwrap_or(&default_episode_id)
|
||||||
|
.as_i64()
|
||||||
|
.unwrap()
|
||||||
|
== episode_id
|
||||||
|
}) {
|
||||||
if download.status == DownloadStatus::Downloading {
|
if download.status == DownloadStatus::Downloading {
|
||||||
return "Downloading".to_owned();
|
return "Downloading".to_owned();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5438,7 +5438,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_get_episode_status_missing() {
|
fn test_get_episode_status_missing() {
|
||||||
let download_record = DownloadRecord {
|
let download_record = DownloadRecord {
|
||||||
episode_id: 1,
|
episode_id: Some(Number::from(1i64)),
|
||||||
..DownloadRecord::default()
|
..DownloadRecord::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -5450,13 +5450,25 @@ mod test {
|
|||||||
assert_str_eq!(get_episode_status(false, &[download_record], 1), "Missing");
|
assert_str_eq!(get_episode_status(false, &[download_record], 1), "Missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_episode_status_missing_if_episode_id_is_missing() {
|
||||||
|
let download_record = DownloadRecord::default();
|
||||||
|
|
||||||
|
assert_str_eq!(
|
||||||
|
get_episode_status(false, &[download_record.clone()], 0),
|
||||||
|
"Missing"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_str_eq!(get_episode_status(false, &[download_record], 1), "Missing");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_episode_status_downloading() {
|
fn test_get_episode_status_downloading() {
|
||||||
assert_str_eq!(
|
assert_str_eq!(
|
||||||
get_episode_status(
|
get_episode_status(
|
||||||
false,
|
false,
|
||||||
&[DownloadRecord {
|
&[DownloadRecord {
|
||||||
episode_id: 1,
|
episode_id: Some(Number::from(1i64)),
|
||||||
status: DownloadStatus::Downloading,
|
status: DownloadStatus::Downloading,
|
||||||
..DownloadRecord::default()
|
..DownloadRecord::default()
|
||||||
}],
|
}],
|
||||||
@@ -5472,7 +5484,7 @@ mod test {
|
|||||||
get_episode_status(
|
get_episode_status(
|
||||||
false,
|
false,
|
||||||
&[DownloadRecord {
|
&[DownloadRecord {
|
||||||
episode_id: 1,
|
episode_id: Some(Number::from(1i64)),
|
||||||
status: DownloadStatus::Completed,
|
status: DownloadStatus::Completed,
|
||||||
..DownloadRecord::default()
|
..DownloadRecord::default()
|
||||||
}],
|
}],
|
||||||
@@ -5523,7 +5535,7 @@ mod test {
|
|||||||
title: "Test Download Title".to_owned(),
|
title: "Test Download Title".to_owned(),
|
||||||
status: DownloadStatus::Downloading,
|
status: DownloadStatus::Downloading,
|
||||||
id: 1,
|
id: 1,
|
||||||
episode_id: 1,
|
episode_id: Some(Number::from(1i64)),
|
||||||
size: 3543348019f64,
|
size: 3543348019f64,
|
||||||
sizeleft: 1771674009f64,
|
sizeleft: 1771674009f64,
|
||||||
output_path: Some(HorizontallyScrollableText::from(
|
output_path: Some(HorizontallyScrollableText::from(
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ use ratatui::style::{Style, Stylize};
|
|||||||
use ratatui::text::{Line, Span, Text};
|
use ratatui::text::{Line, Span, Text};
|
||||||
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
||||||
use ratatui::Frame;
|
use ratatui::Frame;
|
||||||
|
use serde_json::Number;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "episode_details_ui_tests.rs"]
|
#[path = "episode_details_ui_tests.rs"]
|
||||||
@@ -128,13 +129,22 @@ fn draw_episode_details(f: &mut Frame<'_>, app: &App<'_>, area: Rect) {
|
|||||||
if let Some(episode_details_modal) = season_details_modal.episode_details_modal.as_ref() {
|
if let Some(episode_details_modal) = season_details_modal.episode_details_modal.as_ref() {
|
||||||
let episode = season_details_modal.episodes.current_selection().clone();
|
let episode = season_details_modal.episodes.current_selection().clone();
|
||||||
let episode_details = &episode_details_modal.episode_details;
|
let episode_details = &episode_details_modal.episode_details;
|
||||||
|
let default_episode_id = Number::from(-1i64);
|
||||||
let download = app
|
let download = app
|
||||||
.data
|
.data
|
||||||
.sonarr_data
|
.sonarr_data
|
||||||
.downloads
|
.downloads
|
||||||
.items
|
.items
|
||||||
.iter()
|
.iter()
|
||||||
.find(|&download| download.episode_id == episode.id);
|
.find(|&download| {
|
||||||
|
download
|
||||||
|
.episode_id
|
||||||
|
.as_ref()
|
||||||
|
.unwrap_or(&default_episode_id)
|
||||||
|
.as_i64()
|
||||||
|
.unwrap()
|
||||||
|
== episode.id
|
||||||
|
});
|
||||||
let text = Text::from(
|
let text = Text::from(
|
||||||
episode_details
|
episode_details
|
||||||
.items
|
.items
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ use ratatui::layout::{Alignment, Constraint, Rect};
|
|||||||
use ratatui::prelude::{Line, Style, Stylize, Text};
|
use ratatui::prelude::{Line, Style, Stylize, Text};
|
||||||
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
||||||
use ratatui::Frame;
|
use ratatui::Frame;
|
||||||
|
use serde_json::Number;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "season_details_ui_tests.rs"]
|
#[path = "season_details_ui_tests.rs"]
|
||||||
@@ -573,10 +574,16 @@ fn decorate_with_row_style<'a>(
|
|||||||
row: Row<'a>,
|
row: Row<'a>,
|
||||||
) -> Row<'a> {
|
) -> Row<'a> {
|
||||||
if !episode.has_file {
|
if !episode.has_file {
|
||||||
if let Some(download) = downloads_vec
|
let default_episode_id = Number::from(-1i64);
|
||||||
.iter()
|
if let Some(download) = downloads_vec.iter().find(|&download| {
|
||||||
.find(|&download| download.episode_id == episode.id)
|
download
|
||||||
{
|
.episode_id
|
||||||
|
.as_ref()
|
||||||
|
.unwrap_or(&default_episode_id)
|
||||||
|
.as_i64()
|
||||||
|
.unwrap()
|
||||||
|
== episode.id
|
||||||
|
}) {
|
||||||
if download.status == DownloadStatus::Downloading {
|
if download.status == DownloadStatus::Downloading {
|
||||||
return row.downloading();
|
return row.downloading();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user