Replaced deprecated NSURLDownload with NSURLSessionDownloadTask. (#4308)

This commit is contained in:
Cœur 2022-12-16 08:19:27 +08:00 committed by GitHub
parent 30d3ce872f
commit 578099bf1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 80 deletions

View File

@ -26,7 +26,7 @@ typedef NS_ENUM(unsigned int, addType) { //
}; };
@interface Controller @interface Controller
: NSObject<NSApplicationDelegate, NSURLDownloadDelegate, NSUserNotificationCenterDelegate, NSPopoverDelegate, NSSharingServiceDelegate, NSSharingServicePickerDelegate, NSSoundDelegate, NSToolbarDelegate, NSWindowDelegate, QLPreviewPanelDataSource, QLPreviewPanelDelegate, VDKQueueDelegate, SUUpdaterDelegate> : NSObject<NSApplicationDelegate, NSUserNotificationCenterDelegate, NSPopoverDelegate, NSSharingServiceDelegate, NSSharingServicePickerDelegate, NSSoundDelegate, NSToolbarDelegate, NSWindowDelegate, QLPreviewPanelDataSource, QLPreviewPanelDelegate, VDKQueueDelegate, SUUpdaterDelegate>
- (void)openFiles:(NSArray<NSString*>*)filenames addType:(addType)type forcePath:(NSString*)path; - (void)openFiles:(NSArray<NSString*>*)filenames addType:(addType)type forcePath:(NSString*)path;

View File

