2010-09-20 19:44:17 -05:00
//
// MGMInstance . m
// VoiceBase
//
// Created by Mr . Gecko on 8 / 15 / 10.
2011-03-07 19:02:53 -06:00
// 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"
2011-02-24 11:24:19 -06:00
# import "MGMDelegateInfo.h"
2010-09-20 19:44:17 -05:00
# import "MGMInbox.h"
# import "MGMContacts.h"
# import "MGMAddressBook.h"
# import "MGMAddons.h"
2011-03-21 07:43:56 -05:00
# import "MGMXML.h"
2010-09-20 19:44:17 -05:00
# import < MGMUsers / MGMUsers . h >
2011-03-07 19:02:53 -06:00
NSString * const MGMVoiceBaseCopyright = @ "Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/" ;
2010-09-20 19:44:17 -05:00
2011-09-11 14:54:29 -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/" ;
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 {
2011-02-22 12:00:36 -06:00
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 ] ;
2011-02-24 11:24:19 -06:00
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 {
2011-02-22 12:00:36 -06:00
[ 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 ] ;
2011-02-22 12:00:36 -06:00
[ 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 {
2010-09-24 15:35:47 -05:00
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 ;
}
2011-02-24 11:24:19 -06:00
- ( void ) index : ( MGMURLBasicHandler * ) theHandler didFailWithError : ( NSError * ) theError {
2010-09-24 15:35:47 -05:00
if ( delegate ! = nil && [ delegate respondsToSelector : @ selector ( loginError : ) ] ) {
2010-09-20 19:44:17 -05:00
[ delegate loginError : theError ] ;
} else {
NSLog ( @ "Login Error: %@" , theError ) ;
}
}
2011-02-24 11:24:19 -06:00
- ( void ) indexDidFinish : ( MGMURLBasicHandler * ) theHandler {
NSString * returnedString = [ theHandler string ] ;
2010-09-24 12:46:38 -05:00
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;" with : @ "&" ] ;
}
}
}
// NSLog ( @ "Redirecting to %@" , redirectURL ) ;
2011-02-24 11:24:19 -06:00
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 ] ;
2011-09-11 14:54:29 -05:00
} else if ( [ returnedString containsString : @ "verification code" ] ) {
2011-03-21 07:43:56 -05:00
[ verificationParameters release ] ;
verificationParameters = [ NSMutableDictionary new ] ;
2011-09-23 23:29:16 -05:00
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 ) ;
2011-03-21 07:43:56 -05:00
}
2011-09-23 23:29:16 -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 ] ;
2011-03-21 07:43:56 -05:00
} else {
2011-09-23 23:29:16 -05:00
break ;
2011-03-21 07:43:56 -05:00
}
[ pool drain ] ;
}
2011-09-23 23:29:16 -05:00
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 ( ) \ "" ] ) {
2011-09-16 17:04:03 -05:00
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 ] ;
2011-03-21 07:43:56 -05:00
[ request setHTTPMethod : MGMPostMethod ] ;
[ request setValue : MGMURLForm forHTTPHeaderField : MGMContentType ] ;
NSMutableDictionary * parameters = [ NSMutableDictionary dictionary ] ;
2011-09-16 17:04:03 -05:00
NSRange range = NSMakeRange ( 0 , [ returnedString length ] ) ;
while ( range . length > 1 ) {
2011-03-21 07:43:56 -05:00
NSAutoreleasePool * pool = [ NSAutoreleasePool new ] ;
2011-09-16 17:04:03 -05:00
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 ] ;
2011-03-21 07:43:56 -05:00
} else {
2011-09-16 17:04:03 -05:00
break ;
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 ] ;
2013-10-30 13:28:27 -05:00
} 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 ] ] ;
2010-09-24 15:35:47 -05:00
if ( delegate ! = nil && [ delegate respondsToSelector : @ selector ( loginError : ) ] ) {
2010-09-20 19:44:17 -05:00
[ delegate loginError : error ] ;
} else {
NSLog ( @ "Login Error: %@" , error ) ;
}
return ;
}
2010-09-24 12:46:38 -05:00
webLoginTries + + ;
2011-09-16 17:04:03 -05:00
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 ] ;
2010-09-24 12:46:38 -05:00
[ request setHTTPMethod : MGMPostMethod ] ;
[ request setValue : MGMURLForm forHTTPHeaderField : MGMContentType ] ;
NSMutableDictionary * parameters = [ NSMutableDictionary dictionary ] ;
2011-09-16 17:04:03 -05:00
NSRange range = NSMakeRange ( 0 , [ returnedString length ] ) ;
while ( range . length > 1 ) {
2010-09-24 12:46:38 -05:00
NSAutoreleasePool * pool = [ NSAutoreleasePool new ] ;
2011-09-16 17:04:03 -05:00
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 ] ;
2010-09-24 12:46:38 -05:00
} else {
2011-09-16 17:04:03 -05:00
break ;
2010-09-24 12:46:38 -05:00
}
[ pool drain ] ;
2010-09-20 19:44:17 -05:00
}
2010-09-24 12:46:38 -05:00
2011-09-16 17:04:03 -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" ] ;
2010-09-24 12:46:38 -05:00
# if MGMInstanceDebug
2011-09-16 17:04:03 -05:00
NSLog ( @ "%@" , parameters ) ;
2010-09-24 12:46:38 -05:00
# endif
2011-09-16 17:04:03 -05:00
[ parameters setObject : [ user password ] forKey : @ "Passwd" ] ;
2010-09-24 12:46:38 -05:00
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 ] ] ;
2011-02-24 11:24:19 -06:00
MGMURLBasicHandler * handler = [ MGMURLBasicHandler handlerWithRequest : request delegate : self ] ;
[ handler setFailWithError : @ selector ( index : didFailWithError : ) ] ;
[ handler setFinish : @ selector ( indexDidFinish : ) ] ;
[ handler setInvisible : MGMInstanceInvisible ] ;
[ connectionManager addHandler : handler ] ;
2013-07-20 06:56:17 -05:00
} 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 {
2011-02-22 12:00:36 -06:00
[ 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 {
2011-02-22 12:00:36 -06:00
[ 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 {
2011-02-22 12:00:36 -06:00
[ userNumber release ] ;
2010-09-20 19:44:17 -05:00
userNumber = [ [ [ string substringWithRange : NSMakeRange ( 0 , range . location ) ] phoneFormat ] copy ] ;
}
}
}
2011-09-11 14:54:29 -05:00
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 ] ] ;
2010-09-24 15:35:47 -05:00
if ( delegate ! = nil && [ delegate respondsToSelector : @ selector ( loginError : ) ] ) {
2010-09-20 19:44:17 -05:00
[ delegate loginError : error ] ;
} else {
NSLog ( @ "Login Error: %@" , error ) ;
}
return ;
}
2011-02-22 12:00:36 -06:00
[ 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 ) ] ;
}
}
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 {
2011-02-22 12:00:36 -06:00
[ 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 ] ;
2011-02-22 12:00:36 -06:00
[ 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 ] ;
2011-02-22 12:00:36 -06:00
[ 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 ] ;
}
2011-09-11 14:54:29 -05:00
if ( delegate ! = nil && [ delegate respondsToSelector : @ selector ( loginSuccessful ) ] ) [ delegate loginSuccessful ] ;
2010-09-20 19:44:17 -05:00
}
}
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 {
2011-09-23 23:29:16 -05:00
NSMutableURLRequest * request = [ NSMutableURLRequest requestWithURL : verificationURL ] ;
2011-03-21 07:43:56 -05:00
[ request setHTTPMethod : MGMPostMethod ] ;
[ request setValue : MGMURLForm forHTTPHeaderField : MGMContentType ] ;
[ verificationParameters setObject : theCode forKey : @ "smsUserPin" ] ;
2013-10-30 13:28:27 -05:00
[ verificationParameters setObject : @ "1" forKey : @ "pstMsg" ] ;
[ verificationParameters removeObjectForKey : @ "retry" ] ;
[ verificationParameters removeObjectForKey : @ "smsSend" ] ;
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 ;
}
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 ] ;
}
}
}
2011-02-24 11:24:19 -06:00
- ( 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" ) ;
2011-02-22 12:00:36 -06:00
[ 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 {
2011-02-24 11:24:19 -06:00
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
}
2011-02-24 11:24:19 -06: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 ] ;
2010-09-24 15:35:47 -05:00
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 )
2010-09-24 15:35:47 -05:00
if ( delegate ! = nil && [ delegate respondsToSelector : @ selector ( updateVoicemail ) ] ) [ delegate updateVoicemail ] ;
2010-09-20 19:44:17 -05:00
if ( smsCount > 0 )
2010-09-24 15:35:47 -05:00
if ( delegate ! = nil && [ delegate respondsToSelector : @ selector ( updateSMS ) ] ) [ delegate updateSMS ] ;
2011-02-22 12:00:36 -06:00
[ 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 ] ] ;
2011-02-24 11:24:19 -06:00
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
}
2011-02-24 11:24:19 -06: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
2010-09-24 15:35:47 -05:00
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 {
2011-02-24 11:24:19 -06:00
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 ] ] ;
2011-02-24 11:24:19 -06:00
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 {
2011-02-24 11:24:19 -06:00
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 ] ] ;
2011-02-24 11:24:19 -06:00
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 ] ;
2011-02-24 11:24:19 -06:00
[ invocation setSelector : [ info failWithError ] ] ;
[ invocation setArgument : & info atIndex : 2 ] ;
2010-09-20 19:44:17 -05:00
[ invocation setArgument : & theError atIndex : 3 ] ;
2011-02-24 11:24:19 -06:00
[ invocation invokeWithTarget : [ info delegate ] ] ;
displayError = NO ;
2010-09-20 19:44:17 -05:00
}
}
2011-02-24 11:24:19 -06:00
if ( displayError )
NSLog ( @ "MGMInstance Call Error: %@" , theError ) ;
2010-09-20 19:44:17 -05:00
}
2011-02-24 11:24:19 -06: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
2011-02-24 11:24:19 -06:00
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 ] ;
2011-02-24 11:24:19 -06:00
[ invocation setSelector : [ thisInfo finish ] ] ;
[ invocation setArgument : & thisInfo atIndex : 2 ] ;
[ invocation invokeWithTarget : [ thisInfo delegate ] ] ;
2010-09-20 19:44:17 -05:00
}
}
} else {
2011-02-22 12:00:36 -06:00
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 ] ;
2011-02-24 11:24:19 -06:00
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 ] ;
2011-02-24 11:24:19 -06:00
[ invocation setSelector : [ thisInfo failWithError ] ] ;
[ invocation setArgument : & thisInfo atIndex : 2 ] ;
2010-09-20 19:44:17 -05:00
[ invocation setArgument : & error atIndex : 3 ] ;
2011-02-24 11:24:19 -06:00
[ 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