Initial Radarr ui!
This commit is contained in:
@@ -6,12 +6,14 @@ use tokio::sync::Mutex;
|
||||
use crate::app::App;
|
||||
|
||||
pub(crate) mod radarr;
|
||||
mod utils;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||
pub enum RadarrEvent {
|
||||
HealthCheck,
|
||||
GetOverview,
|
||||
GetStatus,
|
||||
GetMovies,
|
||||
}
|
||||
|
||||
pub struct Network<'a> {
|
||||
|
||||
+67
-56
@@ -1,11 +1,14 @@
|
||||
use anyhow::Result;
|
||||
use chrono::{DateTime, Utc};
|
||||
use derivative::Derivative;
|
||||
use log::{debug, error};
|
||||
use reqwest::RequestBuilder;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Deserialize;
|
||||
use serde_json::Number;
|
||||
use crate::app::RadarrConfig;
|
||||
use crate::network::{Network, RadarrEvent};
|
||||
use tokio::sync::MutexGuard;
|
||||
|
||||
use crate::app::{App, RadarrConfig};
|
||||
use crate::network::{Network, RadarrEvent, utils};
|
||||
|
||||
impl RadarrEvent {
|
||||
const fn resource(self) -> &'static str {
|
||||
@@ -13,11 +16,12 @@ impl RadarrEvent {
|
||||
RadarrEvent::HealthCheck => "/health",
|
||||
RadarrEvent::GetOverview => "/diskspace",
|
||||
RadarrEvent::GetStatus => "/system/status",
|
||||
RadarrEvent::GetMovies => "/movie",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct DiskSpace {
|
||||
pub path: String,
|
||||
@@ -33,41 +37,30 @@ struct SystemStatus {
|
||||
start_time: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Derivative, Deserialize, Debug)]
|
||||
#[derivative(Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Movie {
|
||||
#[derivative(Default(value = "Number::from(0)"))]
|
||||
pub id: Number,
|
||||
pub title: String,
|
||||
#[derivative(Default(value = "Number::from(0)"))]
|
||||
pub year: Number,
|
||||
pub monitored: bool,
|
||||
pub has_file: bool,
|
||||
}
|
||||
|
||||
impl<'a> Network<'a> {
|
||||
pub async fn handle_radarr_event(&self, radarr_event: RadarrEvent) {
|
||||
match radarr_event {
|
||||
RadarrEvent::HealthCheck => {
|
||||
self.healthcheck(RadarrEvent::HealthCheck.resource()).await;
|
||||
}
|
||||
RadarrEvent::GetOverview => match self.diskspace(RadarrEvent::GetOverview.resource()).await {
|
||||
Ok(disk_space_vec) => {
|
||||
let mut app = self.app.lock().await;
|
||||
let DiskSpace {
|
||||
free_space,
|
||||
total_space,
|
||||
..
|
||||
} = &disk_space_vec[0];
|
||||
app.data.radarr_data.free_space = free_space.as_u64().unwrap();
|
||||
app.data.radarr_data.total_space = total_space.as_u64().unwrap();
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to fetch disk space. {:?}", e);
|
||||
}
|
||||
},
|
||||
RadarrEvent::GetStatus => match self.status(RadarrEvent::GetStatus.resource()).await {
|
||||
Ok(system_status) => {
|
||||
let mut app = self.app.lock().await;
|
||||
app.data.radarr_data.version = system_status.version;
|
||||
app.data.radarr_data.start_time = system_status.start_time;
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to fetch system status. {:?}", e);
|
||||
}
|
||||
},
|
||||
RadarrEvent::HealthCheck => self.healthcheck(RadarrEvent::HealthCheck.resource()).await,
|
||||
RadarrEvent::GetOverview => self.diskspace(RadarrEvent::GetOverview.resource()).await,
|
||||
RadarrEvent::GetStatus => self.status(RadarrEvent::GetStatus.resource()).await,
|
||||
RadarrEvent::GetMovies => self.movies(RadarrEvent::GetMovies.resource()).await
|
||||
}
|
||||
|
||||
let mut app = self.app.lock().await;
|
||||
app.reset();
|
||||
app.reset_tick_count();
|
||||
}
|
||||
|
||||
async fn healthcheck(&self, resource: &str) {
|
||||
@@ -76,32 +69,30 @@ impl<'a> Network<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
async fn diskspace(&self, resource: &str) -> Result<Vec<DiskSpace>> {
|
||||
debug!("Handling diskspace event: {:?}", resource);
|
||||
async fn diskspace(&self, resource: &str) {
|
||||
self.handle_get_request::<Vec<DiskSpace>>(resource, | disk_space_vec, mut app | {
|
||||
let DiskSpace {
|
||||
free_space,
|
||||
total_space,
|
||||
..
|
||||
} = &disk_space_vec[0];
|
||||
|
||||
Ok(
|
||||
self
|
||||
.call_radarr_api(resource)
|
||||
.await
|
||||
.send()
|
||||
.await?
|
||||
.json::<Vec<DiskSpace>>()
|
||||
.await?,
|
||||
)
|
||||
app.data.radarr_data.free_space = free_space.as_u64().unwrap();
|
||||
app.data.radarr_data.total_space = total_space.as_u64().unwrap();
|
||||
}).await;
|
||||
}
|
||||
|
||||
async fn status(&self, resource: &str) -> Result<SystemStatus> {
|
||||
debug!("Handling system status event: {:?}", resource);
|
||||
async fn status(&self, resource: &str) {
|
||||
self.handle_get_request::<SystemStatus>(resource, | system_status, mut app | {
|
||||
app.data.radarr_data.version = system_status.version;
|
||||
app.data.radarr_data.start_time = system_status.start_time;
|
||||
}).await;
|
||||
}
|
||||
|
||||
Ok(
|
||||
self
|
||||
.call_radarr_api(resource)
|
||||
.await
|
||||
.send()
|
||||
.await?
|
||||
.json::<SystemStatus>()
|
||||
.await?,
|
||||
)
|
||||
async fn movies(&self, resource: &str) {
|
||||
self.handle_get_request::<Vec<Movie>>(resource, |movie_vec, mut app| {
|
||||
app.data.radarr_data.movies.set_items(movie_vec);
|
||||
}).await;
|
||||
}
|
||||
|
||||
async fn call_radarr_api(&self, resource: &str) -> RequestBuilder {
|
||||
@@ -123,4 +114,24 @@ impl<'a> Network<'a> {
|
||||
))
|
||||
.header("X-Api-Key", api_token)
|
||||
}
|
||||
|
||||
async fn handle_get_request<T>(&self, resource: &str, mut app_update_fn: impl FnMut(T, MutexGuard<App>))
|
||||
where
|
||||
T: DeserializeOwned {
|
||||
match self.call_radarr_api(resource)
|
||||
.await
|
||||
.send()
|
||||
.await {
|
||||
Ok(response) => {
|
||||
match utils::parse_response::<T>(response).await {
|
||||
Ok(value) => {
|
||||
let app = self.app.lock().await;
|
||||
app_update_fn(value, app);
|
||||
}
|
||||
Err(e) => error!("Failed to parse movie response! {:?}", e)
|
||||
}
|
||||
}
|
||||
Err(e) => error!("Failed to fetch movies. {:?}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
use reqwest::Response;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
pub async fn parse_response<T: DeserializeOwned>(response: Response) -> Result<T, reqwest::Error> {
|
||||
response.json::<T>().await
|
||||
}
|
||||
Reference in New Issue
Block a user