Fix a bug that made it impossible to add torrents in desktop

This commit is contained in:
Igor Katson 2023-12-08 09:41:54 +00:00
parent 2b9129221d
commit 0751dbc5fc
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
4 changed files with 26 additions and 18 deletions

15
TODO.md
View file

@ -3,7 +3,7 @@
- [x (partial)] per-peer stats - [x (partial)] per-peer stats
- [x] use some concurrent hashmap e.g. flurry or dashmap - [x] use some concurrent hashmap e.g. flurry or dashmap
- [x] tracing instead of logging. Debugging peers: RUST_LOG=[{peer=.*}]=debug - [x] tracing instead of logging. Debugging peers: RUST_LOG=[{peer=.*}]=debug
test-log for tests test-log for tests
- [x] reopen read only is bugged - [x] reopen read only is bugged
- [x] initializing/checking - [x] initializing/checking
- [x] blocks the whole process. Need to break it up. On slower devices (rpi) just hangs for a good while - [x] blocks the whole process. Need to break it up. On slower devices (rpi) just hangs for a good while
@ -19,7 +19,6 @@
- [x] for torrents with a few seeds might be cool to re-query DHT once in a while. - [x] for torrents with a few seeds might be cool to re-query DHT once in a while.
- [x] don't leak memory when deleting torrents (i.e. remove torrent information (seen peers etc) once the torrent is deleted) - [x] don't leak memory when deleting torrents (i.e. remove torrent information (seen peers etc) once the torrent is deleted)
- [x] Routing table - is it balanced properly? - [x] Routing table - is it balanced properly?
- [ ]
- [x] Don't query Bad nodes - [x] Don't query Bad nodes
- [-] Buckets that have not been changed in 15 minutes should be "refreshed." (per RFC) - [-] Buckets that have not been changed in 15 minutes should be "refreshed." (per RFC)
- [x] Did it, but it's flawed: starts repeating the same queries again as neighboring refreshes - [x] Did it, but it's flawed: starts repeating the same queries again as neighboring refreshes
@ -33,25 +32,31 @@
- [x] Ensure that if we query the "returned" nodes, they are even closer to our request than the responding node id was. - [x] Ensure that if we query the "returned" nodes, they are even closer to our request than the responding node id was.
incoming peers: incoming peers:
- [x] error managing peer: expected extended handshake, but got Bitfield(<94 bytes>) - [x] error managing peer: expected extended handshake, but got Bitfield(<94 bytes>)
- [x] do not announce when merely listing the torrent - [x] do not announce when merely listing the torrent
someday: someday:
- [x] cancellation from the client-side for the lib (i.e. stop the torrent manager) - [x] cancellation from the client-side for the lib (i.e. stop the torrent manager)
- [x] favicons for Web UI - [x] favicons for Web UI
desktop: desktop:
- [ ] on first run show options
- [ ] allow to change options later (even with a session restart) - [x] on first run show options
- [x] allow to change options later (even with a session restart)
- [ ] look at logs - allow writing them to files? Set RUST_LOG through API - [ ] look at logs - allow writing them to files? Set RUST_LOG through API
persistence: persistence:
- [ ] store total uploaded bytes, so that on restart it comes back up - [ ] store total uploaded bytes, so that on restart it comes back up
efficiency: efficiency:
- [ ] once the torrent is completed, we don't need to remember old peers - [ ] once the torrent is completed, we don't need to remember old peers
refactor: refactor:
- [x] session persistence: should add torrents even if we haven't resolved it yet - [x] session persistence: should add torrents even if we haven't resolved it yet
- [x] where are peers stored - [x] where are peers stored
- [x] http api pause/unpause etc - [x] http api pause/unpause etc
@ -61,5 +66,5 @@ refactor:
- [x] start from error state should be possible from UI - [x] start from error state should be possible from UI
- [x] checking is very slow on raspberry - [x] checking is very slow on raspberry
checked. nothing much can be done here. Even if raspberry's own libssl.so is used it's still super slow (sha1) checked. nothing much can be done here. Even if raspberry's own libssl.so is used it's still super slow (sha1)
- [ ] .rqbit-session.json file has 0 bytes when disk full. I guess fs::rename does this when disk is full? at least on linux. Couldn't repro on MacOS - [ ] .rqbit-session.json file has 0 bytes when disk full. I guess fs::rename does this when disk is full? at least on linux. Couldn't repro on MacOS

