Add implementer for qbittorrent
This commit is contained in:
parent
34999380db
commit
207f8b1c94
|
@ -1 +1 @@
|
|||
Subproject commit 4c907b940e6a4eaeee0c92581b62173d918b054a
|
||||
Subproject commit d0e087af2b378025416a91085934f396886f3456
|
|
@ -1,21 +1,27 @@
|
|||
pub mod qbittorrent;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
use crate::{torrent::{TorrentInfo, TorrentTracker}, error::ClientError};
|
||||
use crate::{torrent::{TorrentInfo, TorrentTracker, TorrentUpload}, error::ClientError};
|
||||
|
||||
pub type ClientResult<T> = Result<T, ClientError>;
|
||||
|
||||
#[async_trait]
|
||||
pub trait TorrentClient {
|
||||
async fn login(&self, url: &str, username: &str, password: &str) -> ClientResult<()>;
|
||||
pub trait TorrentClient<'a> {
|
||||
async fn login(&mut self, url: &'a str, username: &'a str, password: &'a str) -> ClientResult<()>;
|
||||
|
||||
async fn get_torrent_list(&self) -> 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 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<()>;
|
||||
async fn add_torrent_tracker(&self, torrent: &TorrentInfo, tracker_url: 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<()>;
|
||||
|
||||
|
||||
async fn add_torrent(&self, torrent: &TorrentInfo) -> ClientResult<()>;
|
||||
async fn add_torrent(&self, torrent: &TorrentUpload) -> ClientResult<()>;
|
||||
async fn remove_torrent(&self, torrent: &TorrentInfo, delete_files: bool) -> ClientResult<()>;
|
||||
async fn remove_torrents(&self, torrents: Vec<TorrentInfo>, delete_files: bool) -> ClientResult<()>;
|
||||
|
||||
async fn get_tags(&self) -> ClientResult<Vec<String>>;
|
||||
async fn create_tag(&self, tag: &str) -> ClientResult<()>;
|
||||
async fn delete_tag(&self, tag: &str) -> ClientResult<()>;
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
use crate::torrent::{TorrentInfo, TorrentTracker, TorrentUpload};
|
||||
use super::{TorrentClient, ClientResult};
|
||||
use qbittorrent::QBittorrentClient;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
impl From<&qbittorrent::TorrentInfo> for TorrentInfo {
|
||||
fn from(torrent: &qbittorrent::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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
t.name = self.name.clone();
|
||||
t.tracker = self.trackers.first().unwrap_or(&String::new()).clone();
|
||||
t.category = self.category.clone();
|
||||
t.tags = self.tags.clone();
|
||||
t.hash = self.hash.clone();
|
||||
|
||||
t
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
t.name = self.name.clone();
|
||||
t.tracker = self.trackers.first().unwrap_or(&String::new()).clone();
|
||||
t.category = self.category.clone();
|
||||
t.tags = self.tags.clone();
|
||||
t.hash = self.hash.clone();
|
||||
|
||||
t
|
||||
}
|
||||
}
|
||||
|
||||
impl From<qbittorrent::TorrentUpload> for TorrentUpload {
|
||||
fn from(upload: qbittorrent::TorrentUpload) -> Self {
|
||||
TorrentUpload {
|
||||
urls: upload.urls,
|
||||
torrents: upload.torrents,
|
||||
tags: upload.tags,
|
||||
category: upload.category,
|
||||
paused: upload.paused,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<qbittorrent::TorrentUpload> for &TorrentUpload {
|
||||
fn into(self) -> qbittorrent::TorrentUpload {
|
||||
let mut t = qbittorrent::TorrentUpload::default();
|
||||
t.urls = self.urls.clone();
|
||||
t.torrents = self.torrents.clone();
|
||||
t.tags = self.tags.clone();
|
||||
t.category = self.category.clone();
|
||||
t.paused = self.paused;
|
||||
|
||||
t
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&qbittorrent::TorrentTracker> for TorrentTracker {
|
||||
fn from(tracker: &qbittorrent::TorrentTracker) -> Self {
|
||||
TorrentTracker {
|
||||
url: tracker.url.clone(),
|
||||
status: tracker.status.clone().into(),
|
||||
message: Some(tracker.message.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<qbittorrent::TrackerStatus> for crate::torrent::TrackerStatus {
|
||||
fn from(status: qbittorrent::TrackerStatus) -> Self {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<'a> TorrentClient<'a> for QBittorrentClient<'a> {
|
||||
async fn login(&mut self, url: &'a str, username: &'a str, password: &'a str) -> ClientResult<()> {
|
||||
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_trackers(&self, torrent: &TorrentInfo) -> ClientResult<Vec<TorrentTracker>> {
|
||||
Ok(Self::get_torrent_trackers(self, &torrent.into()).await?.iter().map(|t| t.into()).collect())
|
||||
}
|
||||
|
||||
async fn add_torrent_tracker(&self, torrent: &TorrentInfo, tracker_url: String) -> ClientResult<()> {
|
||||
Ok(Self::add_torrent_tracker(self, &torrent.into(), tracker_url).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?)
|
||||
}
|
||||
|
||||
async fn remove_torrent_tracker(&self, torrent: &TorrentInfo, tracker_url: String) -> ClientResult<()> {
|
||||
Ok(Self::remove_torrent_tracker(self, &torrent.into(), tracker_url).await?)
|
||||
}
|
||||
|
||||
async fn add_torrent(&self, torrent: &TorrentUpload) -> ClientResult<()> {
|
||||
Ok(Self::add_torrent(self, &torrent.into()).await?)
|
||||
}
|
||||
|
||||
async fn remove_torrent(&self, torrent: &TorrentInfo, delete_files: bool) -> ClientResult<()> {
|
||||
Ok(Self::remove_torrent(self, &torrent.into(), delete_files).await?)
|
||||
}
|
||||
|
||||
async fn remove_torrents(&self, torrents: Vec<TorrentInfo>, delete_files: bool) -> ClientResult<()> {
|
||||
let torrents: Vec<qbittorrent::TorrentInfo> = torrents.iter().map(|t| t.into()).collect();
|
||||
Ok(Self::remove_torrents(self, torrents, delete_files).await?)
|
||||
}
|
||||
|
||||
async fn get_tags(&self) -> ClientResult<Vec<String>> {
|
||||
Ok(Self::get_tags(self).await?)
|
||||
}
|
||||
|
||||
async fn create_tag(&self, tag: &str) -> ClientResult<()> {
|
||||
Ok(Self::create_tag(self, tag).await?)
|
||||
}
|
||||
|
||||
async fn delete_tag(&self, tag: &str) -> ClientResult<()> {
|
||||
Ok(Self::delete_tag(self, tag).await?)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,3 @@
|
|||
use qbittorrent::{TorrentInfo as QTorrentInfo, TorrentUpload as QTorrentUpload,
|
||||
TrackerStatus as QTrackerStatus, TorrentTracker as QTorrentTracker};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct TorrentInfo {
|
||||
pub name: String,
|
||||
|
@ -10,19 +7,7 @@ pub struct TorrentInfo {
|
|||
pub hash: String,
|
||||
}
|
||||
|
||||
impl From<QTorrentInfo> for TorrentInfo {
|
||||
fn from(torrent: QTorrentInfo) -> Self {
|
||||
TorrentInfo {
|
||||
name: torrent.name,
|
||||
trackers: vec![torrent.tracker], // NOTE: qBittorrent only gives us one tracker.
|
||||
category: torrent.category,
|
||||
tags: torrent.tags,
|
||||
hash: torrent.hash,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct TorrentUpload {
|
||||
/// URL(s) of the torrent files.
|
||||
pub urls: Vec<String>,
|
||||
|
@ -38,15 +23,9 @@ pub struct TorrentUpload {
|
|||
pub paused: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<QTorrentUpload> for TorrentUpload {
|
||||
fn from(upload: QTorrentUpload) -> Self {
|
||||
TorrentUpload {
|
||||
urls: upload.urls,
|
||||
torrents: upload.torrents,
|
||||
tags: upload.tags,
|
||||
category: upload.category,
|
||||
paused: upload.paused,
|
||||
}
|
||||
impl TorrentUpload {
|
||||
pub fn builder() -> TorrentUploadBuilder {
|
||||
TorrentUploadBuilder::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,6 +85,10 @@ impl TorrentUploadBuilder {
|
|||
self.params.paused = Some(paused);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(&self) -> TorrentUpload {
|
||||
self.params.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -139,25 +122,3 @@ pub enum TrackerStatus {
|
|||
/// Tracker has been contacted, but it is not working (or doesn't send proper replies)
|
||||
NotWorking = 4
|
||||
}
|
||||
|
||||
impl From<QTorrentTracker> for TorrentTracker {
|
||||
fn from(tracker: QTorrentTracker) -> Self {
|
||||
TorrentTracker {
|
||||
url: tracker.url,
|
||||
status: tracker.status.into(),
|
||||
message: Some(tracker.message),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<QTrackerStatus> for TrackerStatus {
|
||||
fn from(status: QTrackerStatus) -> Self {
|
||||
match status {
|
||||
QTrackerStatus::Disabled => TrackerStatus::Disabled,
|
||||
QTrackerStatus::NotContacted => TrackerStatus::NotContacted,
|
||||
QTrackerStatus::Working => TrackerStatus::Working,
|
||||
QTrackerStatus::Updating => TrackerStatus::Updating,
|
||||
QTrackerStatus::NotWorking => TrackerStatus::NotWorking,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue