Fixed typo in about. Added the label to the phone number completion for multiple SMS. Rewrote Login code to get the action from the HTML and read every input existing so if Google updates the login again, I have it covered for the most part. Updated the documentation to exclude information about Gizmo5 as they are no longer in business and Google brought it down.

This commit is contained in:
GRMrGecko 2011-09-16 17:04:03 -05:00
parent 2679510ca0
commit 60262c01cc
6 changed files with 182 additions and 88 deletions

View File

@ -1,8 +1,8 @@
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350
{\rtf1\ansi\ansicpg1252\cocoartf1138
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\margl1440\margr1440\vieww9000\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc\pardirnatural
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\qc
\f0\b\fs36 \cf0 By Mr. Gecko
\b0\fs32 \
@ -10,16 +10,16 @@
\fs34 At {\field{\*\fldinst{HYPERLINK "http://mrgeckosmedia.com/"}}{\fldrslt mrgeckosmedia.com}}
\fs32 \
Special Thanks To\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc\pardirnatural
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\qc
\fs24 \cf0 MegaEduX ({\field{\*\fldinst{HYPERLINK "http://megaedux.com"}}{\fldrslt megaedux.com}})\
RockStar ({\field{\*\fldinst{HYPERLINK "http://rocknthesweater.com"}}{\fldrslt rocknthesweater.com}})\
PowerOfCheese ({\field{\*\fldinst{HYPERLINK "http://xtrememachinez.com"}}{\fldrslt xtrememachinez.com}})\
\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
\cf0 VoiceMac uses {\field{\*\fldinst{HYPERLINK "http://mrgeckosmedia.com"}}{\fldrslt MGMSIP}} as a wrapper for {\field{\*\fldinst{HYPERLINK "http://www.pjsip.org/"}}{\fldrslt PJSIP}} which is a VOIP library, {\field{\*\fldinst{HYPERLINK "http://ffmpeg.org/"}}{\fldrslt FFmpeg}} for audio conversion, {\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org"}}{\fldrslt Sparkle}} for software update, {\field{\*\fldinst{HYPERLINK "http://growl.info/"}}{\fldrslt Growl}} for notifications, and {\field{\*\fldinst{HYPERLINK "http://opensource.mrgeckosmedia.com/GeckoReporter"}}{\fldrslt GeckoReporter}} for crash and reporting.\
\
VoiceMac is the first Google Voice client for the Mac. Send multiple SMS Messages, send SMS Messages, receive SMS Messages, place calls, look at your call history, receive voicemail, reverse lookup a phone number, and search your contact list in one easy interface. When you receive a SMS Message or Voicemail, you get notifications view Growl and hear sounds that is customizable.\
VoiceMac is the first Google Voice client for the Mac. Send multiple SMS Messages, send SMS Messages, receive SMS Messages, place calls, look at your call history, receive voicemail, reverse lookup a phone number, and search your contact list in one easy interface. When you receive a SMS Message or Voicemail, you get notifications via Growl and hear sounds that is customizable.\
\
With SIP support you can place calls from your computer using your favorite SIP service and if you link your Google Voice Number with the SIP service, you can place calls with your Google Voice Number from your computer. With the reverse lookup data, you can see who is calling you, even if their number isn't in your contacts list.\
\

View File

@ -398,7 +398,7 @@ const int MGMCMaxResults = 10;
[search appendFormat:MGMCWordSSA, word];
}
}
MGMLiteResult *result = [contactsConnection query:@"SELECT name, company, number, offsets(contacts) AS offset FROM contacts WHERE contacts MATCH %@ ORDER BY offset LIMIT %d", search, maxResults];
MGMLiteResult *result = [contactsConnection query:@"SELECT name, company, label, number, offsets(contacts) AS offset FROM contacts WHERE contacts MATCH %@ ORDER BY offset LIMIT %d", search, maxResults];
NSDictionary *contact = nil;
while ((contact=[result nextRow])!=nil) {
@ -423,7 +423,10 @@ const int MGMCMaxResults = 10;
name = [name stringByAppendingFormat:MGMCWordS, [nameArray objectAtIndex:i]];
}
}
completion = [NSString stringWithFormat:@"%@ <%@>", name, [[contact objectForKey:MGMCNumber] readableNumber]];
if ([[contact objectForKey:MGMCLabel] isEqual:@""])
completion = [NSString stringWithFormat:@"%@ <%@>", name, [[contact objectForKey:MGMCNumber] readableNumber]];
else
completion = [NSString stringWithFormat:@"%@ <%@> (%@)", name, [[contact objectForKey:MGMCNumber] readableNumber], [contact objectForKey:MGMCLabel]];
} else {
completion = [[contact objectForKey:MGMCNumber] readableNumber];
}

