--- /dev/null
+#!/usr/bin/python
+
+# DialCentral - Front end for Google's Grand Central service.
+# Copyright (C) 2008 Eric Warnke ericew AT gmail DOT com
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+"""
+Filesystem backend for contact support
+"""
+
+
+import os
+import csv
+
+
+class CsvAddressBook(object):
+ """
+ Currently supported file format
+ @li Has the first line as a header
+ @li Escapes with quotes
+ @li Comma as delimiter
+ @li Column 0 is name, column 1 is number
+ """
+
+ def __init__(self, csvPath):
+ self.__csvPath = csvPath
+ self.__contacts = list(
+ self.read_csv(csvPath)
+ )
+
+ @staticmethod
+ def read_csv(csvPath):
+ csvReader = iter(csv.reader(open(csvPath, "rU")))
+ csvReader.next()
+ for i, row in enumerate(csvReader):
+ yield str(i), row[0], row[1]
+
+ def clear_caches(self):
+ pass
+
+ @staticmethod
+ def factory_name():
+ return "csv"
+
+ @staticmethod
+ def contact_source_short_name(contactId):
+ return "csv"
+
+ def get_contacts(self):
+ """
+ @returns Iterable of (contact id, contact name)
+ """
+ for contact in self.__contacts:
+ yield contact[0:2]
+
+ def get_contact_details(self, contactId):
+ """
+ @returns Iterable of (Phone Type, Phone Number)
+ """
+ contactId = int(contactId)
+ yield "", self.__contacts[contactId][2]
+
+
+class FilesystemAddressBookFactory(object):
+
+ FILETYPE_SUPPORT = {
+ "csv": CsvAddressBook,
+ }
+
+ def __init__(self, path):
+ self.__path = path
+
+ def clear_caches(self):
+ pass
+
+ def get_addressbooks(self):
+ """
+ @returns Iterable of (Address Book Factory, Book Id, Book Name)
+ """
+ for root, dirs, files in os.walk(self.__path):
+ for file in files:
+ name, ext = file.rsplit(".", 1)
+ if ext in self.FILETYPE_SUPPORT:
+ yield self, os.path.join(root, file), name
+
+ def open_addressbook(self, bookId):
+ name, ext = bookId.rsplit(".", 1)
+ assert ext in self.FILETYPE_SUPPORT
+ return self.FILETYPE_SUPPORT[ext](bookId)
+
+ @staticmethod
+ def factory_name():
+ return "File"
+
+
+def print_books():
+ """
+ Included here for debugging.
+
+ Either insert it into the code or launch python with the "-i" flag
+ """
+ eab = FilesystemAddressBookFactory(os.path.expanduser("~/Desktop"))
+ for book in eab.get_addressbooks():
+ eab = eab.open_addressbook(book[1])
+ print book
+ for contact in eab.get_contacts():
+ print "\t", contact
+ for details in eab.get_contact_details(contact[0]):
+ print "\t\t", details
_inboxRe = re.compile(r"""<td>.*?(voicemail|received|missed|call return).*?</td>\s+<td>\s+<font size="2">\s+(.*?)\s+ \| \s+<a href="/mobile/contacts/.*?">(.*?)\s?</a>\s+<br/>\s+(.*?)\s?<a href=""", re.S)
_contactsRe = re.compile(r"""<a href="/mobile/contacts/detail/(\d+)">(.*?)</a>""", re.S)
_contactsNextRe = re.compile(r""".*<a href="/mobile/contacts(\?page=\d+)">Next</a>""", re.S)
- _contactDetailGroupRe = re.compile(r"""Group:\s*(\w*)""", re.S)
- _contactDetailPhoneRe = re.compile(r"""(\w+):[0-9\-\(\) \t]*?<a href="/mobile/calls/click_to_call\?destno=(\d+).*?">call</a>""", re.S)
+ _contactDetailGroupRe = re.compile(r"""Group:\s*(\w*)""", re.S)
+ _contactDetailPhoneRe = re.compile(r"""(\w+):[0-9\-\(\) \t]*?<a href="/mobile/calls/click_to_call\?destno=(\d+).*?">call</a>""", re.S)
_validateRe = re.compile("^[0-9]{10,}$")
self._browser = MozillaEmulator(None, 0)
if cookieFile is None:
- cookieFile = os.path.join(os.path.expanduser("~"), ".gc_dialer_cookies.txt")
+ cookieFile = os.path.join(os.path.expanduser("~"), ".gc_cookies.txt")
self._browser.cookies.filename = cookieFile
if os.path.isfile(cookieFile):
self._browser.cookies.load()
os.path.join(os.path.dirname(__file__), "../lib/dialcentral.glade"),
]
+ _data_path = os.path.join(os.path.expanduser("~"), ".dialcentral")
+
def __init__(self):
self._gcBackend = None
self._clipboard = gtk.clipboard_get()
self._widgetTree = gtk.glade.XML(path)
break
else:
- self.display_error_message("Cannot find gc_dialer.glade")
+ self.display_error_message("Cannot find dialcentral.glade")
gtk.main_quit()
return
warnings.warn("No Internet Connectivity API ", UserWarning, 2)
import gc_backend
+ import file_backend
import evo_backend
# import gmail_backend
# import maemo_backend
import views
- self._gcBackend = gc_backend.GCDialer()
+ cookieFile = os.path.join(self._data_path, "cookies.txt")
+ try:
+ os.makedirs(os.path.dirname(cookieFile))
+ except OSError, e:
+ if e.errno != 17:
+ raise
+ self._gcBackend = gc_backend.GCDialer(cookieFile)
gtk.gdk.threads_enter()
try:
self._dialpad = views.Dialpad(self._widgetTree)
else:
self.attempt_login(2)
+ fsContactsPath = os.path.join(self._data_path, "contacts")
addressBooks = [
self._gcBackend,
evo_backend.EvolutionAddressBook(),
+ file_backend.FilesystemAddressBookFactory(fsContactsPath),
]
mergedBook = views.MergedAddressBook(addressBooks, views.MergedAddressBook.basic_lastname_sorter)
self._contactsView.append(mergedBook)