Skip to content

Commit e9476fc

Browse files
committed
feat: [#296] persist torrent comment
and add it to the API responses. - Torrent details endpoint - Torrent list endpoint - Include the comment in the downloaded torrent
1 parent eb26c8d commit e9476fc

File tree

10 files changed

+204
-106
lines changed

10 files changed

+204
-106
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE torrust_torrents ADD COLUMN comment TEXT NULL;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE "torrust_torrents" ADD COLUMN "comment" TEXT NULL;

src/databases/mysql.rs

Lines changed: 95 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ impl Database for Mysql {
300300
})
301301
}
302302

303-
// TODO: refactor this
303+
// todo: refactor this
304+
#[allow(clippy::too_many_lines)]
304305
async fn get_torrents_search_sorted_paginated(
305306
&self,
306307
search: &Option<String>,
@@ -375,7 +376,17 @@ impl Database for Mysql {
375376
};
376377

377378
let mut query_string = format!(
378-
"SELECT tt.torrent_id, tp.username AS uploader, tt.info_hash, ti.title, ti.description, tt.category_id, DATE_FORMAT(tt.date_uploaded, '%Y-%m-%d %H:%i:%s') AS date_uploaded, tt.size AS file_size, tt.name,
379+
"SELECT
380+
tt.torrent_id,
381+
tp.username AS uploader,
382+
tt.info_hash,
383+
ti.title,
384+
ti.description,
385+
tt.category_id,
386+
DATE_FORMAT(tt.date_uploaded, '%Y-%m-%d %H:%i:%s') AS date_uploaded,
387+
tt.size AS file_size,
388+
tt.name,
389+
tt.comment,
379390
CAST(COALESCE(sum(ts.seeders),0) as signed) as seeders,
380391
CAST(COALESCE(sum(ts.leechers),0) as signed) as leechers
381392
FROM torrust_torrents tt
@@ -443,31 +454,47 @@ impl Database for Mysql {
443454
};
444455

445456
// add torrent
446-
let torrent_id = query("INSERT INTO torrust_torrents (uploader_id, category_id, info_hash, size, name, pieces, piece_length, private, root_hash, `source`, date_uploaded) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, UTC_TIMESTAMP())")
447-
.bind(uploader_id)
448-
.bind(category_id)
449-
.bind(info_hash.to_lowercase())
450-
.bind(torrent.file_size())
451-
.bind(torrent.info.name.to_string())
452-
.bind(pieces)
453-
.bind(torrent.info.piece_length)
454-
.bind(torrent.info.private)
455-
.bind(root_hash)
456-
.bind(torrent.info.source.clone())
457-
.execute(&mut tx)
458-
.await
459-
.map(|v| i64::try_from(v.last_insert_id()).expect("last ID is larger than i64"))
460-
.map_err(|e| match e {
461-
sqlx::Error::Database(err) => {
462-
log::error!("DB error: {:?}", err);
463-
if err.message().contains("Duplicate entry") && err.message().contains("info_hash") {
464-
database::Error::TorrentAlreadyExists
465-
} else {
466-
database::Error::Error
467-
}
457+
let torrent_id = query(
458+
"INSERT INTO torrust_torrents (
459+
uploader_id,
460+
category_id,
461+
info_hash,
462+
size,
463+
name,
464+
pieces,
465+
piece_length,
466+
private,
467+
root_hash,
468+
`source`,
469+
comment,
470+
date_uploaded
471+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, UTC_TIMESTAMP())",
472+
)
473+
.bind(uploader_id)
474+
.bind(category_id)
475+
.bind(info_hash.to_lowercase())
476+
.bind(torrent.file_size())
477+
.bind(torrent.info.name.to_string())
478+
.bind(pieces)
479+
.bind(torrent.info.piece_length)
480+
.bind(torrent.info.private)
481+
.bind(root_hash)
482+
.bind(torrent.info.source.clone())
483+
.bind(torrent.comment.clone())
484+
.execute(&mut tx)
485+
.await
486+
.map(|v| i64::try_from(v.last_insert_id()).expect("last ID is larger than i64"))
487+
.map_err(|e| match e {
488+
sqlx::Error::Database(err) => {
489+
log::error!("DB error: {:?}", err);
490+
if err.message().contains("Duplicate entry") && err.message().contains("info_hash") {
491+
database::Error::TorrentAlreadyExists
492+
} else {
493+
database::Error::Error
468494
}
469-
_ => database::Error::Error
470-
})?;
495+
}
496+
_ => database::Error::Error,
497+
})?;
471498

472499
// add torrent canonical infohash
473500

@@ -650,23 +677,19 @@ impl Database for Mysql {
650677
}
651678

652679
async fn get_torrent_info_from_id(&self, torrent_id: i64) -> Result<DbTorrentInfo, database::Error> {
653-
query_as::<_, DbTorrentInfo>(
654-
"SELECT torrent_id, info_hash, name, pieces, piece_length, private, root_hash FROM torrust_torrents WHERE torrent_id = ?",
655-
)
656-
.bind(torrent_id)
657-
.fetch_one(&self.pool)
658-
.await
659-
.map_err(|_| database::Error::TorrentNotFound)
680+
query_as::<_, DbTorrentInfo>("SELECT * FROM torrust_torrents WHERE torrent_id = ?")
681+
.bind(torrent_id)
682+
.fetch_one(&self.pool)
683+
.await
684+
.map_err(|_| database::Error::TorrentNotFound)
660685
}
661686

662687
async fn get_torrent_info_from_info_hash(&self, info_hash: &InfoHash) -> Result<DbTorrentInfo, database::Error> {
663-
query_as::<_, DbTorrentInfo>(
664-
"SELECT torrent_id, info_hash, name, pieces, piece_length, private, root_hash FROM torrust_torrents WHERE info_hash = ?",
665-
)
666-
.bind(info_hash.to_hex_string().to_lowercase())
667-
.fetch_one(&self.pool)
668-
.await
669-
.map_err(|_| database::Error::TorrentNotFound)
688+
query_as::<_, DbTorrentInfo>("SELECT * FROM torrust_torrents WHERE info_hash = ?")
689+
.bind(info_hash.to_hex_string().to_lowercase())
690+
.fetch_one(&self.pool)
691+
.await
692+
.map_err(|_| database::Error::TorrentNotFound)
670693
}
671694

672695
async fn get_torrent_files_from_id(&self, torrent_id: i64) -> Result<Vec<TorrentFile>, database::Error> {
@@ -705,38 +728,58 @@ impl Database for Mysql {
705728

706729
async fn get_torrent_listing_from_id(&self, torrent_id: i64) -> Result<TorrentListing, database::Error> {
707730
query_as::<_, TorrentListing>(
708-
"SELECT tt.torrent_id, tp.username AS uploader, tt.info_hash, ti.title, ti.description, tt.category_id, DATE_FORMAT(tt.date_uploaded, '%Y-%m-%d %H:%i:%s') AS date_uploaded, tt.size AS file_size, tt.name,
731+
"SELECT
732+
tt.torrent_id,
733+
tp.username AS uploader,
734+
tt.info_hash,
735+
ti.title,
736+
ti.description,
737+
tt.category_id,
738+
DATE_FORMAT(tt.date_uploaded, '%Y-%m-%d %H:%i:%s') AS date_uploaded,
739+
tt.size AS file_size,
740+
tt.name,
741+
tt.comment,
709742
CAST(COALESCE(sum(ts.seeders),0) as signed) as seeders,
710743
CAST(COALESCE(sum(ts.leechers),0) as signed) as leechers
711744
FROM torrust_torrents tt
712745
INNER JOIN torrust_user_profiles tp ON tt.uploader_id = tp.user_id
713746
INNER JOIN torrust_torrent_info ti ON tt.torrent_id = ti.torrent_id
714747
LEFT JOIN torrust_torrent_tracker_stats ts ON tt.torrent_id = ts.torrent_id
715748
WHERE tt.torrent_id = ?
716-
GROUP BY torrent_id"
749+
GROUP BY torrent_id",
717750
)
718-
.bind(torrent_id)
719-
.fetch_one(&self.pool)
720-
.await
721-
.map_err(|_| database::Error::TorrentNotFound)
751+
.bind(torrent_id)
752+
.fetch_one(&self.pool)
753+
.await
754+
.map_err(|_| database::Error::TorrentNotFound)
722755
}
723756

724757
async fn get_torrent_listing_from_info_hash(&self, info_hash: &InfoHash) -> Result<TorrentListing, database::Error> {
725758
query_as::<_, TorrentListing>(
726-
"SELECT tt.torrent_id, tp.username AS uploader, tt.info_hash, ti.title, ti.description, tt.category_id, DATE_FORMAT(tt.date_uploaded, '%Y-%m-%d %H:%i:%s') AS date_uploaded, tt.size AS file_size, tt.name,
759+
"SELECT
760+
tt.torrent_id,
761+
tp.username AS uploader,
762+
tt.info_hash,
763+
ti.title,
764+
ti.description,
765+
tt.category_id,
766+
DATE_FORMAT(tt.date_uploaded, '%Y-%m-%d %H:%i:%s') AS date_uploaded,
767+
tt.size AS file_size,
768+
tt.name,
769+
tt.comment,
727770
CAST(COALESCE(sum(ts.seeders),0) as signed) as seeders,
728771
CAST(COALESCE(sum(ts.leechers),0) as signed) as leechers
729772
FROM torrust_torrents tt
730773
INNER JOIN torrust_user_profiles tp ON tt.uploader_id = tp.user_id
731774
INNER JOIN torrust_torrent_info ti ON tt.torrent_id = ti.torrent_id
732775
LEFT JOIN torrust_torrent_tracker_stats ts ON tt.torrent_id = ts.torrent_id
733776
WHERE tt.info_hash = ?
734-
GROUP BY torrent_id"
777+
GROUP BY torrent_id",
735778
)
736-
.bind(info_hash.to_hex_string().to_lowercase())
737-
.fetch_one(&self.pool)
738-
.await
739-
.map_err(|_| database::Error::TorrentNotFound)
779+
.bind(info_hash.to_hex_string().to_lowercase())
780+
.fetch_one(&self.pool)
781+
.await
782+
.map_err(|_| database::Error::TorrentNotFound)
740783
}
741784

742785
async fn get_all_torrents_compact(&self) -> Result<Vec<TorrentCompact>, database::Error> {

0 commit comments

Comments
 (0)