conduit r1459 - in trunk: . conduit/modules/GoogleModule test/python-tests



Author: jstowers
Date: Wed May  7 13:40:55 2008
New Revision: 1459
URL: http://svn.gnome.org/viewvc/conduit?rev=1459&view=rev

Log:
2008-05-08  John Stowers  <john stowers gmail com>

	* conduit/modules/GoogleModule/GoogleModule.py:
	* test/python-tests/TestDataProviderGoogleDocuments.py: Add in-process
	support for google docs upload and download. Upload and download currently
	working, now it needs to be wrapped in the conduit dataprovider interface

2008-05-07  John Stowers  <john stowers gmail com>


Added:
   trunk/test/python-tests/TestDataProviderGoogleDocuments.py
      - copied, changed from r1458, /trunk/test/python-tests/TestDataProviderGoogle.py
Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/conduit/modules/GoogleModule/GoogleModule.py

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Wed May  7 13:40:55 2008
@@ -2,6 +2,7 @@
 ==============
 * Support ZOTO Photos
 * Update to latest version of pyfacebook, flickrapi, pybackpack
+* Updated to latest version of gdata and improved support for google contacts
 
 NEW in 0.3.10:
 ==============

Modified: trunk/conduit/modules/GoogleModule/GoogleModule.py
==============================================================================
--- trunk/conduit/modules/GoogleModule/GoogleModule.py	(original)
+++ trunk/conduit/modules/GoogleModule/GoogleModule.py	Wed May  7 13:40:55 2008
@@ -26,18 +26,19 @@
 #and the appropriate directories
 Utils.dataprovider_add_dir_to_path(__file__)
 try:
-    import atom
-    import gdata
+    import atom.service
     import gdata.service
     import gdata.photos.service    
     import gdata.calendar.service
     import gdata.contacts.service
+    import gdata.docs.service
 
     MODULES = {
         "GoogleCalendarTwoWay" : { "type": "dataprovider" },
         "PicasaTwoWay" :         { "type": "dataprovider" },
         "YouTubeSource" :        { "type": "dataprovider" },    
-        "ContactsTwoWay" :       { "type": "dataprovider" },    
+        "ContactsTwoWay" :       { "type": "dataprovider" },
+#        "DocumentsSink" :        { "type": "dataprovider" },
     }
     log.info("Module Information: %s" % Utils.get_module_information(gdata, None))
 except (ImportError, AttributeError):