@ -233,7 +233,7 @@ static void removeKeRangerRansomware()
NSLog(@"OSX.KeRanger.A ransomware removal completed, proceeding to normal operation"); NSLog(@"OSX.KeRanger.A ransomware removal completed, proceeding to normal operation");
} }
@interface Controller ()<UNUserNotificationCenterDelegate> @interface Controller ()<UNUserNotificationCenterDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
@property(nonatomic) IBOutlet NSWindow* fWindow; @property(nonatomic) IBOutlet NSWindow* fWindow;
@property(nonatomic) IBOutlet NSStackView* fStackView; @property(nonatomic) IBOutlet NSStackView* fStackView;
@ -292,7 +292,7 @@ static void removeKeRangerRansomware()
@property(nonatomic) NSMutableArray<NSString*>* fAutoImportedNames; @property(nonatomic) NSMutableArray<NSString*>* fAutoImportedNames;
@property(nonatomic) NSTimer* fAutoImportTimer; @property(nonatomic) NSTimer* fAutoImportTimer;
@property(nonatomic) NSMutableDictionary<NSURL*, id>* fPendingTorrentDownloads; @property(nonatomic) NSURLSession* fSession;
@property(nonatomic) NSMutableSet<Torrent*>* fAddingTransfers; @property(nonatomic) NSMutableSet<Torrent*>* fAddingTransfers;
@ -591,6 +591,10 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
_fDisplayedTorrents = [[NSMutableArray alloc] init]; _fDisplayedTorrents = [[NSMutableArray alloc] init];
_fTorrentHashes = [[NSMutableDictionary alloc] init]; _fTorrentHashes = [[NSMutableDictionary alloc] init];
NSURLSessionConfiguration* configuration = NSURLSessionConfiguration.defaultSessionConfiguration;
configuration.requestCachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
_fSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
_fInfoController = [[InfoWindowController alloc] init]; _fInfoController = [[InfoWindowController alloc] init];
//needs to be done before init-ing the prefs controller //needs to be done before init-ing the prefs controller
@ -1049,14 +1053,7 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
} }
//remove all torrent downloads //remove all torrent downloads
if (self.fPendingTorrentDownloads) [self.fSession invalidateAndCancel];
{
for (NSDictionary* downloadDict in self.fPendingTorrentDownloads)
{
NSURLDownload* download = downloadDict[@"Download"];
[download cancel];
}
}
//remember window states and close all windows //remember window states and close all windows
[self.fDefaults setBool:self.fInfoController.window.visible forKey:@"InfoVisible"]; [self.fDefaults setBool:self.fInfoController.window.visible forKey:@"InfoVisible"];
@ -1112,77 +1109,87 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
} }
} }
- (void)download:(NSURLDownload*)download decideDestinationWithSuggestedFilename:(NSString*)suggestedName #pragma mark - NSURLSessionDelegate
{
if ([suggestedName.pathExtension caseInsensitiveCompare:@"torrent"] != NSOrderedSame)
{
[download cancel];
[self.fPendingTorrentDownloads removeObjectForKey:download.request.URL]; - (void)URLSession:(nonnull NSURLSession*)session
if (self.fPendingTorrentDownloads.count == 0) dataTask:(nonnull NSURLSessionDataTask*)dataTask
didReceiveResponse:(nonnull NSURLResponse*)response
completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler
{ {
self.fPendingTorrentDownloads = nil; NSString* suggestedName = response.suggestedFilename;
if ([suggestedName.pathExtension caseInsensitiveCompare:@"torrent"] == NSOrderedSame)
{
completionHandler(NSURLSessionResponseBecomeDownload);
return;
} }
completionHandler(NSURLSessionResponseCancel);
NSString* message = [NSString NSString* message = [NSString
stringWithFormat:NSLocalizedString(@"It appears that the file \"%@\" from %@ is not a torrent file.", "Download not a torrent -> message"), stringWithFormat:NSLocalizedString(@"It appears that the file \"%@\" from %@ is not a torrent file.", "Download not a torrent -> message"),
suggestedName, suggestedName,
download.request.URL.absoluteString.stringByRemovingPercentEncoding]; dataTask.originalRequest.URL.absoluteString.stringByRemovingPercentEncoding];
dispatch_async(dispatch_get_main_queue(), ^{
NSAlert* alert = [[NSAlert alloc] init]; NSAlert* alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:NSLocalizedString(@"OK", "Download not a torrent -> button")]; [alert addButtonWithTitle:NSLocalizedString(@"OK", "Download not a torrent -> button")];
alert.messageText = NSLocalizedString(@"Torrent download failed", "Download not a torrent -> title"); alert.messageText = NSLocalizedString(@"Torrent download failed", "Download not a torrent -> title");
alert.informativeText = message; alert.informativeText = message;
[alert runModal]; [alert runModal];
} });
else
{
[download setDestination:[NSTemporaryDirectory() stringByAppendingPathComponent:suggestedName.lastPathComponent]
allowOverwrite:NO];
}
} }
- (void)download:(NSURLDownload*)download didCreateDestination:(NSString*)path - (void)URLSession:(nonnull NSURLSession*)session
dataTask:(nonnull NSURLSessionDataTask*)dataTask
didBecomeDownloadTask:(nonnull NSURLSessionDownloadTask*)downloadTask
{ {
NSMutableDictionary* dict = self.fPendingTorrentDownloads[download.request.URL]; // Required delegate method to proceed with NSURLSessionResponseBecomeDownload.
dict[@"Path"] = path; // nothing to do
} }
- (void)download:(NSURLDownload*)download didFailWithError:(NSError*)error - (void)URLSession:(nonnull NSURLSession*)session
downloadTask:(nonnull NSURLSessionDownloadTask*)downloadTask
didFinishDownloadingToURL:(nonnull NSURL*)location
{ {
NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent:downloadTask.response.suggestedFilename.lastPathComponent];
NSError* error;
[NSFileManager.defaultManager moveItemAtPath:location.path toPath:path error:&error];
if (error)
{
[self URLSession:session task:downloadTask didCompleteWithError:error];
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
[self openFiles:@[ path ] addType:ADD_URL forcePath:nil];
//delete the torrent file after opening
[NSFileManager.defaultManager removeItemAtPath:path error:NULL];
});
}
- (void)URLSession:(nonnull NSURLSession*)session
task:(nonnull NSURLSessionTask*)task
didCompleteWithError:(nullable NSError*)error
{
if (!error || error.code == NSURLErrorCancelled)
{
// no errors or we already displayed an alert
return;
}
NSString* message = [NSString NSString* message = [NSString
stringWithFormat:NSLocalizedString(@"The torrent could not be downloaded from %@: %@.", "Torrent download failed -> message"), stringWithFormat:NSLocalizedString(@"The torrent could not be downloaded from %@: %@.", "Torrent download failed -> message"),
download.request.URL.absoluteString.stringByRemovingPercentEncoding, task.originalRequest.URL.absoluteString.stringByRemovingPercentEncoding,
error.localizedDescription]; error.localizedDescription];
dispatch_async(dispatch_get_main_queue(), ^{
NSAlert* alert = [[NSAlert alloc] init]; NSAlert* alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:NSLocalizedString(@"OK", "Torrent download failed -> button")]; [alert addButtonWithTitle:NSLocalizedString(@"OK", "Torrent download failed -> button")];
alert.messageText = NSLocalizedString(@"Torrent download failed", "Torrent download error -> title"); alert.messageText = NSLocalizedString(@"Torrent download failed", "Torrent download error -> title");
alert.informativeText = message; alert.informativeText = message;
[alert runModal]; [alert runModal];
});
[self.fPendingTorrentDownloads removeObjectForKey:download.request.URL];
if (self.fPendingTorrentDownloads.count == 0)
{
self.fPendingTorrentDownloads = nil;
}
} }
- (void)downloadDidFinish:(NSURLDownload*)download #pragma mark -
{
NSString* path = self.fPendingTorrentDownloads[download.request.URL][@"Path"];
[self openFiles:@[ path ] addType:ADD_URL forcePath:nil];
//delete the torrent file after opening
[NSFileManager.defaultManager removeItemAtPath:path error:NULL];
[self.fPendingTorrentDownloads removeObjectForKey:download.request.URL];
if (self.fPendingTorrentDownloads.count == 0)
{
self.fPendingTorrentDownloads = nil;
}
}
- (void)application:(NSApplication*)app openFiles:(NSArray<NSString*>*)filenames - (void)application:(NSApplication*)app openFiles:(NSArray<NSString*>*)filenames
{ {
@ -1630,23 +1637,18 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
return; return;
} }
NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData [self.fSession getAllTasksWithCompletionHandler:^(NSArray<__kindof NSURLSessionTask*>* _Nonnull tasks) {
timeoutInterval:60]; for (NSURLSessionTask* task in tasks)
if (self.fPendingTorrentDownloads[request.URL])
{ {
NSLog(@"Already downloading %@", request.URL); if ([task.originalRequest.URL isEqual:url])
{
NSLog(@"Already downloading %@", url);
return; return;
} }
NSURLDownload* download = [[NSURLDownload alloc] initWithRequest:request delegate:self];
if (!self.fPendingTorrentDownloads)
{
self.fPendingTorrentDownloads = [[NSMutableDictionary alloc] init];
} }
NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObject:download forKey:@"Download"]; NSURLSessionDataTask* download = [self.fSession dataTaskWithURL:url];
self.fPendingTorrentDownloads[request.URL] = dict; [download resume];
}];
} }
} }
@ -2366,6 +2368,8 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
self.fTotalTorrentsField.stringValue = totalTorrentsString; self.fTotalTorrentsField.stringValue = totalTorrentsString;
} }
#pragma mark - UNUserNotificationCenterDelegate
- (void)userNotificationCenter:(UNUserNotificationCenter*)center - (void)userNotificationCenter:(UNUserNotificationCenter*)center
willPresentNotification:(UNNotification*)notification willPresentNotification:(UNNotification*)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler API_AVAILABLE(macos(10.14)) withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler API_AVAILABLE(macos(10.14))
@ -2493,6 +2497,8 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
[self.fTableView selectAndScrollToRow:row]; [self.fTableView selectAndScrollToRow:row];
} }
#pragma mark -
- (Torrent*)torrentForHash:(NSString*)hash - (Torrent*)torrentForHash:(NSString*)hash
{ {
NSParameterAssert(hash != nil); NSParameterAssert(hash != nil);