CocoaShare/Classes/FTP/MGMFTPPlugIn.m
2011-02-01 10:19:26 -06:00

362 lines
16 KiB
Objective-C

//
// MGMFTPPlugIn.m
// CocoaShare
//
// Created by James 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"];
}
- (void)unlockLogin {
[hostField setEnabled:YES];
[userField setEnabled:YES];
[passwordField setEnabled:YES];
[pathField setEnabled:YES];
[urlField setEnabled:YES];
[loginButton setEnabled:YES];
[loginButton setTitle:@"Login"];
}
- (IBAction)login:(id)sender {
if ([[hostField stringValue] isEqual:@""]) {
NSAlert *alert = [[NSAlert new] autorelease];
[alert setMessageText:@"Host Required"];
[alert setInformativeText:@"Please enter your ftp host."];
[alert runModal];
} else if ([[userField stringValue] isEqual:@""]) {
NSAlert *alert = [[NSAlert new] autorelease];
[alert setMessageText:@"UserName Required"];
[alert setInformativeText:@"Please enter your ftp username."];
[alert runModal];
} else if ([[passwordField stringValue] isEqual:@""]) {
NSAlert *alert = [[NSAlert new] autorelease];
[alert setMessageText:@"Password Required"];
[alert setInformativeText:@"Please enter your ftp password."];
[alert runModal];
} else if ([[urlField stringValue] isEqual:@""]) {
NSAlert *alert = [[NSAlert new] autorelease];
[alert setMessageText:@"URL Required"];
[alert setInformativeText:@"Please enter the URL to where the files will be uploaded."];
[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"];
[alert setInformativeText:@"Incorrect login info."];
[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"];
[alert setInformativeText:@"You have sucessfully logged into your account."];
[alert runModal];
[[FTPInputPipe fileHandleForWriting] writeData:[@"bye\n" dataUsingEncoding:NSUTF8StringEncoding]];
} else if (response==550) {
[self unlockLogin];
NSAlert *alert = [[NSAlert new] autorelease];
[alert setMessageText:@"Account Error"];
[alert setInformativeText:@"You have sucessfully logged into your account, but the path you have entered does not exist."];
[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"];
[alert setInformativeText:@"You have sucessfully logged into your account."];
[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"];
[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"];
[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." 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" 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." 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