View file

@ -203,9 +203,9 @@ fn compute_only_files<ByteBuf: AsRef<[u8]>>(
/// Options for adding new torrents to the session. /// Options for adding new torrents to the session.
#[serde_as] #[serde_as]
#[derive(Default, Clone, Serialize, Deserialize)] #[derive(Default, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct AddTorrentOptions { pub struct AddTorrentOptions {
/// Start in paused state. /// Start in paused state.
#[serde(default)]
pub paused: bool, pub paused: bool,
/// A regex to only download files matching it. /// A regex to only download files matching it.
pub only_files_regex: Option<String>, pub only_files_regex: Option<String>,
@ -214,10 +214,8 @@ pub struct AddTorrentOptions {
pub only_files: Option<Vec<usize>>, pub only_files: Option<Vec<usize>>,
/// Allow writing on top of existing files, including when resuming a torrent. /// Allow writing on top of existing files, including when resuming a torrent.
/// You probably want to set it, however for safety it's not default. /// You probably want to set it, however for safety it's not default.
#[serde(default)]
pub overwrite: bool, pub overwrite: bool,
/// Only list the files in the torrent without starting it. /// Only list the files in the torrent without starting it.
#[serde(default)]
pub list_only: bool, pub list_only: bool,
/// The output folder for the torrent. If not set, the session's default one will be used. /// The output folder for the torrent. If not set, the session's default one will be used.
pub output_folder: Option<String>, pub output_folder: Option<String>,

View file

@ -3,9 +3,12 @@ import { MouseEventHandler } from "react";
export const IconButton: React.FC<{ export const IconButton: React.FC<{
onClick: () => void; onClick: () => void;
disabled?: boolean; disabled?: boolean;
className?: string;
color?: string; color?: string;
children: any; children: any;
}> = ({ onClick, disabled, color, children }) => { }> = (props) => {
const { onClick, disabled, color, children, className, ...otherProps } =
props;
const onClickStopPropagation: MouseEventHandler<HTMLAnchorElement> = (e) => { const onClickStopPropagation: MouseEventHandler<HTMLAnchorElement> = (e) => {
e.stopPropagation(); e.stopPropagation();
if (disabled) { if (disabled) {
@ -16,9 +19,10 @@ export const IconButton: React.FC<{
const colorClassName = color ? `text-${color}` : ""; const colorClassName = color ? `text-${color}` : "";
return ( return (
<a <a
className={`p-1 ${colorClassName}`} className={`p-1 ${colorClassName} ${className}`}
onClick={onClickStopPropagation} onClick={onClickStopPropagation}
href="#" href="#"
{...otherProps}
> >
{children} {children}
</a> </a>

View file

@ -2,6 +2,8 @@ import { useState } from "react";
import { RqbitWebUI } from "./rqbit-webui-src/rqbit-web"; import { RqbitWebUI } from "./rqbit-webui-src/rqbit-web";
import { CurrentDesktopState, RqbitDesktopConfig } from "./configuration"; import { CurrentDesktopState, RqbitDesktopConfig } from "./configuration";
import { ConfigModal } from "./configure"; import { ConfigModal } from "./configure";
import { IconButton } from "./rqbit-webui-src/components/IconButton";
import { BsSliders2 } from "react-icons/bs";
export const RqbitDesktop: React.FC<{ export const RqbitDesktop: React.FC<{
version: string; version: string;
@ -20,15 +22,14 @@ export const RqbitDesktop: React.FC<{
<RqbitWebUI title={`Rqbit Desktop v${version}`}></RqbitWebUI> <RqbitWebUI title={`Rqbit Desktop v${version}`}></RqbitWebUI>
)} )}
{configured && ( {configured && (
<a <IconButton
className="bi bi-sliders2 position-absolute top-0 start-0 p-3 text-primary" className="position-absolute top-0 start-0 p-3 text-primary"
onClick={(e) => { onClick={() => {
e.stopPropagation();
setConfigurationOpened(true); setConfigurationOpened(true);
}} }}
href="#" >
aria-label="Settings" <BsSliders2 />
/> </IconButton>
)} )}
<ConfigModal <ConfigModal
show={!configured || configurationOpened} show={!configured || configurationOpened}