362 lines
16 KiB
Objective-C
362 lines
16 KiB
Objective-C
//
|
|
// MGMFTPPlugIn.m
|
|
// CocoaShare
|
|
//
|
|
// Created by Mr. Gecko on 1/25/11.
|
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/
|
|
//
|
|
|
|
#import "MGMFTPPlugIn.h"
|
|
#import "MGMController.h"
|
|
#import "MGMAddons.h"
|
|
|
|
NSString * const MGMCopyright = @"Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/";
|
|
|
|
NSString * const MGMFTPHost = @"MGMFTPHost";
|
|
NSString * const MGMFTPUser = @"MGMFTPUser";
|
|
NSString * const MGMFTPPath = @"MGMFTPPath";
|
|
NSString * const MGMFTPURL = @"MGMFTPURL";
|
|
|
|
@implementation MGMFTPPlugIn
|
|
- (void)dealloc {
|
|
[self releaseView];
|
|
[filePath release];
|
|
[fileName release];
|
|
[FTPTask terminate];
|
|
[FTPTask release];
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
[FTPPipe release];
|
|
[FTPInputPipe release];
|
|
[super dealloc];
|
|
}
|
|
|
|
- (BOOL)isAccountPlugIn {
|
|
return YES;
|
|
}
|
|
- (NSString *)plugInName {
|
|
return @"FTP";
|
|
}
|
|
- (NSView *)plugInView {
|
|
if (view==nil) {
|
|
if (![NSBundle loadNibNamed:@"FTPAccountPane" owner:self]) {
|
|
NSLog(@"Unable to load FTP Account Pane");
|
|
} else {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
NSString *host = [defaults objectForKey:MGMFTPHost];
|
|
if (host!=nil)
|
|
[hostField setStringValue:host];
|
|
NSString *user = [defaults objectForKey:MGMFTPUser];
|
|
if (user!=nil)
|
|
[userField setStringValue:user];
|
|
NSString *password = [[MGMController sharedController] password];
|
|
if (password!=nil)
|
|
[passwordField setStringValue:password];
|
|
NSString *path = [defaults objectForKey:MGMFTPPath];
|
|
if (path!=nil)
|
|
[pathField setStringValue:path];
|
|
NSString *url = [defaults objectForKey:MGMFTPURL];
|
|
if (url!=nil)
|
|
[urlField setStringValue:url];
|
|
}
|
|
}
|
|
return view;
|
|
}
|
|
- (void)releaseView {
|
|
[view release];
|
|
view = nil;
|
|
hostField = nil;
|
|
userField = nil;
|
|
passwordField = nil;
|
|
pathField = nil;
|
|
urlField = nil;
|
|
loginButton = nil;
|
|
}
|
|
|
|
- (void)setCurrentPlugIn:(BOOL)isCurrent {
|
|
if (!isCurrent) {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
[defaults removeObjectForKey:MGMFTPHost];
|
|
[defaults removeObjectForKey:MGMFTPUser];
|
|
[defaults removeObjectForKey:MGMFTPPath];
|
|
[defaults removeObjectForKey:MGMFTPURL];
|
|
}
|
|
}
|
|
|
|
- (void)lockLogin {
|
|
[hostField setEnabled:NO];
|
|
[userField setEnabled:NO];
|
|
[passwordField setEnabled:NO];
|
|
[pathField setEnabled:NO];
|
|
[urlField setEnabled:NO];
|
|
[loginButton setEnabled:NO];
|
|
[loginButton setTitle:[@"Logging In" localizedFor:self]];
|
|
}
|
|
- (void)unlockLogin {
|
|
[hostField setEnabled:YES];
|
|
[userField setEnabled:YES];
|
|
[passwordField setEnabled:YES];
|
|
[pathField setEnabled:YES];
|
|
[urlField setEnabled:YES];
|
|
[loginButton setEnabled:YES];
|
|
[loginButton setTitle:[@"Login" localizedFor:self]];
|
|
}
|
|
- (IBAction)login:(id)sender {
|
|
if ([[hostField stringValue] isEqual:@""]) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Host Required" localizedFor:self]];
|
|
[alert setInformativeText:[@"Please enter your host." localizedFor:self]];
|
|
[alert runModal];
|
|
} else if ([[userField stringValue] isEqual:@""]) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"UserName Required" localizedFor:self]];
|
|
[alert setInformativeText:[@"Please enter your username." localizedFor:self]];
|
|
[alert runModal];
|
|
} else if ([[passwordField stringValue] isEqual:@""]) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Password Required" localizedFor:self]];
|
|
[alert setInformativeText:[@"Please enter your password." localizedFor:self]];
|
|
[alert runModal];
|
|
} else if ([[urlField stringValue] isEqual:@""]) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"URL Required" localizedFor:self]];
|
|
[alert setInformativeText:[@"Please enter the URL to where the files will be uploaded." localizedFor:self]];
|
|
[alert runModal];
|
|
} else {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
[[MGMController sharedController] setPassword:[passwordField stringValue]];
|
|
[defaults setObject:[hostField stringValue] forKey:MGMFTPHost];
|
|
[defaults setObject:[userField stringValue] forKey:MGMFTPUser];
|
|
[defaults setObject:[pathField stringValue] forKey:MGMFTPPath];
|
|
[defaults setObject:[urlField stringValue] forKey:MGMFTPURL];
|
|
[self lockLogin];
|
|
|
|
FTPTask = [NSTask new];
|
|
[FTPTask setLaunchPath:@"/usr/bin/ftp"];
|
|
[FTPTask setArguments:[NSArray arrayWithObjects:@"-v", [NSString stringWithFormat:@"ftp://%@:%@@%@", [defaults objectForKey:MGMFTPUser], [[MGMController sharedController] password], [defaults objectForKey:MGMFTPHost]], nil]];
|
|
|
|
FTPPipe = [NSPipe new];
|
|
FTPInputPipe = [NSPipe new];
|
|
[FTPTask setStandardError:FTPPipe];
|
|
[FTPTask setStandardOutput:FTPPipe];
|
|
[FTPTask setStandardInput:FTPInputPipe];
|
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
|
[notificationCenter addObserver:self selector:@selector(loginTestExit:) name:NSTaskDidTerminateNotification object:FTPTask];
|
|
[notificationCenter addObserver:self selector:@selector(loginTestRead:) name:NSFileHandleReadCompletionNotification object:[FTPPipe fileHandleForReading]];
|
|
[[FTPPipe fileHandleForReading] readInBackgroundAndNotify];
|
|
|
|
[FTPTask launch];
|
|
}
|
|
}
|
|
- (void)loginTestExit:(NSNotification *)theNotification {
|
|
NSLog(@"FTP Exited");
|
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
|
[notificationCenter removeObserver:self name:NSTaskDidTerminateNotification object:FTPTask];
|
|
[FTPTask release];
|
|
FTPTask = nil;
|
|
[notificationCenter removeObserver:self name:NSFileHandleReadCompletionNotification object:[FTPPipe fileHandleForReading]];
|
|
[FTPPipe release];
|
|
FTPPipe = nil;
|
|
[FTPInputPipe release];
|
|
FTPInputPipe = nil;
|
|
|
|
if (![loginButton isEnabled]) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Account Error" localizedFor:self]];
|
|
[alert setInformativeText:[@"Incorrect login info." localizedFor:self]];
|
|
[alert runModal];
|
|
[self unlockLogin];
|
|
}
|
|
}
|
|
- (void)loginTestProcessFTPString:(NSString *)theString {
|
|
//NSLog(@"%@", theString);
|
|
NSCharacterSet *whiteSpace = [NSCharacterSet whitespaceCharacterSet];
|
|
NSRange range = [theString rangeOfCharacterFromSet:whiteSpace];
|
|
if (range.location!=NSNotFound) {
|
|
int response = [[theString substringToIndex:range.location] intValue];
|
|
NSString *message = [theString substringFromIndex:range.location+range.length];
|
|
if (response==250) {
|
|
[self unlockLogin];
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Login Successful" localizedFor:self]];
|
|
[alert setInformativeText:[@"You have sucessfully logged into your account." localizedFor:self]];
|
|
[alert runModal];
|
|
[[FTPInputPipe fileHandleForWriting] writeData:[@"bye\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
|
} else if (response==550) {
|
|
[self unlockLogin];
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Account Error" localizedFor:self]];
|
|
[alert setInformativeText:[@"You have sucessfully logged into your account, but the path you have entered does not exist." localizedFor:self]];
|
|
[alert runModal];
|
|
[[FTPInputPipe fileHandleForWriting] writeData:[@"bye\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
|
} else if (response==230) {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
if ([[defaults objectForKey:MGMFTPPath] isEqual:@""]) {
|
|
[self unlockLogin];
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Login Successful" localizedFor:self]];
|
|
[alert setInformativeText:[@"You have sucessfully logged into your account." localizedFor:self]];
|
|
[alert runModal];
|
|
[[FTPInputPipe fileHandleForWriting] writeData:[@"bye\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
|
} else {
|
|
[[FTPInputPipe fileHandleForWriting] writeData:[[NSString stringWithFormat:@"cd %@\n", [[defaults objectForKey:MGMFTPPath] escapePath]] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
} else if (response==530) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[self unlockLogin];
|
|
[alert setMessageText:[@"Account Error" localizedFor:self]];
|
|
[alert setInformativeText:message];
|
|
[alert runModal];
|
|
} else if ([message rangeOfString:@"Can't connect or login to host"].location!=NSNotFound && ![loginButton isEnabled]) {
|
|
[self unlockLogin];
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Account Error" localizedFor:self]];
|
|
[alert setInformativeText:message];
|
|
[alert runModal];
|
|
}
|
|
}
|
|
}
|
|
- (void)loginTestRead:(NSNotification *)theNotification {
|
|
NSData *data = [[theNotification userInfo] objectForKey:NSFileHandleNotificationDataItem];
|
|
NSString *dataString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
|
|
NSArray *components = [dataString componentsSeparatedByString:@"\n"];
|
|
NSCharacterSet *newline = [NSCharacterSet newlineCharacterSet];
|
|
for (int i=0; i<[components count]; i++) {
|
|
[self loginTestProcessFTPString:[[components objectAtIndex:i] stringByTrimmingCharactersInSet:newline]];
|
|
}
|
|
[[theNotification object] readInBackgroundAndNotify];
|
|
}
|
|
|
|
- (void)sendFileAtPath:(NSString *)thePath withName:(NSString *)theName {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
if ([defaults objectForKey:MGMFTPHost]==nil || [defaults objectForKey:MGMFTPUser]==nil || [defaults objectForKey:MGMFTPURL]==nil) {
|
|
NSError *error = [NSError errorWithDomain:[[NSBundle bundleForClass:[self class]] bundleIdentifier] code:5 userInfo:[NSDictionary dictionaryWithObject:[@"Account is not logged in." localizedFor:self] forKey:NSLocalizedDescriptionKey]];
|
|
[[MGMController sharedController] upload:thePath receivedError:error];
|
|
return;
|
|
}
|
|
|
|
[filePath release];
|
|
filePath = [thePath retain];
|
|
[fileName release];
|
|
fileName = [theName retain];
|
|
FTPTask = [NSTask new];
|
|
[FTPTask setLaunchPath:@"/usr/bin/ftp"];
|
|
[FTPTask setCurrentDirectoryPath:[filePath stringByDeletingLastPathComponent]];
|
|
[FTPTask setArguments:[NSArray arrayWithObjects:@"-v", [NSString stringWithFormat:@"ftp://%@:%@@%@", [defaults objectForKey:MGMFTPUser], [[MGMController sharedController] password], [defaults objectForKey:MGMFTPHost]], nil]];
|
|
|
|
FTPPipe = [NSPipe new];
|
|
FTPInputPipe = [NSPipe new];
|
|
[FTPTask setStandardError:FTPPipe];
|
|
[FTPTask setStandardOutput:FTPPipe];
|
|
[FTPTask setStandardInput:FTPInputPipe];
|
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
|
[notificationCenter addObserver:self selector:@selector(uploadExit:) name:NSTaskDidTerminateNotification object:FTPTask];
|
|
[notificationCenter addObserver:self selector:@selector(uploadRead:) name:NSFileHandleReadCompletionNotification object:[FTPPipe fileHandleForReading]];
|
|
[[FTPPipe fileHandleForReading] readInBackgroundAndNotify];
|
|
|
|
[FTPTask launch];
|
|
}
|
|
- (void)uploadExit:(NSNotification *)theNotification {
|
|
NSLog(@"FTP Exited");
|
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
|
[notificationCenter removeObserver:self name:NSTaskDidTerminateNotification object:FTPTask];
|
|
[FTPTask release];
|
|
FTPTask = nil;
|
|
[notificationCenter removeObserver:self name:NSFileHandleReadCompletionNotification object:[FTPPipe fileHandleForReading]];
|
|
[FTPPipe release];
|
|
FTPPipe = nil;
|
|
[FTPInputPipe release];
|
|
FTPInputPipe = nil;
|
|
|
|
if (theNotification!=nil) {
|
|
NSError *error = [NSError errorWithDomain:[[NSBundle bundleForClass:[self class]] bundleIdentifier] code:1 userInfo:[NSDictionary dictionaryWithObject:[@"Incorrect login info." localizedFor:self] forKey:NSLocalizedDescriptionKey]];
|
|
NSString *finishPath = [[filePath retain] autorelease];
|
|
[filePath release];
|
|
filePath = nil;
|
|
[fileName release];
|
|
fileName = nil;
|
|
[[MGMController sharedController] upload:finishPath receivedError:error];
|
|
}
|
|
}
|
|
- (void)uploadProcessFTPString:(NSString *)theString {
|
|
//NSLog(@"%@", theString);
|
|
NSCharacterSet *whiteSpace = [NSCharacterSet whitespaceCharacterSet];
|
|
NSRange range = [theString rangeOfCharacterFromSet:whiteSpace];
|
|
if (range.location!=NSNotFound) {
|
|
int response = [[theString substringToIndex:range.location] intValue];
|
|
NSString *message = [theString substringFromIndex:range.location+range.length];
|
|
if (response==250) {
|
|
[[FTPInputPipe fileHandleForWriting] writeData:[[NSString stringWithFormat:@"put %@ %@\n", [[filePath lastPathComponent] escapePath], [fileName escapePath]] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
} else if (response==226) {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
[[FTPInputPipe fileHandleForWriting] writeData:[@"bye\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
|
[self uploadExit:nil];
|
|
NSString *url = [defaults objectForKey:MGMFTPURL];
|
|
if (![url hasSuffix:@"/"])
|
|
url = [url stringByAppendingFormat:@"/%@", fileName];
|
|
else
|
|
url = [url stringByAppendingString:fileName];
|
|
NSString *finishPath = [[filePath retain] autorelease];
|
|
[filePath release];
|
|
filePath = nil;
|
|
[fileName release];
|
|
fileName = nil;
|
|
[[MGMController sharedController] uploadFinished:finishPath url:[NSURL URLWithString:url]];
|
|
} else if (response==550) {
|
|
[[FTPInputPipe fileHandleForWriting] writeData:[@"bye\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
|
[self uploadExit:nil];
|
|
NSError *error = [NSError errorWithDomain:[[NSBundle bundleForClass:[self class]] bundleIdentifier] code:1 userInfo:[NSDictionary dictionaryWithObject:[@"The path to upload files to does not exist." localizedFor:self] forKey:NSLocalizedDescriptionKey]];
|
|
NSString *finishPath = [[filePath retain] autorelease];
|
|
[filePath release];
|
|
filePath = nil;
|
|
[fileName release];
|
|
fileName = nil;
|
|
[[MGMController sharedController] upload:finishPath receivedError:error];
|
|
} else if (response==421) {
|
|
[[FTPInputPipe fileHandleForWriting] writeData:[@"bye\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
|
[self uploadExit:nil];
|
|
NSError *error = [NSError errorWithDomain:[[NSBundle bundleForClass:[self class]] bundleIdentifier] code:1 userInfo:[NSDictionary dictionaryWithObject:message forKey:NSLocalizedDescriptionKey]];
|
|
NSString *finishPath = [[filePath retain] autorelease];
|
|
[filePath release];
|
|
filePath = nil;
|
|
[fileName release];
|
|
fileName = nil;
|
|
[[MGMController sharedController] upload:finishPath receivedError:error];
|
|
} else if (response==230) {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
if ([[defaults objectForKey:MGMFTPPath] isEqual:@""]) {
|
|
[[FTPInputPipe fileHandleForWriting] writeData:[[NSString stringWithFormat:@"put %@ %@\n", [[filePath lastPathComponent] escapePath], [fileName escapePath]] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
} else {
|
|
[[FTPInputPipe fileHandleForWriting] writeData:[[NSString stringWithFormat:@"cd %@\n", [[defaults objectForKey:MGMFTPPath] escapePath]] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
} else if ([message rangeOfString:@"Can't connect or login to host"].location!=NSNotFound) {
|
|
NSError *error = [NSError errorWithDomain:[[NSBundle bundleForClass:[self class]] bundleIdentifier] code:1 userInfo:[NSDictionary dictionaryWithObject:message forKey:NSLocalizedDescriptionKey]];
|
|
NSString *finishPath = [[filePath retain] autorelease];
|
|
[filePath release];
|
|
filePath = nil;
|
|
[fileName release];
|
|
fileName = nil;
|
|
[[MGMController sharedController] upload:finishPath receivedError:error];
|
|
} else if ([message rangeOfString:@"Can't open"].location!=NSNotFound) {
|
|
[[FTPInputPipe fileHandleForWriting] writeData:[@"bye\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
|
[self uploadExit:nil];
|
|
NSError *error = [NSError errorWithDomain:[[NSBundle bundleForClass:[self class]] bundleIdentifier] code:1 userInfo:[NSDictionary dictionaryWithObject:message forKey:NSLocalizedDescriptionKey]];
|
|
NSString *finishPath = [[filePath retain] autorelease];
|
|
[filePath release];
|
|
filePath = nil;
|
|
[fileName release];
|
|
fileName = nil;
|
|
[[MGMController sharedController] upload:finishPath receivedError:error];
|
|
}
|
|
}
|
|
}
|
|
- (void)uploadRead:(NSNotification *)theNotification {
|
|
NSData *data = [[theNotification userInfo] objectForKey:NSFileHandleNotificationDataItem];
|
|
NSString *dataString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
|
|
NSArray *components = [dataString componentsSeparatedByString:@"\n"];
|
|
NSCharacterSet *newline = [NSCharacterSet newlineCharacterSet];
|
|
for (int i=0; i<[components count]; i++) {
|
|
[self uploadProcessFTPString:[[components objectAtIndex:i] stringByTrimmingCharactersInSet:newline]];
|
|
}
|
|
[[theNotification object] readInBackgroundAndNotify];
|
|
}
|
|
@end |