adium 2534:1306b41fd66b: Abstract multipart image uploading a bi...

commits at adium.im commits at adium.im
Sat Jul 11 19:37:15 UTC 2009


details:	http://hg.adium.im/adium/rev/1306b41fd66b
revision:	2534:1306b41fd66b
author:		Zachary West <zacw at adium.im>
date:		Fri Jul 10 22:52:39 2009 -0400

Abstract multipart image uploading a bit and add an imageshack.us service for image uploading.

diffs (575 lines):

diff -r 4fcaa4d8c274 -r 1306b41fd66b Adium.xcodeproj/project.pbxproj
--- a/Adium.xcodeproj/project.pbxproj	Wed Jul 08 20:20:05 2009 -0500
+++ b/Adium.xcodeproj/project.pbxproj	Fri Jul 10 22:52:39 2009 -0400
@@ -172,6 +172,8 @@
 		11CA00110C35EC5200A6BB8D /* SS_PrefsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 344836920BC8510B0083723B /* SS_PrefsController.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		11CA00120C35EC5200A6BB8D /* SS_PrefsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 344836900BC8510B0083723B /* SS_PrefsController.m */; };
 		11D135D90FBE4C65000B0A5E /* AITwitterAccountView.nib in Resources */ = {isa = PBXBuildFile; fileRef = 11D135D80FBE4C65000B0A5E /* AITwitterAccountView.nib */; };
+		11D9156F0FFC0FEB00B39713 /* AIImageShackImageUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 11D915580FFC0E9C00B39713 /* AIImageShackImageUploader.m */; };
+		11D915720FFC100700B39713 /* AIGenericMultipartImageUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 11D915710FFC100700B39713 /* AIGenericMultipartImageUploader.m */; };
 		11E786810F8860210014612E /* AIJumpControlPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 11E7867F0F8860210014612E /* AIJumpControlPlugin.m */; };
 		11EE1B4D0CDCFAF40097F246 /* oscar-adium.c in Sources */ = {isa = PBXBuildFile; fileRef = 11EE1B490CDCFAF40097F246 /* oscar-adium.c */; };
 		11EE1B4E0CDCFAF40097F246 /* oscar-adium.h in Headers */ = {isa = PBXBuildFile; fileRef = 11EE1B4A0CDCFAF40097F246 /* oscar-adium.h */; };
@@ -1974,6 +1976,10 @@
 		11D135F10FBE4CA6000B0A5E /* zh_CN */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = zh_CN; path = "Plugins/Twitter Plugin/zh_CN.lproj/AITwitterAccountView.nib"; sourceTree = "<group>"; };
 		11D135F20FBE4CA9000B0A5E /* zh_TW */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = zh_TW; path = "Plugins/Twitter Plugin/zh_TW.lproj/AITwitterAccountView.nib"; sourceTree = "<group>"; };
 		11D135F30FBE4CB6000B0A5E /* en */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = en; path = "Plugins/Twitter Plugin/en.lproj/AITwitterAccountView.nib"; sourceTree = "<group>"; };
+		11D915570FFC0E9C00B39713 /* AIImageShackImageUploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIImageShackImageUploader.h; path = "Plugins/Image Uploading Plugin/AIImageShackImageUploader.h"; sourceTree = "<group>"; };
+		11D915580FFC0E9C00B39713 /* AIImageShackImageUploader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIImageShackImageUploader.m; path = "Plugins/Image Uploading Plugin/AIImageShackImageUploader.m"; sourceTree = "<group>"; };
+		11D915700FFC100700B39713 /* AIGenericMultipartImageUploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIGenericMultipartImageUploader.h; path = "Plugins/Image Uploading Plugin/AIGenericMultipartImageUploader.h"; sourceTree = "<group>"; };
+		11D915710FFC100700B39713 /* AIGenericMultipartImageUploader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIGenericMultipartImageUploader.m; path = "Plugins/Image Uploading Plugin/AIGenericMultipartImageUploader.m"; sourceTree = "<group>"; };
 		11E7867F0F8860210014612E /* AIJumpControlPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIJumpControlPlugin.m; path = "Plugins/Dual Window Interface/AIJumpControlPlugin.m"; sourceTree = "<group>"; };
 		11E786800F8860210014612E /* AIJumpControlPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIJumpControlPlugin.h; path = "Plugins/Dual Window Interface/AIJumpControlPlugin.h"; sourceTree = "<group>"; };
 		11EE1B490CDCFAF40097F246 /* oscar-adium.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "oscar-adium.c"; sourceTree = "<group>"; };
@@ -4947,6 +4953,10 @@
 				11BE28DE0FCC7D2B000E6A10 /* AIImageUploaderPlugin.m */,
 				11BE28980FCC7C13000E6A10 /* AIPicImImageUploader.h */,
 				11BE28990FCC7C13000E6A10 /* AIPicImImageUploader.m */,
+				11D915570FFC0E9C00B39713 /* AIImageShackImageUploader.h */,
+				11D915580FFC0E9C00B39713 /* AIImageShackImageUploader.m */,
+				11D915700FFC100700B39713 /* AIGenericMultipartImageUploader.h */,
+				11D915710FFC100700B39713 /* AIGenericMultipartImageUploader.m */,
 			);
 			name = "Image Uploading";
 			sourceTree = "<group>";
@@ -10185,6 +10195,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				11D9156F0FFC0FEB00B39713 /* AIImageShackImageUploader.m in Sources */,
 				111E89010F93FE3900A5F18B /* AIRealNameTooltip.m in Sources */,
 				111E89020F93FE3900A5F18B /* AIUserHostTooltip.m in Sources */,
 				111256070F8DA2BF00E76177 /* AWEzv.m in Sources */,
@@ -10530,6 +10541,7 @@
 				11BE29680FCCA9E3000E6A10 /* AIImageUploaderWindowController.m in Sources */,
 				1197F6710FCF8D180032F19B /* AITwitterStatusFollowup.m in Sources */,
 				112939100FD5AE1400FA8F53 /* AIConfirmationsAdvancedPreferences.m in Sources */,
+				11D915720FFC100700B39713 /* AIGenericMultipartImageUploader.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff -r 4fcaa4d8c274 -r 1306b41fd66b Plugins/Image Uploading Plugin/AIGenericMultipartImageUploader.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Image Uploading Plugin/AIGenericMultipartImageUploader.h	Fri Jul 10 22:52:39 2009 -0400
@@ -0,0 +1,26 @@
+//
+//  AIGenericMultipartImageUploader.h
+//  Adium
+//
+//  Created by Zachary West on 2009-07-01.
+//  Copyright 2009  . All rights reserved.
+//
+
+#import "AIImageUploaderPlugin.h"
+#import <AIUtilities/AIProgressDataUploader.h>
+
+ at interface AIGenericMultipartImageUploader : NSObject <AIImageUploader, AIProgressDataUploaderDelegate> {
+	AIChat						*chat;
+	NSImage						*image;
+	AIImageUploaderPlugin		*uploader;
+	
+	AIProgressDataUploader		*dataUploader;
+}
+
+ at property (readonly, nonatomic) NSUInteger maximumSize;
+ at property (readonly, nonatomic) NSString *uploadURL;
+ at property (readonly, nonatomic) NSString *fieldName;
+
+- (void)parseResponse:(NSData *)data;
+
+ at end
diff -r 4fcaa4d8c274 -r 1306b41fd66b Plugins/Image Uploading Plugin/AIGenericMultipartImageUploader.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Image Uploading Plugin/AIGenericMultipartImageUploader.m	Fri Jul 10 22:52:39 2009 -0400
@@ -0,0 +1,161 @@
+//
+//  AIGenericMultipartImageUploader.m
+//  Adium
+//
+//  Created by Zachary West on 2009-07-01.
+//  Copyright 2009  . All rights reserved.
+//
+
+#import "AIGenericMultipartImageUploader.h"
+
+#import <Adium/AIChat.h>
+#import <Adium/AIInterfaceControllerProtocol.h>
+#import <AIUtilities/AIStringAdditions.h>
+#import <AIUtilities/AIProgressDataUploader.h>
+#import <AIUtilities/AIImageAdditions.h>
+
+#define MULTIPART_FORM_BOUNDARY	@"bf5faadd239c17e35f91e6dafe1d2f96"
+
+ at interface AIGenericMultipartImageUploader()
+- (id)initWithImage:(NSImage *)inImage
+		   uploader:(AIImageUploaderPlugin *)inUploader
+			   chat:(AIChat *)inChat;
+- (void)uploadImage;
+ at end
+
+ at implementation AIGenericMultipartImageUploader
++ (id)uploadImage:(NSImage *)image forUploader:(AIImageUploaderPlugin *)uploader inChat:(AIChat *)chat;
+{
+	return [[[self alloc] initWithImage:image uploader:uploader chat:chat] autorelease];
+}
+
++ (NSString *)serviceName
+{
+	NSAssert1(NO, @"Implementation of %@ lacks serviceName", NSStringFromClass(self));
+	
+	return nil;
+}
+
+- (NSString *)uploadURL
+{
+	NSAssert1(NO, @"Implementation of %@ lacks uploadURL", self);
+	
+	return nil;	
+}
+
+- (NSString *)fieldName
+{
+	NSAssert1(NO, @"Implementation of %@ lacks fieldName", self);
+	
+	return nil;	
+}
+
+- (NSUInteger)maximumSize
+{
+	NSAssert1(NO, @"Implementation of %@ lacks maximumSize", self);
+	
+	return 0;
+}
+
+- (void)parseResponse:(NSData *)date
+{
+	NSAssert1(NO, @"Implementation of %@ lacks parseResponse:", self);	
+}
+
+- (id)initWithImage:(NSImage *)inImage
+		   uploader:(AIImageUploaderPlugin *)inUploader
+			   chat:(AIChat *)inChat
+{
+	if ((self = [super init])) {
+		image = [inImage retain];
+		uploader = inUploader;
+		chat = inChat;
+		
+		[self uploadImage];
+	}
+	
+	return self;
+}
+
+- (void)dealloc
+{
+	[dataUploader release]; dataUploader = nil;
+	[image release]; image = nil;
+	
+	[super dealloc];
+}
+
+
+#pragma mark Data uploader delegate
+- (void)updateUploadProgress:(NSUInteger)uploaded total:(NSUInteger)total context:(id)context
+{
+	[uploader updateProgress:uploaded total:total forChat:chat];
+}
+
+- (void)uploadCompleted:(id)context result:(NSData *)result
+{
+	if (result.length) {
+		[self parseResponse:result];
+	} else {
+		[uploader errorWithMessage:AILocalizedString(@"Unable to upload", nil) forChat:chat];
+	}
+}
+
+- (void)uploadFailed:(id)context
+{
+	[uploader errorWithMessage:AILocalizedString(@"Unable to upload", nil) forChat:chat];
+}
+
+#pragma mark Image upload
+
+- (void)uploadImage
+{
+	NSMutableData *body = [NSMutableData data];
+	
+	NSBitmapImageFileType bestType;
+	
+	NSData *pngRepresentation = [[image largestBitmapImageRep] representationUsingType:NSPNGFileType properties:nil];
+	NSData *jpgRepresentation = [[image largestBitmapImageRep] representationUsingType:NSJPEGFileType properties:nil];
+	NSData *imageRepresentation;
+	
+	if (pngRepresentation.length > jpgRepresentation.length) {
+		bestType = NSJPEGFileType;
+		imageRepresentation = jpgRepresentation;
+	} else {
+		bestType = NSPNGFileType;
+		imageRepresentation = pngRepresentation;
+	}
+	
+	if (imageRepresentation.length > self.maximumSize) {
+		imageRepresentation = [image representationWithFileType:bestType maximumFileSize:self.maximumSize];
+	}
+	
+	if (!imageRepresentation) {
+		[uploader errorWithMessage:AILocalizedString(@"Unable to upload", nil) forChat:chat];
+		return;
+	}
+	
+	[body appendData:[[NSString stringWithFormat:@"--%@\r\n", MULTIPART_FORM_BOUNDARY] dataUsingEncoding:NSUTF8StringEncoding]];
+	[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image\"\r\n", self.fieldName] dataUsingEncoding:NSUTF8StringEncoding]];
+	[body appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", (bestType == NSJPEGFileType) ? @"image/jpeg" : @"image/png"] dataUsingEncoding:NSUTF8StringEncoding]];
+	[body appendData:imageRepresentation];
+	[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", MULTIPART_FORM_BOUNDARY] dataUsingEncoding:NSUTF8StringEncoding]];
+	
+	NSDictionary *headers = [NSDictionary dictionaryWithObjectsAndKeys:
+							 [NSString stringWithFormat:@"multipart/form-data; boundary=%@", MULTIPART_FORM_BOUNDARY], @"Content-type", nil];
+	
+	dataUploader = [[AIProgressDataUploader dataUploaderWithData:body
+															 URL:[NSURL URLWithString:self.uploadURL]
+														 headers:headers
+														delegate:self
+														 context:nil] retain];
+	
+	[dataUploader upload];
+}
+
+- (void)cancel
+{
+	[dataUploader cancel];
+}
+
+ at end
diff -r 4fcaa4d8c274 -r 1306b41fd66b Plugins/Image Uploading Plugin/AIImageShackImageUploader.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Image Uploading Plugin/AIImageShackImageUploader.h	Fri Jul 10 22:52:39 2009 -0400
@@ -0,0 +1,23 @@
+//
+//  AIImageShackImageUploader.h
+//  Adium
+//
+//  Created by Zachary West on 2009-07-01.
+//  Copyright 2009  . All rights reserved.
+//
+
+#import "AIGenericMultipartImageUploader.h"
+
+ at interface AIImageShackImageUploader : AIGenericMultipartImageUploader {
+	NSData						*resultData;
+	NSXMLParser					*responseParser;
+	
+	// Parsing
+	NSMutableDictionary			*lastElement;
+	NSString					*currentElementName;
+	NSMutableDictionary			*currentElement;
+
+	NSMutableDictionary			*links;
+}
+
+ at end
diff -r 4fcaa4d8c274 -r 1306b41fd66b Plugins/Image Uploading Plugin/AIImageShackImageUploader.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Image Uploading Plugin/AIImageShackImageUploader.m	Fri Jul 10 22:52:39 2009 -0400
@@ -0,0 +1,110 @@
+//
+//  AIImageShackImageUploader.m
+//  Adium
+//
+//  Created by Zachary West on 2009-07-01.
+//  Copyright 2009  . All rights reserved.
+//
+
+#import "AIImageShackImageUploader.h"
+#import <AIUtilities/AIStringAdditions.h>
+
+ at implementation AIImageShackImageUploader
++ (NSString *)serviceName
+{
+	return @"ImageShack";
+}
+
+- (NSString *)uploadURL
+{
+	return @"http://www.imageshack.us/upload_api.php?key=5FGHPUWX06560cfca5af85e920262ac699251d4d";
+}
+
+- (NSString *)fieldName
+{
+	return @"fileupload";
+}
+
+- (NSUInteger)maximumSize
+{
+	return 2500000;
+}
+
+- (void)dealloc
+{
+	[resultData release]; resultData = nil;
+	[links release]; links = nil;
+	[responseParser release]; responseParser = nil;
+	
+	[super dealloc];
+}
+
+#pragma mark Response parsing
+- (void)parseResponse:(NSData *)data
+{
+	links = [[NSMutableDictionary alloc] init];
+	resultData = [data copy];
+	
+	AILogWithSignature(@"%@", [NSString stringWithData:data encoding:NSUTF8StringEncoding]);
+	
+	responseParser = [[NSXMLParser alloc] initWithData:resultData];
+	[responseParser setDelegate:self];
+	[responseParser parse];
+}
+
+- (void)parserDidStartDocument:(NSXMLParser *)parser
+{
+
+}
+
+- (void)parser:(NSXMLParser *)parser 
+parseErrorOccurred:(NSError *)error
+{
+	AILogWithSignature(@"%@", [error localizedDescription]);
+	
+	[uploader errorWithMessage:[error localizedDescription] forChat:chat];
+}
+
+- (void)parser:(NSXMLParser *)parser
+didStartElement:(NSString *)elementName 
+  namespaceURI:(NSString *)namespaceURI 
+ qualifiedName:(NSString *)qualifiedName
+	attributes:(NSDictionary *)attributes
+{	
+	if ([elementName isEqualToString:@"links"]) {
+		currentElement = links;
+	}
+	
+	currentElementName = elementName;
+}
+
+- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
+{
+	if ([elementName isEqualToString:@"links"]) {
+		currentElement = nil;
+	}
+}
+
+- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
+{
+	if (![currentElementName isEqualToString:@"links"] && ![currentElement objectForKey:currentElementName]) {
+		[currentElement setObject:[NSMutableString string] forKey:currentElementName];
+	}
+	
+	[[currentElement objectForKey:currentElementName] appendString:string];
+}
+
+- (void)parserDidEndDocument:(NSXMLParser *)parser
+{
+	if ([links objectForKey:@"error"]) {
+		NSString *error = [[links objectForKey:@"error"] stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
+		[uploader errorWithMessage:error forChat:chat];	
+	} else if ([links objectForKey:@"yfrog_link"]) {
+		NSString *url = [[links objectForKey:@"yfrog_link"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+		[uploader uploadedURL:url forChat:chat];	
+	} else {
+		[uploader errorWithMessage:AILocalizedString(@"Unable to upload", nil) forChat:chat];
+	}
+}
+
+ at end
diff -r 4fcaa4d8c274 -r 1306b41fd66b Plugins/Image Uploading Plugin/AIImageUploaderPlugin.m
--- a/Plugins/Image Uploading Plugin/AIImageUploaderPlugin.m	Wed Jul 08 20:20:05 2009 -0500
+++ b/Plugins/Image Uploading Plugin/AIImageUploaderPlugin.m	Fri Jul 10 22:52:39 2009 -0400
@@ -8,6 +8,7 @@
 
 #import "AIImageUploaderPlugin.h"
 #import "AIPicImImageUploader.h"
+#import "AIImageShackImageUploader.h"
 #import "AIImageUploaderWindowController.h"
 
 #import <Adium/AIContentControllerProtocol.h>
@@ -35,6 +36,7 @@
 	uploadInstances = [[NSMutableDictionary alloc] init];
 	
 	[uploaders addObject:[AIPicImImageUploader class]];
+	[uploaders addObject:[AIImageShackImageUploader class]];
 	
 	NSMenuItem *menuItem;
 	
diff -r 4fcaa4d8c274 -r 1306b41fd66b Plugins/Image Uploading Plugin/AIPicImImageUploader.h
--- a/Plugins/Image Uploading Plugin/AIPicImImageUploader.h	Wed Jul 08 20:20:05 2009 -0500
+++ b/Plugins/Image Uploading Plugin/AIPicImImageUploader.h	Fri Jul 10 22:52:39 2009 -0400
@@ -6,17 +6,9 @@
 //  Copyright 2009 Adium. All rights reserved.
 //
 
-#import "AIImageUploaderPlugin.h"
+#import "AIGenericMultipartImageUploader.h"
 
-#import <AIUtilities/AIProgressDataUploader.h>
-
- at interface AIPicImImageUploader : NSObject <AIImageUploader, AIProgressDataUploaderDelegate> {
-	AIChat						*chat;
-	NSImage						*image;
-	AIImageUploaderPlugin		*uploader;
-	
-	AIProgressDataUploader		*dataUploader;
-	
+ at interface AIPicImImageUploader : AIGenericMultipartImageUploader {
 	NSData						*resultData;
 	NSXMLParser					*responseParser;
 	
diff -r 4fcaa4d8c274 -r 1306b41fd66b Plugins/Image Uploading Plugin/AIPicImImageUploader.m
--- a/Plugins/Image Uploading Plugin/AIPicImImageUploader.m	Wed Jul 08 20:20:05 2009 -0500
+++ b/Plugins/Image Uploading Plugin/AIPicImImageUploader.m	Fri Jul 10 22:52:39 2009 -0400
@@ -7,24 +7,7 @@
 //
 
 #import "AIPicImImageUploader.h"
-
-#import <Adium/AIChat.h>
-#import <Adium/AIInterfaceControllerProtocol.h>
 #import <AIUtilities/AIStringAdditions.h>
-#import <AIUtilities/AIProgressDataUploader.h>
-#import <AIUtilities/AIImageAdditions.h>
-
-#define MULTIPART_FORM_BOUNDARY	@"bf5faadd239c17e35f91e6dafe1d2f96"
-#define PIC_IM_URL				@"http://api.tr.im/api/picim_url.xml?api_key=zghQN6sv5y0FkLPNlQAopm7qDQz6ItO33ENU21OBsy3dL1Kl"
-#define PIC_IM_MAX_SIZE			2500000
-
- at interface AIPicImImageUploader()
-- (id)initWithImage:(NSImage *)inImage
-		   uploader:(AIImageUploaderPlugin *)inUploader
-			   chat:(AIChat *)inChat;
-- (void)uploadImage;
-- (void)parseResponse:(NSData *)data;
- at end
 
 @implementation AIPicImImageUploader
 + (NSString *)serviceName
@@ -32,109 +15,30 @@
 	return @"pic.im";
 }
 
-+ (id)uploadImage:(NSImage *)image forUploader:(AIImageUploaderPlugin *)uploader inChat:(AIChat *)chat;
+- (NSString *)uploadURL
 {
-	return [[[self alloc] initWithImage:image uploader:uploader chat:chat] autorelease];
+	return @"http://api.tr.im/api/picim_url.xml?api_key=zghQN6sv5y0FkLPNlQAopm7qDQz6ItO33ENU21OBsy3dL1Kl";
 }
 
-- (id)initWithImage:(NSImage *)inImage
-		   uploader:(AIImageUploaderPlugin *)inUploader
-			   chat:(AIChat *)inChat
+- (NSString *)fieldName
 {
-	if ((self = [super init])) {
-		image = [inImage retain];
-		uploader = inUploader;
-		chat = inChat;
-		
-		[self uploadImage];
-	}
-	
-	return self;
+	return @"media";
+}
+
+- (NSUInteger)maximumSize
+{
+	return 2500000;
 }
 
 - (void)dealloc
 {
-	[dataUploader release]; dataUploader = nil;
 	[resultData release]; resultData = nil;
 	[response release]; response = nil;
 	[responseParser release]; responseParser = nil;
-	[image release]; image = nil;
 	
 	[super dealloc];
 }
 
-#pragma mark Data uploader delegate
-- (void)updateUploadProgress:(NSUInteger)uploaded total:(NSUInteger)total context:(id)context
-{
-	[uploader updateProgress:uploaded total:total forChat:chat];
-}
-
-- (void)uploadCompleted:(id)context result:(NSData *)result
-{
-	if (result.length) {
-		[self parseResponse:result];
-	} else {
-		[uploader errorWithMessage:AILocalizedString(@"Unable to upload", nil) forChat:chat];
-	}
-}
-
-- (void)uploadFailed:(id)context
-{
-	[uploader errorWithMessage:AILocalizedString(@"Unable to upload", nil) forChat:chat];
-}
-
-#pragma mark Image upload
-
-- (void)uploadImage
-{
-	NSMutableData *body = [NSMutableData data];
-	
-	NSBitmapImageFileType bestType;
-	
-	NSData *pngRepresentation = [[image largestBitmapImageRep] representationUsingType:NSPNGFileType properties:nil];
-	NSData *jpgRepresentation = [[image largestBitmapImageRep] representationUsingType:NSJPEGFileType properties:nil];
-	NSData *imageRepresentation;
-	
-	if (pngRepresentation.length > jpgRepresentation.length) {
-		bestType = NSJPEGFileType;
-		imageRepresentation = jpgRepresentation;
-	} else {
-		bestType = NSPNGFileType;
-		imageRepresentation = pngRepresentation;
-	}
-	
-	if (imageRepresentation.length > PIC_IM_MAX_SIZE) {
-		imageRepresentation = [image representationWithFileType:bestType maximumFileSize:PIC_IM_MAX_SIZE];
-	}
-	
-	if (!imageRepresentation) {
-		[uploader errorWithMessage:AILocalizedString(@"Unable to upload", nil) forChat:chat];
-		return;
-	}
-	
-	[body appendData:[[NSString stringWithFormat:@"--%@\r\n", MULTIPART_FORM_BOUNDARY] dataUsingEncoding:NSUTF8StringEncoding]];
-	[body appendData:[@"Content-Disposition: form-data; name=\"media\"; filename=\"image.png\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
-	[body appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", (bestType == NSJPEGFileType) ? @"image/jpeg" : @"image/png"] dataUsingEncoding:NSUTF8StringEncoding]];
-	[body appendData:imageRepresentation];
-	[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", MULTIPART_FORM_BOUNDARY] dataUsingEncoding:NSUTF8StringEncoding]];
-
-	NSDictionary *headers = [NSDictionary dictionaryWithObjectsAndKeys:
-							 [NSString stringWithFormat:@"multipart/form-data; boundary=%@", MULTIPART_FORM_BOUNDARY], @"Content-type", nil];
-	
-	dataUploader = [[AIProgressDataUploader dataUploaderWithData:body
-															 URL:[NSURL URLWithString:PIC_IM_URL]
-														 headers:headers
-														delegate:self
-														 context:nil] retain];
-	
-	[dataUploader upload];
-}
-
-- (void)cancel
-{
-	[dataUploader cancel];
-}
-
 #pragma mark Response parsing
 - (void)parseResponse:(NSData *)data
 {




More information about the commits mailing list