Attaching an updated and verified patch, and also a NMU debdiff against the current version in unstable (not uploading yet, I still hope the maintainer will respond here). For me, "google docs upload" and "google docs put somefile.txt" commands work with this patch applied.
-- Dmitry Shachnev
diff -Nru googlecl-0.9.13/debian/changelog googlecl-0.9.13/debian/changelog --- googlecl-0.9.13/debian/changelog 2012-09-01 16:12:30.000000000 +0400 +++ googlecl-0.9.13/debian/changelog 2012-09-01 16:13:37.000000000 +0400 @@ -1,3 +1,11 @@ +googlecl (0.9.13-1.1) unstable; urgency=low + + * Non-maintainer upload. + * debian/patches/fix_664989.patch: Fix crashes with new python-gdata + versions (Closes: #664989). + + -- Dmitry Shachnev <[email protected]> Fri, 31 Aug 2012 14:48:42 +0400 + googlecl (0.9.13-1) unstable; urgency=low * New upstream release. diff -Nru googlecl-0.9.13/debian/patches/fix_664989.patch googlecl-0.9.13/debian/patches/fix_664989.patch --- googlecl-0.9.13/debian/patches/fix_664989.patch 1970-01-01 03:00:00.000000000 +0300 +++ googlecl-0.9.13/debian/patches/fix_664989.patch 2012-09-01 16:03:41.000000000 +0400 @@ -0,0 +1,167 @@ +From: Dmitry Shachnev <[email protected]> +Description: Fix Docs module not working +Bug-Upstream: http://code.google.com/p/googlecl/issues/detail?id=449 +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=664989 + +Index: src/googlecl/docs/client.py +=================================================================== +--- a/src/googlecl/docs/client.py ++++ b/src/googlecl/docs/client.py +@@ -37,7 +37,7 @@ + import googlecl.client + from googlecl.docs import SECTION_HEADER + import googlecl.docs.base +- ++import atom.data + + LOG = logging.getLogger(googlecl.docs.LOGGER_NAME + '.client') + +@@ -52,8 +52,35 @@ + app with a command line interface. + + """ +- DOCLIST_FEED_URI = gdata.docs.client.DOCLIST_FEED_URI ++ DOCLIST_FEED_URI = '/feeds/default/private/full' + ++ # File extension/mimetype pairs of common format. ++ # These seem to have disappeared in python-gdata 2.0.15 and 2.0.16, so here ++ # they are given explicitly. ++ MIMETYPES = { ++ 'CSV': 'text/csv', ++ 'TSV': 'text/tab-separated-values', ++ 'TAB': 'text/tab-separated-values', ++ 'DOC': 'application/msword', ++ 'DOCX': ('application/vnd.openxmlformats-officedocument.' ++ 'wordprocessingml.document'), ++ 'ODS': 'application/x-vnd.oasis.opendocument.spreadsheet', ++ 'ODT': 'application/vnd.oasis.opendocument.text', ++ 'RTF': 'application/rtf', ++ 'SXW': 'application/vnd.sun.xml.writer', ++ 'TXT': 'text/plain', ++ 'XLS': 'application/vnd.ms-excel', ++ 'XLSX': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', ++ 'PDF': 'application/pdf', ++ 'PNG': 'image/png', ++ 'PPT': 'application/vnd.ms-powerpoint', ++ 'PPS': 'application/vnd.ms-powerpoint', ++ 'HTM': 'text/html', ++ 'HTML': 'text/html', ++ 'ZIP': 'application/zip', ++ 'SWF': 'application/x-shockwave-flash' ++ } ++ + def __init__(self, config): + """Constructor.""" + gdata.docs.client.DocsClient.__init__(self, source='GoogleCL') +@@ -65,9 +92,8 @@ + folder_or_uri) + + def _determine_content_type(self, file_ext): +- from gdata.docs.data import MIMETYPES + try: +- return MIMETYPES[file_ext.upper()] ++ return DocsClientCL.MIMETYPES[file_ext.upper()] + except KeyError: + LOG.info('No supported filetype found for extension %s', file_ext) + return None +@@ -111,7 +137,7 @@ + issue + + Args: +- entry_or_id_or_url: gdata.docs.data.DocsEntry or string representing a ++ entry_or_id_or_url: gdata.data.GDEntry or string representing a + resource id or URL to download the document from (such as the content + src link). + file_path: str The full path to save the file to. The export +@@ -169,11 +195,11 @@ + # folder.content.src is the uri to query for documents in that folder. + entries.extend(self.GetEntries(folder.content.src, + titles, +- desired_class=gdata.docs.data.DocList)) ++ desired_class=gdata.docs.data.ResourceFeed)) + else: +- entries = self.GetEntries(gdata.docs.client.DOCLIST_FEED_URI, ++ entries = self.GetEntries(self.DOCLIST_FEED_URI, + titles, +- desired_class=gdata.docs.data.DocList) ++ desired_class=gdata.docs.data.ResourceFeed) + return entries + + def get_single_doc(self, title=None, folder_entry_list=None): +@@ -192,16 +218,16 @@ + if len(folder_entry_list) == 1: + return self.GetSingleEntry(folder_entry_list[0].content.src, + title, +- desired_class=gdata.docs.data.DocList) ++ desired_class=gdata.docs.data.ResourceFeed) + else: + entries = self.get_doclist(title, folder_entry_list) + # Technically don't need the desired_class for this call + # because we have the entries. + return self.GetSingleEntry(entries, title) + else: +- return self.GetSingleEntry(gdata.docs.client.DOCLIST_FEED_URI, ++ return self.GetSingleEntry(self.DOCLIST_FEED_URI, + title, +- desired_class=gdata.docs.data.DocList) ++ desired_class=gdata.docs.data.ResourceFeed) + + GetSingleDoc = get_single_doc + +@@ -216,7 +242,7 @@ + + """ + if title: +- uri = gdata.docs.client.DOCLIST_FEED_URI + '-/folder' ++ uri = self.DOCLIST_FEED_URI + '-/folder' + folder_entries = self.GetEntries(uri, title) + if not folder_entries: + LOG.warning('No folder found that matches ' + title) +@@ -229,7 +255,7 @@ + def is_token_valid(self, test_uri=None): + """Check that the token being used is valid.""" + if not test_uri: +- docs_uri = gdata.docs.client.DOCLIST_FEED_URI ++ docs_uri = self.DOCLIST_FEED_URI + sheets_uri = ('https://spreadsheets.google.com/feeds/spreadsheets' + '/private/full') + docs_test = googlecl.client.BaseClientCL.IsTokenValid(self, docs_uri) +@@ -292,7 +318,35 @@ + Returns: + Entry representing the document uploaded. + """ +- return self.upload(path, entry_title, post_uri, content_type) +- +- ++ ++ # GoogleCL that uses gdata-2.0.0 through 2.0.4 won't ever see this code. ++ # If it uses gdata-2.0.5 through 2.0.7, it would otherwise give an error ++ # about a resumable uploader that it doesn't have. This avoids that error. ++ # If it uses gdata-2.0.8, 2.0.9, or 2.0.11 it can't upload docs due to an SSL error. ++ # If it uses gdata-2.0.10, 2.0.12, 2.0.13, 2.0.14 this should allow it to ++ # upload all allowable file types. ++ ++ if hasattr(gdata.client,"ResumableUploader"): ++ f = open(path) ++ file_size = os.path.getsize(f.name) ++ uploader = gdata.client.ResumableUploader( ++ self, f, content_type, file_size, chunk_size=1048576, ++ desired_class=gdata.data.GDEntry) ++ ++ # Set metadata for our upload. ++ entry = gdata.data.GDEntry(title=atom.data.Title(text=entry_title)) ++ new_entry = uploader.UploadFile('/feeds/upload/create-session/default/private/full', entry=entry) ++ # These might be useful for a verbose debug statement: ++ # print 'Document uploaded: ' + new_entry.title.text ++ # print 'Quota used: %s' % new_entry.quota_bytes_used.text ++ f.close() ++ ++ return new_entry ++ ++ else: ++ # If we have reached this point, we must be in gdata-2.0.5 through 2.0.7 ++ # The upload is guaranteed to fail, so the self.upload call is here to ++ # return whatever the caller wanted. ++ return self.upload(path, entry_title, post_uri, content_type) ++ + SERVICE_CLASS = DocsClientCL diff -Nru googlecl-0.9.13/debian/patches/series googlecl-0.9.13/debian/patches/series --- googlecl-0.9.13/debian/patches/series 1970-01-01 03:00:00.000000000 +0300 +++ googlecl-0.9.13/debian/patches/series 2012-08-31 14:48:18.000000000 +0400 @@ -0,0 +1 @@ +fix_664989.patch
From: Dmitry Shachnev <[email protected]> Description: Fix Docs module not working Bug-Upstream: http://code.google.com/p/googlecl/issues/detail?id=449 Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=664989 Index: src/googlecl/docs/client.py =================================================================== --- a/src/googlecl/docs/client.py +++ b/src/googlecl/docs/client.py @@ -37,7 +37,7 @@ import googlecl.client from googlecl.docs import SECTION_HEADER import googlecl.docs.base - +import atom.data LOG = logging.getLogger(googlecl.docs.LOGGER_NAME + '.client') @@ -52,8 +52,35 @@ app with a command line interface. """ - DOCLIST_FEED_URI = gdata.docs.client.DOCLIST_FEED_URI + DOCLIST_FEED_URI = '/feeds/default/private/full' + # File extension/mimetype pairs of common format. + # These seem to have disappeared in python-gdata 2.0.15 and 2.0.16, so here + # they are given explicitly. + MIMETYPES = { + 'CSV': 'text/csv', + 'TSV': 'text/tab-separated-values', + 'TAB': 'text/tab-separated-values', + 'DOC': 'application/msword', + 'DOCX': ('application/vnd.openxmlformats-officedocument.' + 'wordprocessingml.document'), + 'ODS': 'application/x-vnd.oasis.opendocument.spreadsheet', + 'ODT': 'application/vnd.oasis.opendocument.text', + 'RTF': 'application/rtf', + 'SXW': 'application/vnd.sun.xml.writer', + 'TXT': 'text/plain', + 'XLS': 'application/vnd.ms-excel', + 'XLSX': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'PDF': 'application/pdf', + 'PNG': 'image/png', + 'PPT': 'application/vnd.ms-powerpoint', + 'PPS': 'application/vnd.ms-powerpoint', + 'HTM': 'text/html', + 'HTML': 'text/html', + 'ZIP': 'application/zip', + 'SWF': 'application/x-shockwave-flash' + } + def __init__(self, config): """Constructor.""" gdata.docs.client.DocsClient.__init__(self, source='GoogleCL') @@ -65,9 +92,8 @@ folder_or_uri) def _determine_content_type(self, file_ext): - from gdata.docs.data import MIMETYPES try: - return MIMETYPES[file_ext.upper()] + return DocsClientCL.MIMETYPES[file_ext.upper()] except KeyError: LOG.info('No supported filetype found for extension %s', file_ext) return None @@ -111,7 +137,7 @@ issue Args: - entry_or_id_or_url: gdata.docs.data.DocsEntry or string representing a + entry_or_id_or_url: gdata.data.GDEntry or string representing a resource id or URL to download the document from (such as the content src link). file_path: str The full path to save the file to. The export @@ -169,11 +195,11 @@ # folder.content.src is the uri to query for documents in that folder. entries.extend(self.GetEntries(folder.content.src, titles, - desired_class=gdata.docs.data.DocList)) + desired_class=gdata.docs.data.ResourceFeed)) else: - entries = self.GetEntries(gdata.docs.client.DOCLIST_FEED_URI, + entries = self.GetEntries(self.DOCLIST_FEED_URI, titles, - desired_class=gdata.docs.data.DocList) + desired_class=gdata.docs.data.ResourceFeed) return entries def get_single_doc(self, title=None, folder_entry_list=None): @@ -192,16 +218,16 @@ if len(folder_entry_list) == 1: return self.GetSingleEntry(folder_entry_list[0].content.src, title, - desired_class=gdata.docs.data.DocList) + desired_class=gdata.docs.data.ResourceFeed) else: entries = self.get_doclist(title, folder_entry_list) # Technically don't need the desired_class for this call # because we have the entries. return self.GetSingleEntry(entries, title) else: - return self.GetSingleEntry(gdata.docs.client.DOCLIST_FEED_URI, + return self.GetSingleEntry(self.DOCLIST_FEED_URI, title, - desired_class=gdata.docs.data.DocList) + desired_class=gdata.docs.data.ResourceFeed) GetSingleDoc = get_single_doc @@ -216,7 +242,7 @@ """ if title: - uri = gdata.docs.client.DOCLIST_FEED_URI + '-/folder' + uri = self.DOCLIST_FEED_URI + '-/folder' folder_entries = self.GetEntries(uri, title) if not folder_entries: LOG.warning('No folder found that matches ' + title) @@ -229,7 +255,7 @@ def is_token_valid(self, test_uri=None): """Check that the token being used is valid.""" if not test_uri: - docs_uri = gdata.docs.client.DOCLIST_FEED_URI + docs_uri = self.DOCLIST_FEED_URI sheets_uri = ('https://spreadsheets.google.com/feeds/spreadsheets' '/private/full') docs_test = googlecl.client.BaseClientCL.IsTokenValid(self, docs_uri) @@ -292,7 +318,35 @@ Returns: Entry representing the document uploaded. """ - return self.upload(path, entry_title, post_uri, content_type) - - + + # GoogleCL that uses gdata-2.0.0 through 2.0.4 won't ever see this code. + # If it uses gdata-2.0.5 through 2.0.7, it would otherwise give an error + # about a resumable uploader that it doesn't have. This avoids that error. + # If it uses gdata-2.0.8, 2.0.9, or 2.0.11 it can't upload docs due to an SSL error. + # If it uses gdata-2.0.10, 2.0.12, 2.0.13, 2.0.14 this should allow it to + # upload all allowable file types. + + if hasattr(gdata.client,"ResumableUploader"): + f = open(path) + file_size = os.path.getsize(f.name) + uploader = gdata.client.ResumableUploader( + self, f, content_type, file_size, chunk_size=1048576, + desired_class=gdata.data.GDEntry) + + # Set metadata for our upload. + entry = gdata.data.GDEntry(title=atom.data.Title(text=entry_title)) + new_entry = uploader.UploadFile('/feeds/upload/create-session/default/private/full', entry=entry) + # These might be useful for a verbose debug statement: + # print 'Document uploaded: ' + new_entry.title.text + # print 'Quota used: %s' % new_entry.quota_bytes_used.text + f.close() + + return new_entry + + else: + # If we have reached this point, we must be in gdata-2.0.5 through 2.0.7 + # The upload is guaranteed to fail, so the self.upload call is here to + # return whatever the caller wanted. + return self.upload(path, entry_title, post_uri, content_type) + SERVICE_CLASS = DocsClientCL

