Add `TorrentState` enum, update qbittorrent, bugfixes
This commit is contained in:
parent
edf45342fb
commit
2b4cd84d7f
|
@ -599,7 +599,6 @@ dependencies = [
|
|||
"serde_json",
|
||||
"serde_repr",
|
||||
"serde_with",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e3e9e26be49aeb34b3985dafbfd043ba6fcc51e2
|
||||
Subproject commit c3395926894fda44c6a203f8293beac609cabb5e
|
|
@ -1,4 +1,7 @@
|
|||
pub mod qbittorrent;
|
||||
mod qbittorrent_client;
|
||||
pub use qbittorrent_client::*;
|
||||
|
||||
use crate::common;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
|
@ -10,10 +13,11 @@ pub type ClientResult<T> = Result<T, ClientError>;
|
|||
pub trait TorrentClient {
|
||||
async fn login(&mut self, url: &str, username: &str, password: &str) -> ClientResult<()>;
|
||||
|
||||
async fn get_torrent_list(&self) -> ClientResult<Vec<TorrentInfo>>;
|
||||
async fn get_torrent_list(&self, params: Option<common::GetTorrentListParams>) -> ClientResult<Vec<TorrentInfo>>;
|
||||
|
||||
async fn get_torrent_trackers(&self, torrent: &TorrentInfo) -> ClientResult<Vec<TorrentTracker>>;
|
||||
async fn add_torrent_tracker(&self, torrent: &TorrentInfo, tracker_url: String) -> ClientResult<()>;
|
||||
async fn add_torrent_trackers(&self, torrent: &TorrentInfo, trackers: Vec<String>) -> ClientResult<()>;
|
||||
async fn replace_torrent_tracker(&self, torrent: &TorrentInfo, old_url: String, new_url: String) -> ClientResult<()>;
|
||||
async fn remove_torrent_tracker(&self, torrent: &TorrentInfo, tracker_url: String) -> ClientResult<()>;
|
||||
|
||||
|
|
|
@ -1,25 +1,29 @@
|
|||
use crate::torrent::{TorrentInfo, TorrentTracker, TorrentUpload};
|
||||
use super::{TorrentClient, ClientResult};
|
||||
use qbittorrent::QBittorrentClient;
|
||||
|
||||
pub use qbittorrent;
|
||||
|
||||
use qbittorrent::{client::QBittorrentClient, common::GetTorrentListParams};
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
impl From<&qbittorrent::TorrentInfo> for TorrentInfo {
|
||||
fn from(torrent: &qbittorrent::TorrentInfo) -> Self {
|
||||
impl From<&qbittorrent::torrent::TorrentInfo> for TorrentInfo {
|
||||
fn from(torrent: &qbittorrent::torrent::TorrentInfo) -> Self {
|
||||
TorrentInfo {
|
||||
name: torrent.name.clone(),
|
||||
trackers: vec![torrent.tracker.clone()], // NOTE: qBittorrent only gives us one tracker.
|
||||
category: torrent.category.clone(),
|
||||
tags: torrent.tags.clone(),
|
||||
hash: torrent.hash.clone(),
|
||||
state: torrent.state.clone().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For some reason I have to implement this twice smh
|
||||
impl Into<qbittorrent::TorrentInfo> for &TorrentInfo {
|
||||
fn into(self) -> qbittorrent::TorrentInfo {
|
||||
let mut t = qbittorrent::TorrentInfo::default();
|
||||
impl Into<qbittorrent::torrent::TorrentInfo> for &TorrentInfo {
|
||||
fn into(self) -> qbittorrent::torrent::TorrentInfo {
|
||||
let mut t = qbittorrent::torrent::TorrentInfo::default();
|
||||
t.name = self.name.clone();
|
||||
t.tracker = self.trackers.first().unwrap_or(&String::new()).clone();
|
||||
t.category = self.category.clone();
|
||||
|
@ -31,9 +35,9 @@ impl Into<qbittorrent::TorrentInfo> for &TorrentInfo {
|
|||
}
|
||||
|
||||
// For some reason I have to implement this twice smh
|
||||
impl Into<qbittorrent::TorrentInfo> for TorrentInfo {
|
||||
fn into(self) -> qbittorrent::TorrentInfo {
|
||||
let mut t = qbittorrent::TorrentInfo::default();
|
||||
impl Into<qbittorrent::torrent::TorrentInfo> for TorrentInfo {
|
||||
fn into(self) -> qbittorrent::torrent::TorrentInfo {
|
||||
let mut t = qbittorrent::torrent::TorrentInfo::default();
|
||||
t.name = self.name.clone();
|
||||
t.tracker = self.trackers.first().unwrap_or(&String::new()).clone();
|
||||
t.category = self.category.clone();
|
||||
|
@ -44,8 +48,8 @@ impl Into<qbittorrent::TorrentInfo> for TorrentInfo {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<qbittorrent::TorrentUpload> for TorrentUpload {
|
||||
fn from(upload: qbittorrent::TorrentUpload) -> Self {
|
||||
impl From<qbittorrent::torrent::TorrentUpload> for TorrentUpload {
|
||||
fn from(upload: qbittorrent::torrent::TorrentUpload) -> Self {
|
||||
TorrentUpload {
|
||||
urls: upload.urls,
|
||||
torrents: upload.torrents,
|
||||
|
@ -56,9 +60,9 @@ impl From<qbittorrent::TorrentUpload> for TorrentUpload {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<qbittorrent::TorrentUpload> for &TorrentUpload {
|
||||
fn into(self) -> qbittorrent::TorrentUpload {
|
||||
let mut t = qbittorrent::TorrentUpload::default();
|
||||
impl Into<qbittorrent::torrent::TorrentUpload> for &TorrentUpload {
|
||||
fn into(self) -> qbittorrent::torrent::TorrentUpload {
|
||||
let mut t = qbittorrent::torrent::TorrentUpload::default();
|
||||
t.urls = self.urls.clone();
|
||||
t.torrents = self.torrents.clone();
|
||||
t.tags = self.tags.clone();
|
||||
|
@ -69,8 +73,8 @@ impl Into<qbittorrent::TorrentUpload> for &TorrentUpload {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<&qbittorrent::TorrentTracker> for TorrentTracker {
|
||||
fn from(tracker: &qbittorrent::TorrentTracker) -> Self {
|
||||
impl From<&qbittorrent::torrent::TorrentTracker> for TorrentTracker {
|
||||
fn from(tracker: &qbittorrent::torrent::TorrentTracker) -> Self {
|
||||
TorrentTracker {
|
||||
url: tracker.url.clone(),
|
||||
status: tracker.status.clone().into(),
|
||||
|
@ -79,14 +83,36 @@ impl From<&qbittorrent::TorrentTracker> for TorrentTracker {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<qbittorrent::TrackerStatus> for crate::torrent::TrackerStatus {
|
||||
fn from(status: qbittorrent::TrackerStatus) -> Self {
|
||||
impl From<qbittorrent::torrent::TrackerStatus> for crate::torrent::TrackerStatus {
|
||||
fn from(status: qbittorrent::torrent::TrackerStatus) -> Self {
|
||||
use qbittorrent::torrent::TrackerStatus as QBStatus;
|
||||
|
||||
match status {
|
||||
qbittorrent::TrackerStatus::Disabled => crate::torrent::TrackerStatus::Disabled,
|
||||
qbittorrent::TrackerStatus::NotContacted => crate::torrent::TrackerStatus::NotContacted,
|
||||
qbittorrent::TrackerStatus::Working => crate::torrent::TrackerStatus::Working,
|
||||
qbittorrent::TrackerStatus::Updating => crate::torrent::TrackerStatus::Updating,
|
||||
qbittorrent::TrackerStatus::NotWorking => crate::torrent::TrackerStatus::NotWorking,
|
||||
QBStatus::Disabled => Self::Disabled,
|
||||
QBStatus::NotContacted => Self::NotContacted,
|
||||
QBStatus::Working => Self::Working,
|
||||
QBStatus::Updating => Self::Updating,
|
||||
QBStatus::NotWorking => Self::NotWorking,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<qbittorrent::torrent::TorrentState> for crate::torrent::TorrentState {
|
||||
fn from(state: qbittorrent::torrent::TorrentState) -> Self {
|
||||
use qbittorrent::torrent::TorrentState as QBState;
|
||||
|
||||
match state {
|
||||
QBState::Error => Self::Error,
|
||||
QBState::MissingFiles => Self::MissingFiles,
|
||||
QBState::Uploading | QBState::StalledUP | QBState::ForcedUP | QBState::CheckingUP => Self::Uploading,
|
||||
QBState::PausedUP => Self::PausedUploading,
|
||||
QBState::QueuedUP => Self::QueuedUploading,
|
||||
QBState::Downloading | QBState::StalledDL | QBState::ForcedDL |
|
||||
QBState::Allocating | QBState::MetaDownloading | QBState::CheckingDL |
|
||||
QBState::CheckingResumeData | QBState::Moving => Self::Downloading,
|
||||
QBState::PausedDL => Self::PausedDownloading,
|
||||
QBState::QueuedDL => Self::QueuedDownloading,
|
||||
QBState::Unknown => Self::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,8 +123,8 @@ impl TorrentClient for QBittorrentClient {
|
|||
Ok(Self::login(&mut self, url, username, password).await?)
|
||||
}
|
||||
|
||||
async fn get_torrent_list(&self) -> ClientResult<Vec<TorrentInfo>> {
|
||||
Ok(Self::get_torrent_list(self).await?.iter().map(|t| t.into()).collect())
|
||||
async fn get_torrent_list(&self, params: Option<GetTorrentListParams>) -> ClientResult<Vec<TorrentInfo>> {
|
||||
Ok(Self::get_torrent_list(self, params).await?.iter().map(|t| t.into()).collect())
|
||||
}
|
||||
|
||||
async fn get_torrent_trackers(&self, torrent: &TorrentInfo) -> ClientResult<Vec<TorrentTracker>> {
|
||||
|
@ -109,6 +135,10 @@ impl TorrentClient for QBittorrentClient {
|
|||
Ok(Self::add_torrent_tracker(self, &torrent.into(), tracker_url).await?)
|
||||
}
|
||||
|
||||
async fn add_torrent_trackers(&self, torrent: &TorrentInfo, trackers: Vec<String>) -> ClientResult<()> {
|
||||
Ok(Self::add_torrent_trackers(self, &torrent.into(), trackers).await?)
|
||||
}
|
||||
|
||||
async fn replace_torrent_tracker(&self, torrent: &TorrentInfo, old_url: String, new_url: String) -> ClientResult<()> {
|
||||
Ok(Self::replace_torrent_tracker(self, &torrent.into(), old_url, new_url).await?)
|
||||
}
|
||||
|
@ -126,7 +156,7 @@ impl TorrentClient for QBittorrentClient {
|
|||
}
|
||||
|
||||
async fn remove_torrents(&self, torrents: Vec<TorrentInfo>, delete_files: bool) -> ClientResult<()> {
|
||||
let torrents: Vec<qbittorrent::TorrentInfo> = torrents.iter().map(|t| t.into()).collect();
|
||||
let torrents: Vec<qbittorrent::torrent::TorrentInfo> = torrents.iter().map(|t| t.into()).collect();
|
||||
Ok(Self::remove_torrents(self, torrents, delete_files).await?)
|
||||
}
|
||||
|
|
@ -5,13 +5,13 @@ use qbittorrent::error::ClientError as QClientError;
|
|||
#[derive(Debug)]
|
||||
pub enum ClientError {
|
||||
/// Http error
|
||||
Http(Box<dyn Error>),
|
||||
Http(Box<dyn Error + Send + Sync>),
|
||||
|
||||
/// Authorization error
|
||||
Authorization,
|
||||
|
||||
/// Parsing error (json for qBittorrent)
|
||||
Parsing(Box<dyn Error>),
|
||||
Parsing(Box<dyn Error + Send + Sync>),
|
||||
}
|
||||
|
||||
impl From<QClientError> for ClientError {
|
||||
|
|
|
@ -5,3 +5,5 @@ pub mod client;
|
|||
//pub use client::*;
|
||||
|
||||
pub mod error;
|
||||
|
||||
pub use qbittorrent::common;
|
|
@ -1,10 +1,56 @@
|
|||
#[derive(Debug, Default)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct TorrentInfo {
|
||||
pub name: String,
|
||||
pub trackers: Vec<String>,
|
||||
pub category: String,
|
||||
pub tags: Vec<String>,
|
||||
pub hash: String,
|
||||
pub state: TorrentState,
|
||||
}
|
||||
|
||||
impl TorrentInfo {
|
||||
pub fn from_hash(hash: String) -> TorrentInfo {
|
||||
let mut def = TorrentInfo::default();
|
||||
def.hash = hash;
|
||||
|
||||
def
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum TorrentState {
|
||||
/// Some error occurred
|
||||
Error,
|
||||
|
||||
/// Torrent data files is missing
|
||||
MissingFiles,
|
||||
|
||||
/// Torrent is being seeded and data is being transferred
|
||||
Uploading,
|
||||
|
||||
/// Torrent is paused but in a seeding state.
|
||||
PausedUploading,
|
||||
|
||||
/// Torrent is queued but in a seeding state.
|
||||
QueuedUploading,
|
||||
|
||||
/// Torrent is being downloaded and data is being transferred
|
||||
Downloading,
|
||||
|
||||
/// Torrent is paused but in a downloading state.
|
||||
PausedDownloading,
|
||||
|
||||
/// Torrent is queued but in a downloading state.
|
||||
QueuedDownloading,
|
||||
|
||||
/// The state is unknown
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl Default for TorrentState {
|
||||
fn default() -> Self {
|
||||
Self::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
|
@ -81,8 +127,9 @@ impl TorrentUploadBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn paused(&mut self, paused: bool) -> &mut Self {
|
||||
self.params.paused = Some(paused);
|
||||
/// Set the upload to be paused by default.
|
||||
pub fn paused(&mut self) -> &mut Self {
|
||||
self.params.paused = Some(true);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue