Skip to content

Commit

Permalink
refactor: [torrust#296] extract duplicate code
Browse files Browse the repository at this point in the history
  • Loading branch information
josecelano committed Sep 19, 2023
1 parent f0ad6a4 commit b6fe36b
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 103 deletions.
4 changes: 2 additions & 2 deletions src/databases/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ pub trait Database: Sync + Send {

let torrent_announce_urls = self.get_torrent_announce_urls_from_id(torrent_info.torrent_id).await?;

Ok(Torrent::from_database(torrent_info, torrent_files, torrent_announce_urls))
Ok(Torrent::from_database(&torrent_info, &torrent_files, torrent_announce_urls))
}

/// Get `Torrent` from `torrent_id`.
Expand All @@ -220,7 +220,7 @@ pub trait Database: Sync + Send {

let torrent_announce_urls = self.get_torrent_announce_urls_from_id(torrent_id).await?;

Ok(Torrent::from_database(torrent_info, torrent_files, torrent_announce_urls))
Ok(Torrent::from_database(&torrent_info, &torrent_files, torrent_announce_urls))
}

/// It returns the list of all infohashes producing the same canonical
Expand Down
127 changes: 78 additions & 49 deletions src/models/torrent_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,57 +98,18 @@ impl Torrent {
/// hex string.
#[must_use]
pub fn from_database(
db_torrent: DbTorrent,
torrent_files: Vec<TorrentFile>,
db_torrent: &DbTorrent,
torrent_files: &Vec<TorrentFile>,
torrent_announce_urls: Vec<Vec<String>>,
) -> Self {
let mut info_dict = TorrentInfoDictionary {
name: db_torrent.name,
pieces: None,
piece_length: db_torrent.piece_length,
md5sum: None,
length: None,
files: None,
private: db_torrent.private,
path: None,
root_hash: None,
source: None,
};

// a torrent file has a root hash or a pieces key, but not both.
if db_torrent.root_hash > 0 {
info_dict.root_hash = Some(db_torrent.pieces);
} else {
let buffer = into_bytes(&db_torrent.pieces).expect("variable `torrent_info.pieces` is not a valid hex string");
info_dict.pieces = Some(ByteBuf::from(buffer));
}

// either set the single file or the multiple files information
if torrent_files.len() == 1 {
let torrent_file = torrent_files
.first()
.expect("vector `torrent_files` should have at least one element");

info_dict.md5sum = torrent_file.md5sum.clone();

info_dict.length = Some(torrent_file.length);

let path = if torrent_file
.path
.first()
.as_ref()
.expect("the vector for the `path` should have at least one element")
.is_empty()
{
None
} else {
Some(torrent_file.path.clone())
};

info_dict.path = path;
} else {
info_dict.files = Some(torrent_files);
}
let info_dict = TorrentInfoDictionary::with(
&db_torrent.name,
db_torrent.piece_length,
db_torrent.private,
db_torrent.root_hash,
&db_torrent.pieces,
torrent_files,
);

Self {
info: info_dict,
Expand Down Expand Up @@ -246,6 +207,74 @@ impl Torrent {
}

impl TorrentInfoDictionary {
/// Constructor.
///
/// # Panics
///
/// This function will panic if:
///
/// - The `pieces` field is not a valid hex string.
/// - For single files torrents the `TorrentFile` path is empty.
#[must_use]
pub fn with(
name: &str,
piece_length: i64,
private: Option<u8>,
root_hash: i64,
pieces: &str,
files: &Vec<TorrentFile>,
) -> Self {
let mut info_dict = Self {
name: name.to_string(),
pieces: None,
piece_length,
md5sum: None,
length: None,
files: None,
private,
path: None,
root_hash: None,
source: None,
};

// a torrent file has a root hash or a pieces key, but not both.
if root_hash > 0 {
info_dict.root_hash = Some(pieces.to_owned());
} else {
let buffer = into_bytes(pieces).expect("variable `torrent_info.pieces` is not a valid hex string");
info_dict.pieces = Some(ByteBuf::from(buffer));
}

// either set the single file or the multiple files information
if files.len() == 1 {
let torrent_file = files
.first()
.expect("vector `torrent_files` should have at least one element");

info_dict.md5sum = torrent_file.md5sum.clone();

info_dict.length = Some(torrent_file.length);

let path = if torrent_file
.path
.first()
.as_ref()
.expect("the vector for the `path` should have at least one element")
.is_empty()
{
None
} else {
Some(torrent_file.path.clone())
};

info_dict.path = path;
} else {
info_dict.files = Some(files.clone());
}

info_dict
}

/// torrent file can only hold a pieces key or a root hash key:
/// [BEP 39](http://www.bittorrent.org/beps/bep_0030.html)
#[must_use]
Expand Down
60 changes: 8 additions & 52 deletions src/services/torrent_file.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
//! This module contains the services related to torrent file management.
use serde_bytes::ByteBuf;
use uuid::Uuid;

use crate::models::torrent_file::{Torrent, TorrentFile, TorrentInfoDictionary};
use crate::services::hasher::sha1;
use crate::utils::hex::into_bytes;

/// It contains the information required to create a new torrent file.
///
Expand All @@ -31,56 +29,14 @@ impl CreateTorrentRequest {
/// This function will panic if the `pieces` field is not a valid hex string.
#[must_use]
pub fn build_info_dictionary(&self) -> TorrentInfoDictionary {
let mut info_dict = TorrentInfoDictionary {
name: self.name.to_string(),
pieces: None,
piece_length: self.piece_length,
md5sum: None,
length: None,
files: None,
private: self.private,
path: None,
root_hash: None,
source: None,
};

// a torrent file has a root hash or a pieces key, but not both.
if self.root_hash > 0 {
info_dict.root_hash = Some(self.pieces.clone());
} else {
let buffer = into_bytes(&self.pieces).expect("variable `torrent_info.pieces` is not a valid hex string");
info_dict.pieces = Some(ByteBuf::from(buffer));
}

// either set the single file or the multiple files information
if self.files.len() == 1 {
let torrent_file = self
.files
.first()
.expect("vector `torrent_files` should have at least one element");

info_dict.md5sum = torrent_file.md5sum.clone();

info_dict.length = Some(torrent_file.length);

let path = if torrent_file
.path
.first()
.as_ref()
.expect("the vector for the `path` should have at least one element")
.is_empty()
{
None
} else {
Some(torrent_file.path.clone())
};

info_dict.path = path;
} else {
info_dict.files = Some(self.files.clone());
}

info_dict
TorrentInfoDictionary::with(
&self.name,
self.piece_length,
self.private,
self.root_hash,
&self.pieces,
&self.files,
)
}
}

Expand Down

0 comments on commit b6fe36b

Please sign in to comment.