use crate::util::*;
use anyhow::{Context, Result};
use clap::Args;
use smol::{
fs::OpenOptions,
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
};
use std::path::PathBuf;
use willow25::{prelude::*, storage::*};
#[derive(Args)]
pub struct BlockArgs {
pub domain: String,
#[arg(short, long)]
pub collection: Option<PathBuf>,
}
pub async fn block(args: &BlockArgs) -> Result<()> {
let (domain, _) = get_domain(Some(&args.domain), "block")?;
warn_deprecated_domain_encoding(&args.domain, &domain).await;
let sneakerweb_fs_path = sneakerweb_dir(args.collection.as_ref()).await?;
let mut store = PersistentStore::new(&sneakerweb_fs_path)
.await
.context("could not open sneakerweb storage")?;
match store
.forget_area(
&NamespaceId::from_bytes(&SNEAKERWEB_NAMESPACE_ID_BYTES),
&Area::new_subspace_area(domain),
)
.await
{
Ok(_) => {
yay(&format!(
"forgot entries for domain {}",
domain_style(&args.domain)
))
.await
}
Err(_) => {
oh_no(&format!(
"failed to forget sneakerweb entries for domain {}",
domain_style(&args.domain)
))
.await
}
}
let blocklist_path = sneakerweb_fs_path.join("blocked");
let blocklist = OpenOptions::new()
.create(true)
.read(true)
.write(true)
.open(blocklist_path)
.await
.context(
"could neither create nor open 'blocked' file in the sneakerweb config directory",
)?;
let mut blocklist = BufReader::new(blocklist);
let mut line = String::new();
while let Ok(n) = blocklist.read_line(&mut line).await
&& n > 0
{
if line
.split_ascii_whitespace()
.next()
.is_some_and(|domain| domain == args.domain)
{
hmm(&format!(
"domain {} is already in your list of blocked domains",
domain_style(&args.domain)
))
.await;
return Ok(());
}
line.clear();
}
blocklist
.write_all(format!("{}\n", args.domain).as_bytes())
.await?;
yay("updated list of blocked domains").await;
Ok(())
}