Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 7 commits
  • 19 files changed
  • 0 commit comments
  • 1 contributor
22 Puttio.xcodeproj/project.pbxproj
View
@@ -44,10 +44,11 @@
6085D279151B9DBA0068929C /* V1PutIOAPIClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 6085D278151B9DBA0068929C /* V1PutIOAPIClient.m */; };
6085D27F151BA3AF0068929C /* NSDictionary+JSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 6085D27E151BA3AF0068929C /* NSDictionary+JSON.m */; };
6085D297151BAB230068929C /* Constants.m in Sources */ = {isa = PBXBuildFile; fileRef = 6085D296151BAB230068929C /* Constants.m */; };
+ 6096FC1B155FF0B1009C524C /* PutIOOAuthHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 6096FC1A155FF0B1009C524C /* PutIOOAuthHelper.m */; };
60A1B19815287343002A6A7E /* ModalZoomView.m in Sources */ = {isa = PBXBuildFile; fileRef = 60A1B19715287343002A6A7E /* ModalZoomView.m */; };
60A1B1B01528788E002A6A7E /* FileInfoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 60A1B1AF1528788E002A6A7E /* FileInfoViewController.m */; };
60A7A6B5151F6E0D00DB71E0 /* ORSimpleProgress.m in Sources */ = {isa = PBXBuildFile; fileRef = 60A7A6B4151F6E0D00DB71E0 /* ORSimpleProgress.m */; };
- 60A7A6C6151FBA9900DB71E0 /* NetworkConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 60A7A6C5151FBA9900DB71E0 /* NetworkConstants.m */; };
+ 60A7A6C6151FBA9900DB71E0 /* PutIONetworkConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 60A7A6C5151FBA9900DB71E0 /* PutIONetworkConstants.m */; };
60A7A6D0151FD2A100DB71E0 /* File.m in Sources */ = {isa = PBXBuildFile; fileRef = 60A7A6CF151FD2A100DB71E0 /* File.m */; };
60A7A6D4151FD34700DB71E0 /* NSManagedObject+ActiveRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 60A7A6D3151FD34700DB71E0 /* NSManagedObject+ActiveRecord.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
60A7AB1515290771009DD716 /* Transfer.m in Sources */ = {isa = PBXBuildFile; fileRef = 60A7AB1415290771009DD716 /* Transfer.m */; };
@@ -152,6 +153,8 @@
6085D27E151BA3AF0068929C /* NSDictionary+JSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+JSON.m"; sourceTree = "<group>"; };
6085D295151BAB230068929C /* Constants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = "<group>"; };
6085D296151BAB230068929C /* Constants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Constants.m; sourceTree = "<group>"; };
+ 6096FC19155FF0B1009C524C /* PutIOOAuthHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PutIOOAuthHelper.h; path = Networking/PutIOOAuthHelper.h; sourceTree = "<group>"; };
+ 6096FC1A155FF0B1009C524C /* PutIOOAuthHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PutIOOAuthHelper.m; path = Networking/PutIOOAuthHelper.m; sourceTree = "<group>"; };
60A1B19615287343002A6A7E /* ModalZoomView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ModalZoomView.h; path = ViewControllers/ModalZoomView.h; sourceTree = "<group>"; };
60A1B19715287343002A6A7E /* ModalZoomView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ModalZoomView.m; path = ViewControllers/ModalZoomView.m; sourceTree = "<group>"; };
60A1B1AE1528788E002A6A7E /* FileInfoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileInfoViewController.h; path = ViewControllers/FileInfoViewController.h; sourceTree = "<group>"; };
@@ -159,8 +162,8 @@
60A7A6B3151F6E0D00DB71E0 /* ORSimpleProgress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORSimpleProgress.h; path = Views/ORSimpleProgress.h; sourceTree = "<group>"; };
60A7A6B4151F6E0D00DB71E0 /* ORSimpleProgress.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORSimpleProgress.m; path = Views/ORSimpleProgress.m; sourceTree = "<group>"; };
60A7A6C3151FBA1D00DB71E0 /* APP_SECRET.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = APP_SECRET.h; path = ../APP_SECRET.h; sourceTree = "<group>"; };
- 60A7A6C4151FBA9900DB71E0 /* NetworkConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkConstants.h; path = Networking/NetworkConstants.h; sourceTree = "<group>"; };
- 60A7A6C5151FBA9900DB71E0 /* NetworkConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NetworkConstants.m; path = Networking/NetworkConstants.m; sourceTree = "<group>"; };
+ 60A7A6C4151FBA9900DB71E0 /* PutIONetworkConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; name = PutIONetworkConstants.h; path = Networking/PutIONetworkConstants.h; sourceTree = "<group>"; };
+ 60A7A6C5151FBA9900DB71E0 /* PutIONetworkConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PutIONetworkConstants.m; path = Networking/PutIONetworkConstants.m; sourceTree = "<group>"; };
60A7A6CB151FC1CF00DB71E0 /* APP_SECRET_EX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = APP_SECRET_EX.h; path = ../APP_SECRET_EX.h; sourceTree = "<group>"; };
60A7A6CE151FD2A100DB71E0 /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = File.h; path = Models/File.h; sourceTree = SOURCE_ROOT; };
60A7A6CF151FD2A100DB71E0 /* File.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = File.m; path = Models/File.m; sourceTree = SOURCE_ROOT; };
@@ -385,6 +388,8 @@
6085D27B151B9E550068929C /* View Controllers */ = {
isa = PBXGroup;
children = (
+ 60DB0AB2151C670800DA8A33 /* OAuthViewController.h */,
+ 60DB0AB3151C670800DA8A33 /* OAuthViewController.m */,
600641F9151F24AF00EF85F9 /* StatusViewController.h */,
600641FA151F24AF00EF85F9 /* StatusViewController.m */,
600641FD151F24C100EF85F9 /* SearchViewController.h */,
@@ -455,16 +460,16 @@
60DB0AB1151C665E00DA8A33 /* Network */ = {
isa = PBXGroup;
children = (
- 60A7A6C4151FBA9900DB71E0 /* NetworkConstants.h */,
- 60A7A6C5151FBA9900DB71E0 /* NetworkConstants.m */,
- 60DB0AB2151C670800DA8A33 /* OAuthViewController.h */,
- 60DB0AB3151C670800DA8A33 /* OAuthViewController.m */,
+ 60A7A6C4151FBA9900DB71E0 /* PutIONetworkConstants.h */,
+ 60A7A6C5151FBA9900DB71E0 /* PutIONetworkConstants.m */,
6085D277151B9DBA0068929C /* V1PutIOAPIClient.h */,
6085D278151B9DBA0068929C /* V1PutIOAPIClient.m */,
60B1A933151E157E00FBCD27 /* V2PutIOAPIClient.h */,
60B1A934151E157F00FBCD27 /* V2PutIOAPIClient.m */,
60BD4F45151C701300DCD686 /* PutIOClient.h */,
60BD4F46151C701300DCD686 /* PutIOClient.m */,
+ 6096FC19155FF0B1009C524C /* PutIOOAuthHelper.h */,
+ 6096FC1A155FF0B1009C524C /* PutIOOAuthHelper.m */,
);
name = Network;
sourceTree = "<group>";
@@ -591,7 +596,7 @@
60064205151F24DA00EF85F9 /* RootViewController.m in Sources */,
60AB50D3151F650A00473448 /* UIColor+PutioColours.m in Sources */,
60A7A6B5151F6E0D00DB71E0 /* ORSimpleProgress.m in Sources */,
- 60A7A6C6151FBA9900DB71E0 /* NetworkConstants.m in Sources */,
+ 60A7A6C6151FBA9900DB71E0 /* PutIONetworkConstants.m in Sources */,
60A7A6D0151FD2A100DB71E0 /* File.m in Sources */,
60A7A6D4151FD34700DB71E0 /* NSManagedObject+ActiveRecord.m in Sources */,
60F5AD6115224DF400DD7A6F /* ORImageViewCell.m in Sources */,
@@ -612,6 +617,7 @@
60D9B7EE1535C67300A64E0F /* ORSearchCell.m in Sources */,
6064D89B15398E4600E454E5 /* SearchController.m in Sources */,
6064D8B315399D8B00E454E5 /* NSString+StripHTML.m in Sources */,
+ 6096FC1B155FF0B1009C524C /* PutIOOAuthHelper.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
12 Puttio/Networking/OAuthViewController.h
View
@@ -7,16 +7,22 @@
//
#import <UIKit/UIKit.h>
+#import "PutIOOAuthHelper.h"
@class OAuthViewController;
+
@protocol OAuthVCDelegate <NSObject>
- (void)authorizationDidFinishWithController:(OAuthViewController *)controller;
@end
-@interface OAuthViewController : UIViewController <UIWebViewDelegate>
-@property (weak, nonatomic) IBOutlet UIWebView *webView;
+@interface OAuthViewController : UIViewController <UIWebViewDelegate, PutIOOAuthHelperDelegate>
@property (weak, nonatomic) id <OAuthVCDelegate>delegate;
+@property (weak, nonatomic) IBOutlet UITextField *usernameTextfield;
+@property (weak, nonatomic) IBOutlet UITextField *passwordTextfield;
+@property (weak, nonatomic) IBOutlet UILabel *warningLabel;
+@property (weak, nonatomic) IBOutlet UIView *loginViewWrapper;
+@property (strong, nonatomic) IBOutlet PutIOOAuthHelper *authHelper;
-- (IBAction)okPressed:(id)sender;
+- (IBAction)loginPressed:(id)sender;
@end
140 Puttio/Networking/OAuthViewController.m
View
@@ -6,38 +6,40 @@
// Copyright (c) 2012 ortatherox.com. All rights reserved.
//
+#import <QuartzCore/QuartzCore.h>
#import "OAuthViewController.h"
-#import "APP_SECRET.h"
-#import "AFNetworking.h"
-
-// http://put.io/v2/docs/#authentication
-
-// The order of this is
-
-// Login in via website in webkit
-// Redirect to the OAuth dialog
-// Make a request to the OAuth authenticate URL ( getAccessTokenFromOauthCode )
-// Load Accounts page and parse out the tokens
-// Then call delegate method.
-
-@interface OAuthViewController ()
-- (void)auth;
-- (void)loadAccountSettingsPage;
-- (void)getAccessTokenFromOauthCode:(NSString *)code;
-@end
+#import "PutIOOAuthHelper.h"
@implementation OAuthViewController
-@synthesize webView, delegate;
+@synthesize usernameTextfield, passwordTextfield;
+@synthesize warningLabel;
+@synthesize loginViewWrapper;
+@synthesize authHelper;
+@synthesize delegate;
-- (void)viewDidLoad
-{
+- (void)viewDidLoad {
[super viewDidLoad];
- [self auth];
+ [self setupShadow];
+ self.warningLabel.text = @"";
}
-- (void)viewDidUnload
-{
- [self setWebView:nil];
+- (void)setupShadow {
+ self.loginViewWrapper.clipsToBounds = NO;
+
+ CALayer *layer = self.loginViewWrapper.layer;
+ layer.masksToBounds = NO;
+ layer.shadowOffset = CGSizeZero;
+ layer.shadowColor = [[UIColor blackColor] CGColor];
+ layer.shadowRadius = 20;
+ layer.shadowOpacity = 0.15;
+}
+
+
+- (void)viewDidUnload {
+ [self setUsernameTextfield:nil];
+ [self setPasswordTextfield:nil];
+ [self setWarningLabel:nil];
+ [self setLoginViewWrapper:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
@@ -46,92 +48,18 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface
return YES;
}
-- (IBAction)okPressed:(id)sender {
-}
-
-- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
- // after you log in, it redrects to root, we actually want it
- if ([[request.URL absoluteString] isEqualToString: PTRootURL]) {
- [self auth];
- return NO;
- }
- return YES;
+- (IBAction)loginPressed:(id)sender {
+ [authHelper loginWithUsername:usernameTextfield.text andPassword:passwordTextfield.text];
}
-- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
- if (error.code == 101) {
- NSString *code = [[error userInfo] objectForKey:@"NSErrorFailingURLStringKey"];
- NSArray *URLComponents = [code componentsSeparatedByString:@"%3D"];
-
- if (URLComponents.count > 1 && [code hasPrefix: PTCallbackModified]) {
- [self getAccessTokenFromOauthCode:[URLComponents objectAtIndex:1]];
- }
- }else{
- if (error.code == 102) {
- // no-op as the puttio:// url causes errors 101/102
- }else{
- // actually unexpected
- NSLog(@"uh oh webview fail! %@", error);
- }
+- (void)authHelperDidLogin:(PutIOOAuthHelper *)helper {
+ if([delegate respondsToSelector:@selector(authorizationDidFinishWithController:)]){
+ [delegate authorizationDidFinishWithController:self];
}
}
-- (void)getAccessTokenFromOauthCode:(NSString *)code {
- // https://api.put.io/v2/oauth2/access_token?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=authorization_code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=CODE
-
- NSString *address = [NSString stringWithFormat:PTFormatOauthTokenURL, @"10", APP_SECRET, @"authorization_code", PTCallbackOriginal, code];
- NSLog(@"URL %@", address);
-
- NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:address]];
- AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
- [self loadAccountSettingsPage];
-
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- [defaults setObject:[JSON valueForKeyPath:@"access_token"] forKey:AppAuthTokenDefault];
- [defaults synchronize];
- [[NSNotificationCenter defaultCenter] postNotificationName:OAuthTokenWasSavedNotification object:nil userInfo:nil];
-
- }failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
- NSLog(@"error %@", error);
- }];
- [operation start];
-}
-
-#warning there's a lot of magic strings in this file. fix.
-
-- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
- if([aWebView.request.URL.absoluteString isEqualToString:PTSettingsURL]){
- [self parseForV1Tokens];
- if([delegate respondsToSelector:@selector(authorizationDidFinishWithController:)]){
- [delegate authorizationDidFinishWithController:self];
- }
- }
-}
-
-- (void)auth {
- NSString *address = [NSString stringWithFormat:@"https://api.put.io/v2/oauth2/authenticate?client_id=%@&response_type=code&redirect_uri=%@", AppOAuthID, AppOAuthCallback];
- NSURL * url = [NSURL URLWithString:address];
- [webView loadRequest:[NSURLRequest requestWithURL:url]];
-}
-
-- (void)loadAccountSettingsPage {
- NSURL * url = [NSURL URLWithString:PTSettingsURL];
- [webView loadRequest:[NSURLRequest requestWithURL:url]];
-}
-
-- (void)parseForV1Tokens {
- NSString *apiKey = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByClassName('api-key')[0].getElementsByTagName('input')[0].value"];
- NSString *apiSecret = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByClassName('api-key')[0].getElementsByTagName('input')[1].value"];
- if (apiKey && apiSecret) {
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- [defaults setObject:apiKey forKey:APIKeyDefault];
- [defaults setObject:apiSecret forKey:APISecretDefault];
- [defaults synchronize];
-
- [[NSNotificationCenter defaultCenter] postNotificationName:V1TokensWereSavedNotification object:nil userInfo:nil];
- }else{
- NSLog(@"HTML Syntax changed!");
- }
+- (void)authHelperLoginFailedWithDesription:(NSString *)errorDescription {
+ self.warningLabel.text = errorDescription;
}
@end
2  Puttio/Networking/PutIOClient.m
View
@@ -58,7 +58,7 @@ + (NSString *)appendOauthToken:(NSString *)inputURL {
+ (NSString *)appendStreamToken:(NSString *)inputURL {
NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:ORStreamTokenDefault];
- return [NSString stringWithFormat:@"%@/atk/%@", inputURL, token];
+ return [NSString stringWithFormat:@"%@?token=%@", inputURL, token];
}
- (void)getUserInfo:(void(^)(id userInfoObject))onComplete {
1  Puttio/Networking/NetworkConstants.h → Puttio/Networking/PutIONetworkConstants.h
View
@@ -11,5 +11,6 @@ extern NSString *const PTCallbackModified;
extern NSString *const PTRootURL;
extern NSString *const PTFormatOauthTokenURL;
+extern NSString *const PTFormatOauthLoginURL;
extern NSString *const PTFormatOauthURL;
extern NSString *const PTSettingsURL;
2  Puttio/Networking/NetworkConstants.m → Puttio/Networking/PutIONetworkConstants.m
View
@@ -12,6 +12,6 @@
NSString *const PTRootURL = @"https://put.io/";
NSString *const PTFormatOauthTokenURL = @"https://api.put.io/v2/oauth2/access_token?client_id=%@&client_secret=%@&grant_type=%@&redirect_uri=%@&code=%@";
-
+NSString *const PTFormatOauthLoginURL = @"https://api.put.io/v2/oauth2/authenticate?client_id=%@&response_type=code&redirect_uri=%@";
NSString *const PTFormatOauthURL = @"https://api.put.io/v2/oauth2/authenticate?client_id=%@&response_type=code&redirect_uri=%@";
NSString *const PTSettingsURL = @"https://put.io/account/settings";
25 Puttio/Networking/PutIOOAuthHelper.h
View
@@ -0,0 +1,25 @@
+//
+// OAuthController.h
+// Puttio
+//
+// Created by orta therox on 13/05/2012.
+// Copyright (c) 2012 ortatherox.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class PutIOOAuthHelper;
+@protocol PutIOOAuthHelperDelegate <NSObject>
+
+- (void)authHelperDidLogin:(PutIOOAuthHelper *)helper;
+- (void)authHelperLoginFailedWithDesription:(NSString *)errorDescription;
+
+@end
+
+@interface PutIOOAuthHelper : NSObject <UIWebViewDelegate>
+@property (weak, nonatomic) IBOutlet UIWebView *webView;
+@property (weak) IBOutlet NSObject <PutIOOAuthHelperDelegate> *delegate;
+
+- (void)loginWithUsername:(NSString *)username andPassword:(NSString *)password;
+
+@end
131 Puttio/Networking/PutIOOAuthHelper.m
View
@@ -0,0 +1,131 @@
+//
+// OAuthController.m
+// Puttio
+//
+// Created by orta therox on 13/05/2012.
+// Copyright (c) 2012 ortatherox.com. All rights reserved.
+//
+
+#import "PutIOOAuthHelper.h"
+#import "APP_SECRET.h"
+#import "AFNetworking.h"
+#import "PutIONetworkConstants.h"
+
+// http://put.io/v2/docs/#authentication
+
+// The order of this is
+
+// Login in via website in webkit
+// Redirect to the OAuth dialog
+// Make a request to the OAuth authenticate URL ( getAccessTokenFromOauthCode )
+// Load Accounts page and parse out the tokens
+// Then call delegate method.
+
+@implementation PutIOOAuthHelper
+
+@synthesize webView, delegate;
+
+- (void)loginWithUsername:(NSString *)username andPassword:(NSString *)password {
+ webView.delegate = self;
+
+ [self loadAuthPage];
+
+ NSLog(@"%@ %s\n%@", NSStringFromSelector(_cmd), __FILE__, self);
+
+ NSString *setUsername = [NSString stringWithFormat:@"document.getElementsByTagName('input')[0].value = '%@'", username];
+ [webView stringByEvaluatingJavaScriptFromString:setUsername];
+
+ NSString *setPassword = [NSString stringWithFormat:@"document.getElementsByTagName('input')[1].value = '%@'", password];
+ [webView stringByEvaluatingJavaScriptFromString:setPassword];
+
+ [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByTagName('form')[0].submit()"];
+}
+
+- (void)getAccessTokenFromOauthCode:(NSString *)code {
+ // https://api.put.io/v2/oauth2/access_token?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=authorization_code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=CODE
+
+ NSString *address = [NSString stringWithFormat:PTFormatOauthTokenURL, @"10", APP_SECRET, @"authorization_code", PTCallbackOriginal, code];
+
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:address]];
+ AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
+ [self loadAccountSettingsPage];
+
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ [defaults setObject:[JSON valueForKeyPath:@"access_token"] forKey:AppAuthTokenDefault];
+ [defaults synchronize];
+ [[NSNotificationCenter defaultCenter] postNotificationName:OAuthTokenWasSavedNotification object:nil userInfo:nil];
+
+ }failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
+ NSLog(@"error %@", error);
+ }];
+ [operation start];
+}
+
+- (void)loadAuthPage {
+ NSString *address = [NSString stringWithFormat:PTFormatOauthLoginURL, AppOAuthID, AppOAuthCallback];
+ NSURL * url = [NSURL URLWithString:address];
+ [webView loadRequest:[NSURLRequest requestWithURL:url]];
+}
+
+- (void)loadAccountSettingsPage {
+ NSURL * url = [NSURL URLWithString:PTSettingsURL];
+ [webView loadRequest:[NSURLRequest requestWithURL:url]];
+}
+
+- (void)parseForV1Tokens {
+ NSString *apiKey = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByClassName('api-key')[0].getElementsByTagName('input')[0].value"];
+ NSString *apiSecret = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByClassName('api-key')[0].getElementsByTagName('input')[1].value"];
+ if (apiKey && apiSecret) {
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ [defaults setObject:apiKey forKey:APIKeyDefault];
+ [defaults setObject:apiSecret forKey:APISecretDefault];
+ [defaults synchronize];
+
+ }else{
+ NSLog(@"HTML Syntax changed!");
+ }
+
+ [[NSNotificationCenter defaultCenter] postNotificationName:V1TokensWereSavedNotification object:nil userInfo:nil];
+}
+
+#pragma mark -
+#pragma mark Webview delegate methods
+
+- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
+ // after you log in, it redrects to root, we actually want it
+ if ([[request.URL absoluteString] isEqualToString: PTRootURL]) {
+ [self loadAuthPage];
+ return NO;
+ }
+ return YES;
+}
+
+- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
+ if (error.code == 101) {
+ NSString *code = [[error userInfo] objectForKey:@"NSErrorFailingURLStringKey"];
+ NSArray *URLComponents = [code componentsSeparatedByString:@"%3D"];
+
+ if (URLComponents.count > 1 && [code hasPrefix: PTCallbackModified]) {
+ [self getAccessTokenFromOauthCode:[URLComponents objectAtIndex:1]];
+ }
+ }else{
+ if (error.code == 102) {
+ // no-op as the puttio:// url causes both errors 101/102
+ }else if (error.code == -1009) {
+ [self.delegate authHelperLoginFailedWithDesription:@"Your iPad is currently offline."];
+ }else {
+ // actually unexpected
+ NSString *error = [NSString stringWithFormat:@"WebView not acting as expected %@", error];
+ [self.delegate authHelperLoginFailedWithDesription:error];
+ }
+ }
+}
+
+- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
+ if([aWebView.request.URL.absoluteString isEqualToString:PTSettingsURL]){
+ [self parseForV1Tokens];
+ [self.delegate authHelperDidLogin:self];
+ }
+}
+
+@end
8 Puttio/Networking/V2PutIOAPIClient.m
View
@@ -9,6 +9,7 @@
// http://put.io/v2/docs/
#import "V2PutIOAPIClient.h"
+#import "PutIONetworkConstants.h"
#import "ORAppDelegate.h"
#import "NSDictionary+ObjectForKey.h"
#import "APP_SECRET.h"
@@ -127,7 +128,7 @@ - (void)getInfoForFile:(File*)file :(void(^)(id userInfoObject))onComplete {
}
- (void)getMP4InfoForFile:(File*)file :(void(^)(id userInfoObject))onComplete {
- NSString *path = [NSString stringWithFormat:@"/v2/files/%@/mp4-status", file.id];
+ NSString *path = [NSString stringWithFormat:@"/v2/files/%@/mp4", file.id];
[self genericGetAtPath:path :^(id userInfoObject) {
onComplete(userInfoObject);
}];
@@ -156,7 +157,7 @@ - (void)getTransfers :(void(^)(id userInfoObject))onComplete {
}
- (void)requestMP4ForFile:(File*)file {
- NSString *path = [NSString stringWithFormat:@"/v2/files/%@/convert-to-mp4?oauth_token=%@", file.id, self.apiToken];
+ NSString *path = [NSString stringWithFormat:@"/v2/files/%@/mp4?oauth_token=%@", file.id, self.apiToken];
[self postPath:path parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
NSLog(@"request MP4 response %@", json);
@@ -183,6 +184,9 @@ - (void)genericGetAtPath:(NSString *)path :(void(^)(id userInfoObject))onComplet
onComplete(json);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
+ NSLog(@"request %@", operation.request.URL);
+
+ NSLog(@"failure!");
onComplete(error);
}];
}
1  Puttio/Puttio-Prefix.pch
View
@@ -14,7 +14,6 @@
#import <CoreData/CoreData.h>
#import "PutIOClient.h"
#import "Constants.h"
- #import "NetworkConstants.h"
#import "UIColor+PutioColours.h"
#import "NSString+StripHTML.h"
#import "NSManagedObject+ActiveRecord.h"
1  Puttio/Utils/MoviePlayer.m
View
@@ -88,6 +88,7 @@ + (void)streamMovieAtPath:(NSString *)path {
path = [[path componentsSeparatedByString:@"/atk"] objectAtIndex:0];
NSString *address = [PutIOClient appendStreamToken:path];
+ TFLog(@"playing: %@", address);
MPMoviePlayerController *movieController = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:address]];
movieController.controlStyle = MPMovieControlStyleDefault;
movieController.shouldAutoplay = YES;
2  Puttio/Utils/SearchController.m
View
@@ -30,12 +30,12 @@ + (SearchController *)sharedInstance {
}
+ (void)searchForString:(NSString *)query {
+ query = [query stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
[self searchISOHunt:query];
[self searchMininova:query];
}
+ (void)searchISOHunt:(NSString *)query {
-#warning html encode for spaces
NSString *address = [NSString stringWithFormat:@"http://isohunt.com/js/json.php?ihq=%@", query];
NSURL *url = [NSURL URLWithString:address];
1  Puttio/ViewControllers/FileInfoViewController.h
View
@@ -16,6 +16,7 @@
@property (weak, nonatomic) IBOutlet UIButton *downloadButton;
@property (weak, nonatomic) IBOutlet UIImageView *thumbnailImageView;
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
+@property (assign) BOOL hasMP4;
- (IBAction)backButton:(id)sender;
- (IBAction)streamTapped:(id)sender;
103 Puttio/ViewControllers/FileInfoViewController.m
View
@@ -17,11 +17,11 @@
@interface FileInfoViewController() {
File *_item;
- NSString *streamPath;
- NSString *downloadPath;
NSInteger fileSize;
BOOL fileDownloaded;
BOOL stopRefreshing;
+
+ BOOL _hasMP4;
}
@end
@@ -35,6 +35,7 @@ @implementation FileInfoViewController
@synthesize thumbnailImageView;
@synthesize progressView;
@dynamic item;
+@dynamic hasMP4;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
@@ -53,29 +54,22 @@ - (void)setItem:(File *)item {
titleLabel.text = object.displayName;
_item = item;
[thumbnailImageView setImageWithURL:[NSURL URLWithString:[PutIOClient appendOauthToken:object.screenShotURL]]];
- [Analytics event:@"opened %@ content type more info", object.contentType];
- [self getMP4Info];
+ [self getMP4Info];
+
[self getFileInfo];
}
- (void)getFileInfo {
[[PutIOClient sharedClient] getInfoForFile:_item :^(id userInfoObject) {
if (![userInfoObject isMemberOfClass:[NSError class]]) {
-
-// if ([self.item.contentType isEqualToString:@"video/mp4"]) {
-// streamPath = [[userInfoObject valueForKey:@"stream_url"] objectAtIndex:0];
-// downloadPath = [[userInfoObject valueForKeyPath:@"mp4_url"] objectAtIndex:0];
-// }
-
+ NSString *contentType = [[userInfoObject valueForKeyPath:@"content_type"] objectAtIndex:0];
+
titleLabel.text = [[userInfoObject valueForKeyPath:@"name"] objectAtIndex:0];
fileSize = [[[userInfoObject valueForKeyPath:@"size"] objectAtIndex:0] intValue];
fileSizeLabel.text = unitStringFromBytes(fileSize);
- additionalInfoLabel.text = [[userInfoObject valueForKeyPath:@"content_type"] objectAtIndex:0];
-
- streamButton.enabled = !!streamPath;
- downloadButton.enabled = !!downloadPath;
+ additionalInfoLabel.text = contentType;
}
}];
}
@@ -83,31 +77,28 @@ - (void)getFileInfo {
- (void)getMP4Info {
[[PutIOClient sharedClient] getMP4InfoForFile:_item :^(id userInfoObject) {
if (![userInfoObject isMemberOfClass:[NSError class]]) {
- if (![self.item.contentType isEqualToString:@"video/mp4"]) {
- streamPath = [userInfoObject valueForKeyPath:@"mp4.stream_url"];
- downloadPath = [userInfoObject valueForKeyPath:@"mp4.download_url"];
+ NSString *status = [userInfoObject valueForKeyPath:@"mp4.status"];
+
+ self.hasMP4 = NO;
+ if ([status isEqualToString:@"COMPLETED"]) {
+ self.hasMP4 = YES;
+ }
+
+ if ([status isEqualToString:@"NotAvailable"]) {
+ additionalInfoLabel.text = @"Requested an iPad version (this takes a *very* long time.)";
+ [[PutIOClient sharedClient] requestMP4ForFile:_item];
+ [self performSelector:@selector(getMP4Info) withObject:self afterDelay:30];
}
- streamButton.enabled = !!streamPath;
- downloadButton.enabled = !!downloadPath;
-
- if(!streamPath || !downloadPath) {
- NSString *status = [userInfoObject valueForKeyPath:@"mp4.status"];
- if ([status isEqualToString:@"NotAvailable"]) {
- additionalInfoLabel.text = @"Requested an iPad version (this takes a *very* long time.)";
- [[PutIOClient sharedClient] requestMP4ForFile:_item];
- [self performSelector:@selector(getMP4Info) withObject:self afterDelay:30];
+ if ([status isEqualToString:@"CONVERTING"]) {
+ additionalInfoLabel.text = @"Converting to iPad version (this takes a *very* long time.)";
+ if ([userInfoObject valueForKeyPath:@"mp4.percent_done"] != [NSNull null]) {
+ progressView.hidden = NO;
+ progressView.progress = [[userInfoObject valueForKeyPath:@"mp4.percent_done"] floatValue] / 100;
}
- if ([status isEqualToString:@"CONVERTING"]) {
- additionalInfoLabel.text = @"Converting to iPad version (this takes a *very* long time.)";
- if ([userInfoObject valueForKeyPath:@"mp4.percent_done"] != [NSNull null]) {
- progressView.hidden = NO;
- progressView.progress = [[userInfoObject valueForKeyPath:@"mp4.percent_done"] floatValue] / 100;
- }
- if (!stopRefreshing) {
- #warning this loop can run multiple times
- [self performSelector:@selector(getMP4Info) withObject:self afterDelay:1];
- }
+ if (!stopRefreshing) {
+ #warning this loop can run multiple times
+ [self performSelector:@selector(getMP4Info) withObject:self afterDelay:1];
}
}
}
@@ -135,24 +126,18 @@ - (IBAction)backButton:(id)sender {
}
- (IBAction)streamTapped:(id)sender {
- if (streamPath) {
- [MoviePlayer streamMovieAtPath:streamPath];
+ if (_hasMP4) {
+ [MoviePlayer streamMovieAtPath:[NSString stringWithFormat:@"http://put.io/v2/files/%@/mp4/stream", _item.id]];
}
}
- (IBAction)downloadTapped:(id)sender {
- if (!fileDownloaded) {
- if (downloadPath) {
- self.progressView.hidden = NO;
- self.progressView.progress = 0;
- self.additionalInfoLabel.text = @"Downloading";
- self.downloadButton.enabled = NO;
- self.streamButton.enabled = NO;
- [self downloadItem];
- }
- }else{
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"photos:"]];
- }
+ self.progressView.hidden = NO;
+ self.progressView.progress = 0;
+ self.additionalInfoLabel.text = @"Downloading";
+ self.downloadButton.enabled = NO;
+ self.streamButton.enabled = NO;
+ [self downloadItem];
}
- (void)downloadItem {
@@ -160,11 +145,8 @@ - (void)downloadItem {
struct statfs tStats;
statfs([[paths lastObject] cString], &tStats);
uint64_t totalSpace = tStats.f_bavail * tStats.f_bsize;
-
-#warning this should be replaced with the real downloadPath
- NSMutableArray *components = [[downloadPath componentsSeparatedByString:@"/"] mutableCopy];
- [components replaceObjectAtIndex:components.count -1 withObject:_item.id];
- NSString *requestURL = [components componentsJoinedByString:@"/"];
+
+ NSString *requestURL = [NSString stringWithFormat:@"http://put.io/v2/files/%@/mp4/download", _item.id];
if (fileSize < totalSpace) {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[PutIOClient appendOauthToken:requestURL]]];
@@ -175,6 +157,8 @@ - (void)downloadItem {
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
+ additionalInfoLabel.text = @"Moving to Photos app";
+
NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:_item.id];
NSString *fullPath = [NSString stringWithFormat:@"%@.mp4", filePath];
@@ -190,8 +174,7 @@ - (void)downloadItem {
} else {
// TODO: success handling
NSLog(@"success kid");
- self.additionalInfoLabel.text = @"Downloaded - open in Photos";
- self.downloadButton.titleLabel.text = @"Photos!";
+ self.additionalInfoLabel.text = @"Downloaded - it's available in Photos";
fileDownloaded = YES;
}
}];
@@ -205,15 +188,15 @@ - (void)downloadItem {
NSLog(@"mega fail");
NSLog(@"request %@", operation.request.URL);
- self.additionalInfoLabel.text = @"Download failed, oh no!";
+ self.additionalInfoLabel.text = @"Download failed!";
progressView.hidden = YES;
self.downloadButton.enabled = YES;
self.streamButton.enabled = NO;
-
}];
[operation start];
+
}else {
- NSString *message = [NSString stringWithFormat:@"Your iPad doesn't have enough free disk space to sync."];
+ NSString *message = [NSString stringWithFormat:@"Your iPad doesn't have enough free disk space to download."];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Not enough disk space" message:message delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
[alert show];
}
32 Puttio/ViewControllers/SearchViewController.m
View
@@ -35,7 +35,6 @@ - (void)viewDidLoad {
[self stylizeSearchTextField];
[self setupShadow];
[SearchController sharedInstance].delegate = self;
- searchResults = [NSArray array];
}
- (void)viewDidUnload {
@@ -71,13 +70,32 @@ - (void)setupShadow {
layer.shadowRadius = 4;
layer.shadowOpacity = 0.2;
}
+
+#pragma mark -
#pragma mark searchbar gubbins
- (void)searchBarSearchButtonClicked:(UISearchBar *)aSearchBar {
- [SearchController searchForString:aSearchBar.text];
+ [self searchBarTextDidEndEditing:aSearchBar];
+}
+
+- (void)searchBarTextDidEndEditing:(UISearchBar *)aSearchBar {
+ searchResults = [NSArray array];
+ [SearchController searchForString:aSearchBar.text];
+ [self.tableView reloadData];
+}
+
+#pragma mark -
+#pragma mark search controller
+
+- (void)searchController:(SearchController *)controller foundResults:(NSArray *)moreSearchResults {
+ searchResults = [searchResults arrayByAddingObjectsFromArray:moreSearchResults];
+ [self.tableView reloadData];
}
+
+#pragma mark -
#pragma mark tableview gubbins
+
- (int)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
@@ -103,15 +121,5 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa
return 88;
}
-- (void)searchBarTextDidEndEditing:(UISearchBar *)aSearchBar {
- searchResults = [NSArray array];
- [SearchController searchForString:aSearchBar.text];
- [self.tableView reloadData];
-}
-
-- (void)searchController:(SearchController *)controller foundResults:(NSArray *)moreSearchResults {
- searchResults = [searchResults arrayByAddingObjectsFromArray:moreSearchResults];
- [self.tableView reloadData];
-}
@end
1  Puttio/ViewControllers/StatusViewController.h
View
@@ -12,7 +12,6 @@
@interface StatusViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
-@property (weak, nonatomic) IBOutlet ORSimpleProgress *bandwidthProgressView;
@property (weak, nonatomic) IBOutlet ORSimpleProgress *spaceProgressView;
- (void)setup;
@end
8 Puttio/ViewControllers/StatusViewController.m
View
@@ -29,7 +29,6 @@ @implementation StatusViewController
} Display;
@synthesize tableView;
-@synthesize bandwidthProgressView;
@synthesize spaceProgressView;
- (void)setup {
@@ -68,12 +67,8 @@ - (void)getUserInfo {
[[NSUserDefaults standardUserDefaults] setObject:[userInfoObject valueForKeyPath:@"id"] forKey:ORUserIdDefault];
NSString *diskQuotaString = [[userInfoObject valueForKeyPath:@"response.results.disk_quota"] objectAtIndex:0];
NSString *diskQuotaAvailableString = [[userInfoObject valueForKeyPath:@"response.results.disk_quota_available"] objectAtIndex:0];
-
- NSString *bandwidthQuotaString = [[userInfoObject valueForKeyPath:@"response.results.bw_quota"] objectAtIndex:0];
- NSString *bandwidthQuotaAvailableString = [[userInfoObject valueForKeyPath:@"response.results.bw_quota_available"] objectAtIndex:0];
-
+
self.spaceProgressView.progress = [diskQuotaAvailableString longLongValue] / [diskQuotaString longLongValue] ;
- self.bandwidthProgressView.progress = [bandwidthQuotaAvailableString longLongValue] / [bandwidthQuotaString longLongValue];
}
}];
}
@@ -131,7 +126,6 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa
}
- (void)viewDidUnload {
- [self setBandwidthProgressView:nil];
[self setSpaceProgressView:nil];
[self setTableView:nil];
[super viewDidUnload];
129 Puttio/en.lproj/MainStoryboard.storyboard
View
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="1.1" toolsVersion="2182" systemVersion="11D50b" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="TCb-XQ-jcM">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="1.1" toolsVersion="2182" systemVersion="11E53" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="TCb-XQ-jcM">
<dependencies>
<deployment defaultVersion="1296" identifier="iOS"/>
<development defaultVersion="4200" identifier="xcode"/>
@@ -27,28 +27,16 @@
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
- <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Space" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="JVc-iZ-mfQ">
- <rect key="frame" x="30" y="716" width="66" height="36"/>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Space" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="w79-AE-0mt">
+ <rect key="frame" x="85" y="716" width="111" height="36"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="Futura-CondensedMedium" family="Futura" pointSize="28"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
- <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Bandwidth" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="w79-AE-0mt">
- <rect key="frame" x="158" y="716" width="111" height="36"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <fontDescription key="fontDescription" name="Futura-CondensedMedium" family="Futura" pointSize="28"/>
- <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
- <nil key="highlightedColor"/>
- </label>
- <view contentMode="scaleToFill" id="iLk-Zv-WaC" customClass="ORSimpleProgress">
- <rect key="frame" x="30" y="635" width="66" height="73"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <color key="backgroundColor" red="0.42571601269999998" green="0.73212200400000005" blue="1" alpha="1" colorSpace="calibratedRGB"/>
- </view>
<view contentMode="scaleToFill" id="EYi-oQ-Ygh" customClass="ORSimpleProgress">
- <rect key="frame" x="166" y="635" width="66" height="73"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <rect key="frame" x="107" y="635" width="66" height="73"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.42571601269999998" green="0.73212200400000005" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="76" sectionHeaderHeight="22" sectionFooterHeight="22" id="uHV-X3-dFo">
@@ -128,7 +116,7 @@
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="bandwidthProgressView" destination="EYi-oQ-Ygh" id="NAX-gO-wMV"/>
- <outlet property="spaceProgressView" destination="iLk-Zv-WaC" id="rRm-Cg-doo"/>
+ <outlet property="spaceProgressView" destination="EYi-oQ-Ygh" id="hYG-ZV-h1H"/>
<outlet property="tableView" destination="uHV-X3-dFo" id="vh6-6v-36J"/>
</connections>
</viewController>
@@ -425,7 +413,7 @@
</connections>
</viewController>
</objects>
- <point key="canvasLocation" x="-2251" y="-1257"/>
+ <point key="canvasLocation" x="-2222" y="-1169"/>
</scene>
<!--Auth View Controller-->
<scene sceneID="SiC-1L-FYf">
@@ -437,25 +425,102 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<webView contentMode="scaleToFill" id="vzR-Xs-Iu9">
- <rect key="frame" x="0.0" y="0.0" width="1024" height="748"/>
+ <rect key="frame" x="776" y="542" width="235" height="199"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<connections>
- <outlet property="delegate" destination="gND-ap-Oq0" id="SaG-fq-xD7"/>
+ <outlet property="delegate" destination="kuB-Ee-JBF" id="KC9-uR-IRO"/>
</connections>
</webView>
+ <view contentMode="scaleToFill" id="RTs-9t-64d">
+ <rect key="frame" x="260" y="147" width="504" height="455"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <subviews>
+ <view contentMode="scaleToFill" id="itN-bJ-ed3">
+ <rect key="frame" x="20" y="61" width="464" height="374"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <subviews>
+ <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Username" minimumFontSize="17" id="eU6-zT-B2t">
+ <rect key="frame" x="90" y="40" width="284" height="31"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
+ <textInputTraits key="textInputTraits" keyboardType="emailAddress" returnKeyType="go" enablesReturnKeyAutomatically="YES"/>
+ </textField>
+ <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Password" minimumFontSize="17" id="7qr-I8-ulE">
+ <rect key="frame" x="90" y="89" width="284" height="31"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
+ <textInputTraits key="textInputTraits" secureTextEntry="YES"/>
+ </textField>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Huw-f5-DTe">
+ <rect key="frame" x="291" y="143" width="83" height="33"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+ <color key="backgroundColor" red="0.42571601269999998" green="0.73212200400000005" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+ <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
+ <state key="normal" title="Log in">
+ <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <color key="titleShadowColor" white="0.5" alpha="0.0" colorSpace="calibratedWhite"/>
+ </state>
+ <state key="highlighted">
+ <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ </state>
+ <connections>
+ <action selector="backPressed:" destination="u9h-fZ-wfU" eventType="touchUpInside" id="h1d-z4-Xld"/>
+ <action selector="feedbackPressed:" destination="u9h-fZ-wfU" eventType="touchUpInside" id="tf3-vT-fEI"/>
+ <action selector="loginPressed:" destination="gND-ap-Oq0" eventType="touchUpInside" id="oMF-Za-XkE"/>
+ </connections>
+ </button>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumFontSize="10" id="P60-EY-4Xo">
+ <rect key="frame" x="97" y="139" width="187" height="41"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <string key="text">Error
+Message</string>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ </view>
+ <view contentMode="scaleToFill" id="b2f-9e-LRi">
+ <rect key="frame" x="0.0" y="20" width="504" height="44"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <subviews>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Log in to Put.io" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="jZL-kI-4uf">
+ <rect key="frame" x="64" y="4" width="299" height="36"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+ <fontDescription key="fontDescription" name="Futura-CondensedMedium" family="Futura" pointSize="28"/>
+ <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <color key="backgroundColor" red="0.97776401040000005" green="0.92181301120000003" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ </view>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ </view>
</subviews>
- <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ <color key="backgroundColor" red="1" green="1" blue="0.87237682481751821" alpha="1" colorSpace="calibratedRGB"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
</view>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
- <outlet property="webView" destination="vzR-Xs-Iu9" id="rin-xf-Y80"/>
+ <outlet property="authHelper" destination="kuB-Ee-JBF" id="T2o-YW-IMN"/>
+ <outlet property="loginViewWrapper" destination="RTs-9t-64d" id="Qbn-HY-tTk"/>
+ <outlet property="passwordTextfield" destination="7qr-I8-ulE" id="UeA-O1-aYA"/>
+ <outlet property="usernameTextfield" destination="eU6-zT-B2t" id="Jac-y1-Suk"/>
+ <outlet property="warningLabel" destination="P60-EY-4Xo" id="Kw1-bf-PYa"/>
</connections>
</viewController>
+ <customObject id="kuB-Ee-JBF" customClass="PutIOOAuthHelper">
+ <connections>
+ <outlet property="delegate" destination="gND-ap-Oq0" id="01f-hb-rfi"/>
+ <outlet property="webView" destination="vzR-Xs-Iu9" id="ymS-Nw-OXY"/>
+ </connections>
+ </customObject>
</objects>
- <point key="canvasLocation" x="-3422" y="217"/>
+ <point key="canvasLocation" x="-3424" y="457"/>
</scene>
</scenes>
<classes>
@@ -493,8 +558,12 @@
<class className="OAuthViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/OAuthViewController.h"/>
<relationships>
- <relationship kind="action" name="okPressed:"/>
- <relationship kind="outlet" name="webView" candidateClass="UIWebView"/>
+ <relationship kind="action" name="loginPressed:"/>
+ <relationship kind="outlet" name="authHelper" candidateClass="PutIOOAuthHelper"/>
+ <relationship kind="outlet" name="loginViewWrapper" candidateClass="UIView"/>
+ <relationship kind="outlet" name="passwordTextfield" candidateClass="UITextField"/>
+ <relationship kind="outlet" name="usernameTextfield" candidateClass="UITextField"/>
+ <relationship kind="outlet" name="warningLabel" candidateClass="UILabel"/>
</relationships>
</class>
<class className="ORMessageCell" superclassName="UITableViewCell">
@@ -514,6 +583,13 @@
<class className="ORSimpleProgress" superclassName="UIView">
<source key="sourceIdentifier" type="project" relativePath="./Classes/ORSimpleProgress.h"/>
</class>
+ <class className="PutIOOAuthHelper" superclassName="NSObject">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/PutIOOAuthHelper.h"/>
+ <relationships>
+ <relationship kind="outlet" name="delegate" candidateClass="NSObject"/>
+ <relationship kind="outlet" name="webView" candidateClass="UIWebView"/>
+ </relationships>
+ </class>
<class className="RootViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/RootViewController.h"/>
<relationships>
@@ -530,7 +606,6 @@
<class className="StatusViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/StatusViewController.h"/>
<relationships>
- <relationship kind="outlet" name="bandwidthProgressView" candidateClass="ORSimpleProgress"/>
<relationship kind="outlet" name="spaceProgressView" candidateClass="ORSimpleProgress"/>
<relationship kind="outlet" name="tableView" candidateClass="UITableView"/>
</relationships>
3  Puttio/main.m
View
@@ -10,8 +10,7 @@
#import "ORAppDelegate.h"
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([ORAppDelegate class]));
}

No commit comments for this range

Something went wrong with that request. Please try again.