Skip to content

Commit

Permalink
Adding Posterous support to ShareKit
Browse files Browse the repository at this point in the history
  • Loading branch information
Arik Devens committed Apr 20, 2011
1 parent 9139332 commit d82288b
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 1 deletion.
1 change: 1 addition & 0 deletions Classes/ShareKit/Core/SHKSharers.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<string>SHKReadItLater</string>
<string>SHKInstapaper</string>
<string>SHKTumblr</string>
<string>SHKPosterous</string>
</array>
</dict>
</plist>
3 changes: 2 additions & 1 deletion Classes/ShareKit/SHKConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
leaving that decision up to the user.
*/


// Posterous - http://apidocs.posterous.com/
#define SHKPosterousAPIKey @""

// Delicious - https://developer.apps.yahoo.com/projects
#define SHKDeliciousConsumerKey @""
Expand Down
17 changes: 17 additions & 0 deletions Classes/ShareKit/Sharers/Services/SHKPosterous.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// SHKPinboard.h
// ShareKit
//
// Created by Arik Devens on 4/8/11.

#import <Foundation/Foundation.h>
#import "SHKSharer.h"

@interface SHKPosterous : SHKSharer {
NSMutableData *photoData;
NSHTTPURLResponse *URLResponse;
}

- (void)finish;

@end
176 changes: 176 additions & 0 deletions Classes/ShareKit/Sharers/Services/SHKPosterous.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
//
// SHKPinboard.m
// ShareKit
//
// Created by Arik Devens on 4/8/11.

#import "SHKPosterous.h"
#include "Base64Transcoder.h"

static NSString * const kPosterousPostURL = @"http://posterous.com/api/2/sites/primary/posts";

@implementation SHKPosterous

#pragma mark -
#pragma mark Memory management
- (void)dealloc {
[photoData release];
[URLResponse release];

[super dealloc];
}

#pragma mark -
#pragma mark Configuration : Service Definition

+ (NSString *)sharerTitle {
return @"Posterous";
}

+ (BOOL)canShareText {
return YES;
}

+ (BOOL)canShareImage {
return YES;
}

#pragma mark -
#pragma mark Authorization

+ (NSString *)authorizationFormCaption {
return SHKLocalizedString(@"Create an account at %@", @"http://posterous.com");
}

- (void)authorizationFormValidate:(SHKFormController *)form {
if (!quiet) {
[[SHKActivityIndicator currentIndicator] displayActivity:SHKLocalizedString(@"Logging In...")];
}

[form saveForm];
}

- (void)authFinished:(SHKRequest *)aRequest {
[[SHKActivityIndicator currentIndicator] hide];
}


#pragma mark -
#pragma mark Share Form

- (NSArray *)shareFormFieldsForType:(SHKShareType)type {
if (type == SHKShareTypeText) {
return [NSArray arrayWithObjects:[SHKFormFieldSettings label:SHKLocalizedString(@"Title") key:@"title" type:SHKFormFieldTypeText start:item.title], nil];
}

return nil;
}

#pragma mark -
#pragma mark Share API Methods

- (NSString *)httpAuthBasicHeaderWith:(NSString *)user andPass:(NSString *)pass {
NSData *data = [[NSString stringWithFormat:@"%@:%@", user, pass] dataUsingEncoding:NSUTF8StringEncoding];

size_t est_out_len = EstimateBas64DecodedDataSize([data length]);
size_t out_len = est_out_len + 512; // a safety margin of 512 is perhaps too big
char outdata[out_len];
Base64EncodeData([data bytes], [data length], outdata, &out_len);
outdata[out_len] = '\0'; // make it a null terminated string

NSString *value = [NSString stringWithFormat:@"Basic %@", [NSString stringWithCString:outdata encoding:NSUTF8StringEncoding]];

return value;
}

- (BOOL)send {
if ([self validateItem]) {
NSMutableURLRequest *aRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:kPosterousPostURL] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:90];

NSString *username = [self getAuthValueForKey:@"username"];
NSString *password = [self getAuthValueForKey:@"password"];
NSString *boundary = @"0xKhTmLbOuNdArY";

