mirror of
https://github.com/transmission/transmission.git
synced 2025-12-23 20:08:43 +00:00
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:
@@ -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;
|
||||
|
||||
@@ -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,14 +245,26 @@ 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
|
||||
selector: @selector( updateUI: ) userInfo: nil repeats: YES];
|
||||
selector: @selector(updateUI:) userInfo: nil repeats: YES];
|
||||
[[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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
4
macosx/English.lproj/PrefsWindow.nib/classes.nib
generated
4
macosx/English.lproj/PrefsWindow.nib/classes.nib
generated
@@ -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;
|
||||
|
||||
7
macosx/English.lproj/PrefsWindow.nib/info.nib
generated
7
macosx/English.lproj/PrefsWindow.nib/info.nib
generated
@@ -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>
|
||||
|
||||
BIN
macosx/English.lproj/PrefsWindow.nib/keyedobjects.nib
generated
BIN
macosx/English.lproj/PrefsWindow.nib/keyedobjects.nib
generated
Binary file not shown.
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user