VoiceMac/Classes/VoiceBase/MGMInstance.m

959 lines
42 KiB
Mathematica
Raw Normal View History

2010-09-20 19:44:17 -05:00
//
// MGMInstance.m
// VoiceBase
//
// Created by Mr. Gecko on 8/15/10.
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2010-09-20 19:44:17 -05:00
//
#import "MGMInstance.h"
#import "MGMDelegateInfo.h"
2010-09-20 19:44:17 -05:00
#import "MGMInbox.h"
#import "MGMContacts.h"
#import "MGMAddressBook.h"
#import "MGMAddons.h"
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
#import "MGMXML.h"
2010-09-20 19:44:17 -05:00
#import <MGMUsers/MGMUsers.h>
NSString * const MGMVoiceBaseCopyright = @"Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/";
2010-09-20 19:44:17 -05:00
NSString * const MGMVoiceIndexURL = @"https://www.google.com/voice/";
NSString * const MGMLoginURL = @"https://accounts.google.com/ServiceLoginAuth";
2010-09-20 19:44:17 -05:00
NSString * const MGMXPCPath = @"/voice/xpc/?xpc=%7B%22cn%22%3A%22i70avDIMsA%22%2C%22tp%22%3Anull%2C%22pru%22%3A%22https%3A%2F%2Fwww.google.com%2Fvoice%2Fxpc%2Frelay%22%2C%22ppu%22%3A%22https%3A%2F%2Fwww.google.com%2Fvoice%2Fxpc%2Fblank%2F%22%2C%22lpu%22%3A%22https%3A%2F%2Fclients4.google.com%2Fvoice%2Fxpc%2Fblank%2F%22%7D";
NSString * const MGMCheckPath = @"/voice/xpc/checkMessages?r=%@";
NSString * const MGMCreditURL = @"https://www.google.com/voice/settings/billingcredit/";
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
NSString * const MGMPhonesURL = @"https://www.google.com/voice/settings/tab/phones";
2010-09-20 19:44:17 -05:00
NSString * const MGMCallURL = @"https://www.google.com/voice/call/connect/";
NSString * const MGMCallCancelURL = @"https://www.google.com/voice/call/cancel/";
NSString * const MGMPostMethod = @"POST";
NSString * const MGMURLForm = @"application/x-www-form-urlencoded";
NSString * const MGMContentType = @"content-type";
NSString * const MGMPhoneNumber = @"phoneNumber";
NSString * const MGMPhone = @"phone";
NSString * const MGMName = @"name";
NSString * const MGMType = @"type";
NSString * const MGMSContactsSourceKey = @"MGMContactsSource";
NSString * const MGMSContactsActionKey = @"MGMContactsAction";
NSString * const MGMUCAll = @"all";
NSString * const MGMUCInbox = @"inbox";
NSString * const MGMUCMissed = @"missed";
NSString * const MGMUCPlaced = @"placed";
NSString * const MGMUCReceived = @"received";
NSString * const MGMUCRecorded = @"recorded";
NSString * const MGMUCSMS = @"sms";
NSString * const MGMUCSpam = @"spam";
NSString * const MGMUCStarred = @"starred";
NSString * const MGMUCTrash = @"trash";
NSString * const MGMUCUnread = @"unread";
NSString * const MGMUCVoicemail = @"voicemail";
const BOOL MGMInstanceInvisible = YES;
@implementation MGMInstance
+ (id)instanceWithUser:(MGMUser *)theUser delegate:(id)theDelegate {
return [[[self alloc] initWithUser:theUser delegate:theDelegate isCheck:NO] autorelease];
}
+ (id)instanceWithUser:(MGMUser *)theUser delegate:(id)theDelegate isCheck:(BOOL)isCheck {
return [[[self alloc] initWithUser:theUser delegate:theDelegate isCheck:isCheck] autorelease];
}
- (id)initWithUser:(MGMUser *)theUser delegate:(id)theDelegate isCheck:(BOOL)isCheck {
if ((self = [super init])) {
2010-09-20 19:44:17 -05:00
checkingAccount = isCheck;
loggedIn = NO;
webLoginTries = 0;
delegate = theDelegate;
user = [theUser retain];
cookeStorage = [[theUser cookieStorage] retain];
connectionManager = [[MGMURLConnectionManager managerWithCookieStorage:cookeStorage] retain];
[self registerSettings];
inbox = [[MGMInbox inboxWithInstance:self] retain];
if (!checkingAccount)
contacts = [[MGMContacts contactsWithClass:NSClassFromString([user settingForKey:MGMSContactsSourceKey]) delegate:self] retain];
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:MGMVoiceIndexURL]] delegate:self];
[handler setFailWithError:@selector(index:didFailWithError:)];
[handler setFinish:@selector(indexDidFinish:)];
[handler setInvisible:MGMInstanceInvisible];
[connectionManager addHandler:handler];
2010-09-20 19:44:17 -05:00
}
return self;
}
- (void)dealloc {
[connectionManager cancelAll];
[connectionManager release];
[user release];
[cookeStorage release];
[inbox release];
[contacts release];
[XPCURL release];
[XPCCD release];
[rnr_se release];
[userName release];
[userNumber release];
[userAreacode release];
[userPhoneNumbers release];
[checkTimer invalidate];
[checkTimer release];
checkTimer = nil;
[unreadCounts release];
[creditTimer invalidate];
[creditTimer release];
creditTimer = nil;
2010-09-20 19:44:17 -05:00
[super dealloc];
}
- (NSString *)description {
return [NSString stringWithFormat:@"%@ Number: %@ Account: %@", [super description], userNumber, userName];
}
- (void)stop {
if (!checkingAccount)
[contacts stop];
[inbox stop];
[connectionManager cancelAll];
[checkTimer invalidate];
[checkTimer release];
checkTimer = nil;
[creditTimer invalidate];
[creditTimer release];
creditTimer = nil;
2010-09-20 19:44:17 -05:00
}
- (void)registerSettings {
NSMutableDictionary *settings = [NSMutableDictionary dictionary];
[settings setObject:NSStringFromClass([MGMAddressBook class]) forKey:MGMSContactsSourceKey];
[settings setObject:[NSNumber numberWithInt:0] forKey:MGMSContactsActionKey];
[user registerSettings:settings];
}
- (void)setDelegate:(id)theDelegate {
delegate = theDelegate;
}
- (id<MGMInstanceDelegate>)delegate {
return delegate;
}
- (MGMUser *)user {
return user;
}
- (MGMHTTPCookieStorage *)cookieStorage {
return cookeStorage;
}
- (MGMURLConnectionManager *)connectionManager {
return connectionManager;
}
- (MGMInbox *)inbox {
return inbox;
}
- (MGMContacts *)contacts {
return contacts;
}
- (void)updatedContacts {
if (delegate!=nil && [delegate respondsToSelector:@selector(updatedContacts)]) [delegate updatedContacts];
2010-09-20 19:44:17 -05:00
}
- (NSString *)XPCURL {
return XPCURL;
}
- (NSString *)XPCCD {
return XPCCD;
}
- (NSString *)rnr_se {
return rnr_se;
}
- (NSString *)userName {
return userName;
}
- (NSString *)userNumber {
return userNumber;
}
- (NSString *)userAreaCode {
return userAreacode;
}
- (NSString *)areaCode {
return userAreacode;
}
- (NSArray *)userPhoneNumbers {
return userPhoneNumbers;
}
- (NSDictionary *)unreadCounts {
return unreadCounts;
}
- (void)index:(MGMURLBasicHandler *)theHandler didFailWithError:(NSError *)theError {
if (delegate!=nil && [delegate respondsToSelector:@selector(loginError:)]) {
2010-09-20 19:44:17 -05:00
[delegate loginError:theError];
} else {
NSLog(@"Login Error: %@", theError);
}
}
- (void)indexDidFinish:(MGMURLBasicHandler *)theHandler {
NSString *returnedString = [theHandler string];
if ([returnedString containsString:@"<title>Redirecting</title>"]) {
NSRange range;
NSString *redirectURL = MGMVoiceIndexURL;
range = [returnedString rangeOfString:@"http-equiv="];
if (range.location!=NSNotFound) {
NSString *string = [returnedString substringFromIndex:range.location + range.length];
range = [string rangeOfString:@"url="];
if (range.location==NSNotFound) {
NSLog(@"failed 683476");
} else {
string = [string substringFromIndex:range.location + range.length];
range = [string rangeOfString:@"\""];
if (range.location==NSNotFound) {
range = [string rangeOfString:@"'"];
}
if (range.location==NSNotFound) {
NSLog(@"failed 683476");
} else {
string = [string substringWithRange:NSMakeRange(0, range.location)];
string = [string flattenHTML];
string = [string replace:@"\"" with:@""];
string = [string replace:@"'" with:@""];
//string = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
redirectURL = [string replace:@"&amp;amp;" with:@"&"];
}
}
}
//NSLog(@"Redirecting to %@", redirectURL);
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:redirectURL]] delegate:self];
[handler setFailWithError:@selector(index:didFailWithError:)];
[handler setFinish:@selector(indexDidFinish:)];
[handler setInvisible:MGMInstanceInvisible];
[connectionManager addHandler:handler];
} else if ([returnedString containsString:@"verification code"]) {
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
[verificationParameters release];
verificationParameters = [NSMutableDictionary new];
NSRange formRange = [returnedString rangeOfString:@"<form"];
NSRange formEndRange = [returnedString rangeOfString:@"</form>"];
if (formRange.location==NSNotFound || formEndRange.location==NSNotFound) {
NSError *error = [NSError errorWithDomain:@"com.MrGeckosMedia.MGMInstance.Login" code:56 userInfo:[NSDictionary dictionaryWithObject:@"Unable to login. There is a bug with 2 step verification." forKey:NSLocalizedDescriptionKey]];
if (delegate!=nil && [delegate respondsToSelector:@selector(loginError:)]) {
[delegate loginError:error];
} else {
NSLog(@"Login Error: %@", error);
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
}
return;
}
NSString *form = [returnedString substringWithRange:NSMakeRange(formRange.location, (formEndRange.location+formEndRange.length)-formRange.location)];
NSString *loginURL = [@"" retain];
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSRange actionRange = [form rangeOfString:@"action="];
if (actionRange.location!=NSNotFound) {
NSString *end = [form substringWithRange:NSMakeRange(actionRange.location+actionRange.length, 1)];
actionRange.location += 1;
NSString *string = [form substringFromIndex:actionRange.location+actionRange.length];
actionRange = [string rangeOfString:end];
[loginURL release];
loginURL = [[string substringWithRange:NSMakeRange(0, actionRange.location)] copy];
}
[pool drain];
[verificationURL release];
verificationURL = [[NSURL URLWithString:loginURL relativeToURL:[[theHandler response] URL]] retain];
[loginURL release];
NSRange range = NSMakeRange(0, [form length]);
while (range.length>1) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSRange inputRange = [form rangeOfString:@"<input " options:NSCaseInsensitiveSearch range:range];
if (inputRange.location!=NSNotFound) {
range.location = inputRange.location+inputRange.length;
range.length = [form length]-range.location;
NSRange endInputRange = [form rangeOfString:@">" options:NSCaseInsensitiveSearch range:range];
if (endInputRange.location==NSNotFound)
endInputRange.length = range.length;
else
endInputRange.length = endInputRange.location-range.location;
endInputRange.location = range.location;
NSRange nameRange = [form rangeOfString:@"name=" options:NSCaseInsensitiveSearch range:endInputRange];
if (nameRange.location==NSNotFound)
continue;
NSString *end = [form substringWithRange:NSMakeRange(nameRange.location+nameRange.length, 1)];
nameRange.location += 1;
NSRange endRange = nameRange;
endRange.location = nameRange.location+nameRange.length;
endRange.length = [form length]-endRange.location;
endRange = [form rangeOfString:end options:NSCaseInsensitiveSearch range:endRange];
if (endRange.location==NSNotFound)
continue;
NSString *name = [form substringWithRange:NSMakeRange(nameRange.location+nameRange.length, endRange.location-(nameRange.location+nameRange.length))];
range.location = inputRange.location+inputRange.length;
range.length = [form length]-range.location;
NSRange valueRange = [form rangeOfString:@"value=" options:NSCaseInsensitiveSearch range:endInputRange];
if (valueRange.location==NSNotFound)
continue;
end = [form substringWithRange:NSMakeRange(valueRange.location+valueRange.length, 1)];
valueRange.location += 1;
endRange = valueRange;
endRange.location = valueRange.location+valueRange.length;
endRange.length = [form length]-endRange.location;
endRange = [form rangeOfString:end options:NSCaseInsensitiveSearch range:endRange];
if (endRange.location==NSNotFound)
continue;
NSString *value = [form substringWithRange:NSMakeRange(valueRange.location+valueRange.length, endRange.location-(valueRange.location+valueRange.length))];
[verificationParameters setObject:value forKey:name];
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
} else {
break;
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
}
[pool drain];
}
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
if ([delegate respondsToSelector:@selector(loginVerificationRequested)]) {
#if MGMInstanceDebug
NSLog(@"%@", verificationParameters);
#endif
[delegate loginVerificationRequested];
} else {
NSError *error = [NSError errorWithDomain:@"com.MrGeckosMedia.MGMInstance.Login" code:54 userInfo:[NSDictionary dictionaryWithObject:@"Unable to login. The application does not implument with 2 step verification." forKey:NSLocalizedDescriptionKey]];
if (delegate!=nil && [delegate respondsToSelector:@selector(loginError:)]) {
[delegate loginError:error];
} else {
NSLog(@"Login Error: %@", error);
}
return;
}
} else if ([returnedString containsString:@"onload=\"autoSubmit()\""]) {
NSRange actionRange = [returnedString rangeOfString:@"<form"];
NSString *loginURL = [MGMLoginURL copy];
if (actionRange.location!=NSNotFound) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSString *string = [returnedString substringFromIndex:actionRange.location+actionRange.length];
actionRange = [string rangeOfString:@"action="];
if (actionRange.location!=NSNotFound) {
NSString *end = [string substringWithRange:NSMakeRange(actionRange.location+actionRange.length, 1)];
actionRange.location += 1;
string = [string substringFromIndex:actionRange.location+actionRange.length];
actionRange = [string rangeOfString:end];
[loginURL release];
loginURL = [[string substringWithRange:NSMakeRange(0, actionRange.location)] copy];
}
[pool drain];
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:loginURL]];
[loginURL release];
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
[request setHTTPMethod:MGMPostMethod];
[request setValue:MGMURLForm forHTTPHeaderField:MGMContentType];
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
NSRange range = NSMakeRange(0, [returnedString length]);
while (range.length>1) {
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSRange inputRange = [returnedString rangeOfString:@"<input " options:NSCaseInsensitiveSearch range:range];
if (inputRange.location!=NSNotFound) {
range.location = inputRange.location+inputRange.length;
range.length = [returnedString length]-range.location;
NSRange endInputRange = [returnedString rangeOfString:@">" options:NSCaseInsensitiveSearch range:range];
if (endInputRange.location==NSNotFound)
endInputRange.length = range.length;
else
endInputRange.length = endInputRange.location-range.location;
endInputRange.location = range.location;
NSRange nameRange = [returnedString rangeOfString:@"name=" options:NSCaseInsensitiveSearch range:endInputRange];
if (nameRange.location==NSNotFound)
continue;
NSString *end = [returnedString substringWithRange:NSMakeRange(nameRange.location+nameRange.length, 1)];
nameRange.location += 1;
NSRange endRange = nameRange;
endRange.location = nameRange.location+nameRange.length;
endRange.length = [returnedString length]-endRange.location;
endRange = [returnedString rangeOfString:end options:NSCaseInsensitiveSearch range:endRange];
if (endRange.location==NSNotFound)
continue;
NSString *name = [returnedString substringWithRange:NSMakeRange(nameRange.location+nameRange.length, endRange.location-(nameRange.location+nameRange.length))];
range.location = inputRange.location+inputRange.length;
range.length = [returnedString length]-range.location;
NSRange valueRange = [returnedString rangeOfString:@"value=" options:NSCaseInsensitiveSearch range:endInputRange];
if (valueRange.location==NSNotFound)
continue;
end = [returnedString substringWithRange:NSMakeRange(valueRange.location+valueRange.length, 1)];
valueRange.location += 1;
endRange = valueRange;
endRange.location = valueRange.location+valueRange.length;
endRange.length = [returnedString length]-endRange.location;
endRange = [returnedString rangeOfString:end options:NSCaseInsensitiveSearch range:endRange];
if (endRange.location==NSNotFound)
continue;
NSString *value = [returnedString substringWithRange:NSMakeRange(valueRange.location+valueRange.length, endRange.location-(valueRange.location+valueRange.length))];
[parameters setObject:value forKey:name];
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
} else {
break;
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
}
[pool drain];
}
#if MGMInstanceDebug
NSLog(@"%@", parameters);
#endif
NSArray *parametersKeys = [parameters allKeys];
NSMutableString *bodyString = [NSMutableString string];
for (int i=0; i<[parametersKeys count]; i++) {
if (i!=0)
[bodyString appendString:@"&"];
[bodyString appendFormat:@"%@=%@", [[parametersKeys objectAtIndex:i] addPercentEscapes], [[parameters objectForKey:[parametersKeys objectAtIndex:i]] addPercentEscapes]];
}
[request setHTTPBody:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:request delegate:self];
[handler setFailWithError:@selector(index:didFailWithError:)];
[handler setFinish:@selector(indexDidFinish:)];
[handler setInvisible:MGMInstanceInvisible];
[connectionManager addHandler:handler];
} else if ([returnedString containsString:@"id=\"gaia_loginform\""]) {
2010-09-20 19:44:17 -05:00
if (webLoginTries>2) {
NSError *error = [NSError errorWithDomain:@"com.MrGeckosMedia.MGMInstance.Login" code:1 userInfo:[NSDictionary dictionaryWithObject:@"Unable to login. Please check your Credentials." forKey:NSLocalizedDescriptionKey]];
if (delegate!=nil && [delegate respondsToSelector:@selector(loginError:)]) {
2010-09-20 19:44:17 -05:00
[delegate loginError:error];
} else {
NSLog(@"Login Error: %@", error);
}
return;
}
webLoginTries++;
NSRange actionRange = [returnedString rangeOfString:@"<form"];
NSString *loginURL = [MGMLoginURL copy];
if (actionRange.location!=NSNotFound) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSString *string = [returnedString substringFromIndex:actionRange.location+actionRange.length];
actionRange = [string rangeOfString:@"action="];
if (actionRange.location!=NSNotFound) {
NSString *end = [string substringWithRange:NSMakeRange(actionRange.location+actionRange.length, 1)];
actionRange.location += 1;
string = [string substringFromIndex:actionRange.location+actionRange.length];
actionRange = [string rangeOfString:end];
[loginURL release];
loginURL = [[string substringWithRange:NSMakeRange(0, actionRange.location)] copy];
}
[pool drain];
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:loginURL]];
[loginURL release];
[request setHTTPMethod:MGMPostMethod];
[request setValue:MGMURLForm forHTTPHeaderField:MGMContentType];
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
NSRange range = NSMakeRange(0, [returnedString length]);
while (range.length>1) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSRange inputRange = [returnedString rangeOfString:@"<input " options:NSCaseInsensitiveSearch range:range];
if (inputRange.location!=NSNotFound) {
range.location = inputRange.location+inputRange.length;
range.length = [returnedString length]-range.location;
NSRange endInputRange = [returnedString rangeOfString:@">" options:NSCaseInsensitiveSearch range:range];
if (endInputRange.location==NSNotFound)
endInputRange.length = range.length;
else
endInputRange.length = endInputRange.location-range.location;
endInputRange.location = range.location;
NSRange nameRange = [returnedString rangeOfString:@"name=" options:NSCaseInsensitiveSearch range:endInputRange];
if (nameRange.location==NSNotFound)
continue;
NSString *end = [returnedString substringWithRange:NSMakeRange(nameRange.location+nameRange.length, 1)];
nameRange.location += 1;
NSRange endRange = nameRange;
endRange.location = nameRange.location+nameRange.length;
endRange.length = [returnedString length]-endRange.location;
endRange = [returnedString rangeOfString:end options:NSCaseInsensitiveSearch range:endRange];
if (endRange.location==NSNotFound)
continue;
NSString *name = [returnedString substringWithRange:NSMakeRange(nameRange.location+nameRange.length, endRange.location-(nameRange.location+nameRange.length))];
range.location = inputRange.location+inputRange.length;
range.length = [returnedString length]-range.location;
NSRange valueRange = [returnedString rangeOfString:@"value=" options:NSCaseInsensitiveSearch range:endInputRange];
if (valueRange.location==NSNotFound)
continue;
end = [returnedString substringWithRange:NSMakeRange(valueRange.location+valueRange.length, 1)];
valueRange.location += 1;
endRange = valueRange;
endRange.location = valueRange.location+valueRange.length;
endRange.length = [returnedString length]-endRange.location;
endRange = [returnedString rangeOfString:end options:NSCaseInsensitiveSearch range:endRange];
if (endRange.location==NSNotFound)
continue;
NSString *value = [returnedString substringWithRange:NSMakeRange(valueRange.location+valueRange.length, endRange.location-(valueRange.location+valueRange.length))];
[parameters setObject:value forKey:name];
} else {
break;
}
[pool drain];
2010-09-20 19:44:17 -05:00
}
if ([parameters objectForKey:@"PersistentCookie"]!=nil)
[parameters setObject:@"yes" forKey:@"PersistentCookie"];
if ([[parameters objectForKey:@"Email"] isEqual:@""])
[parameters setObject:(webLoginTries==2 ? [[user settingForKey:MGMUserName] stringByAppendingString:@"@gmail.com"] : [user settingForKey:MGMUserName]) forKey:@"Email"];
#if MGMInstanceDebug
NSLog(@"%@", parameters);
#endif
[parameters setObject:[user password] forKey:@"Passwd"];
NSArray *parametersKeys = [parameters allKeys];
NSMutableString *bodyString = [NSMutableString string];
for (int i=0; i<[parametersKeys count]; i++) {
if (i!=0)
[bodyString appendString:@"&"];
[bodyString appendFormat:@"%@=%@", [[parametersKeys objectAtIndex:i] addPercentEscapes], [[parameters objectForKey:[parametersKeys objectAtIndex:i]] addPercentEscapes]];
}
[request setHTTPBody:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:request delegate:self];
[handler setFailWithError:@selector(index:didFailWithError:)];
[handler setFinish:@selector(indexDidFinish:)];
[handler setInvisible:MGMInstanceInvisible];
[connectionManager addHandler:handler];
} else if ([[[[theHandler request] URL] relativeString] containsString:@"NewPrivacyPolicy"]) {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://accounts.google.com/b/0/NewPrivacyPolicy"]];
[request setHTTPMethod:MGMPostMethod];
[request setValue:MGMURLForm forHTTPHeaderField:MGMContentType];
[request setHTTPBody:[@"service=grandcentral&continue=https://www.google.com/voice&submitbutton=OK,%20got%20it" dataUsingEncoding:NSUTF8StringEncoding]];
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:request delegate:self];
[handler setFailWithError:@selector(index:didFailWithError:)];
[handler setFinish:@selector(indexDidFinish:)];
[handler setInvisible:MGMInstanceInvisible];
[connectionManager addHandler:handler];
} else {
NSString *string, *guser = @"", *phonesInfo = @"";
2010-09-20 19:44:17 -05:00
NSRange range;
#if MGMInstanceDebug
NSLog(@"Parsing rnr_se");
#endif
range = [returnedString rangeOfString:@"'_rnr_se': '"];
if (range.location!=NSNotFound) {
string = [returnedString substringFromIndex:range.location+range.length];
range = [string rangeOfString:@"',"];
if (range.location==NSNotFound) {
NSLog(@"failed 0001");
} else {
[rnr_se release];
2010-09-20 19:44:17 -05:00
rnr_se = [[[string substringWithRange:NSMakeRange(0, range.location)] addPercentEscapes] copy];
}
}
#if MGMInstanceDebug
NSLog(@"rnr_se = %@", rnr_se);
NSLog(@"Parsing Right Header");
#endif
range = [returnedString rangeOfString:@"<div id=guser"];
if (range.location!=NSNotFound) {
string = [returnedString substringFromIndex:range.location+range.length];
range = [string rangeOfString:@">"];
if (range.location==NSNotFound) {
NSLog(@"failed 0002");
} else {
string = [string substringFromIndex:range.location+range.length];
range = [string rangeOfString:@"</div>"];
if (range.location==NSNotFound) {
NSLog(@"failed 0002.1");
} else {
guser = [string substringWithRange:NSMakeRange(0, range.location)];
}
}
}
#if MGMInstanceDebug
NSLog(@"Parsing User Name");
#endif
range = [guser rangeOfString:@"<b"];
if (range.location!=NSNotFound) {
string = [guser substringFromIndex:range.location+range.length];
range = [string rangeOfString:@">"];
if (range.location==NSNotFound) {
NSLog(@"failed 0003");
} else {
string = [string substringFromIndex:range.location+range.length];
range = [string rangeOfString:@"</b>"];
if (range.location==NSNotFound) {
NSLog(@"failed 0003.1");
} else {
[userName release];
2010-09-20 19:44:17 -05:00
userName = [[string substringWithRange:NSMakeRange(0, range.location)] copy];
}
}
}
#if MGMInstanceDebug
NSLog(@"User Name = %@", userName);
NSLog(@"Parsing Google Number Header");
#endif
range = [returnedString rangeOfString:@"gc-header-info"];
if (range.location!=NSNotFound) {
string = [returnedString substringFromIndex:range.location+range.length];
range = [string rangeOfString:@">"];
if (range.location==NSNotFound) {
NSLog(@"failed 0002");
} else {
string = [string substringFromIndex:range.location+range.length];
range = [string rangeOfString:@"</div>"];
if (range.location==NSNotFound) {
NSLog(@"failed 0002.1");
} else {
guser = [string substringWithRange:NSMakeRange(0, range.location)];
}
}
}
#if MGMInstanceDebug
NSLog(@"Parsing Google Number");
#endif
range = [guser rangeOfString:@"href=\"#phones\""];
if (range.location!=NSNotFound) {
string = [guser substringFromIndex:range.location+range.length];
range = [string rangeOfString:@">"];
if (range.location==NSNotFound) {
NSLog(@"failed 0004");
} else {
string = [string substringFromIndex:range.location+range.length];
range = [string rangeOfString:@"</a>"];
if (range.location==NSNotFound) {
NSLog(@"failed 0004.1");
} else {
[userNumber release];
2010-09-20 19:44:17 -05:00
userNumber = [[[string substringWithRange:NSMakeRange(0, range.location)] phoneFormat] copy];
}
}
}
if ([returnedString containsString:@"cookie functionality"]) {
NSError *error = [NSError errorWithDomain:@"com.MrGeckosMedia.MGMInstance.Login" code:3 userInfo:[NSDictionary dictionaryWithObject:@"There is a problem with VoiceMac's Cookie system, please contact the developer via the help menu." forKey:NSLocalizedDescriptionKey]];
if (delegate!=nil && [delegate respondsToSelector:@selector(loginError:)]) {
[delegate loginError:error];
} else {
NSLog(@"Login Error: %@", error);
}
return;
} else if (![returnedString containsString:@"gc-header-did-display"] && ![userNumber isPhoneComplete]) {
2010-09-20 19:44:17 -05:00
NSError *error = [NSError errorWithDomain:@"com.MrGeckosMedia.MGMInstance.Login" code:2 userInfo:[NSDictionary dictionaryWithObject:@"Your Google Account does not appear to have a Google Number, please visit voice.google.com and setup one before continuing." forKey:NSLocalizedDescriptionKey]];
if (delegate!=nil && [delegate respondsToSelector:@selector(loginError:)]) {
2010-09-20 19:44:17 -05:00
[delegate loginError:error];
} else {
NSLog(@"Login Error: %@", error);
}
return;
}
[userAreacode release];
2010-09-20 19:44:17 -05:00
userAreacode = [[userNumber areaCode] copy];
#if MGMInstanceDebug
NSLog(@"Google Number = %@", userNumber);
NSLog(@"Areacode = %@", userAreacode);
NSLog(@"Parsing User Phones");
#endif
range = [returnedString rangeOfString:@"'phones': "];
if (range.location!=NSNotFound) {
string = [returnedString substringFromIndex:range.location+range.length];
range = [string rangeOfString:@",\n"];
if (range.location==NSNotFound) {
NSLog(@"failed 0005");
} else {
phonesInfo = [string substringWithRange:NSMakeRange(0, range.location)];
}
}
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
[self parseUserPhones:[phonesInfo parseJSON]];
2010-09-20 19:44:17 -05:00
#if MGMInstanceDebug
NSLog(@"User Phones = %@", userPhoneNumbers);
NSLog(@"Parsing XPCURL");
#endif
range = [returnedString rangeOfString:@"'xpcUrl': '"];
if (range.location!=NSNotFound) {
string = [returnedString substringFromIndex:range.location+range.length];
range = [string rangeOfString:@"'"];
if (range.location==NSNotFound) {
NSLog(@"failed 0008");
} else {
[XPCURL release];
2010-09-20 19:44:17 -05:00
XPCURL = [[string substringWithRange:NSMakeRange(0, range.location)] copy];
}
}
#if MGMInstanceDebug
NSLog(@"XPCURL = %@", XPCURL);
#endif
loggedIn = YES;
if (!checkingAccount) {
[contacts updateContacts];
[checkTimer invalidate];
[checkTimer release];
2010-09-20 19:44:17 -05:00
checkTimer = [[NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:@selector(checkTimer) userInfo:nil repeats:YES] retain];
[checkTimer fire];
[creditTimer invalidate];
[creditTimer release];
2010-09-20 19:44:17 -05:00
creditTimer = [[NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(creditTimer) userInfo:nil repeats:YES] retain];
[creditTimer fire];
}
if (delegate!=nil && [delegate respondsToSelector:@selector(loginSuccessful)]) [delegate loginSuccessful];
2010-09-20 19:44:17 -05:00
}
}
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
- (void)cancelVerification {
[verificationParameters release];
verificationParameters = nil;
NSError *error = [NSError errorWithDomain:@"com.MrGeckosMedia.MGMInstance.Login" code:54 userInfo:[NSDictionary dictionaryWithObject:@"Unable to login. Verification was canceled." forKey:NSLocalizedDescriptionKey]];
if (delegate!=nil && [delegate respondsToSelector:@selector(loginError:)]) {
[delegate loginError:error];
} else {
NSLog(@"Login Error: %@", error);
}
}
- (void)verifyWithCode:(NSString *)theCode {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:verificationURL];
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
[request setHTTPMethod:MGMPostMethod];
[request setValue:MGMURLForm forHTTPHeaderField:MGMContentType];
[verificationParameters setObject:theCode forKey:@"smsUserPin"];
[verificationParameters setObject:@"1" forKey:@"pstMsg"];
[verificationParameters removeObjectForKey:@"retry"];
[verificationParameters removeObjectForKey:@"smsSend"];
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
NSArray *parametersKeys = [verificationParameters allKeys];
NSMutableString *bodyString = [NSMutableString string];
for (int i=0; i<[parametersKeys count]; i++) {
if (i!=0)
[bodyString appendString:@"&"];
[bodyString appendFormat:@"%@=%@", [[parametersKeys objectAtIndex:i] addPercentEscapes], [[verificationParameters objectForKey:[parametersKeys objectAtIndex:i]] addPercentEscapes]];
}
[request setHTTPBody:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:request delegate:self];
[handler setFailWithError:@selector(index:didFailWithError:)];
[handler setFinish:@selector(indexDidFinish:)];
[handler setInvisible:MGMInstanceInvisible];
[connectionManager addHandler:handler];
[verificationParameters release];
verificationParameters = nil;
}
2010-09-20 19:44:17 -05:00
- (BOOL)isLoggedIn {
return loggedIn;
}
Added support for iPhone to MGMFFmpeg. Updated settings in Theme Tester. Updated settings in VoiceMac for the Theme Manager. Added the ability to hide icons in themes. Added the ability to change the font in themes. Fixed issue in MGMAddressBook where getting group members is not accurate. Made it so SIP addresses and Email addresses would not be recognized as phone numbers. Added support for 2 step verification. Added the ability to reload the user phone numbers. Added the ability to place the next message at any point in the previous message. Added the ability to do css based on the class of the message view with %MESSAGECLASSES%. Added the ability to get the codecs available and change the top codec in MGMSIP. Made it stop ring back before hanging up. Added initWithRootElement: to MGMXMLDocument. Added initWithName: and initWithName:stringValue: to MGMXMLElement. Added initWithKind:, setStringValue:, and fixed issues with reading attributes value. Made MGMVoiceUser support 2 step verification API, reload the user phones when it becomes active, and display a message if there is no phone numbers in Google Voice. Fixed issue where Google Chat will not appear in the User Phones list. Added a 2 Step Verification Dialog. Added Codec selection in MGMSIPPane. Fixed issues with MGMMultiSMS where it wouldn't alert the user if the message was blank and it wouldn't make the text field non editable. Added support for new SMS protocol to MGMSMSMessageView. Added support in the FFmpeg install script to build for iOS. Added ability to compile for the Simulator only in the PJProject build script. Made iOS and Mac OS final path go to 2 different folders. Updated to Revision 3466 of PJProject.
2011-03-21 07:43:56 -05:00
- (void)checkPhones {
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:MGMPhonesURL]] delegate:self];
[handler setFinish:@selector(phonesFinished:)];
[handler setInvisible:MGMInstanceInvisible];
[connectionManager addHandler:handler];
}
- (void)phonesFinished:(MGMURLBasicHandler *)theHandler {
MGMXMLElement *XML = [(MGMXMLDocument *)[[[MGMXMLDocument alloc] initWithData:[theHandler data] options:MGMXMLDocumentTidyXML error:nil] autorelease] rootElement];
NSDictionary *info = [[[[XML elementsForName:@"json"] objectAtIndex:0] stringValue] parseJSON];
[self parseUserPhones:[info objectForKey:@"phones"]];
if ([delegate respondsToSelector:@selector(updatedUserPhones)]) [delegate updatedUserPhones];
}
- (void)parseUserPhones:(NSDictionary *)thePhones {
if (thePhones==nil)
return;
NSArray *phones = [thePhones allKeys];
[userPhoneNumbers release];
userPhoneNumbers = [NSMutableArray new];
for (int i=0; i<[phones count]; i++) {
NSDictionary *phoneInfo = [thePhones objectForKey:[phones objectAtIndex:i]];
if ([[phoneInfo objectForKey:@"verified"] intValue]==1) {
NSMutableDictionary *phone = [NSMutableDictionary dictionary];
[phone setObject:[[phoneInfo objectForKey:MGMPhoneNumber] phoneFormat] forKey:MGMPhoneNumber];
[phone setObject:[[phoneInfo objectForKey:MGMName] flattenHTML] forKey:MGMName];
[phone setObject:[phoneInfo objectForKey:MGMType] forKey:MGMType];
[userPhoneNumbers addObject:phone];
}
}
}
- (void)xpcFinished:(MGMURLBasicHandler *)theHandler {
NSString *returnedString = [theHandler string];
2010-09-20 19:44:17 -05:00
NSRange range = [returnedString rangeOfString:@"new _cd('"];
if (range.location!=NSNotFound) {
NSString *string = [returnedString substringFromIndex:range.location+range.length];
range = [string rangeOfString:@"'"];
if (range.location==NSNotFound) NSLog(@"failed 0009");
[XPCCD release];
2010-09-20 19:44:17 -05:00
XPCCD = [[[string substringWithRange:NSMakeRange(0, range.location)] addPercentEscapes] copy];
}
#if MGMInstanceDebug
NSLog(@"XPCCD = %@", XPCCD);
#endif
[checkTimer fire];
}
- (void)checkTimer {
if (XPCCD) {
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:[XPCURL stringByAppendingString:MGMCheckPath], XPCCD]]] delegate:self];
[handler setFinish:@selector(checkFinished:)];
[handler setInvisible:MGMInstanceInvisible];
[connectionManager addHandler:handler];
} else {
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[XPCURL stringByAppendingString:MGMXPCPath]]] delegate:self];
[handler setFinish:@selector(xpcFinished:)];
[handler setInvisible:MGMInstanceInvisible];
[connectionManager addHandler:handler];
}
2010-09-20 19:44:17 -05:00
}
- (void)checkFinished:(MGMURLBasicHandler *)theHandler {
NSDictionary *returnDic = [[theHandler data] parseJSON];
2010-09-20 19:44:17 -05:00
if (returnDic!=nil) {
if ([[returnDic objectForKey:@"ok"] intValue]!=0) {
NSDictionary *currentUnreadCounts = [[returnDic objectForKey:@"data"] objectForKey:@"unreadCounts"];
#if MGMInstanceDebug
NSLog(@"unreadCounts = %@", currentUnreadCounts);
#endif
int inboxCount = [[currentUnreadCounts objectForKey:MGMUCInbox] intValue];
//int recordedCount = [[currentUnreadCounts objectForKey:MGMUCRecorded] intValue];
int voicemailCount = [[currentUnreadCounts objectForKey:MGMUCVoicemail] intValue];
int smsCount = [[currentUnreadCounts objectForKey:MGMUCSMS] intValue];
if ([[unreadCounts objectForKey:MGMUCInbox] intValue]!=inboxCount)
if (delegate!=nil && [delegate respondsToSelector:@selector(updateUnreadCount:)]) [delegate updateUnreadCount:inboxCount];
2010-09-20 19:44:17 -05:00
if (voicemailCount>0)
if (delegate!=nil && [delegate respondsToSelector:@selector(updateVoicemail)]) [delegate updateVoicemail];
2010-09-20 19:44:17 -05:00
if (smsCount>0)
if (delegate!=nil && [delegate respondsToSelector:@selector(updateSMS)]) [delegate updateSMS];
[unreadCounts release];
2010-09-20 19:44:17 -05:00
unreadCounts = [currentUnreadCounts copy];
}
}
}
- (void)creditTimer {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:MGMCreditURL]];
[request setHTTPMethod:MGMPostMethod];
[request setValue:MGMURLForm forHTTPHeaderField:MGMContentType];
[request setHTTPBody:[[NSString stringWithFormat:@"_rnr_se=%@", rnr_se] dataUsingEncoding:NSUTF8StringEncoding]];
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:request delegate:self];
[handler setFinish:@selector(creditFinished:)];
[handler setInvisible:MGMInstanceInvisible];
[connectionManager addHandler:handler];
2010-09-20 19:44:17 -05:00
}
- (void)creditFinished:(MGMURLBasicHandler *)theHandler {
NSString *credit = [[[theHandler data] parseJSON] objectForKey:@"formattedCredit"];
2010-09-20 19:44:17 -05:00
#if MGMInstanceDebug
NSLog(@"Credit = %@", credit);
#endif
if (delegate!=nil && [delegate respondsToSelector:@selector(updateCredit:)]) [delegate updateCredit:credit];
2010-09-20 19:44:17 -05:00
}
- (void)placeCall:(NSString *)thePhoneNumber usingPhone:(int)thePhone delegate:(id)theDelegate {
[self placeCall:thePhoneNumber usingPhone:thePhone delegate:theDelegate didFailWithError:@selector(call:didFailWithError:) didFinish:@selector(callDidFinish:)];
}
- (void)placeCall:(NSString *)thePhoneNumber usingPhone:(int)thePhone delegate:(id)theDelegate didFailWithError:(SEL)didFailWithError didFinish:(SEL)didFinish {
MGMDelegateInfo *info = [MGMDelegateInfo infoWithDelegate:theDelegate];
[info setFinish:didFinish];
[info setFailWithError:didFailWithError];
[info setPhoneNumbers:[NSArray arrayWithObject:thePhoneNumber]];
[info setPhone:[userPhoneNumbers objectAtIndex:thePhone]];
2010-09-20 19:44:17 -05:00
if (thePhoneNumber==nil || [thePhoneNumber isEqual:@""]) {
NSMethodSignature *signature = [theDelegate methodSignatureForSelector:didFailWithError];
if (signature!=nil) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:didFailWithError];
[invocation setArgument:&info atIndex:2];
NSError *error = [NSError errorWithDomain:@"com.MrGeckosMedia.MGMInstance.Call" code:1 userInfo:nil];
[invocation setArgument:&error atIndex:3];
[invocation invokeWithTarget:theDelegate];
}
return;
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:MGMCallURL]];
[request setHTTPMethod:MGMPostMethod];
[request setValue:MGMURLForm forHTTPHeaderField:MGMContentType];
[request setHTTPBody:[[NSString stringWithFormat:@"outgoingNumber=%@&forwardingNumber=%@&subscriberNumber=undefined&phoneType=%@&remember=1&_rnr_se=%@", thePhoneNumber, [[userPhoneNumbers objectAtIndex:thePhone] objectForKey:MGMPhoneNumber], [[userPhoneNumbers objectAtIndex:thePhone] objectForKey:MGMType], rnr_se] dataUsingEncoding:NSUTF8StringEncoding]];
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:request delegate:self];
[handler setFailWithError:@selector(call:didFailWithError:)];
[handler setFinish:@selector(callDidFinish:)];
[handler setInvisible:MGMInstanceInvisible];
[handler setObject:info];
[connectionManager addHandler:handler];
2010-09-20 19:44:17 -05:00
}
- (void)cancelCallWithDelegate:(id)theDelegate {
[self cancelCallWithDelegate:theDelegate didFailWithError:@selector(callCancel:didFailWithError:) didFinish:@selector(callCancelDidFinish:)];
}
- (void)cancelCallWithDelegate:(id)theDelegate didFailWithError:(SEL)didFailWithError didFinish:(SEL)didFinish {
MGMDelegateInfo *info = [MGMDelegateInfo infoWithDelegate:theDelegate];
[info setFinish:didFinish];
[info setFailWithError:didFailWithError];
2010-09-20 19:44:17 -05:00
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:MGMCallCancelURL]];
[request setHTTPMethod:MGMPostMethod];
[request setValue:MGMURLForm forHTTPHeaderField:MGMContentType];
[request setHTTPBody:[[NSString stringWithFormat:@"outgoingNumber=undefined&forwardingNumber=undefined&cancelType=C2C&_rnr_se=%@", rnr_se] dataUsingEncoding:NSUTF8StringEncoding]];
MGMURLBasicHandler *handler = [MGMURLBasicHandler handlerWithRequest:request delegate:self];
[handler setFailWithError:@selector(call:didFailWithError:)];
[handler setFinish:@selector(callDidFinish:)];
[handler setInvisible:MGMInstanceInvisible];
[handler setObject:info];
[connectionManager addHandler:handler];
}
- (void)call:(MGMURLBasicHandler *)theHandler didFailWithError:(NSError *)theError {
MGMDelegateInfo *info = [theHandler object];
BOOL displayError = YES;
if ([info failWithError]!=nil) {
NSMethodSignature *signature = [[info delegate] methodSignatureForSelector:[info failWithError]];
2010-09-20 19:44:17 -05:00
if (signature!=nil) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:[info failWithError]];
[invocation setArgument:&info atIndex:2];
2010-09-20 19:44:17 -05:00
[invocation setArgument:&theError atIndex:3];
[invocation invokeWithTarget:[info delegate]];
displayError = NO;
2010-09-20 19:44:17 -05:00
}
}
if (displayError)
NSLog(@"MGMInstance Call Error: %@", theError);
2010-09-20 19:44:17 -05:00
}
- (void)callDidFinish:(MGMURLBasicHandler *)theHandler {
NSDictionary *infoDic = [[theHandler data] parseJSON];
MGMDelegateInfo *thisInfo = [theHandler object];
2010-09-20 19:44:17 -05:00
if ([[infoDic objectForKey:@"ok"] boolValue]) {
#if MGMInstanceDebug
NSLog(@"MGMInstance Did Call %@", infoDic);
#endif
if ([thisInfo finish]!=nil) {
NSMethodSignature *signature = [[thisInfo delegate] methodSignatureForSelector:[thisInfo finish]];
2010-09-20 19:44:17 -05:00
if (signature!=nil) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:[thisInfo finish]];
[invocation setArgument:&thisInfo atIndex:2];
[invocation invokeWithTarget:[thisInfo delegate]];
2010-09-20 19:44:17 -05:00
}
}
} else {
NSDictionary *info = nil;
if ([infoDic objectForKey:@"error"]!=nil)
info = [NSDictionary dictionaryWithObject:[infoDic objectForKey:@"error"] forKey:NSLocalizedDescriptionKey];
2010-09-20 19:44:17 -05:00
NSError *error = [NSError errorWithDomain:@"com.MrGeckosMedia.VoiceBase.Call" code:1 userInfo:info];
if ([thisInfo failWithError]!=nil) {
NSMethodSignature *signature = [[thisInfo delegate] methodSignatureForSelector:[thisInfo failWithError]];
2010-09-20 19:44:17 -05:00
if (signature!=nil) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:[thisInfo failWithError]];
[invocation setArgument:&thisInfo atIndex:2];
2010-09-20 19:44:17 -05:00
[invocation setArgument:&error atIndex:3];
[invocation invokeWithTarget:[thisInfo delegate]];
2010-09-20 19:44:17 -05:00
} else {
NSLog(@"MGMInstance Call Error: %@", error);
}
} else {
NSLog(@"MGMInstance Call Error: %@", error);
}
}
}
@end