NSMutableDictionary *headers = [NSMutableDictionary dictionaryWithDictionary: self.request.headerFields];
[headers setObject:[self httpAuthBasicHeaderWith:username andPass:password] forKey:@"Authorization"];
[headers setObject:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary] forKey:@"Content-Type"];

[aRequest setAllHTTPHeaderFields:headers];
[aRequest setHTTPMethod:@"POST"];

NSMutableData *body = [NSMutableData data];

[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"api_token\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:SHKPosterousAPIKey] dataUsingEncoding:NSUTF8StringEncoding]];

if ([item title]) {
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"post[title]\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[item.title dataUsingEncoding:NSUTF8StringEncoding]];
}

if ([item text]) {
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"post[body]\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[item.text dataUsingEncoding:NSUTF8StringEncoding]];
}

if ([item image]) {
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"media[0]\"; filename=\"upload.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Transfer-Encoding: image/jpg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:UIImageJPEGRepresentation([item image], 0.9)];
}

[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[aRequest setHTTPBody:body];

[NSURLConnection connectionWithRequest:aRequest delegate:self];
[aRequest release];

[self sendDidStart];

return YES;
}

return NO;
}

#pragma mark -
#pragma mark NSURLConnection delegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)theResponse {
[URLResponse release];
URLResponse = [theResponse retain];

[photoData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d {
[photoData appendData:d];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[self finish];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[self finish];
}

- (void)finish {
if (URLResponse.statusCode == 200 || URLResponse.statusCode == 201) {
[self sendDidFinish];
} else {
if (URLResponse.statusCode == 403) {
[self sendDidFailWithError:[SHK error:SHKLocalizedString(@"Invalid username or password.")] shouldRelogin:YES];
} else if (URLResponse.statusCode == 500) {
[self sendDidFailWithError:[SHK error:SHKLocalizedString(@"The service encountered an error. Please try again later.")]];
} else {
[self sendDidFailWithError:[SHK error:SHKLocalizedString(@"There was an error sending your post to Posterous.")]];
}
}
}

@end
14 changes: 14 additions & 0 deletions ShareKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
07FE2747135FA99000E05A8E /* SHKPosterous.m in Sources */ = {isa = PBXBuildFile; fileRef = 07FE2746135FA99000E05A8E /* SHKPosterous.m */; };
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
Expand Down Expand Up @@ -109,6 +110,8 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
07FE2745135FA99000E05A8E /* SHKPosterous.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKPosterous.h; sourceTree = "<group>"; };
07FE2746135FA99000E05A8E /* SHKPosterous.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKPosterous.m; sourceTree = "<group>"; };
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1D6058910D05DD3D006BFB54 /* ShareKit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ShareKit.app; sourceTree = BUILT_PRODUCTS_DIR; };
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -330,6 +333,15 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
07FE2744135FA98000E05A8E /* Posterous */ = {
isa = PBXGroup;
children = (
07FE2745135FA99000E05A8E /* SHKPosterous.h */,
07FE2746135FA99000E05A8E /* SHKPosterous.m */,
);
name = Posterous;
sourceTree = "<group>";
};
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -726,6 +738,7 @@
43A536DE11DBE3B9004A1712 /* Google Reader */,
43150A8A11E78697008C6B68 /* Instapaper */,
43A536E111DBE3B9004A1712 /* Pinboard */,
07FE2744135FA98000E05A8E /* Posterous */,
43A536E411DBE3B9004A1712 /* Read It Later */,
43C91DF211EBAE4800F31FAE /* Tumblr */,
43A536E711DBE3B9004A1712 /* Twitter */,
Expand Down Expand Up @@ -1052,6 +1065,7 @@
4379F2C11291AC9700D2A41E /* SHKEvernote.m in Sources */,
4379F2EA1291AE5700D2A41E /* NSData+md5.m in Sources */,
4379F3B21291C45700D2A41E /* SHKTextMessage.m in Sources */,
07FE2747135FA99000E05A8E /* SHKPosterous.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down

0 comments on commit d82288b

Please sign in to comment.