Skip to content

Commit

Permalink
Merge pull request #35 from mipstian/recents_window
Browse files Browse the repository at this point in the history
Recents window + error handling refactor
  • Loading branch information
Kaylee committed Jun 9, 2023
2 parents eef65ef + ba0ab8f commit fbed96d
Show file tree
Hide file tree
Showing 14 changed files with 261 additions and 233 deletions.
147 changes: 60 additions & 87 deletions Base.lproj/UI.xib

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion CTCFeedParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

@interface CTCFeedParser : NSObject

+ (NSArray*)parseFiles:(NSXMLDocument*)feed;
+ (NSArray*)parseFiles:(NSXMLDocument*)feed
error:(NSError * __autoreleasing *)error;

@end
5 changes: 3 additions & 2 deletions CTCFeedParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

@implementation CTCFeedParser

+ (NSArray*)parseFiles:(NSXMLDocument*)feed {
+ (NSArray*)parseFiles:(NSXMLDocument*)feed
error:(NSError * __autoreleasing *)outError {
NSLog(@"Parsing feed");

NSError *error = nil;
Expand All @@ -12,7 +13,7 @@ + (NSArray*)parseFiles:(NSXMLDocument*)feed {
NSArray *fileNodes = [feed nodesForXPath:@"//rss/channel/item" error:&error];

if (!fileNodes) {
NSLog(@"Parsing for URLs failed: %@", error);
*outError = error;
return nil;
}

Expand Down
6 changes: 6 additions & 0 deletions CTCFileUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

@interface CTCFileUtils : NSObject

+ (NSData *)bookmarkForURL:(NSURL *)url
error:(NSError * __autoreleasing *)error;

+ (NSURL *)URLFromBookmark:(NSData *)bookmark
error:(NSError * __autoreleasing *)error;

+ (NSString *)computeFilenameFromURL:(NSURL*)fileURL;

+ (NSString *)addTorrentExtensionTo:(NSString*)filename;
Expand Down
36 changes: 36 additions & 0 deletions CTCFileUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,42 @@

@implementation CTCFileUtils

+ (NSData *)bookmarkForURL:(NSURL *)url
error:(NSError * __autoreleasing *)outError {
// Create a bookmark so we can transfer access to the downloads path
// to the feed checker service
NSError *error = nil;
NSData *downloadFolderBookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
includingResourceValuesForKeys:@[]
relativeToURL:nil
error:&error];
if (!downloadFolderBookmark || error) {
*outError = error;
return nil;
}

return downloadFolderBookmark;
}

+ (NSURL *)URLFromBookmark:(NSData *)bookmark
error:(NSError * __autoreleasing *)outError {
NSError *error = nil;
BOOL isStale = NO;
NSURL *URL = [NSURL URLByResolvingBookmarkData:bookmark
options:kNilOptions
relativeToURL:nil
bookmarkDataIsStale:&isStale
error:&error];

if (!URL || error) {
NSLog(@"Could not get URL from bookmark: %@", error);
*outError = error;
return nil;
}

return URL;
}

+ (NSString *)computeFilenameFromURL:(NSURL*)fileURL {
// Compute destination filename
NSString *filename = fileURL.path.pathComponents.lastObject;
Expand Down
33 changes: 14 additions & 19 deletions CTCMenuController.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@ @interface CTCMenuController ()

@property (strong, nonatomic) NSStatusItem *menuBarItem;

@property (strong, nonatomic) NSDateFormatter *lastUpdateDateFormatter;

@end


@implementation CTCMenuController

- (void)awakeFromNib {
// Create a date formatter for "last update" dates
self.lastUpdateDateFormatter = NSDateFormatter.new;
self.lastUpdateDateFormatter.timeStyle = NSDateFormatterShortStyle;

[self setupMenuItem];

// Update UI with initial values
Expand Down Expand Up @@ -95,27 +101,16 @@ - (void)refreshSchedulerStatus {

- (void)setLastUpdateStatus:(BOOL)lastUpdateWasSuccessful time:(NSDate *)time {
// Create something like "Last update: 3:45 AM" and place it in the menu
NSString *baseLastUpdateString = nil;
NSString *lastUpdateString = nil;
NSString *lastUpdateStatusFormat = lastUpdateWasSuccessful ?
NSLocalizedString(@"lastupdate", @"Title for the last update time") :
NSLocalizedString(@"lastupdatefailed", @"Title for the last update time if it fails");

if (lastUpdateWasSuccessful) {
baseLastUpdateString = NSLocalizedString(@"lastupdate", @"Title for the last update time");
}
else {
baseLastUpdateString = NSLocalizedString(@"lastupdatefailed", @"Title for the last update time if it fails");
}

if (time) {
NSDateFormatter *dateFormatter = NSDateFormatter.new;
dateFormatter.timeStyle = NSDateFormatterShortStyle;
NSString *lastUpdateTime = [dateFormatter stringFromDate:time];
lastUpdateString = [NSString stringWithFormat:baseLastUpdateString, lastUpdateTime];
}
else {
lastUpdateString = [NSString stringWithFormat:baseLastUpdateString, NSLocalizedString(@"never", @"Never happened")];
}
NSString *lastUpdateStatus = time ?
[NSString stringWithFormat:lastUpdateStatusFormat,
[self.lastUpdateDateFormatter stringFromDate:time]] :
[NSString stringWithFormat:lastUpdateStatusFormat, NSLocalizedString(@"never", @"Never happened")];

[self.menuLastUpdate setTitle:lastUpdateString];
[self.menuLastUpdate setTitle:lastUpdateStatus];
}

- (void)setIdle {
Expand Down
9 changes: 9 additions & 0 deletions CTCRecentsCellView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#import <Cocoa/Cocoa.h>


@interface CTCRecentsCellView : NSTableCellView

@property (weak, nonatomic) IBOutlet NSTextField *downloadDateTextField;
@property (weak, nonatomic) IBOutlet NSButton *downloadAgainButton;

@end
4 changes: 4 additions & 0 deletions CTCRecentsCellView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#import "CTCRecentsCellView.h"


@implementation CTCRecentsCellView @end
93 changes: 34 additions & 59 deletions CTCRecentsController.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "CTCRecentsController.h"
#import "CTCDefaults.h"
#import "CTCScheduler.h"
#import "CTCRecentsCellView.h"


@interface CTCRecentsController ()
Expand All @@ -20,8 +21,6 @@ - (void)awakeFromNib {
self.downloadDateFormatter.dateStyle = NSDateFormatterShortStyle;
self.downloadDateFormatter.doesRelativeDateFormatting = YES;

self.table.selectionHighlightStyle = NSTableViewSelectionHighlightStyleSourceList;

[self setupObservers];
}

Expand All @@ -46,66 +45,42 @@ - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return CTCDefaults.downloadHistory.count;
}

- (IBAction)downloadRecentItemAgain:(id)sender {
NSLog(@"download again");
- (IBAction)downloadRecentItemAgain:(NSButton *)senderButton {
NSUInteger clickedRow = [self.table rowForView:senderButton];
NSDictionary *recentToDownload = CTCDefaults.downloadHistory[clickedRow];
if (!recentToDownload) return;

BOOL isMagnetLink = [recentToDownload[@"isMagnetLink"] boolValue];
if (isMagnetLink) {
[NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:recentToDownload[@"url"]]];
}
else {
[CTCScheduler.sharedScheduler downloadFile:recentToDownload
completion:^(NSDictionary *downloadedFile, NSError *error) {
if (downloadedFile && CTCDefaults.shouldOpenTorrentsAutomatically) {
[NSWorkspace.sharedWorkspace openFile:downloadedFile[@"torrentFilePath"]];
}
}];
}
}

- (NSView *)tableView:(NSTableView *)tableView
viewForTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)row {
NSDictionary *recent = CTCDefaults.downloadHistory[row];

// // Also refresh the list of recently downloaded torrents
// // Get the full list
// NSArray *downloadHistory = CTCDefaults.downloadHistory;
//
// // Get last 9 elements (changed from 10 so everything aligns nicer in the menu.. small tweak)
// NSUInteger recentsCount = MIN(downloadHistory.count, 9U);
// NSArray *recents = [downloadHistory subarrayWithRange:NSMakeRange(0U, recentsCount)];
//
// // Clear menu
// [self.menuRecentTorrents.submenu removeAllItems];
//
// // Add new items
// [recents enumerateObjectsUsingBlock:^(NSDictionary *recent, NSUInteger index, BOOL *stop) {
// NSString *menuTitle = [NSString stringWithFormat:@"%lu %@", index + 1, recent[@"title"]];
// NSMenuItem *recentMenuItem = [[NSMenuItem alloc] initWithTitle:menuTitle
// action:NULL
// keyEquivalent:@""];
//
// recentMenuItem.submenu = [self submenuForRecentItem:recent atIndex:index];
// [self.menuRecentTorrents.submenu addItem:recentMenuItem];
// }];
//
// // Put the Show in finder menu back
// [self.menuRecentTorrents.submenu addItem:self.menuShowInFinder];
CTCRecentsCellView *cell = [tableView makeViewWithIdentifier:@"RecentCell" owner:self];

// // Create a "download again" item
// NSMenuItem *downloadAgainItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"redownload", @"Button to download a downloaded torrent file again")
// action:@selector(downloadRecentItemAgain:)
// keyEquivalent:@""];
// downloadAgainItem.target = self;
// downloadAgainItem.tag = index;
// [submenu addItem:downloadAgainItem];
//
// // Create a disabled item with the download date, if available
// NSDate *downloadDate = (NSDate *)recent[@"date"];
// if (downloadDate) {
// // it may be interesting to have a bit more structure or intelligence to showing the dates for recent
// // items (just stuff this week based on preference?), or show the date in the list.. this solves
// // the problem of "how recent was recent?" tho with the tooltip.
// NSString *relativeDownloadDateDescription = [self.downloadDateFormatter stringFromDate:downloadDate];
// NSMenuItem *downloadDateItem = [[NSMenuItem alloc] initWithTitle:relativeDownloadDateDescription
// action:NULL
// keyEquivalent:@""];
// downloadAgainItem.enabled = NO;
// [submenu addItem:downloadDateItem];
// }
cell.textField.stringValue = recent[@"title"];

// NSDictionary *recentToDownload = CTCDefaults.downloadHistory[senderMenuItem.tag];
// if (!recentToDownload) return;
//
// BOOL isMagnetLink = [recentToDownload[@"isMagnetLink"] boolValue];
// if (isMagnetLink) {
// [NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:recentToDownload[@"url"]]];
// }
// else {
// [CTCScheduler.sharedScheduler downloadFile:recentToDownload];
// }
NSDate *downloadDate = (NSDate *)recent[@"date"];
cell.downloadDateTextField.stringValue = downloadDate ? [self.downloadDateFormatter stringFromDate:downloadDate] : @"";

return cell;
}

- (BOOL)selectionShouldChangeInTableView:(NSTableView *)tableView {
return NO;
}

- (void)dealloc {
Expand Down
3 changes: 2 additions & 1 deletion CTCScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ extern NSString * const kCTCSchedulerLastUpdateStatusNotificationName;

- (void)forceCheck;

- (void)downloadFile:(NSDictionary *)file;
- (void)downloadFile:(NSDictionary *)file
completion:(void (^)(NSDictionary *downloadedFile, NSError *error))completion;

@end
35 changes: 20 additions & 15 deletions CTCScheduler.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "CTCScheduler.h"
#import "CTCFeedChecker.h"
#import "CTCDefaults.h"
#import "CTCFileUtils.h"
#import "NSDate+TimeOfDayMath.h"


Expand Down Expand Up @@ -81,6 +82,7 @@ - (void)setChecking:(BOOL)checking {

- (void)setPolling:(BOOL)polling {
_polling = polling;

[self reportStatus];
}

Expand Down Expand Up @@ -108,23 +110,17 @@ - (void)checkFeed {
}

- (NSData *)downloadFolderBookmark {
NSString *downloadPath = CTCDefaults.torrentsSavePath;
NSError *error;
NSURL *url = [NSURL fileURLWithPath:CTCDefaults.torrentsSavePath];
NSData *bookmark = [CTCFileUtils bookmarkForURL:url error:&error];

// Create a bookmark so we can transfer access to the downloads path
// to the feed checker service
NSURL *downloadFolderURL = [NSURL fileURLWithPath:downloadPath];
NSError *error = nil;
NSData *downloadFolderBookmark = [downloadFolderURL bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
includingResourceValuesForKeys:@[]
relativeToURL:nil
error:&error];
if (!downloadFolderBookmark || error) {
// Not really handling this error
if (!bookmark) {
// Not really handling this at all
[NSException raise:@"Couldn't create bookmark for downloads folder"
format:@"Error: %@", error];
}

return downloadFolderBookmark;
return bookmark;
}

- (void)callFeedCheckerWithReplyHandler:(CTCFeedCheckCompletionHandler)replyHandler {
Expand All @@ -143,6 +139,9 @@ - (void)callFeedCheckerWithReplyHandler:(CTCFeedCheckCompletionHandler)replyHand
organizingByFolder:CTCDefaults.shouldOrganizeTorrentsInFolders
skippingURLs:previouslyDownloadedURLs
withReply:^(NSArray *downloadedFeedFiles, NSError *error) {
if (error) {
NSLog(@"Feed Checker error (checking feed): %@", error);
}
dispatch_async(dispatch_get_main_queue(), ^{
replyHandler(downloadedFeedFiles, error);
});
Expand Down Expand Up @@ -181,14 +180,20 @@ - (void)forceCheck {
[self checkFeed];
}

- (void)downloadFile:(NSDictionary *)file {
- (void)downloadFile:(NSDictionary *)file
completion:(void (^)(NSDictionary *downloadedFile, NSError *error))completion {
// Call feed checker service
CTCFeedChecker *feedChecker = [self.feedCheckerConnection remoteObjectProxy];
[feedChecker downloadFile:file
toBookmark:[self downloadFolderBookmark]
organizingByFolder:CTCDefaults.shouldOrganizeTorrentsInFolders
withReply:^(NSError *error) {
// TODO
withReply:^(NSDictionary *downloadedFile, NSError *error) {
if (error) {
NSLog(@"Feed Checker error (downloading file): %@", error);
}
dispatch_async(dispatch_get_main_queue(), ^{
completion(downloadedFile, error);
});
}];
}

Expand Down
Loading

0 comments on commit fbed96d

Please sign in to comment.