@@ -328,82 +328,9 @@ impl Index {
328
328
) -> Result < TorrentResponse , ServiceError > {
329
329
let torrent_listing = self . torrent_listing_generator . one_torrent_by_info_hash ( info_hash) . await ?;
330
330
331
- let torrent_id = torrent_listing. torrent_id ;
332
-
333
- let category = match torrent_listing. category_id {
334
- Some ( category_id) => Some ( self . category_repository . get_by_id ( & category_id) . await ?) ,
335
- None => None ,
336
- } ;
337
-
338
- let mut torrent_response = TorrentResponse :: from_listing ( torrent_listing, category) ;
339
-
340
- // Add files
341
-
342
- torrent_response. files = self . torrent_file_repository . get_by_torrent_id ( & torrent_id) . await ?;
343
-
344
- if torrent_response. files . len ( ) == 1 {
345
- let torrent_info = self . torrent_info_repository . get_by_info_hash ( info_hash) . await ?;
346
-
347
- torrent_response
348
- . files
349
- . iter_mut ( )
350
- . for_each ( |v| v. path = vec ! [ torrent_info. name. to_string( ) ] ) ;
351
- }
352
-
353
- // Add trackers
354
-
355
- // code-review: duplicate logic. We have to check the same in the
356
- // download torrent file endpoint. Here he have only one list of tracker
357
- // like the `announce_list` in the torrent file.
358
-
359
- torrent_response. trackers = self . torrent_announce_url_repository . get_by_torrent_id ( & torrent_id) . await ?;
360
-
361
- let tracker_url = self . get_tracker_url ( ) . await ;
362
- let tracker_mode = self . get_tracker_mode ( ) . await ;
363
-
364
- if tracker_mode. is_open ( ) {
365
- torrent_response. include_url_as_main_tracker ( & tracker_url) ;
366
- } else {
367
- // Add main tracker URL
368
- match opt_user_id {
369
- Some ( user_id) => {
370
- let personal_announce_url = self . tracker_service . get_personal_announce_url ( user_id) . await ?;
371
-
372
- torrent_response. include_url_as_main_tracker ( & personal_announce_url) ;
373
- }
374
- None => {
375
- torrent_response. include_url_as_main_tracker ( & tracker_url) ;
376
- }
377
- }
378
- }
379
-
380
- // Add magnet link
381
-
382
- // todo: extract a struct or function to build the magnet links
383
- let mut magnet = format ! (
384
- "magnet:?xt=urn:btih:{}&dn={}" ,
385
- torrent_response. info_hash,
386
- urlencoding:: encode( & torrent_response. title)
387
- ) ;
388
-
389
- // Add trackers from torrent file to magnet link
390
- for tracker in & torrent_response. trackers {
391
- magnet. push_str ( & format ! ( "&tr={}" , urlencoding:: encode( tracker) ) ) ;
392
- }
393
-
394
- torrent_response. magnet_link = magnet;
395
-
396
- // Get realtime seeders and leechers
397
- if let Ok ( torrent_info) = self
398
- . tracker_statistics_importer
399
- . import_torrent_statistics ( torrent_response. torrent_id , & torrent_response. info_hash )
400
- . await
401
- {
402
- torrent_response. seeders = torrent_info. seeders ;
403
- torrent_response. leechers = torrent_info. leechers ;
404
- }
405
-
406
- torrent_response. tags = self . torrent_tag_repository . get_tags_for_torrent ( & torrent_id) . await ?;
331
+ let torrent_response = self
332
+ . build_full_torrent_response ( torrent_listing, info_hash, opt_user_id)
333
+ . await ?;
407
334
408
335
Ok ( torrent_response)
409
336
}
@@ -497,12 +424,7 @@ impl Index {
497
424
. one_torrent_by_torrent_id ( & torrent_listing. torrent_id )
498
425
. await ?;
499
426
500
- let category = match torrent_listing. category_id {
501
- Some ( category_id) => Some ( self . category_repository . get_by_id ( & category_id) . await ?) ,
502
- None => None ,
503
- } ;
504
-
505
- let torrent_response = TorrentResponse :: from_listing ( torrent_listing, category) ;
427
+ let torrent_response = self . build_short_torrent_response ( torrent_listing, info_hash) . await ?;
506
428
507
429
Ok ( torrent_response)
508
430
}
@@ -516,6 +438,109 @@ impl Index {
516
438
let settings = self . configuration . settings . read ( ) . await ;
517
439
settings. tracker . mode . clone ( )
518
440
}
441
+
442
+ async fn build_short_torrent_response (
443
+ & self ,
444
+ torrent_listing : TorrentListing ,
445
+ info_hash : & InfoHash ,
446
+ ) -> Result < TorrentResponse , ServiceError > {
447
+ let category = match torrent_listing. category_id {
448
+ Some ( category_id) => Some ( self . category_repository . get_by_id ( & category_id) . await ?) ,
449
+ None => None ,
450
+ } ;
451
+
452
+ let canonical_info_hash_group = self
453
+ . torrent_info_hash_repository
454
+ . get_canonical_info_hash_group ( info_hash)
455
+ . await ?;
456
+
457
+ Ok ( TorrentResponse :: from_listing (
458
+ torrent_listing,
459
+ category,
460
+ & canonical_info_hash_group,
461
+ ) )
462
+ }
463
+
464
+ async fn build_full_torrent_response (
465
+ & self ,
466
+ torrent_listing : TorrentListing ,
467
+ info_hash : & InfoHash ,
468
+ opt_user_id : Option < UserId > ,
469
+ ) -> Result < TorrentResponse , ServiceError > {
470
+ let torrent_id: i64 = torrent_listing. torrent_id ;
471
+
472
+ let mut torrent_response = self . build_short_torrent_response ( torrent_listing, info_hash) . await ?;
473
+
474
+ // Add files
475
+
476
+ torrent_response. files = self . torrent_file_repository . get_by_torrent_id ( & torrent_id) . await ?;
477
+
478
+ if torrent_response. files . len ( ) == 1 {
479
+ let torrent_info = self . torrent_info_repository . get_by_info_hash ( info_hash) . await ?;
480
+
481
+ torrent_response
482
+ . files
483
+ . iter_mut ( )
484
+ . for_each ( |v| v. path = vec ! [ torrent_info. name. to_string( ) ] ) ;
485
+ }
486
+
487
+ // Add trackers
488
+
489
+ // code-review: duplicate logic. We have to check the same in the
490
+ // download torrent file endpoint. Here he have only one list of tracker
491
+ // like the `announce_list` in the torrent file.
492
+
493
+ torrent_response. trackers = self . torrent_announce_url_repository . get_by_torrent_id ( & torrent_id) . await ?;
494
+
495
+ let tracker_url = self . get_tracker_url ( ) . await ;
496
+ let tracker_mode = self . get_tracker_mode ( ) . await ;
497
+
498
+ if tracker_mode. is_open ( ) {
499
+ torrent_response. include_url_as_main_tracker ( & tracker_url) ;
500
+ } else {
501
+ // Add main tracker URL
502
+ match opt_user_id {
503
+ Some ( user_id) => {
504
+ let personal_announce_url = self . tracker_service . get_personal_announce_url ( user_id) . await ?;
505
+
506
+ torrent_response. include_url_as_main_tracker ( & personal_announce_url) ;
507
+ }
508
+ None => {
509
+ torrent_response. include_url_as_main_tracker ( & tracker_url) ;
510
+ }
511
+ }
512
+ }
513
+
514
+ // Add magnet link
515
+
516
+ // todo: extract a struct or function to build the magnet links
517
+ let mut magnet = format ! (
518
+ "magnet:?xt=urn:btih:{}&dn={}" ,
519
+ torrent_response. info_hash,
520
+ urlencoding:: encode( & torrent_response. title)
521
+ ) ;
522
+
523
+ // Add trackers from torrent file to magnet link
524
+ for tracker in & torrent_response. trackers {
525
+ magnet. push_str ( & format ! ( "&tr={}" , urlencoding:: encode( tracker) ) ) ;
526
+ }
527
+
528
+ torrent_response. magnet_link = magnet;
529
+
530
+ // Get realtime seeders and leechers
531
+ if let Ok ( torrent_info) = self
532
+ . tracker_statistics_importer
533
+ . import_torrent_statistics ( torrent_response. torrent_id , & torrent_response. info_hash )
534
+ . await
535
+ {
536
+ torrent_response. seeders = torrent_info. seeders ;
537
+ torrent_response. leechers = torrent_info. leechers ;
538
+ }
539
+
540
+ torrent_response. tags = self . torrent_tag_repository . get_tags_for_torrent ( & torrent_id) . await ?;
541
+
542
+ Ok ( torrent_response)
543
+ }
519
544
}
520
545
521
546
pub struct DbTorrentRepository {
@@ -579,6 +604,7 @@ pub struct DbTorrentInfoHash {
579
604
/// This function returns the original infohashes of a canonical infohash.
580
605
///
581
606
/// The relationship is 1 canonical infohash -> N original infohashes.
607
+ #[ derive( PartialEq , Eq , Debug , Clone , Serialize , Deserialize ) ]
582
608
pub struct CanonicalInfoHashGroup {
583
609
pub canonical_info_hash : InfoHash ,
584
610
/// The list of original infohashes associated to the canonical one.
0 commit comments