VoiceMac/Classes/VoiceBase/MGMInstance.m

670 lines
27 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"
#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/#inbox";
NSString * const MGMLoginURL = @"https://www.google.com/accounts/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/";
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:@"<div id=\"gaia_loginbox\">"]) {
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++;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:MGMLoginURL]];
[request setHTTPMethod:MGMPostMethod];
[request setValue:MGMURLForm forHTTPHeaderField:MGMContentType];
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
[parameters setObject:(webLoginTries==2 ? [[user settingForKey:MGMUserName] stringByAppendingString:@"@gmail.com"] : [user settingForKey:MGMUserName]) forKey:@"Email"];
[parameters setObject:[user password] forKey:@"Passwd"];
[parameters setObject:@"yes" forKey:@"PersistentCookie"];
NSString *nameValue = @"name=\"%@\"";
NSString *valueStart = @"value=\"";
NSString *valueEnd = @"\"";
NSString *valueStartQ = @"value='";
NSString *valueEndQ = @"'";
NSArray *names = [NSArray arrayWithObjects:@"ltmpl", @"continue", @"followup", @"service", @"dsh", @"GALX", @"rmShown", nil];
for (int i=0; i<[names count]; i++) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSString *nameString = [NSString stringWithFormat:nameValue, [names objectAtIndex:i]];
NSRange range = [returnedString rangeOfString:nameString];
if (range.location==NSNotFound) {
nameString = [nameString replace:@"\"" with:@"'"];
range = [returnedString rangeOfString:nameString];
}
if (range.location==NSNotFound) {
NSLog(@"Unable to find %@", [names objectAtIndex:i]);
} else {
NSString *string = [returnedString substringFromIndex:range.location+range.length];
range = [string rangeOfString:valueStart];
if (range.location==NSNotFound) {
range = [string rangeOfString:valueStartQ];
if (range.location==NSNotFound) {
NSLog(@"Unable to find value for %@", [names objectAtIndex:i]);
[pool drain];
continue;
}
string = [string substringFromIndex:range.location+range.length];
range = [string rangeOfString:valueEndQ];
} else {
string = [string substringFromIndex:range.location+range.length];
range = [string rangeOfString:valueEnd];
}
if (range.location==NSNotFound) NSLog(@"failed 532");
[parameters setObject:[[[string substringWithRange:NSMakeRange(0, range.location)] copy] autorelease] forKey:[names objectAtIndex:i]];
}
[pool drain];
2010-09-20 19:44:17 -05:00
}
#if MGMInstanceDebug
NSMutableDictionary *parametersDebug = [[parameters mutableCopy] autorelease];
[parametersDebug removeObjectForKey:@"Passwd"];
NSLog(@"%@", parametersDebug);
#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];
2010-09-20 19:44:17 -05:00
} else {
NSString *string, *guser = @"", *phonesInfo = @"";
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:@"gc-header-did-display"] && ![userNumber isPhoneComplete]) {
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)];
}
}
NSDictionary *phones = [phonesInfo parseJSON];
//NSLog(@"%@", phones);
NSArray *phoneKeys = [phones allKeys];
[userPhoneNumbers release];
2010-09-20 19:44:17 -05:00
userPhoneNumbers = [NSMutableArray new];
for (int i=0; i<[phoneKeys count]; i++) {
NSDictionary *phoneInfo = [phones objectForKey:[phoneKeys objectAtIndex:i]];
if ([[phoneInfo objectForKey:@"telephonyVerified"] 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];
}
}
#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 (delegate!=nil && [delegate respondsToSelector:@selector(loginSuccessful)]) [delegate loginSuccessful];
2010-09-20 19:44:17 -05:00
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];
}
}
}
- (BOOL)isLoggedIn {
return loggedIn;
}
- (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