adium 5464:794a4d6869e2: Bring STTwitter more up to date with wh...
commits at adium.im
commits at adium.im
Fri May 3 10:58:34 UTC 2013
details: http://hg.adium.im/adium/rev/794a4d6869e2
revision: 5464:794a4d6869e2
branch: adium-1.6
author: Thijs Alkemade <me at thijsalkema.de>
date: Fri May 03 11:30:45 2013 +0200
Bring STTwitter more up to date with what's on github (specifically, merge a leak fix from upstream).
Subject: adium 5465:0d3d3a9afde1: Merged with wixardy.
details: http://hg.adium.im/adium/rev/0d3d3a9afde1
revision: 5465:0d3d3a9afde1
branch: adium-1.6
author: Thijs Alkemade <me at thijsalkema.de>
date: Fri May 03 12:58:24 2013 +0200
Merged with wixardy.
diffs (704 lines):
diff -r 0c51e1c6487d -r 0d3d3a9afde1 Adium.xcodeproj/project.pbxproj
--- a/Adium.xcodeproj/project.pbxproj Fri May 03 02:31:52 2013 +0200
+++ b/Adium.xcodeproj/project.pbxproj Fri May 03 12:58:24 2013 +0200
@@ -1361,6 +1361,7 @@
76AA110D1635585E00A6EC4B /* AIAccountSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 76AA110B1635585E00A6EC4B /* AIAccountSelectionViewController.m */; };
76AA1110163558B200A6EC4B /* AIRejoinGroupChatViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 76AA110F163558B200A6EC4B /* AIRejoinGroupChatViewController.m */; };
76C1AF9C125A906A00D269A9 /* AIAdiumURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 76C1AF9B125A906A00D269A9 /* AIAdiumURLProtocol.m */; };
+ 76FBDAC91733B9CA00C9F10B /* STTwitterHTML.m in Sources */ = {isa = PBXBuildFile; fileRef = 76FBDAC61733B9C900C9F10B /* STTwitterHTML.m */; };
76FF925A14B524B40043E23B /* AIIRCConsoleController.h in Headers */ = {isa = PBXBuildFile; fileRef = 76FF925814B524B40043E23B /* AIIRCConsoleController.h */; };
76FF925B14B524B40043E23B /* AIIRCConsoleController.m in Sources */ = {isa = PBXBuildFile; fileRef = 76FF925914B524B40043E23B /* AIIRCConsoleController.m */; };
76FF926414B62A980043E23B /* AIConsole.xib in Resources */ = {isa = PBXBuildFile; fileRef = 76FF926314B62A980043E23B /* AIConsole.xib */; };
@@ -4420,6 +4421,10 @@
76AA110F163558B200A6EC4B /* AIRejoinGroupChatViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRejoinGroupChatViewController.m; path = "Plugins/Dual Window Interface/AIRejoinGroupChatViewController.m"; sourceTree = "<group>"; };
76C1AF9A125A906A00D269A9 /* AIAdiumURLProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIAdiumURLProtocol.h; path = "Plugins/WebKit Message View/AIAdiumURLProtocol.h"; sourceTree = "<group>"; };
76C1AF9B125A906A00D269A9 /* AIAdiumURLProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIAdiumURLProtocol.m; path = "Plugins/WebKit Message View/AIAdiumURLProtocol.m"; sourceTree = "<group>"; };
+ 76FBDAC51733B9C900C9F10B /* STTwitterHTML.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STTwitterHTML.h; path = "Plugins/Twitter Plugin/STTwitter/STTwitterHTML.h"; sourceTree = "<group>"; };
+ 76FBDAC61733B9C900C9F10B /* STTwitterHTML.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = STTwitterHTML.m; path = "Plugins/Twitter Plugin/STTwitter/STTwitterHTML.m"; sourceTree = "<group>"; };
+ 76FBDAC71733B9C900C9F10B /* STTwitterOAuthOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STTwitterOAuthOSX.h; path = "Plugins/Twitter Plugin/STTwitter/STTwitterOAuthOSX.h"; sourceTree = "<group>"; };
+ 76FBDAC81733B9C900C9F10B /* STTwitterOAuthOSX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = STTwitterOAuthOSX.m; path = "Plugins/Twitter Plugin/STTwitter/STTwitterOAuthOSX.m"; sourceTree = "<group>"; };
76FF925814B524B40043E23B /* AIIRCConsoleController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIIRCConsoleController.h; path = "Plugins/Purple Service/AIIRCConsoleController.h"; sourceTree = "<group>"; };
76FF925914B524B40043E23B /* AIIRCConsoleController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIIRCConsoleController.m; path = "Plugins/Purple Service/AIIRCConsoleController.m"; sourceTree = "<group>"; };
76FF926314B62A980043E23B /* AIConsole.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = AIConsole.xib; path = "Frameworks/Adium Framework/Resources/AIConsole.xib"; sourceTree = "<group>"; };
@@ -7330,6 +7335,10 @@
5A3B4D7116D878AB00903E40 /* STTwitterOAuth.h */,
5A3B4D7216D878AB00903E40 /* STTwitterOAuth.m */,
5A3B4D7516D878AB00903E40 /* STTwitterOAuthProtocol.h */,
+ 76FBDAC51733B9C900C9F10B /* STTwitterHTML.h */,
+ 76FBDAC61733B9C900C9F10B /* STTwitterHTML.m */,
+ 76FBDAC71733B9C900C9F10B /* STTwitterOAuthOSX.h */,
+ 76FBDAC81733B9C900C9F10B /* STTwitterOAuthOSX.m */,
5A3B4D7616D878AC00903E40 /* Vendor */,
);
name = STTwitter;
@@ -10565,6 +10574,7 @@
5A3B4D7E16D878AC00903E40 /* STHTTPRequest.m in Sources */,
5A0D236A16F4C7BC005DF211 /* STTwitterAppOnly.m in Sources */,
5A4B77E916FBDDC700DF398C /* NSData+Base64.m in Sources */,
+ 76FBDAC91733B9CA00C9F10B /* STTwitterHTML.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff -r 0c51e1c6487d -r 0d3d3a9afde1 Frameworks/PSMTabBarControl.framework/Versions/A/PSMTabBarControl
Binary file Frameworks/PSMTabBarControl.framework/Versions/A/PSMTabBarControl has changed
diff -r 0c51e1c6487d -r 0d3d3a9afde1 Plugins/Twitter Plugin/STTwitter/STTwitterAPIWrapper.h
--- a/Plugins/Twitter Plugin/STTwitter/STTwitterAPIWrapper.h Fri May 03 02:31:52 2013 +0200
+++ b/Plugins/Twitter Plugin/STTwitter/STTwitterAPIWrapper.h Fri May 03 12:58:24 2013 +0200
@@ -89,8 +89,12 @@
@property (nonatomic, readonly) NSString *bearerToken;
- (void)profileImageFor:(NSString *)screenName
- successBlock:(void(^)(NSImage *image))successBlock
- errorBlock:(void(^)(NSError *error))errorBlock;;
+#if TARGET_OS_IPHONE
+ successBlock:(void(^)(UIImage *image))successBlock
+#else
+ successBlock:(void(^)(NSImage *image))successBlock
+#endif
+ errorBlock:(void(^)(NSError *error))errorBlock;
#pragma mark Timelines
@@ -284,7 +288,11 @@
// POST account/update_profile_image
// Returns Users (1: the user)
+#if TARGET_OS_IPHONE
+- (void)postUpdateProfileImage:(UIImage *)newImage
+#else
- (void)postUpdateProfileImage:(NSImage *)newImage
+#endif
successBlock:(void(^)(NSDictionary *myInfo))successBlock
errorBlock:(void(^)(NSError *error))errorBlock;
diff -r 0c51e1c6487d -r 0d3d3a9afde1 Plugins/Twitter Plugin/STTwitter/STTwitterAPIWrapper.m
--- a/Plugins/Twitter Plugin/STTwitter/STTwitterAPIWrapper.m Fri May 03 02:31:52 2013 +0200
+++ b/Plugins/Twitter Plugin/STTwitter/STTwitterAPIWrapper.m Fri May 03 12:58:24 2013 +0200
@@ -22,18 +22,6 @@
@synthesize consumerName = _consumerName;
@synthesize userName = _userName;
-#if TARGET_OS_IPHONE
-#else
-
-- (id)init {
- self = [super init];
-
- return self;
-}
-
-
-#endif
-
+ (STTwitterAPIWrapper *)twitterAPIWithOAuthConsumerName:(NSString *)consumerName
consumerKey:(NSString *)consumerKey
consumerSecret:(NSString *)consumerSecret
@@ -160,8 +148,14 @@
/**/
- (void)profileImageFor:(NSString *)screenName
- successBlock:(void(^)(NSImage *image))successBlock
- errorBlock:(void(^)(NSError *error))errorBlock {
+
+#if TARGET_OS_IPHONE
+ successBlock:(void(^)(UIImage *image))successBlock
+#else
+ successBlock:(void(^)(NSImage *image))successBlock
+#endif
+
+ errorBlock:(void(^)(NSError *error))errorBlock {
[self getUserInformationFor:screenName
successBlock:^(NSDictionary *response) {
NSString *imageURL = [response objectForKey:@"profile_image_url"];
@@ -169,7 +163,13 @@
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:imageURL]];
NSData *imageData = [NSURLConnection sendSynchronousRequest:imageRequest returningResponse:nil error:nil];
- successBlock([[NSImage alloc] initWithData:imageData]);
+
+#if TARGET_OS_IPHONE
+ successBlock([[[UIImage alloc] initWithData:imageData] autorelease]);
+#else
+ successBlock([[[NSImage alloc] initWithData:imageData] autorelease]);
+#endif
+
} errorBlock:^(NSError *error) {
errorBlock(error);
}];
@@ -471,7 +471,7 @@
errorBlock:(void(^)(NSError *error))errorBlock {
NSDictionary *d = @{@"screen_name" : screenName};
- [_oauth getResource:@"friendships/create.json" parameters:d successBlock:^(id response) {
+ [_oauth postResource:@"friendships/create.json" parameters:d successBlock:^(id response) {
successBlock(removeNull(response));
} errorBlock:^(NSError *error) {
errorBlock(error);
@@ -483,7 +483,7 @@
errorBlock:(void(^)(NSError *error))errorBlock {
NSDictionary *d = @{@"screen_name" : screenName};
- [_oauth getResource:@"friendships/destroy.json" parameters:d successBlock:^(id response) {
+ [_oauth postResource:@"friendships/destroy.json" parameters:d successBlock:^(id response) {
successBlock(removeNull(response));
} errorBlock:^(NSError *error) {
errorBlock(error);
@@ -497,7 +497,7 @@
NSMutableDictionary *d = [NSMutableDictionary dictionaryWithObject:screenName forKey:@"screen_name"];
[d setObject:notify ? @"true" : @"false" forKey:@"device"];
- [_oauth getResource:@"friendships/update.json" parameters:d successBlock:^(id response) {
+ [_oauth postResource:@"friendships/update.json" parameters:d successBlock:^(id response) {
successBlock(removeNull(response));
} errorBlock:^(NSError *error) {
errorBlock(error);
@@ -541,7 +541,11 @@
}];
}
+#if TARGET_OS_IPHONE
+- (void)postUpdateProfileImage:(UIImage *)newImage
+#else
- (void)postUpdateProfileImage:(NSImage *)newImage
+#endif
successBlock:(void(^)(NSDictionary *myInfo))successBlock
errorBlock:(void(^)(NSError *error))errorBlock {
NSMutableDictionary *md = [NSMutableDictionary dictionaryWithObject:newImage forKey:@"image"];
diff -r 0c51e1c6487d -r 0d3d3a9afde1 Plugins/Twitter Plugin/STTwitter/STTwitterHTML.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Twitter Plugin/STTwitter/STTwitterHTML.h Fri May 03 12:58:24 2013 +0200
@@ -0,0 +1,35 @@
+//
+// STTwitterWeb.h
+// STTwitterRequests
+//
+// Created by Nicolas Seriot on 9/13/12.
+// Copyright (c) 2012 Nicolas Seriot. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+ at interface STTwitterHTML : NSObject
+
+- (void)getLoginForm:(void(^)(NSString *authenticityToken))successBlock
+ errorBlock:(void(^)(NSError *error))errorBlock;
+
+- (void)postLoginFormWithUsername:(NSString *)username
+ password:(NSString *)password
+ authenticityToken:(NSString *)authenticityToken
+ successBlock:(void(^)())successBlock
+ errorBlock:(void(^)(NSError *error))errorBlock;
+
+
+/**/
+
+- (void)getAuthorizeFormAtURL:(NSURL *)url
+ successBlock:(void(^)(NSString *authenticityToken, NSString *oauthToken))successBlock
+ errorBlock:(void(^)(NSError *error))errorBlock;
+
+- (void)postAuthorizeFormResultsAtURL:(NSURL *)url
+ authenticityToken:(NSString *)authenticityToken
+ oauthToken:(NSString *)oauthToken
+ successBlock:(void(^)(NSString *PIN))successBlock
+ errorBlock:(void(^)(NSError *error))errorBlock;
+
+ at end
diff -r 0c51e1c6487d -r 0d3d3a9afde1 Plugins/Twitter Plugin/STTwitter/STTwitterHTML.m
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Twitter Plugin/STTwitter/STTwitterHTML.m Fri May 03 12:58:24 2013 +0200
@@ -0,0 +1,142 @@
+//
+// STTwitterWeb.m
+// STTwitterRequests
+//
+// Created by Nicolas Seriot on 9/13/12.
+// Copyright (c) 2012 Nicolas Seriot. All rights reserved.
+//
+
+#import "STTwitterHTML.h"
+#import "STHTTPRequest.h"
+#import "NSString+STTwitter.h"
+
+ at implementation STTwitterHTML
+
+- (void)getLoginForm:(void(^)(NSString *authenticityToken))successBlock errorBlock:(void(^)(NSError *error))errorBlock {
+
+ STHTTPRequest *r = [STHTTPRequest requestWithURLString:@"https://twitter.com/login"];
+
+ r.completionBlock = ^(NSDictionary *headers, NSString *body) {
+
+ NSError *error = nil;
+// NSString *token = [body firstMatchWithRegex:@"<input type=\"hidden\" value=\"(\\S+)\" name=\"authenticity_token\"/>" error:&error];
+ NSString *token = [body firstMatchWithRegex:@"formAuthenticityToken":"(\\S+?)"" error:&error];
+
+ if(token == nil) {
+ errorBlock(error);
+ return;
+ }
+
+ successBlock(token);
+ };
+
+ r.errorBlock = ^(NSError *error) {
+ errorBlock(error);
+ };
+
+ [r startAsynchronous];
+}
+
+- (void)postLoginFormWithUsername:(NSString *)username
+ password:(NSString *)password
+ authenticityToken:(NSString *)authenticityToken
+ successBlock:(void(^)())successBlock
+ errorBlock:(void(^)(NSError *error))errorBlock {
+
+ if([username length] == 0 || [password length] == 0) {
+ NSString *errorDescription = [NSString stringWithFormat:@"Missing credentials"];
+ NSError *error = [NSError errorWithDomain:NSStringFromClass([self class]) code:0 userInfo:@{NSLocalizedDescriptionKey : errorDescription}];
+ errorBlock(error);
+ return;
+ }
+
+ STHTTPRequest *r = [STHTTPRequest requestWithURLString:@"https://twitter.com/sessions"];
+
+ r.POSTDictionary = @{@"authenticity_token" : authenticityToken,
+ @"session[username_or_email]" : username,
+ @"session[password]" : password,
+ @"remember_me" : @"1",
+ @"commit" : @"Sign in"};
+
+ r.completionBlock = ^(NSDictionary *headers, NSString *body) {
+ successBlock();
+ };
+
+ r.errorBlock = ^(NSError *error) {
+ errorBlock(error);
+ };
+
+ [r startAsynchronous];
+}
+
+- (void)getAuthorizeFormAtURL:(NSURL *)url successBlock:(void(^)(NSString *authenticityToken, NSString *oauthToken))successBlock errorBlock:(void(^)(NSError *error))errorBlock {
+
+ STHTTPRequest *r = [STHTTPRequest requestWithURL:url];
+
+ r.completionBlock = ^(NSDictionary *headers, NSString *body) {
+ /*
+ <form action="https://api.twitter.com/oauth/authorize" id="oauth_form" method="post"><div style="margin:0;padding:0"><input name="authenticity_token" type="hidden" value="dacd811cf06655518633ad93e950132614eab7f4" /></div>
+
+ <input id="oauth_token" name="oauth_token" type="hidden" value="3qp5r3Ya65aVks8lNZEZm7313080zTdMQTOplalzQI" />
+ */
+
+ NSError *error1 = nil;
+ NSString *authenticityToken = [body firstMatchWithRegex:@"<input name=\"authenticity_token\" type=\"hidden\" value=\"(\\S+)\" />" error:&error1];
+
+ if(authenticityToken == nil) {
+ errorBlock(error1);
+ return;
+ }
+
+ /**/
+
+ NSError *error2 = nil;
+
+ NSString *oauthToken = [body firstMatchWithRegex:@"<input id=\"oauth_token\" name=\"oauth_token\" type=\"hidden\" value=\"(\\S+)\" />" error:&error2];
+
+ if(oauthToken == nil) {
+ errorBlock(error2);
+ return;
+ }
+
+ /**/
+
+ successBlock(authenticityToken, oauthToken);
+ };
+
+ r.errorBlock = ^(NSError *error) {
+ errorBlock(error);
+ };
+
+ [r startAsynchronous];
+}
+
+- (void)postAuthorizeFormResultsAtURL:(NSURL *)url authenticityToken:(NSString *)authenticityToken oauthToken:(NSString *)oauthToken successBlock:(void(^)(NSString *PIN))successBlock errorBlock:(void(^)(NSError *error))errorBlock {
+
+ STHTTPRequest *r = [STHTTPRequest requestWithURL:url];
+
+ r.POSTDictionary = @{@"authenticity_token" : authenticityToken,
+ @"oauth_token" : oauthToken};
+
+ r.completionBlock = ^(NSDictionary *headers, NSString *body) {
+
+ NSError *error = nil;
+ NSString *pin = [body firstMatchWithRegex:@"<code>(\\d+)</code>" error:&error];
+
+ if(pin == nil) {
+ errorBlock(error);
+ return;
+ }
+
+ successBlock(pin);
+ };
+
+ r.errorBlock = ^(NSError *error) {
+ errorBlock(error);
+ };
+
+ [r startAsynchronous];
+}
+
+ at end
+
diff -r 0c51e1c6487d -r 0d3d3a9afde1 Plugins/Twitter Plugin/STTwitter/STTwitterOAuthOSX.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Twitter Plugin/STTwitter/STTwitterOAuthOSX.h Fri May 03 12:58:24 2013 +0200
@@ -0,0 +1,35 @@
+//
+// MGTwitterEngine+TH.h
+// TwitHunter
+//
+// Created by Nicolas Seriot on 5/1/10.
+// Copyright 2010 seriot.ch. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "STTwitterOAuthProtocol.h"
+
+#if TARGET_OS_IPHONE
+#else
+
+typedef void (^STTE_completionBlock_t)(NSArray *statuses);
+typedef void (^STTE_errorBlock_t)(NSError *error);
+
+ at class ACAccount;
+
+ at interface STTwitterOAuthOSX : NSObject <STTwitterOAuthProtocol> {
+
+}
+
+
+- (BOOL)canVerifyCredentials;
+- (void)verifyCredentialsWithSuccessBlock:(void(^)(NSString *username))successBlock errorBlock:(void(^)(NSError *error))errorBlock;
+
+- (void)getResource:(NSString *)resource parameters:(NSDictionary *)params successBlock:(STTE_completionBlock_t)completionBlock errorBlock:(STTE_errorBlock_t)errorBlock;
+- (void)postResource:(NSString *)resource parameters:(NSDictionary *)params successBlock:(STTE_completionBlock_t)completionBlock errorBlock:(STTE_errorBlock_t)errorBlock;
+
+- (NSString *)username;
+
+ at end
+
+#endif
diff -r 0c51e1c6487d -r 0d3d3a9afde1 Plugins/Twitter Plugin/STTwitter/STTwitterOAuthOSX.m
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Twitter Plugin/STTwitter/STTwitterOAuthOSX.m Fri May 03 12:58:24 2013 +0200
@@ -0,0 +1,181 @@
+//
+// MGTwitterEngine+TH.m
+// TwitHunter
+//
+// Created by Nicolas Seriot on 5/1/10.
+// Copyright 2010 seriot.ch. All rights reserved.
+//
+
+#import "STTwitterOAuthOSX.h"
+#import <Social/Social.h>
+#import <Accounts/Accounts.h>
+
+#if TARGET_OS_IPHONE
+#else
+
+ at implementation STTwitterOAuthOSX
+
+- (void)verifyCredentialsWithSuccessBlock:(void(^)(NSString *username))successBlock errorBlock:(void(^)(NSError *error))errorBlock {
+ [self requestAccessWithCompletionBlock:^(ACAccount *twitterAccount) {
+ successBlock(twitterAccount.username);
+ } errorBlock:^(NSError *error) {
+ errorBlock(error);
+ }];
+}
+
+- (NSString *)username {
+ ACAccountStore *accountStore = [[[ACAccountStore alloc] init] autorelease];
+ ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
+ NSArray *accounts = [accountStore accountsWithAccountType:accountType];
+ ACAccount *twitterAccount = [accounts lastObject];
+ return twitterAccount.username;
+}
+
+- (void)requestAccessWithCompletionBlock:(void(^)(ACAccount *twitterAccount))completionBlock errorBlock:(void(^)(NSError *))errorBlock {
+
+ ACAccountStore *accountStore = [[ACAccountStore alloc] init];
+ ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
+
+ [accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
+
+ [[NSOperationQueue mainQueue] addOperationWithBlock:^{
+ if(granted) {
+
+ NSArray *accounts = [accountStore accountsWithAccountType:accountType];
+
+ // TODO: let the user choose the account he wants
+ ACAccount *twitterAccount = [accounts lastObject];
+
+// id cred = [twitterAccount credential];
+
+ completionBlock(twitterAccount);
+ } else {
+ NSError *e = error;
+ if(e == nil) {
+ NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : @"Cannot access OS X Twitter account." };
+ e = [NSError errorWithDomain:@"STTwitterOAuthOSX" code:0 userInfo:userInfo];
+ }
+ errorBlock(e);
+ }
+ }];
+ }];
+}
+
+- (void)fetchAPIResource:(NSString *)resource httpMethod:(int)httpMethod parameters:(NSDictionary *)params completionBlock:(STTE_completionBlock_t)completionBlock errorBlock:(STTE_errorBlock_t)errorBlock {
+
+ NSData *mediaData = [params valueForKey:@"media[]"];
+
+ NSMutableDictionary *paramsWithoutMedia = [[params mutableCopy] autorelease];
+ [paramsWithoutMedia removeObjectForKey:@"media[]"];
+
+ [self requestAccessWithCompletionBlock:^(ACAccount *twitterAccount) {
+ NSString *urlString = [@"https://api.twitter.com/1.1/" stringByAppendingString:resource];
+ NSURL *url = [NSURL URLWithString:urlString];
+ SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:httpMethod URL:url parameters:paramsWithoutMedia];
+ request.account = twitterAccount;
+
+ if(mediaData) {
+ [request addMultipartData:mediaData withName:@"media[]" type:@"application/octet-stream" filename:@"media.jpg"];
+ }
+
+ [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
+ if(responseData == nil) {
+ [[NSOperationQueue mainQueue] addOperationWithBlock:^{
+ errorBlock(nil);
+ }];
+ return;
+ }
+
+ NSError *jsonError = nil;
+ NSJSONSerialization *json = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&jsonError];
+
+ if(json == nil) {
+ [[NSOperationQueue mainQueue] addOperationWithBlock:^{
+ errorBlock(jsonError);
+ }];
+ return;
+ }
+
+ /**/
+
+ if([json isKindOfClass:[NSArray class]] == NO && [json valueForKey:@"error"]) {
+
+ NSString *message = [json valueForKey:@"error"];
+ NSDictionary *userInfo = [NSDictionary dictionaryWithObject:message forKey:NSLocalizedDescriptionKey];
+ NSError *jsonErrorFromResponse = [NSError errorWithDomain:NSStringFromClass([self class]) code:0 userInfo:userInfo];
+
+ [[NSOperationQueue mainQueue] addOperationWithBlock:^{
+ errorBlock(jsonErrorFromResponse);
+ }];
+
+ return;
+ }
+
+ /**/
+
+ id jsonErrors = [json valueForKey:@"errors"];
+
+ if(jsonErrors != nil && [jsonErrors isKindOfClass:[NSArray class]] == NO) {
+ if(jsonErrors == nil) jsonErrors = @"";
+ jsonErrors = [NSArray arrayWithObject:@{@"message":jsonErrors, @"code" : @(0)}];
+ }
+
+ if([jsonErrors count] > 0 && [[jsonErrors lastObject] isEqualTo:[NSNull null]] == NO) {
+
+ NSDictionary *jsonErrorDictionary = [jsonErrors lastObject];
+ NSString *message = jsonErrorDictionary[@"message"];
+ NSInteger code = [jsonErrorDictionary[@"code"] intValue];
+ NSDictionary *userInfo = [NSDictionary dictionaryWithObject:message forKey:NSLocalizedDescriptionKey];
+ NSError *jsonErrorFromResponse = [NSError errorWithDomain:NSStringFromClass([self class]) code:code userInfo:userInfo];
+
+ [[NSOperationQueue mainQueue] addOperationWithBlock:^{
+ errorBlock(jsonErrorFromResponse);
+ }];
+
+ return;
+ }
+
+ /**/
+
+ if(json) {
+
+ [[NSOperationQueue mainQueue] addOperationWithBlock:^{
+ completionBlock((NSArray *)json);
+ }];
+
+ } else {
+
+ [[NSOperationQueue mainQueue] addOperationWithBlock:^{
+ errorBlock(jsonError);
+ }];
+ }
+ }];
+
+ } errorBlock:^(NSError *error) {
+ errorBlock(error);
+ }];
+}
+
+- (BOOL)canVerifyCredentials {
+ return YES;
+}
+
+- (void)getResource:(NSString *)resource parameters:(NSDictionary *)params successBlock:(STTE_completionBlock_t)completionBlock errorBlock:(STTE_errorBlock_t)errorBlock {
+
+ int HTTPMethod = SLRequestMethodGET;
+
+ [self fetchAPIResource:resource httpMethod:HTTPMethod parameters:params completionBlock:completionBlock errorBlock:errorBlock];
+}
+
+- (void)postResource:(NSString *)resource parameters:(NSDictionary *)params successBlock:(STTE_completionBlock_t)completionBlock errorBlock:(STTE_errorBlock_t)errorBlock {
+
+ int HTTPMethod = SLRequestMethodPOST;
+
+ NSDictionary *d = params ? params : @{};
+
+ [self fetchAPIResource:resource httpMethod:HTTPMethod parameters:d completionBlock:completionBlock errorBlock:errorBlock];
+}
+
+ at end
+
+#endif
diff -r 0c51e1c6487d -r 0d3d3a9afde1 Plugins/Twitter Plugin/STTwitter/Vendor/STHTTPRequest.m
--- a/Plugins/Twitter Plugin/STTwitter/Vendor/STHTTPRequest.m Fri May 03 02:31:52 2013 +0200
+++ b/Plugins/Twitter Plugin/STTwitter/Vendor/STHTTPRequest.m Fri May 03 12:58:24 2013 +0200
@@ -332,7 +332,7 @@
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPMethod:@"POST"];
- [request setValue:[NSString stringWithFormat:@"%lu", [body length]] forHTTPHeaderField:@"Content-Length"];
+ [request setValue:[NSString stringWithFormat:@"%u", (unsigned int)[body length]] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:body];
} else if(_POSTDictionary != nil) { // may be empty (POST request without body)
@@ -365,11 +365,11 @@
NSData *data = [s dataUsingEncoding:_postDataEncoding allowLossyConversion:YES];
[request setHTTPMethod:@"POST"];
- [request setValue:[NSString stringWithFormat:@"%lu", [data length]] forHTTPHeaderField:@"Content-Length"];
+ [request setValue:[NSString stringWithFormat:@"%u", (unsigned int)[data length]] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:data];
} else if (_POSTData != nil) {
[request setHTTPMethod:@"POST"];
- [request setValue:[NSString stringWithFormat:@"%lu", [_POSTData length]] forHTTPHeaderField:@"Content-Length"];
+ [request setValue:[NSString stringWithFormat:@"%u", (unsigned int)[_POSTData length]] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:_POSTData];
}
@@ -442,6 +442,82 @@
return [[[NSString alloc] initWithData:data encoding:encoding] autorelease];
}
+#if DEBUG
+- (NSString *)curlDescription {
+
+ NSMutableArray *ma = [NSMutableArray array];
+ [ma addObject:@"$ curl -i"];
+
+ // -u usernane:password
+
+ NSURLCredential *credential = [[self class] sessionAuthenticationCredentialsForURL:[self url]];
+ if(credential) {
+ NSString *s = [NSString stringWithFormat:@"-u \"%@:%@\"", credential.user, credential.password];
+ [ma addObject:s];
+ }
+
+ // -d "k1=v1&k2=v2" // POST, url encoded params
+
+ if(_POSTDictionary) {
+ NSMutableArray *postParameters = [NSMutableArray array];
+ [_POSTDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
+ NSString *s = [NSString stringWithFormat:@"%@=%@", key, obj];
+ [postParameters addObject:s];
+ }];
+ NSString *ss = [postParameters componentsJoinedByString:@"&"];
+ [ma addObject:[NSString stringWithFormat:@"-d \"%@\"", ss]];
+ }
+
+ // -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html" // file upload
+
+ if(_POSTFileParameter && _POSTFilePath) {
+
+ NSString *s = [NSString stringWithFormat:@"%@@%@", _POSTFileParameter, _POSTFilePath];
+
+ if(_POSTFileMimeType) {
+ s = [s stringByAppendingFormat:@";type=%@", _POSTFileMimeType];
+ }
+
+ [ma addObject:[NSString stringWithFormat:@"-F \"%@\"", s]];
+ }
+
+ // -b "name=Daniel;age=35" // cookies
+
+ NSArray *cookies = [self requestCookies];
+
+ NSMutableArray *cookiesStrings = [NSMutableArray array];
+ for(NSHTTPCookie *cookie in cookies) {
+ NSString *s = [NSString stringWithFormat:@"%@=%@", [cookie name], [cookie value]];
+ [cookiesStrings addObject:s];
+ }
+
+ if([cookiesStrings count] > 0) {
+ [ma addObject:[NSString stringWithFormat:@"-b \"%@\"", [cookiesStrings componentsJoinedByString:@";"]]];
+ }
+
+ // -H "X-you-and-me: yes" // extra headers
+
+ NSMutableDictionary *headers = [[[self requestHeaders] mutableCopy] autorelease];
+
+ [headers addEntriesFromDictionary:[self.request allHTTPHeaderFields]];
+
+ NSMutableArray *headersStrings = [NSMutableArray array];
+ [headers enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
+ NSString *s = [NSString stringWithFormat:@"-H \"%@: %@\"", key, obj];
+ [headersStrings addObject:s];
+ }];
+
+ if([headersStrings count] > 0) {
+ [ma addObject:[headersStrings componentsJoinedByString:@" \\\n"]];
+ }
+
+ // url
+
+ [ma addObject:[NSString stringWithFormat:@"\"%@\"", _url]];
+
+ return [ma componentsJoinedByString:@" \\\n"];
+}
+
- (void)logRequest:(NSURLRequest *)request {
NSLog(@"--------------------------------------");
@@ -481,14 +557,17 @@
NSLog(@"\t %@ = %@", _POSTFileParameter, _POSTFilePath);
} else if (_POSTFileParameter && _POSTFileData) {
NSLog(@"UPLOAD DATA");
- NSLog(@"\t %@ = [%lu bytes]", _POSTFileParameter, [_POSTFileData length]);
+ NSLog(@"\t %@ = [%u bytes]", _POSTFileParameter, (unsigned int)[_POSTFileData length]);
} else if (_POSTData) {
NSLog(@"UPLOAD DATA");
- NSLog(@"\t [%lu bytes]", [_POSTData length]);
+ NSLog(@"\t [%u bytes]", (unsigned int)[_POSTData length]);
}
+ NSLog(@"--");
+ NSLog(@"%@", [self curlDescription]);
NSLog(@"--------------------------------------");
}
+#endif
#pragma mark Start Request
More information about the commits
mailing list