Monitor a folder for torrent files, adding them as they are added (by polling the folder). Growl notifications for import, and only try to reimport the same torrent if the setting is changed, the app is restarted, or the torrent file is moved to a different folder then moved back.

Original code from Steve (brilla on the forums).
This commit is contained in:
Mitchell Livingston
2006-07-07 01:03:52 +00:00
parent 59ddd1f75c
commit cb8baebb35
8 changed files with 173 additions and 32 deletions

View File

@@ -71,6 +71,9 @@
io_connect_t fRootPort;
NSTimer * fTimer;
NSTimer * fAutoImportTimer;
NSArray * fAutoImportedNames;
BOOL fHasGrowl;
Badger * fBadger;
BOOL fUpdateInProgress;
@@ -142,6 +145,9 @@
- (void) reloadInspectorSettings: (NSNotification *) notification;
- (void) checkAutoImportDirectory: (NSTimer *) t;
- (void) autoImportChange: (NSNotification *) notification;
- (void) sleepCallBack: (natural_t) messageType argument:
(void *) messageArgument;
@@ -155,7 +161,7 @@
- (void) linkHomepage: (id) sender;
- (void) linkForums: (id) sender;
- (void) notifyGrowl: (NSString *) file;
- (void) notifyGrowl: (NSString * ) title message: (NSString *) message notification: (NSString *) notification;
- (void) growlRegister;
- (void) checkUpdate: (id) sender;

View File

