Skip to content

Commit

Permalink
refactor(api): [#143] extract service tracker::services::torrent::get…
Browse files Browse the repository at this point in the history
…_torrents

It will be used in the new Axum implementaion for the API. In the API
enpoint:

```
GET /api/torrents?offset=:u32&limit=:u32
```
  • Loading branch information
josecelano committed Jan 9, 2023
1 parent a806179 commit c36b121
Show file tree
Hide file tree
Showing 3 changed files with 256 additions and 46 deletions.
61 changes: 55 additions & 6 deletions src/api/resource/torrent.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};

use super::peer;
use crate::tracker::services::torrent::Info;
use crate::tracker::services::torrent::{BasicInfo, Info};

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct Torrent {
Expand All @@ -16,13 +16,31 @@ pub struct Torrent {
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct ListItem {
pub info_hash: String,
pub seeders: u32,
pub completed: u32,
pub leechers: u32,
pub seeders: u64,
pub completed: u64,
pub leechers: u64,
// todo: this is always None. Remove field from endpoint?
pub peers: Option<Vec<super::peer::Peer>>,
}

impl ListItem {
#[must_use]
pub fn new_vec(basic_info_vec: &[BasicInfo]) -> Vec<Self> {
basic_info_vec
.iter()
.map(|basic_info| ListItem::from((*basic_info).clone()))
.collect()
}
}

#[must_use]
pub fn to_resource(basic_info_vec: &[BasicInfo]) -> Vec<ListItem> {
basic_info_vec
.iter()
.map(|basic_info| ListItem::from((*basic_info).clone()))
.collect()
}

impl From<Info> for Torrent {
fn from(info: Info) -> Self {
Self {
Expand All @@ -37,6 +55,18 @@ impl From<Info> for Torrent {
}
}

impl From<BasicInfo> for ListItem {
fn from(basic_info: BasicInfo) -> Self {
Self {
info_hash: basic_info.info_hash.to_string(),
seeders: basic_info.seeders,
completed: basic_info.completed,
leechers: basic_info.leechers,
peers: None,
}
}
}

#[cfg(test)]
mod tests {
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
Expand All @@ -45,11 +75,11 @@ mod tests {
use aquatic_udp_protocol::{AnnounceEvent, NumberOfBytes};

use crate::api::resource::peer::Peer;
use crate::api::resource::torrent::Torrent;
use crate::api::resource::torrent::{ListItem, Torrent};
use crate::protocol::clock::DurationSinceUnixEpoch;
use crate::protocol::info_hash::InfoHash;
use crate::tracker::peer;
use crate::tracker::services::torrent::Info;
use crate::tracker::services::torrent::{BasicInfo, Info};

fn sample_peer() -> peer::Peer {
peer::Peer {
Expand Down Expand Up @@ -82,4 +112,23 @@ mod tests {
}
);
}

#[test]
fn torrent_resource_list_item_should_be_converted_from_the_basic_torrent_info() {
assert_eq!(
ListItem::from(BasicInfo {
info_hash: InfoHash::from_str("9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d").unwrap(),
seeders: 1,
completed: 2,
leechers: 3,
}),
ListItem {
info_hash: "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_string(),
seeders: 1,
completed: 2,
leechers: 3,
peers: None,
}
);
}
}
23 changes: 4 additions & 19 deletions src/api/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::{ActionStatus, TorrentInfoQuery};
use crate::protocol::info_hash::InfoHash;
use crate::tracker;
use crate::tracker::services::statistics::get_metrics;
use crate::tracker::services::torrent::get_torrent_info;
use crate::tracker::services::torrent::{get_torrent_info, get_torrents};

fn authenticate(tokens: HashMap<String, String>) -> impl Filter<Extract = (), Error = warp::reject::Rejection> + Clone {
#[derive(Deserialize)]
Expand Down Expand Up @@ -64,24 +64,9 @@ pub fn routes(tracker: &Arc<tracker::Tracker>) -> impl Filter<Extract = impl war
let offset = limits.offset.unwrap_or(0);
let limit = min(limits.limit.unwrap_or(1000), 4000);

let db = tracker.get_torrents().await;
let results: Vec<_> = db
.iter()
.map(|(info_hash, torrent_entry)| {
let (seeders, completed, leechers) = torrent_entry.get_stats();
ListItem {
info_hash: info_hash.to_string(),
seeders,
completed,
leechers,
peers: None,
}
})
.skip(offset as usize)
.take(limit as usize)
.collect();

Result::<_, warp::reject::Rejection>::Ok(reply::json(&results))
Result::<_, warp::reject::Rejection>::Ok(reply::json(&ListItem::new_vec(
&get_torrents(tracker.clone(), offset, limit).await,
)))
});

// GET /api/stats
Expand Down
Loading

0 comments on commit c36b121

Please sign in to comment.