Added the full Radarr CLI so users can programmatically access all the same management features as in the TUI

This commit is contained in:
2024-10-29 18:47:40 -06:00
parent 217d3242a8
commit 1f8d72c939
65 changed files with 9401 additions and 1370 deletions
+60 -20
View File
@@ -1,11 +1,11 @@
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter};
use std::sync::atomic::{AtomicUsize, Ordering};
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use radarr_models::RadarrSerdeable;
use regex::Regex;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use serde_json::Number;
pub mod radarr_models;
pub mod servarr_data;
pub mod stateful_list;
@@ -29,6 +29,12 @@ pub enum Route {
Tautulli,
}
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[serde(untagged)]
pub enum Serdeable {
Radarr(RadarrSerdeable),
}
pub trait Scrollable {
fn scroll_down(&mut self);
fn scroll_up(&mut self);
@@ -88,19 +94,42 @@ impl Scrollable for ScrollableText {
}
}
#[derive(Default, Deserialize, Debug, Clone, PartialEq, Eq)]
#[derive(Default, Deserialize, Debug)]
#[serde(from = "String")]
pub struct HorizontallyScrollableText {
pub text: String,
pub offset: RefCell<usize>,
pub offset: AtomicUsize,
}
impl Clone for HorizontallyScrollableText {
fn clone(&self) -> Self {
HorizontallyScrollableText {
text: self.text.clone(),
offset: AtomicUsize::new(self.offset.load(Ordering::SeqCst)),
}
}
}
impl PartialEq for HorizontallyScrollableText {
fn eq(&self, other: &Self) -> bool {
self.text == other.text
}
}
impl Eq for HorizontallyScrollableText {}
impl From<String> for HorizontallyScrollableText {
fn from(text: String) -> HorizontallyScrollableText {
HorizontallyScrollableText::new(text)
}
}
impl From<&String> for HorizontallyScrollableText {
fn from(text: &String) -> HorizontallyScrollableText {
HorizontallyScrollableText::new(text.clone())
}
}
impl From<&str> for HorizontallyScrollableText {
fn from(text: &str) -> HorizontallyScrollableText {
HorizontallyScrollableText::new(text.to_owned())
@@ -109,14 +138,14 @@ impl From<&str> for HorizontallyScrollableText {
impl Display for HorizontallyScrollableText {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if *self.offset.borrow() == 0 {
if self.offset.load(Ordering::SeqCst) == 0 {
write!(f, "{}", self.text)
} else {
let text_vec = self.text.chars().collect::<Vec<_>>();
write!(
f,
"{}",
text_vec[*self.offset.borrow()..]
text_vec[self.offset.load(Ordering::SeqCst)..]
.iter()
.cloned()
.collect::<String>()
@@ -138,7 +167,7 @@ impl HorizontallyScrollableText {
pub fn new(text: String) -> HorizontallyScrollableText {
HorizontallyScrollableText {
text,
offset: RefCell::new(0),
offset: AtomicUsize::new(0),
}
}
@@ -147,46 +176,44 @@ impl HorizontallyScrollableText {
}
pub fn scroll_left(&self) {
if *self.offset.borrow() < self.len() {
let new_offset = *self.offset.borrow() + 1;
*self.offset.borrow_mut() = new_offset;
if self.offset.load(Ordering::SeqCst) < self.len() {
self.offset.fetch_add(1, Ordering::SeqCst);
}
}
pub fn scroll_right(&self) {
if *self.offset.borrow() > 0 {
let new_offset = *self.offset.borrow() - 1;
*self.offset.borrow_mut() = new_offset;
if self.offset.load(Ordering::SeqCst) > 0 {
self.offset.fetch_sub(1, Ordering::SeqCst);
}
}
pub fn scroll_home(&self) {
*self.offset.borrow_mut() = self.len();
self.offset.store(self.len(), Ordering::SeqCst);
}
pub fn reset_offset(&self) {
*self.offset.borrow_mut() = 0;
self.offset.store(0, Ordering::SeqCst);
}
pub fn scroll_left_or_reset(&self, width: usize, is_current_selection: bool, can_scroll: bool) {
if can_scroll && is_current_selection && self.len() >= width {
if *self.offset.borrow() < self.len() {
if self.offset.load(Ordering::SeqCst) < self.len() {
self.scroll_left();
} else {
self.reset_offset();
}
} else if *self.offset.borrow() != 0 && !is_current_selection {
} else if self.offset.load(Ordering::SeqCst) != 0 && !is_current_selection {
self.reset_offset();
}
}
pub fn pop(&mut self) {
if *self.offset.borrow() < self.len() {
if self.offset.load(Ordering::SeqCst) < self.len() {
let (index, _) = self
.text
.chars()
.enumerate()
.nth(self.len() - *self.offset.borrow() - 1)
.nth(self.len() - self.offset.load(Ordering::SeqCst) - 1)
.unwrap();
self.text = self
.text
@@ -202,7 +229,7 @@ impl HorizontallyScrollableText {
if self.text.is_empty() {
self.text.push(character);
} else {
let index = self.len() - *self.offset.borrow();
let index = self.len() - self.offset.load(Ordering::SeqCst);
if index == self.len() {
self.text.push(character);
@@ -338,3 +365,16 @@ pub fn strip_non_search_characters(input: &str) -> String {
.replace_all(&input.to_lowercase(), "")
.to_string()
}
#[macro_export]
macro_rules! serde_enum_from {
($enum_name:ident { $($variant:ident($ty:ty),)* }) => {
$(
impl From<$ty> for $enum_name {
fn from(value: $ty) -> Self {
$enum_name::$variant(value)
}
}
)*
}
}