Start creating the TorrentClient trait and other structs around it
This commit is contained in:
parent
20e061a2e5
commit
34999380db
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
.vscode
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "qbittorrent-rs"]
|
||||||
|
path = qbittorrent-rs
|
||||||
|
url = git@github.com:SeanOMik/qbittorrent-rs.git
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "abstracttorrent"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
async-trait = "0.1.56"
|
||||||
|
qbittorrent = { path = "qbittorrent-rs" }
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 4c907b940e6a4eaeee0c92581b62173d918b054a
|
|
@ -0,0 +1,21 @@
|
||||||
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
use crate::{torrent::{TorrentInfo, TorrentTracker}, 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<()>;
|
||||||
|
|
||||||
|
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(&self, torrent: &TorrentInfo) -> ClientResult<()>;
|
||||||
|
async fn remove_torrent(&self, torrent: &TorrentInfo, delete_files: bool) -> ClientResult<()>;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
use qbittorrent::error::ClientError as QClientError;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ClientError {
|
||||||
|
/// Http error
|
||||||
|
Http(Box<dyn Error>),
|
||||||
|
|
||||||
|
/// Authorization error
|
||||||
|
Authorization,
|
||||||
|
|
||||||
|
/// Parsing error (json for qBittorrent)
|
||||||
|
Parsing(Box<dyn Error>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<QClientError> for ClientError {
|
||||||
|
fn from(err: QClientError) -> Self {
|
||||||
|
match err {
|
||||||
|
QClientError::Http(err) => ClientError::Http(Box::new(err)),
|
||||||
|
QClientError::Authorization => ClientError::Authorization,
|
||||||
|
QClientError::Json(err) => ClientError::Parsing(Box::new(err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
pub mod torrent;
|
||||||
|
//pub use torrent::*;
|
||||||
|
|
||||||
|
pub mod client;
|
||||||
|
//pub use client::*;
|
||||||
|
|
||||||
|
pub mod error;
|
|
@ -0,0 +1,163 @@
|
||||||
|
use qbittorrent::{TorrentInfo as QTorrentInfo, TorrentUpload as QTorrentUpload,
|
||||||
|
TrackerStatus as QTrackerStatus, TorrentTracker as QTorrentTracker};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct TorrentInfo {
|
||||||
|
pub name: String,
|
||||||
|
pub trackers: Vec<String>,
|
||||||
|
pub category: String,
|
||||||
|
pub tags: Vec<String>,
|
||||||
|
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)]
|
||||||
|
pub struct TorrentUpload {
|
||||||
|
/// URL(s) of the torrent files.
|
||||||
|
pub urls: Vec<String>,
|
||||||
|
|
||||||
|
/// Binary data of the torrents that are being added.
|
||||||
|
/// Torrent file data that is being added. (Name, Bytes)
|
||||||
|
pub torrents: Vec<(String, Vec<u8>)>,
|
||||||
|
|
||||||
|
pub tags: Option<Vec<String>>,
|
||||||
|
|
||||||
|
pub category: Option<String>,
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct TorrentUploadBuilder {
|
||||||
|
params: TorrentUpload
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TorrentUploadBuilder {
|
||||||
|
pub fn url(&mut self, url: &str) -> &mut Self {
|
||||||
|
self.params.urls.push(url.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn torrent_file(&mut self, torrent_path: &str) -> &mut Self {
|
||||||
|
let path = std::path::Path::new(torrent_path);
|
||||||
|
|
||||||
|
self.torrent_path(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn torrent_path(&mut self, torrent_path: &std::path::Path) -> &mut Self {
|
||||||
|
let torrents = &mut self.params.torrents;
|
||||||
|
torrents.push((
|
||||||
|
torrent_path.file_name().unwrap().to_str().unwrap().to_string(),
|
||||||
|
std::fs::read(torrent_path).unwrap(),
|
||||||
|
));
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn torrent_data(&mut self, filename: String, data: Vec<u8>) -> &mut Self {
|
||||||
|
let torrents = &mut self.params.torrents;
|
||||||
|
torrents.push((
|
||||||
|
filename,
|
||||||
|
data,
|
||||||
|
));
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tags(&mut self, tags: Vec<String>) -> &mut Self {
|
||||||
|
self.params.tags = Some(tags);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tag(&mut self, tag: String) -> &mut Self {
|
||||||
|
self.params.tags.as_mut().unwrap_or(&mut vec![]).push(tag);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn category(&mut self, category: String) -> &mut Self {
|
||||||
|
self.params.category = Some(category);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn paused(&mut self, paused: bool) -> &mut Self {
|
||||||
|
self.params.paused = Some(paused);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TorrentTracker {
|
||||||
|
/// Tracker URL
|
||||||
|
pub url: String,
|
||||||
|
|
||||||
|
/// Tracker status
|
||||||
|
pub status: TrackerStatus,
|
||||||
|
|
||||||
|
/// Tracker message (there is no way of knowing what this message is - it's up to tracker admins)
|
||||||
|
pub message: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An enum that represents the status of a tracker.
|
||||||
|
/// Some of these statuses may not be supported by other trackers.
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum TrackerStatus {
|
||||||
|
/// Tracker is disabled (used for DHT, PeX, and LSD)
|
||||||
|
Disabled = 0,
|
||||||
|
|
||||||
|
/// Tracker has not been contacted yet
|
||||||
|
NotContacted = 1,
|
||||||
|
|
||||||
|
/// Tracker has been contacted and is working
|
||||||
|
Working = 2,
|
||||||
|
|
||||||
|
/// Tracker is updating
|
||||||
|
Updating = 3,
|
||||||
|
|
||||||
|
/// 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