From 349cdbdfad97e0598be577bb58aab80a20bb8b04 Mon Sep 17 00:00:00 2001 From: jan-gerhard-schopp Date: Mon, 16 Sep 2024 14:37:42 +0200 Subject: [PATCH] Add request date sort --- Cargo.lock | 11 ++++++ readme.md | 2 ++ src/main.rs | 69 ++++++++++++++++++++------------------ src/media_item.rs | 5 +++ src/overseerr/responses.rs | 2 +- src/shared.rs | 33 +++++++++++++++--- 6 files changed, 84 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 422fea3..0fa5527 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,6 +656,7 @@ dependencies = [ "futures", "itertools", "once_cell", + "openssl", "reqwest", "serde", "serde-xml-rs", @@ -792,6 +793,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-src" +version = "111.28.2+1.1.1w" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb1830e20a48a975ca898ca8c1d036a36c3c6c5cb7dabc1c216706587857920f" +dependencies = [ + "cc", +] + [[package]] name = "openssl-sys" version = "0.9.80" @@ -801,6 +811,7 @@ dependencies = [ "autocfg", "cc", "libc", + "openssl-src", "pkg-config", "vcpkg", ] diff --git a/readme.md b/readme.md index d39cc26..f76830b 100644 --- a/readme.md +++ b/readme.md @@ -80,6 +80,8 @@ You can also pass an argument to the program to skip the sorting screen and go s - `-n`: Sort by name - `-nd`: Sort by name, in descending order - `-t`: Sort by media type +- `-r`: Sort by request date +- `-rd`: Sort by request date, in descending order #### Getting a list of all media diff --git a/src/main.rs b/src/main.rs index ebd0562..453bcf1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ use itertools::Itertools; use overseerr::MediaRequest; use shared::{Order, SortingOption, SortingValue}; use std::{io, process::Command}; - +use std::cmp::PartialEq; use arguments::Arguments; use config::Config; use dialoguer::MultiSelect; @@ -30,15 +30,17 @@ async fn main() -> Result<()> { Arguments::read_args()?; - let mut deletion_items = get_deletion_items().await?; + let deletion_items = get_deletion_items().await?; show_requests_result(&deletion_items)?; clear_screen()?; - let chosen = choose_items_to_delete(&mut deletion_items)?; + let sorted_requests = choose_sorting(deletion_items)?; + + let chosen_indexes = choose_items_to_delete(&sorted_requests)?; - delete_chosen_items(&mut deletion_items, &chosen).await?; + delete_chosen_items(sorted_requests, chosen_indexes).await?; Ok(()) } @@ -168,16 +170,14 @@ fn show_requests_result(requests: &Vec) -> Result<()> { Ok(()) } -fn choose_items_to_delete(requests: &mut Vec) -> Result> { - choose_sorting(requests)?; - +fn choose_items_to_delete(requests: &Vec) -> Result> { clear_screen()?; let items_to_show = Config::global().items_shown; let chosen: Vec = MultiSelect::new() .with_prompt("Choose what media to delete (SPACE to select, ENTER to confirm selection)") .max_length(items_to_show) - .items(&requests) + .items(requests) .interact()?; if chosen.len() == 0 { @@ -187,14 +187,13 @@ fn choose_items_to_delete(requests: &mut Vec) -> Result) -> Result<()> { +fn choose_sorting(mut requests: Vec) -> Result> { clear_screen()?; - let args = Arguments::get_args(); let sort = match args.sorting { @@ -205,15 +204,16 @@ fn choose_sorting(requests: &mut Vec) -> Result<()> { match sort.sorting_value { SortingValue::Name => (), SortingValue::Size => requests.sort_by_key(|req| req.get_disk_size()), - SortingValue::Type => requests.sort_by_key(|req| req.media_type), - }; + SortingValue::Type => requests.sort_by_key(|req| req.media_type.clone()), + SortingValue::RequestedDate => requests.sort_by_key(|req| req.get_requested_date()), + } - match sort.sorting_direction { - Order::Asc => (), - Order::Desc => requests.reverse(), - }; + // Reverse if sorting direction is descending + if sort.sorting_direction == Order::Desc { + requests.reverse(); + } - Ok(()) + Ok(requests) } fn choose_sorting_dialogue() -> Result { @@ -224,6 +224,8 @@ fn choose_sorting_dialogue() -> Result { println!("Size - Descending: s"); println!("Size - Ascending: sa"); println!("Type - Descending: t"); + println!("Requested Date - Ascending: r"); + println!("Requested Date - Descending: rd"); let input = get_user_input()?; @@ -275,32 +277,35 @@ fn verify_chosen(requests: &Vec, chosen: &Vec) -> Resu } async fn delete_chosen_items( - requests: &mut Vec, - chosen: &Vec, + mut requests: Vec, + chosen: Vec, ) -> Result<()> { let mut errs: Vec<(String, Report)> = Vec::new(); for selection in chosen.into_iter().rev() { - let media_item = requests.swap_remove(*selection); + let media_item = requests.swap_remove(selection); let title = media_item.title.clone(); if let Err(err) = media_item.remove_from_server().await { errs.push((title, err)); } } - if errs.len() > 0 { - println!("Had some errors deleting items:\n"); - errs.iter().for_each(|err| { - println!( - "Got the following error while deleting {}: {}", - err.0, err.0 - ); - print_line(); - }); - - wait(None)?; + // If there are no errors, return early + if errs.is_empty() { + return Ok(()); } + // Log errors if there are any + println!("Had some errors deleting items:\n"); + errs.iter().for_each(|(title, err)| { + println!( + "Got the following error while deleting {}: {}", + title, err + ); + print_line(); + }); + + wait(None)?; Ok(()) } diff --git a/src/media_item.rs b/src/media_item.rs index c6652a3..939dec9 100644 --- a/src/media_item.rs +++ b/src/media_item.rs @@ -1,5 +1,6 @@ use color_eyre::{eyre::eyre, owo_colors::OwoColorize, Result}; use std::fmt::{Debug, Display}; +use chrono::{DateTime, Utc}; use tokio::try_join; use crate::{ @@ -175,6 +176,10 @@ impl CompleteMediaItem { Ok(()) } + pub fn get_requested_date(&self) -> Option> { + self.request.as_ref().map(|request| request.created_at) + } + pub fn get_disk_size(&self) -> i64 { match (self.arr_data.as_ref(), self.arr_4k_data.as_ref()) { (Some(arr_data), None) => arr_data.get_disk_size(), diff --git a/src/overseerr/responses.rs b/src/overseerr/responses.rs index aaf84c0..c7bf537 100644 --- a/src/overseerr/responses.rs +++ b/src/overseerr/responses.rs @@ -2,7 +2,7 @@ use color_eyre::owo_colors::OwoColorize; use serde::Deserialize; use serde_repr::Deserialize_repr; use std::fmt::Display; - +use openssl::pkey::Public; use crate::shared::MediaType; #[derive(Debug, Deserialize)] diff --git a/src/shared.rs b/src/shared.rs index 8745051..6d01f3b 100644 --- a/src/shared.rs +++ b/src/shared.rs @@ -24,11 +24,22 @@ pub enum Order { Asc, } +impl PartialEq for Order { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Order::Asc, Order::Asc) => true, + (Order::Desc, Order::Desc) => true, + _ => false, + } + } +} + #[derive(Debug, Clone, Copy)] pub enum SortingValue { Name, Size, Type, + RequestedDate, } #[derive(Debug, Clone)] @@ -50,35 +61,47 @@ impl SortingOption { pub fn from_str(s: &str) -> Result { match s { "nd" => { - return Ok(SortingOption { + Ok(SortingOption { sorting_value: SortingValue::Name, sorting_direction: Order::Desc, }) } "n" => { - return Ok(SortingOption { + Ok(SortingOption { sorting_value: SortingValue::Name, sorting_direction: Order::Asc, }) } "sa" => { - return Ok(SortingOption { + Ok(SortingOption { sorting_value: SortingValue::Size, sorting_direction: Order::Asc, }) } "s" => { - return Ok(SortingOption { + Ok(SortingOption { sorting_value: SortingValue::Size, sorting_direction: Order::Desc, }) } "t" => { - return Ok(SortingOption { + Ok(SortingOption { sorting_value: SortingValue::Type, sorting_direction: Order::Desc, }) } + "r" => { + Ok(SortingOption { + sorting_value: SortingValue::RequestedDate, + sorting_direction: Order::Asc, + }) + } + "rd" => { + Ok(SortingOption { + sorting_value: SortingValue::RequestedDate, + sorting_direction: Order::Desc, + }) + } _ => Err(eyre!("Not a valid Sorting Option")), } }