@@ -765,7 +766,7 @@
     Contacts GData provider
     """
     _name_ = _("Google Contacts")
-    _description_ = _("Sync contacts from Google")
+    _description_ = _("Sync your Gmail contacts")
     _category_ = conduit.dataproviders.CATEGORY_OFFICE
     _module_type_ = "twoway"
     _out_type_ = "contact"
@@ -988,6 +989,155 @@
             self._set_password(password.get_text())
         dlg.destroy()    
 
+class DocumentsSink(GoogleBase,  DataProvider.DataSink):
+    """
+    Contacts GData provider
+    
+    See: http://code.google.com/p/gdatacopier/source/browse/trunk/python/gdatacopier.py
+    """
+    _name_ = _("Google Documents")
+    _description_ = _("Sync your Google Documents")
+    _category_ = conduit.dataproviders.CATEGORY_OFFICE
+    _module_type_ = "twoway"
+    _out_type_ = "contact"
+    _icon_ = "applications-office"
+    
+    SUPPORTED_DOCS = ('DOC','ODT','SWX','TXT','RTF','HTM','HTML')
+    SUPPORTED_SHEETS = ('ODS','XLS','CSV','TSV')
+    SUPPORTED_PRESENTATIONS = ('PPT','PPS')
+
+    def __init__(self, *args):
+        GoogleBase.__init__(self)
+        DataProvider.DataSink.__init__(self)
+        self.service = gdata.docs.service.DocsService()
+        
+    def _do_login(self):
+        self.service.ClientLogin(self.username, self.password)
+        
+    def _upload_document(self, f):
+        name,ext = f.get_filename_and_extension()
+        ext = ext[1:].upper()
+
+        ms = gdata.MediaSource(
+                    file_path=f.get_local_uri(),
+                    content_type=gdata.docs.service.SUPPORTED_FILETYPES[ext])
+
+        #upload using the appropriate service
+        if ext in self.SUPPORTED_DOCS:
+            entry = self.service.UploadDocument(ms,name)
+        elif ext in self.SUPPORTED_SHEETS:
+            entry = self.service.UploadSpreadsheet(ms,name)
+        elif ext in self.SUPPORTED_PRESENTATIONS:
+            entry = self.service.UploadPresentation(ms,name)
+        else:
+            log.info("Unknown document format")
+            return None
+
+        return Rid(uid=entry.id.text)
+        
+    def _get_all_documents(self):
+        feed = self.service.GetDocumentListFeed()
+        if not feed.entry:
+            return []
+        return [str(doc.id.text) for doc in feed.entry]
+        
+    def _get_document(self, LUID):
+        if not LUID:
+            return None
+
+        #get the gdata contact from google
+        try:
+            gd = self.service.GetDocumentListEntry(LUID)
+        except gdata.service.RequestError:
+            return None
+
+        return gd
+        
+    def _download_doc(self, docid):
+        print self.service.additional_headers
+        self.service.debug = True
+        #https://docs.google.com/MiscCommands?command=saveasdoc&exportformat=%s&docID=%s
+        resp = atom.service.HttpRequest(
+                                service=self.service,
+                                operation='GET',
+                                data=None,
+                                uri='/MiscCommands',
+                                extra_headers={'Authorization':self.service._GetAuthToken()},
+                                url_params={'command':'saveasdoc','exportformat':'doc','docID':docid},
+                                escape_params=True,
+                                content_type='application/atom+xml')
+
+        file_handle = open("/home/john/Desktop/%s.doc" % docid, 'wb')
+        file_handle.write(resp.read())
+        file_handle.close()
+        
+    def refresh(self):
+        DataProvider.DataSink.refresh(self)
+        self._login()
+        if not self.loggedIn:
+            raise Exceptions.RefreshError("Could not log in")
+
+#    def put(self, doc, overwrite, LUID=None):            
+#        #Check if we have already uploaded the document
+#        if LUID != None:
+#            info = self._get_photo_info(LUID)
+#            #check if a photo exists at that UID
+#            if info != None:
+#                if overwrite == True:
+#                    #replace the photo
+#                    return self._replace_photo(LUID, uploadInfo)
+#                else:
+#                    #Only upload the photo if it is newer than the Remote one
+#                    url = self._get_raw_photo_url(info)
+#                    remoteFile = File.File(url)
+#
+#                    #this is a limited test for equality type comparison
+#                    comp = photo.compare(remoteFile,True)
+#                    log.debug("Compared %s with %s to check if they are the same (size). Result = %s" % 
+#                            (photo.get_filename(),remoteFile.get_filename(),comp))
+#                    if comp != conduit.datatypes.COMPARISON_EQUAL:
+#                        raise Exceptions.SynchronizeConflictError(comp, photo, remoteFile)
+#                    else:
+#                        return conduit.datatypes.Rid(uid=LUID)
+#
+#        log.debug("Uploading Photo URI = %s, Mimetype = %s, Original Name = %s" % (photoURI, mimeType, originalName))
+#
+#        #upload the file
+#        return self._upload_photo (uploadInfo)
+
+    def delete(self, LUID):
+        DataProvider.DataSink.delete(self, LUID)
+        self._login()
+        #get the gdata contact from google
+        #try:
+        #    gc = self.service.Get(LUID, converter=gdata.contacts.ContactEntryFromString)
+        #    self.service.DeleteContact(gc.GetEditLink().href)
+        #except gdata.service.RequestError, e:
+        #    log.warn("Error deleting: %s" % e)        
+
+    def configure(self, window):
+        """
+        Configures the PicasaTwoWay
+        """
+        widget = Utils.dataprovider_glade_get_widget(
+                        __file__, 
+                        "contacts-config.glade", 
+                        "GoogleContactsConfigDialog")
+                        
+        #get a whole bunch of widgets
+        username = widget.get_widget("username")
+        password = widget.get_widget("password")
+        
+        #preload the widgets        
+        username.set_text(self.username)
+        password.set_text(self.password)
+        
+        dlg = widget.get_widget("GoogleContactsConfigDialog")
+        response = Utils.run_dialog (dlg, window)
+        if response == True:
+            self._set_username(username.get_text())
+            self._set_password(password.get_text())
+        dlg.destroy()   
 
 class YouTubeSource(DataProvider.DataSource):
     """

