Function for the [`Commands::Remove`] in the CLI.
( interaction: &mut I, remove_args: RemoveArgs, )
| 37 | #[allow(clippy::too_many_arguments)] |
| 38 | /// Function for the [`Commands::Remove`] in the CLI. |
| 39 | pub async fn remove<I: UserInteraction>( |
| 40 | interaction: &mut I, |
| 41 | remove_args: RemoveArgs, |
| 42 | ) -> Result<()> { |
| 43 | let RemoveArgs { query, filter, dry_run, force, remove_pdf, keep_pdf } = remove_args; |
| 44 | |
| 45 | // First find matching papers |
| 46 | let mut papers = Query::text(&query).execute(&mut interaction.learner().database).await?; |
| 47 | |
| 48 | // Apply filters |
| 49 | if let Some(author) = &filter.author { |
| 50 | let author_papers = |
| 51 | Query::by_author(author).execute(&mut interaction.learner().database).await?; |
| 52 | papers.retain(|p| author_papers.contains(p)); |
| 53 | } |
| 54 | |
| 55 | if let Some(source) = &filter.source { |
| 56 | papers.retain(|p| p.source == *source); |
| 57 | } |
| 58 | |
| 59 | if let Some(date_str) = &filter.before { |
| 60 | let date = parse_date(date_str)?; |
| 61 | papers.retain(|p| p.publication_date < date); |
| 62 | } |
| 63 | |
| 64 | if papers.is_empty() { |
| 65 | interaction.reply(ResponseContent::Info("No papers found matching criteria"))?; |
| 66 | return Ok(()); |
| 67 | } |
| 68 | |
| 69 | // Show matching papers and their PDF status |
| 70 | interaction.reply(ResponseContent::Papers(&papers))?; |
| 71 | |
| 72 | // For dry run, stop here |
| 73 | if dry_run { |
| 74 | interaction |
| 75 | .reply(ResponseContent::Info(&format!("Dry run: would remove {} papers", papers.len())))?; |
| 76 | return Ok(()); |
| 77 | } |
| 78 | |
| 79 | // TODO: This is absurd with alloc... lol |
| 80 | let reply: String; |
| 81 | if !force |
| 82 | && !interaction.confirm(if papers.len() == 1 { |
| 83 | reply = "Are you sure you want to remove this paper?".to_string(); |
| 84 | &reply |
| 85 | } else { |
| 86 | reply = format!("Are you sure you want to remove these {} papers?", papers.len()); |
| 87 | &reply |
| 88 | })? |
| 89 | { |
| 90 | interaction.reply(ResponseContent::Info("Operation cancelled"))?; |
| 91 | return Ok(()); |
| 92 | } |
| 93 | |
| 94 | // Determine PDF handling |
| 95 | let should_remove_pdfs = if remove_pdf { |
| 96 | true |