@@ -89,6 +89,7 @@ static void sleepCallBack(void * controller, io_service_t y,
[fInfoController release];
[fBadger release];
[fSortType release];
[fAutoImportedNames release];
tr_close( fLib );
[super dealloc];
@@ -244,7 +245,11 @@ static void sleepCallBack(void * controller, io_service_t y,
[nc addObserver: self selector: @selector(reloadInspectorSettings:)
name: @"TorrentSettingChange" object: nil];
//timer to update the interface
//reset auto import
[nc addObserver: self selector: @selector(autoImportChange:)
name: @"AutoImportSettingChange" object: nil];
//timer to update the interface every second
fCompleted = 0;
[self updateUI: nil];
fTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target: self
@@ -252,6 +257,14 @@ static void sleepCallBack(void * controller, io_service_t y,
[[NSRunLoop currentRunLoop] addTimer: fTimer forMode: NSModalPanelRunLoopMode];
[[NSRunLoop currentRunLoop] addTimer: fTimer forMode: NSEventTrackingRunLoopMode];
//timer for auto import, will check every 60 seconds
fAutoImportedNames = [[NSArray alloc] init];
[self checkAutoImportDirectory: nil];
fAutoImportTimer = [NSTimer scheduledTimerWithTimeInterval: 5.0 target: self
selector: @selector(checkAutoImportDirectory:) userInfo: nil repeats: YES];
[[NSRunLoop currentRunLoop] addTimer: fAutoImportTimer forMode: NSDefaultRunLoopMode];
[self sortTorrents];
[fWindow makeKeyAndOrderFront: nil];
@@ -310,7 +323,8 @@ static void sleepCallBack(void * controller, io_service_t y,
- (void) applicationWillTerminate: (NSNotification *) notification
{
//stop updating the interface
//stop timers
[fAutoImportTimer invalidate];
[fTimer invalidate];
//save history and stop running torrents
@@ -456,11 +470,6 @@ static void sleepCallBack(void * controller, io_service_t y,
@selector(openSheetClosed:returnCode:contextInfo:) contextInfo: nil];
}
- (void) openFromSheet: (NSArray *) filenames
{
[self application: NSApp openFiles: filenames];
}
- (void) openSheetClosed: (NSOpenPanel *) panel returnCode: (int) code
contextInfo: (void *) info
{
@@ -469,6 +478,11 @@ static void sleepCallBack(void * controller, io_service_t y,
withObject: [panel filenames] waitUntilDone: NO];
}
- (void) openFromSheet: (NSArray *) filenames
{
[self application: NSApp openFiles: filenames];
}
- (void) resumeTorrent: (id) sender
{
[self resumeTorrentWithIndex: [fTableView selectedRowIndexes]];
@@ -771,7 +785,7 @@ static void sleepCallBack(void * controller, io_service_t y,
[self checkWaitingForFinished: torrent];
//notifications
[self notifyGrowl: [torrent name]];
[self notifyGrowl: @"Download Complete" message: [torrent name] notification: @"Download Complete"];
if (![fWindow isKeyWindow])
fCompleted++;
}
@@ -1127,6 +1141,52 @@ static void sleepCallBack(void * controller, io_service_t y,
[fInfoController updateInfoStatsAndSettings];
}
- (void) checkAutoImportDirectory: (NSTimer *) timer
{
if (![fDefaults boolForKey: @"AutoImport"])
return;
NSString * path = [[fDefaults stringForKey: @"AutoImportDirectory"] stringByExpandingTildeInPath];
//if folder cannot be found simply give up
NSArray * allFileNames;
if (!(allFileNames = [[NSFileManager defaultManager] directoryContentsAtPath: path]))
return;
//try to add files that haven't already been added
NSMutableArray * newFileNames = [NSMutableArray arrayWithArray: allFileNames];
[newFileNames removeObjectsInArray: fAutoImportedNames];
//save the current list of files
[fAutoImportedNames release];
fAutoImportedNames = [allFileNames retain];
NSEnumerator * enumerator = [newFileNames objectEnumerator];
NSString * file;
unsigned oldCount;
while ((file = [enumerator nextObject]))
if ([[file pathExtension] caseInsensitiveCompare: @"torrent"] == NSOrderedSame)
{
NSString * fullPath = [path stringByAppendingPathComponent: file];
oldCount = [fTorrents count];
[self openFromSheet: [NSArray arrayWithObject: fullPath]];
//import only actually happened if the torrent array is larger
if (oldCount < [fTorrents count])
[self notifyGrowl: [file stringByAppendingString: @" Imported"] message: @"Torrent file imported"
notification: @"Import Performed"];
}
}
- (void) autoImportChange: (NSNotification *) notification
{
[fAutoImportedNames release];
fAutoImportedNames = [[NSArray alloc] init];
[self checkAutoImportDirectory: nil];
}
- (int) numberOfRowsInTableView: (NSTableView *) t
{
return [fTorrents count];
@@ -1700,7 +1760,7 @@ static void sleepCallBack(void * controller, io_service_t y,
[[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: FORUM_URL]];
}
- (void) notifyGrowl: (NSString * ) file
- (void) notifyGrowl: (NSString * ) title message: (NSString *) message notification: (NSString *) notification
{
if (!fHasGrowl)
return;
@@ -1709,13 +1769,13 @@ static void sleepCallBack(void * controller, io_service_t y,
@"tell application \"System Events\"\n"
" if exists application process \"GrowlHelperApp\" then\n"
" tell application \"GrowlHelperApp\"\n "
" notify with name \"Download Complete\""
" title \"Download Complete\""
" notify with name \"%@\""
" title \"%@\""
" description \"%@\""
" application name \"Transmission\"\n"
" end tell\n"
" end if\n"
"end tell", file];
"end tell", notification, title, message];
NSAppleScript * appleScript = [[NSAppleScript alloc] initWithSource: growlScript];
NSDictionary * error;
@@ -1729,17 +1789,16 @@ static void sleepCallBack(void * controller, io_service_t y,
if (!fHasGrowl)
return;
NSString * growlScript = [NSString stringWithFormat:
@"tell application \"System Events\"\n"
NSString * growlScript = @"tell application \"System Events\"\n"
" if exists application process \"GrowlHelperApp\" then\n"
" tell application \"GrowlHelperApp\"\n"
" register as application \"Transmission\" "
" all notifications {\"Download Complete\"}"
" default notifications {\"Download Complete\"}"
" all notifications {\"Download Complete\", \"Import Performed\"}"
" default notifications {\"Download Complete\", \"Import Performed\"}"
" icon of application \"Transmission\"\n"
" end tell\n"
" end if\n"
"end tell"];
"end tell";
NSAppleScript * appleScript = [[NSAppleScript alloc] initWithSource: growlScript];
NSDictionary * error;

View File

@@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AutoImport</key>
<false/>
<key>AutoImportDirectory</key>
<string>~/Desktop</string>
<key>BadgeDownloadRate</key>
<false/>
<key>BadgeUploadRate</key>

View File

@@ -5,6 +5,8 @@
{
ACTIONS = {
folderSheetShow = id;
importFolderSheetShow = id;
setAutoImport = id;
setBadge = id;
setDownloadLocation = id;
setLimit = id;
@@ -22,6 +24,7 @@
CLASS = PrefsController;
LANGUAGE = ObjC;
OUTLETS = {
fAutoImportCheck = NSButton;
fBadgeDownloadRateCheck = NSButton;
fBadgeUploadRateCheck = NSButton;
fBandwidthView = NSView;
@@ -31,6 +34,7 @@
fDownloadField = NSTextField;
fFolderPopUp = NSPopUpButton;
fGeneralView = NSView;
fImportFolderPopUp = NSPopUpButton;
fNetworkView = NSView;
fPortField = NSTextField;
fQuitCheck = NSButton;

View File

@@ -9,18 +9,21 @@
<key>153</key>
<string>275 334 554 217 0 0 1152 842 </string>
<key>28</key>
<string>299 451 554 254 0 0 1152 842 </string>
<string>443 473 554 254 0 0 1440 878 </string>
<key>41</key>
<string>299 429 554 297 0 0 1152 842 </string>
<string>241 434 554 342 0 0 1440 878 </string>
<key>66</key>
<string>299 526 554 104 0 0 1152 842 </string>
</dict>
<key>IBFramework Version</key>
<string>446.1</string>
<<<<<<< .mine
=======
<key>IBOpenObjects</key>
<array>
<integer>153</integer>
</array>
>>>>>>> .r537
<key>IBSystem Version</key>
<string>8J135</string>
</dict>

View File

@@ -33,11 +33,13 @@
NSToolbar * fToolbar;
IBOutlet NSView * fGeneralView, * fTransfersView, * fBandwidthView, * fNetworkView;
IBOutlet NSPopUpButton * fFolderPopUp;
IBOutlet NSPopUpButton * fFolderPopUp, * fImportFolderPopUp;
IBOutlet NSButton * fQuitCheck, * fRemoveCheck,
* fQuitDownloadingCheck, * fRemoveDownloadingCheck,
* fBadgeDownloadRateCheck, * fBadgeUploadRateCheck,
* fCopyTorrentCheck, * fDeleteOriginalTorrentCheck;
* fCopyTorrentCheck, * fDeleteOriginalTorrentCheck,
* fAutoImportCheck;
IBOutlet NSPopUpButton * fUpdatePopUp;
IBOutlet NSTextField * fUploadField, * fDownloadField,
@@ -54,7 +56,7 @@
IBOutlet SUUpdater * fUpdater;
NSString * fDownloadFolder;
NSString * fDownloadFolder, * fImportFolder;
NSUserDefaults * fDefaults;
}
@@ -82,6 +84,9 @@
- (void) enableSpeedLimit: (BOOL) enable;
- (void) setAutoImport: (id) sender;
- (void) importFolderSheetShow: (id) sender;
- (void) setRatio: (id) sender;
- (void) setRatioCheck: (id) sender;
- (void) setRatioEnabled: (BOOL) enable;

View File

@@ -57,6 +57,9 @@
- (void) folderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info;
- (void) updatePopUp;
- (void) importFolderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info;
- (void) updateImportPopUp;
@end
@implementation PrefsController
@@ -91,9 +94,7 @@
//set download folder
NSString * downloadChoice = [fDefaults stringForKey: @"DownloadChoice"];
fDownloadFolder = [[fDefaults stringForKey: @"DownloadFolder"] stringByExpandingTildeInPath];
[fDownloadFolder retain];
fDownloadFolder = [[[fDefaults stringForKey: @"DownloadFolder"] stringByExpandingTildeInPath] retain];
if ([downloadChoice isEqualToString: @"Constant"])
[fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
else if ([downloadChoice isEqualToString: @"Torrent"])
@@ -102,6 +103,14 @@
[fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
[self updatePopUp];
//set auto import
fImportFolder = [[[fDefaults stringForKey: @"AutoImportDirectory"] stringByExpandingTildeInPath] retain];
[self updateImportPopUp];
BOOL autoImport = [fDefaults boolForKey: @"AutoImport"];
[fAutoImportCheck setState: autoImport];
[fImportFolderPopUp setEnabled: autoImport];
//set bind port
int bindPort = [fDefaults integerForKey: @"BindPort"];
[fPortField setIntValue: bindPort];
@@ -597,8 +606,31 @@
[panel beginSheetForDirectory: nil file: nil types: nil
modalForWindow: [self window] modalDelegate: self didEndSelector:
@selector( folderSheetClosed:returnCode:contextInfo: )
contextInfo: nil];
@selector(folderSheetClosed:returnCode:contextInfo:) contextInfo: nil];
}
- (void) setAutoImport: (id) sender
{
int state = [fAutoImportCheck state];
[fDefaults setBool: state forKey: @"AutoImport"];
[fImportFolderPopUp setEnabled: state];
[[NSNotificationCenter defaultCenter] postNotificationName: @"AutoImportSettingChange" object: self];
}
- (void) importFolderSheetShow: (id) sender
{
NSOpenPanel * panel = [NSOpenPanel openPanel];
[panel setPrompt: @"Select"];
[panel setAllowsMultipleSelection: NO];
[panel setCanChooseFiles: NO];
[panel setCanChooseDirectories: YES];
[panel setCanCreateDirectories: YES];
[panel beginSheetForDirectory: nil file: nil types: nil
modalForWindow: [self window] modalDelegate: self didEndSelector:
@selector(importFolderSheetClosed:returnCode:contextInfo:) contextInfo: nil];
}
- (void) windowWillClose: (NSNotification *) notification
@@ -652,8 +684,7 @@
if (code == NSOKButton)
{
[fDownloadFolder release];
fDownloadFolder = [[openPanel filenames] objectAtIndex: 0];
[fDownloadFolder retain];
fDownloadFolder = [[[openPanel filenames] objectAtIndex: 0] retain];
[fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
[fDefaults setObject: fDownloadFolder forKey: @"DownloadFolder"];
@@ -687,4 +718,33 @@
[menuItem setImage: icon];
}
- (void) importFolderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info
{
if (code == NSOKButton)
{
[fImportFolder release];
fImportFolder = [[[openPanel filenames] objectAtIndex: 0] retain];
[fDefaults setObject: fImportFolder forKey: @"AutoImportDirectory"];
[self updateImportPopUp];
[[NSNotificationCenter defaultCenter] postNotificationName: @"AutoImportSettingChange" object: self];
}
[fImportFolderPopUp selectItemAtIndex: 0];
}
- (void) updateImportPopUp
{
//get and resize the icon
NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFile: fImportFolder];
[icon setScalesWhenResized: YES];
[icon setSize: NSMakeSize(16.0, 16.0)];
//update menu item
NSMenuItem * menuItem = (NSMenuItem *) [fImportFolderPopUp itemAtIndex: 0];
[menuItem setTitle: [fImportFolder lastPathComponent]];
[menuItem setImage: icon];
}
@end