Replaced deprecated NSURLDownload with NSURLSessionDownloadTask. (#4308)
This commit is contained in:
parent
30d3ce872f
commit
578099bf1c
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue