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