diff --git a/crates/librqbit/src/http_api.rs b/crates/librqbit/src/http_api.rs index 3c227f0..f461384 100644 --- a/crates/librqbit/src/http_api.rs +++ b/crates/librqbit/src/http_api.rs @@ -447,13 +447,13 @@ impl ApiInternal { } fn api_torrent_action_forget(&self, idx: TorrentId) -> Result { - Err(ApiError::not_implemented("forgetting not implemented yet")) + self.session.delete(idx, false)?; + Ok(Default::default()) } fn api_torrent_action_delete(&self, idx: TorrentId) -> Result { - Err(ApiError::not_implemented( - "deleting torrent not implemented yet", - )) + self.session.delete(idx, true)?; + Ok(Default::default()) } pub async fn api_add_torrent( diff --git a/crates/librqbit/src/session.rs b/crates/librqbit/src/session.rs index e073a84..143e8b0 100644 --- a/crates/librqbit/src/session.rs +++ b/crates/librqbit/src/session.rs @@ -1,4 +1,6 @@ -use std::{borrow::Cow, io::Read, net::SocketAddr, path::PathBuf, time::Duration}; +use std::{ + borrow::Cow, collections::HashMap, io::Read, net::SocketAddr, path::PathBuf, time::Duration, +}; use anyhow::{bail, Context}; use buffers::ByteString; @@ -26,13 +28,15 @@ pub type TorrentId = usize; #[derive(Default)] pub struct SessionLocked { - torrents: Vec, + next_id: usize, + torrents: HashMap, } impl SessionLocked { fn add_torrent(&mut self, torrent: ManagedTorrentHandle) -> TorrentId { - let idx = self.torrents.len(); - self.torrents.push(torrent); + let idx = self.next_id; + self.torrents.insert(idx, torrent); + self.next_id += 1; idx } } @@ -205,7 +209,7 @@ impl Session { &self, callback: impl Fn(&mut dyn Iterator) -> R, ) -> R { - callback(&mut self.locked.read().torrents.iter().enumerate()) + callback(&mut self.locked.read().torrents.iter().map(|(id, t)| (*id, t))) } pub async fn add_torrent( @@ -404,13 +408,9 @@ impl Session { let (managed_torrent, id) = { let mut g = self.locked.write(); - if let Some((id, handle)) = g - .torrents - .iter() - .enumerate() - .find(|(_, t)| t.info_hash() == info_hash) + if let Some((id, handle)) = g.torrents.iter().find(|(_, t)| t.info_hash() == info_hash) { - return Ok(AddTorrentResponse::AlreadyManaged(id, handle.clone())); + return Ok(AddTorrentResponse::AlreadyManaged(*id, handle.clone())); } let next_id = g.torrents.len(); let managed_torrent = builder.build(error_span!("torrent", id = next_id))?; @@ -430,7 +430,25 @@ impl Session { } pub fn get(&self, id: TorrentId) -> Option { - self.locked.read().torrents.get(id).cloned() + self.locked.read().torrents.get(&id).cloned() + } + + pub fn delete(&self, id: TorrentId, delete_files: bool) -> anyhow::Result<()> { + let removed = self + .locked + .write() + .torrents + .remove(&id) + .with_context(|| format!("torrent with id {} did not exist", id))?; + + if let Some(live) = removed.live() { + let _ = live.pause()?; + } + + if delete_files { + bail!("torrent deleted, but deleting files not implemented") + } + Ok(()) } pub fn unpause(&self, handle: &ManagedTorrentHandle) -> anyhow::Result<()> { diff --git a/crates/librqbit/webui/vite.config.ts b/crates/librqbit/webui/vite.config.ts index 877950a..2317a04 100644 --- a/crates/librqbit/webui/vite.config.ts +++ b/crates/librqbit/webui/vite.config.ts @@ -1,5 +1,4 @@ import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react' // https://vitejs.dev/config/ export default defineConfig({