use std::fs;
use learner::database::Remove;
use super::*;
#[allow(clippy::too_many_arguments)]
pub async fn remove<I: UserInteraction>(
interaction: &I,
mut learner: Learner,
query: &str,
filter: &SearchFilter,
dry_run: bool,
force: bool,
remove_pdf: bool,
keep_pdf: bool,
) -> Result<()> {
let mut papers = Query::text(query).execute(&mut learner.database).await?;
if let Some(author) = &filter.author {
let author_papers = Query::by_author(author).execute(&mut learner.database).await?;
papers.retain(|p| author_papers.contains(p));
}
if let Some(source) = &filter.source {
papers.retain(|p| p.source == *source);
}
if let Some(date_str) = &filter.before {
let date = parse_date(date_str)?;
papers.retain(|p| p.publication_date < date);
}
if papers.is_empty() {
interaction.reply(ResponseContent::Info("No papers found matching criteria"))?;
return Ok(());
}
interaction.reply(ResponseContent::Papers(&papers))?;
if dry_run {
interaction
.reply(ResponseContent::Info(&format!("Dry run: would remove {} papers", papers.len())))?;
return Ok(());
}
let reply: String;
if !force
&& !interaction.confirm(if papers.len() == 1 {
reply = "Are you sure you want to remove this paper?".to_string();
&reply
} else {
reply = format!("Are you sure you want to remove these {} papers?", papers.len());
&reply
})?
{
interaction.reply(ResponseContent::Info("Operation cancelled"))?;
return Ok(());
}
let should_remove_pdfs = if remove_pdf {
true
} else if keep_pdf {
false
} else {
let storage_path = &learner.config.storage_path;
let has_pdfs = papers.iter().any(|p| storage_path.join(p.filename()).exists());
has_pdfs && interaction.confirm("Do you also want to remove associated PDFs?")?
};
for paper in &papers {
if let Err(e) = Remove::by_source(&paper.source, &paper.source_identifier)
.execute(&mut learner.database)
.await
{
interaction.reply(ResponseContent::Error(e.into()))?;
continue;
}
interaction.reply(ResponseContent::Success(&format!("Removed paper: {}", paper.title)))?;
if should_remove_pdfs {
let pdf_path = learner.config.storage_path.join(paper.filename());
if pdf_path.exists() {
fs::remove_file(&pdf_path)?;
interaction
.reply(ResponseContent::Success(&format!("Removed PDF: {}", pdf_path.display())))?;
}
}
}
Ok(())
}