Copied: trunk/test/python-tests/TestDataProviderGoogleDocuments.py (from r1458, /trunk/test/python-tests/TestDataProviderGoogle.py)
==============================================================================
--- /trunk/test/python-tests/TestDataProviderGoogle.py	(original)
+++ trunk/test/python-tests/TestDataProviderGoogleDocuments.py	Wed May  7 13:40:55 2008
@@ -1,85 +1,29 @@
 #common sets up the conduit environment
 from common import *
+import conduit.datatypes.File as File
 
-import conduit.datatypes.Event as Event
-import conduit.utils as Utils
-
-import random
-
-SAFE_CALENDAR_NAME="Conduit Project"
-SAFE_EVENT_UID="2bh7mbagsc880g64qaps06tbp4 google com"
-MAX_YOUTUBE_VIDEOS=5
-
-if not is_online():
-    skip()
-
-#-------------------------------------------------------------------------------
-# Calendar
-#-------------------------------------------------------------------------------
-#setup the test
-test = SimpleTest(sinkName="GoogleCalendarTwoWay")
+test = SimpleTest(sinkName="DocumentsSink")
 config = {
     "username":     os.environ.get("TEST_USERNAME","conduitproject gmail com"),
     "password":     os.environ["TEST_PASSWORD"],
-    "selectedCalendarURI"   :   "conduitproject%40gmail.com",
-    "selectedCalendarName"  :   SAFE_CALENDAR_NAME,
 }
 test.configure(sink=config)
 google = test.get_sink().module
 
-#check we can get the calendar
-found = False
-for cal in google._get_all_calendars():
-    if cal.get_name() == SAFE_CALENDAR_NAME:
-        found = True
-        break
-        
-ok("Found calendar: '%s'" % SAFE_CALENDAR_NAME, found)    
-
-#make a simple event
-hour=random.randint(12,23)
-ics="""BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//PYVOBJECT//NONSGML Version 1//EN
-BEGIN:VEVENT
-DTSTART:2008%(month)02d%(day)02dT%(hour)02d0000Z
-DTEND:2008%(month)02d%(day)02dT%(end)02d0000Z
-SUMMARY:Test Event
-END:VEVENT
-END:VCALENDAR""" % {    "month" :   random.randint(1,12),
-                        "day"   :   random.randint(1,28),
-                        "hour"  :   hour,
-                        "end"   :   hour+1}
-
-event = Event.Event()
-event.set_from_ical_string(ics)
-test.do_dataprovider_tests(
-        supportsGet=True,
-        supportsDelete=False,
-        safeLUID=SAFE_EVENT_UID,
-        data=event,
-        name="event"
-        )
-
-#-------------------------------------------------------------------------------
-# Youtube
-#-------------------------------------------------------------------------------
-#Now a very simple youtube test...
-test = SimpleTest(sourceName="YouTubeSource")
-config = {
-    "max_downloads" :   MAX_YOUTUBE_VIDEOS
-}
-test.configure(source=config)
-youtube = test.get_source().module
-
+#Log in
 try:
-    youtube.refresh()
-    ok("Refresh youtube", True)
+    google.refresh()
+    ok("Logged in", google.loggedIn == True)
 except Exception, err:
-    ok("Refresh youtube (%s)" % err, False) 
+    ok("Logged in (%s)" % err, False) 
+
+print google._get_all_documents()
+
+#f = File.File(URI="/home/john/Desktop/test2.odt")
+#print google._upload_document(f)
+
+#print google._get_document("http://docs.google.com/feeds/documents/private/full/document%3Adf32bhnd_6dvqk4x2f";)
 
-videos = youtube.get_all()
-num = len(videos)
-ok("Got %s videos" % num, num == MAX_YOUTUBE_VIDEOS)
+google._download_doc('df32bhnd_6dvqk4x2f')
 
 finished()



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]