View File

@ -293,44 +293,72 @@ const BOOL MGMInstanceInvisible = YES;
return;
}
} else if ([returnedString containsString:@"onload=\"autoSubmit()\""]) {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:MGMLoginURL]];
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];
NSString *nameValue = @"name=\"%@\"";
NSString *valueStart = @"value=\"";
NSString *valueEnd = @"\"";
NSString *valueStartQ = @"value='";
NSString *valueEndQ = @"'";
NSArray *names = [NSArray arrayWithObjects:@"dsh", @"smsToken", @"followup", @"continue", @"PersistentCookie", @"service", @"rmShown", @"GALX", @"ltmpl", nil];
for (int i=0; i<[names count]; i++) {
NSRange range = NSMakeRange(0, [returnedString length]);
while (range.length>1) {
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]);
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 {
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]];
break;
}
[pool drain];
}
@ -353,7 +381,7 @@ const BOOL MGMInstanceInvisible = YES;
[handler setFinish:@selector(indexDidFinish:)];
[handler setInvisible:MGMInstanceInvisible];
[connectionManager addHandler:handler];
} else if ([returnedString containsString:@"<div id=\"gaia_loginbox\">"]) {
} else if ([returnedString containsString:@"<div class=\"sign-in\""]) {
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:)]) {
@ -364,57 +392,88 @@ const BOOL MGMInstanceInvisible = YES;
return;
}
webLoginTries++;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:MGMLoginURL]];
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];
[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", @"pstMsg", @"dnConn", @"continue", @"followup", @"service", @"dsh", @"timeStmp", @"secTok", @"GALX", @"signIn", @"asts", @"rmShown", nil];
for (int i=0; i<[names count]; i++) {
NSRange range = NSMakeRange(0, [returnedString length]);
while (range.length>1) {
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]);
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 {
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]];
break;
}
[pool drain];
}
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
NSMutableDictionary *parametersDebug = [[parameters mutableCopy] autorelease];
[parametersDebug removeObjectForKey:@"Passwd"];
NSLog(@"%@", parametersDebug);
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++) {

View File

@ -680,7 +680,11 @@
1DEB91B208733DA50010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ARCHS = (
ppc,
i386,
x86_64,
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
@ -699,7 +703,11 @@
1DEB91B308733DA50010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ARCHS = (
ppc,
i386,
x86_64,
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
@ -716,7 +724,11 @@
2A1172E612456A6700D119B5 /* Debug SIP */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ARCHS = (
ppc,
i386,
x86_64,
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
@ -794,7 +806,11 @@
2A1172E812456A6C00D119B5 /* Release SIP */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ARCHS = (
ppc,
i386,
x86_64,
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;

Binary file not shown.

View File

@ -1027,7 +1027,11 @@
2A117648124570C300D119B5 /* Debug SIP */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ARCHS = (
ppc,
i386,
x86_64,
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
@ -1086,7 +1090,11 @@
2A11764A124570C800D119B5 /* Release SIP */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ARCHS = (
ppc,
i386,
x86_64,
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
@ -1207,7 +1215,11 @@
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ARCHS = (
ppc,
i386,
x86_64,
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
@ -1225,7 +1237,11 @@
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ARCHS = (
ppc,
i386,
x86_64,
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;