@@ -20,8 +20,6 @@ use crate::tracker::statistics_importer::StatisticsImporter;
2020use crate :: utils:: parse_torrent;
2121use crate :: { tracker, AsCSV } ;
2222
23- const MIN_TORRENT_TITLE_LENGTH : usize = 3 ;
24-
2523pub struct Index {
2624 configuration : Arc < Configuration > ,
2725 tracker_statistics_importer : Arc < StatisticsImporter > ,
@@ -128,22 +126,34 @@ impl Index {
128126 /// * Unable to parse the torrent info-hash.
129127 pub async fn add_torrent (
130128 & self ,
131- add_torrent_form : AddTorrentRequest ,
129+ add_torrent_req : AddTorrentRequest ,
132130 user_id : UserId ,
133131 ) -> Result < AddTorrentResponse , ServiceError > {
134- let metadata = Metadata {
135- title : add_torrent_form. title ,
136- description : add_torrent_form. description ,
137- category : add_torrent_form. category ,
138- tags : add_torrent_form. tags ,
139- } ;
132+ // Authorization: only authenticated users ere allowed to upload torrents
133+
134+ let _user = self . user_repository . get_compact ( & user_id) . await ?;
135+
136+ // Validate and build metadata
137+
138+ let metadata = Metadata :: new (
139+ & add_torrent_req. title ,
140+ & add_torrent_req. description ,
141+ & add_torrent_req. category ,
142+ & add_torrent_req. tags ,
143+ ) ?;
144+
145+ let category = self
146+ . category_repository
147+ . get_by_name ( & metadata. category )
148+ . await
149+ . map_err ( |_| ServiceError :: InvalidCategory ) ?;
140150
141- metadata . verify ( ) ? ;
151+ // Validate and build torrent file
142152
143- let original_info_hash = parse_torrent:: calculate_info_hash ( & add_torrent_form . torrent_buffer ) ;
153+ let original_info_hash = parse_torrent:: calculate_info_hash ( & add_torrent_req . torrent_buffer ) ;
144154
145155 let mut torrent =
146- parse_torrent:: decode_torrent ( & add_torrent_form . torrent_buffer ) . map_err ( |_| ServiceError :: InvalidTorrentFile ) ?;
156+ parse_torrent:: decode_torrent ( & add_torrent_req . torrent_buffer ) . map_err ( |_| ServiceError :: InvalidTorrentFile ) ?;
147157
148158 // Make sure that the pieces key has a length that is a multiple of 20
149159 if let Some ( pieces) = torrent. info . pieces . as_ref ( ) {
@@ -152,22 +162,12 @@ impl Index {
152162 }
153163 }
154164
155- let _user = self . user_repository . get_compact ( & user_id) . await ?;
156-
157165 torrent. set_announce_urls ( & self . configuration ) . await ;
158166
159- if metadata. title . len ( ) < MIN_TORRENT_TITLE_LENGTH {
160- return Err ( ServiceError :: InvalidTorrentTitleLength ) ;
161- }
162-
163- let category = self
164- . category_repository
165- . get_by_name ( & metadata. category )
166- . await
167- . map_err ( |_| ServiceError :: InvalidCategory ) ?;
168-
169167 let canonical_info_hash = torrent. canonical_info_hash ( ) ;
170168
169+ // Canonical InfoHash Group checks
170+
171171 let original_info_hashes = self
172172 . torrent_info_hash_repository
173173 . get_canonical_info_hash_group ( & canonical_info_hash)
@@ -194,35 +194,44 @@ impl Index {
194194 return Err ( ServiceError :: CanonicalInfoHashAlreadyExists ) ;
195195 }
196196
197- // First time a torrent with this original infohash is uploaded.
197+ // Store the torrent into the database
198198
199199 let torrent_id = self
200200 . torrent_repository
201201 . add ( & original_info_hash, & torrent, & metadata, user_id, category)
202202 . await ?;
203- let info_hash = torrent. canonical_info_hash ( ) ;
203+
204+ self . torrent_tag_repository
205+ . link_torrent_to_tags ( & torrent_id, & metadata. tags )
206+ . await ?;
207+
208+ // Secondary task: import torrent statistics from the tracker
204209
205210 drop (
206211 self . tracker_statistics_importer
207- . import_torrent_statistics ( torrent_id, & torrent. info_hash_hex ( ) )
212+ . import_torrent_statistics ( torrent_id, & torrent. canonical_info_hash_hex ( ) )
208213 . await ,
209214 ) ;
210215
216+ // Secondary task: whitelist torrent on the tracker
217+
211218 // We always whitelist the torrent on the tracker because even if the tracker mode is `public`
212219 // it could be changed to `private` later on.
213- if let Err ( e) = self . tracker_service . whitelist_info_hash ( torrent. info_hash_hex ( ) ) . await {
220+ if let Err ( e) = self
221+ . tracker_service
222+ . whitelist_info_hash ( torrent. canonical_info_hash_hex ( ) )
223+ . await
224+ {
214225 // If the torrent can't be whitelisted somehow, remove the torrent from database
215226 drop ( self . torrent_repository . delete ( & torrent_id) . await ) ;
216227 return Err ( e) ;
217228 }
218229
219- self . torrent_tag_repository
220- . link_torrent_to_tags ( & torrent_id, & metadata. tags )
221- . await ?;
230+ // Build response
222231
223232 Ok ( AddTorrentResponse {
224233 torrent_id,
225- info_hash : info_hash . to_string ( ) ,
234+ info_hash : torrent . canonical_info_hash_hex ( ) ,
226235 original_info_hash : original_info_hash. to_string ( ) ,
227236 } )
228237 }
0 commit comments