Skip to content

Instantly share code, notes, and snippets.

@andermoran
Created January 2, 2017 19:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andermoran/27ae3da740524ef14741d4367e5f95eb to your computer and use it in GitHub Desktop.
Save andermoran/27ae3da740524ef14741d4367e5f95eb to your computer and use it in GitHub Desktop.
grabs user's phone number (works on el capitan)
#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <cstdio>
#include <memory>
#include <stdexcept>
#include <fstream>
#include <cstdlib>
using namespace std;
string getPhoneNumber(string name, string username);
string exec(const char* cmd);
void removeExtraneousCharacters(string& s);
string keepOnlyPhone(string& p);
void formatNumber (string& n);
int main(int argc, char *argv[]) {
string name = exec("osascript -e 'tell application \"System Events\"' -e 'return full name of current user' -e 'end tell'");
//string name = "Ander";
name.erase(remove(name.begin(), name.end(), '\n'), name.end());
string username = exec("whoami");
username.erase(remove(username.begin(), username.end(), '\n'), username.end());
cout << getPhoneNumber(name,username) << endl;
}
string exec(const char* cmd) {
char buffer[128];
string result = "";
shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) throw runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer, 128, pipe.get()) != NULL)
result += buffer;
}
return result;
}
string getPhoneNumber(string name, string username) {
size_t space = name.find(" ");
string firstName = "";
string lastName = "";
if (space != -1) {
firstName = name.substr(0, space);
lastName = name.substr(space);
} else {
firstName = name;
lastName = "";
}
string cFile = exec(("cd && cd Library/Application\\ Support/AddressBook/Sources/ && grep -ril " + firstName + " * | xargs grep -ril " + lastName).c_str());
//cout << "file = " << cFile << "endOfCFile" << endl;
if (cFile.length() == 0) {
return "No number found!";
}
vector <string> locations;
int index = 0;
while (index >= 0) {
int newIndex = cFile.find("\n", index+1);
string s = cFile.substr(index, newIndex-index);
s.erase(remove(s.begin(), s.end(), '\n'), s.end());
locations.push_back(s);
index = newIndex;
}
int largest = 0;
for (int i = 1; i < locations.size(); i++) {
if (locations.at(i).length() > locations.at(largest).length()) {
largest = i;
}
}
cFile = locations.at(largest);
//cout << "cFile = " << cFile << endl;
/*for (int i = 0; i < locations.size(); i++) {
cout << i << ": " << locations.at(i) << endl;
}*/
string location = "/Users/" + username + "/Library/Application Support/AddressBook/Sources/" + cFile;
if (location == ("/Users/" + username + "/Library/Application Support/AddressBook/Sources/")) {
return "no phone number";
}
//clog << "location: " << location << endl;
ifstream path(location);
string fileContents((istreambuf_iterator<char>(path)), istreambuf_iterator<char>());
size_t mobile = fileContents.find("<Mobile>");
size_t start = fileContents.find("(", mobile);
int endIndex = mobile+14;
cout << "endIndex: " << endIndex << endl;
//cout << fileContents.at(endIndex+3) << " & " << fileContents.at(endIndex+4) << " & " << fileContents.at(endIndex+5) << endl;
while (isdigit(fileContents.at(endIndex+3)) || isdigit(fileContents.at(endIndex+4)) || isdigit(fileContents.at(endIndex+5))) {
endIndex++;
}
endIndex -= 3;
//cout << "endIndex: " << endIndex << endl;
//cout << "length = " << endIndex-mobile << endl;
//string phoneNumber = fileContents.substr(mobile+14, endIndex-mobile-8);
string phoneNumber = fileContents.substr(mobile+14, 100);
removeExtraneousCharacters(phoneNumber);
phoneNumber = keepOnlyPhone(phoneNumber);
formatNumber(phoneNumber);
return phoneNumber;
}
void removeExtraneousCharacters(string& s) {
vector <int> indexToBeErased;
for (int i = 0; i < s.length(); i++) {
char chr = s.at(i);
if (!isdigit(chr)) {
//cout << chr << ":" << (int)chr << " is not a digit" << endl;
//s.erase (s.begin()+i);
indexToBeErased.push_back(i);
} else {
//cout << chr << ":" << (int)chr << " is a digit" << endl;
}
}
for (int i = indexToBeErased.size() - 1; i >= 0; i--) {
s.erase (s.begin()+indexToBeErased.at(i));
}
}
string keepOnlyPhone(string& p) {
int i = 0;
vector <char> digits;
while (digits.size() < 10) {
char chr = p.at(i);
if (chr == '1' && i == 0) {
//do nothing because it's the country code for USA
}
else if (isdigit(chr)) {
digits.push_back(chr);
}
i++;
}
//cout << digits.size() << " digits" << endl;
string number = "";
for (int i = 0; i < digits.size(); i++) {
number += digits.at(i);
}
return number;
}
void formatNumber(string& n) {
n.insert(0,1,'(');
n.insert(4,1,')');
n.insert(5,1, ' ');
n.insert(9,1,'-');
}
@andermoran
Copy link
Author

Not meant for macOS as it seems the data for the contacts are encrypted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment