faset over fra Z3950 til google books
This commit is contained in:
269
python/gdata/docs/__init__.py
Normal file
269
python/gdata/docs/__init__.py
Normal file
@@ -0,0 +1,269 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright 2009 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Contains extensions to Atom objects used with Google Documents."""
|
||||
|
||||
__author__ = ('api.jfisher (Jeff Fisher), '
|
||||
'api.eric@google.com (Eric Bidelman)')
|
||||
|
||||
import atom
|
||||
import gdata
|
||||
|
||||
|
||||
DOCUMENTS_NAMESPACE = 'http://schemas.google.com/docs/2007'
|
||||
|
||||
|
||||
class Scope(atom.AtomBase):
|
||||
"""The DocList ACL scope element"""
|
||||
|
||||
_tag = 'scope'
|
||||
_namespace = gdata.GACL_NAMESPACE
|
||||
_children = atom.AtomBase._children.copy()
|
||||
_attributes = atom.AtomBase._attributes.copy()
|
||||
_attributes['value'] = 'value'
|
||||
_attributes['type'] = 'type'
|
||||
|
||||
def __init__(self, value=None, type=None, extension_elements=None,
|
||||
extension_attributes=None, text=None):
|
||||
self.value = value
|
||||
self.type = type
|
||||
self.text = text
|
||||
self.extension_elements = extension_elements or []
|
||||
self.extension_attributes = extension_attributes or {}
|
||||
|
||||
|
||||
class Role(atom.AtomBase):
|
||||
"""The DocList ACL role element"""
|
||||
|
||||
_tag = 'role'
|
||||
_namespace = gdata.GACL_NAMESPACE
|
||||
_children = atom.AtomBase._children.copy()
|
||||
_attributes = atom.AtomBase._attributes.copy()
|
||||
_attributes['value'] = 'value'
|
||||
|
||||
def __init__(self, value=None, extension_elements=None,
|
||||
extension_attributes=None, text=None):
|
||||
self.value = value
|
||||
self.text = text
|
||||
self.extension_elements = extension_elements or []
|
||||
self.extension_attributes = extension_attributes or {}
|
||||
|
||||
|
||||
class FeedLink(atom.AtomBase):
|
||||
"""The DocList gd:feedLink element"""
|
||||
|
||||
_tag = 'feedLink'
|
||||
_namespace = gdata.GDATA_NAMESPACE
|
||||
_attributes = atom.AtomBase._attributes.copy()
|
||||
_attributes['rel'] = 'rel'
|
||||
_attributes['href'] = 'href'
|
||||
|
||||
def __init__(self, href=None, rel=None, text=None, extension_elements=None,
|
||||
extension_attributes=None):
|
||||
self.href = href
|
||||
self.rel = rel
|
||||
atom.AtomBase.__init__(self, extension_elements=extension_elements,
|
||||
extension_attributes=extension_attributes, text=text)
|
||||
|
||||
|
||||
class ResourceId(atom.AtomBase):
|
||||
"""The DocList gd:resourceId element"""
|
||||
|
||||
_tag = 'resourceId'
|
||||
_namespace = gdata.GDATA_NAMESPACE
|
||||
_children = atom.AtomBase._children.copy()
|
||||
_attributes = atom.AtomBase._attributes.copy()
|
||||
_attributes['value'] = 'value'
|
||||
|
||||
def __init__(self, value=None, extension_elements=None,
|
||||
extension_attributes=None, text=None):
|
||||
self.value = value
|
||||
self.text = text
|
||||
self.extension_elements = extension_elements or []
|
||||
self.extension_attributes = extension_attributes or {}
|
||||
|
||||
|
||||
class LastModifiedBy(atom.Person):
|
||||
"""The DocList gd:lastModifiedBy element"""
|
||||
|
||||
_tag = 'lastModifiedBy'
|
||||
_namespace = gdata.GDATA_NAMESPACE
|
||||
|
||||
|
||||
class LastViewed(atom.Person):
|
||||
"""The DocList gd:lastViewed element"""
|
||||
|
||||
_tag = 'lastViewed'
|
||||
_namespace = gdata.GDATA_NAMESPACE
|
||||
|
||||
|
||||
class WritersCanInvite(atom.AtomBase):
|
||||
"""The DocList docs:writersCanInvite element"""
|
||||
|
||||
_tag = 'writersCanInvite'
|
||||
_namespace = DOCUMENTS_NAMESPACE
|
||||
_attributes = atom.AtomBase._attributes.copy()
|
||||
_attributes['value'] = 'value'
|
||||
|
||||
|
||||
class DocumentListEntry(gdata.GDataEntry):
|
||||
"""The Google Documents version of an Atom Entry"""
|
||||
|
||||
_tag = gdata.GDataEntry._tag
|
||||
_namespace = atom.ATOM_NAMESPACE
|
||||
_children = gdata.GDataEntry._children.copy()
|
||||
_attributes = gdata.GDataEntry._attributes.copy()
|
||||
_children['{%s}feedLink' % gdata.GDATA_NAMESPACE] = ('feedLink', FeedLink)
|
||||
_children['{%s}resourceId' % gdata.GDATA_NAMESPACE] = ('resourceId',
|
||||
ResourceId)
|
||||
_children['{%s}lastModifiedBy' % gdata.GDATA_NAMESPACE] = ('lastModifiedBy',
|
||||
LastModifiedBy)
|
||||
_children['{%s}lastViewed' % gdata.GDATA_NAMESPACE] = ('lastViewed',
|
||||
LastViewed)
|
||||
_children['{%s}writersCanInvite' % DOCUMENTS_NAMESPACE] = (
|
||||
'writersCanInvite', WritersCanInvite)
|
||||
|
||||
def __init__(self, resourceId=None, feedLink=None, lastViewed=None,
|
||||
lastModifiedBy=None, writersCanInvite=None, author=None,
|
||||
category=None, content=None, atom_id=None, link=None,
|
||||
published=None, title=None, updated=None, text=None,
|
||||
extension_elements=None, extension_attributes=None):
|
||||
self.feedLink = feedLink
|
||||
self.lastViewed = lastViewed
|
||||
self.lastModifiedBy = lastModifiedBy
|
||||
self.resourceId = resourceId
|
||||
self.writersCanInvite = writersCanInvite
|
||||
gdata.GDataEntry.__init__(
|
||||
self, author=author, category=category, content=content,
|
||||
atom_id=atom_id, link=link, published=published, title=title,
|
||||
updated=updated, extension_elements=extension_elements,
|
||||
extension_attributes=extension_attributes, text=text)
|
||||
|
||||
def GetAclLink(self):
|
||||
"""Extracts the DocListEntry's <gd:feedLink>.
|
||||
|
||||
Returns:
|
||||
A FeedLink object.
|
||||
"""
|
||||
return self.feedLink
|
||||
|
||||
def GetDocumentType(self):
|
||||
"""Extracts the type of document from the DocListEntry.
|
||||
|
||||
This method returns the type of document the DocListEntry
|
||||
represents. Possible values are document, presentation,
|
||||
spreadsheet, folder, or pdf.
|
||||
|
||||
Returns:
|
||||
A string representing the type of document.
|
||||
"""
|
||||
if self.category:
|
||||
for category in self.category:
|
||||
if category.scheme == gdata.GDATA_NAMESPACE + '#kind':
|
||||
return category.label
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def DocumentListEntryFromString(xml_string):
|
||||
"""Converts an XML string into a DocumentListEntry object.
|
||||
|
||||
Args:
|
||||
xml_string: string The XML describing a Document List feed entry.
|
||||
|
||||
Returns:
|
||||
A DocumentListEntry object corresponding to the given XML.
|
||||
"""
|
||||
return atom.CreateClassFromXMLString(DocumentListEntry, xml_string)
|
||||
|
||||
|
||||
class DocumentListAclEntry(gdata.GDataEntry):
|
||||
"""A DocList ACL Entry flavor of an Atom Entry"""
|
||||
|
||||
_tag = gdata.GDataEntry._tag
|
||||
_namespace = gdata.GDataEntry._namespace
|
||||
_children = gdata.GDataEntry._children.copy()
|
||||
_attributes = gdata.GDataEntry._attributes.copy()
|
||||
_children['{%s}scope' % gdata.GACL_NAMESPACE] = ('scope', Scope)
|
||||
_children['{%s}role' % gdata.GACL_NAMESPACE] = ('role', Role)
|
||||
|
||||
def __init__(self, category=None, atom_id=None, link=None,
|
||||
title=None, updated=None, scope=None, role=None,
|
||||
extension_elements=None, extension_attributes=None, text=None):
|
||||
gdata.GDataEntry.__init__(self, author=None, category=category,
|
||||
content=None, atom_id=atom_id, link=link,
|
||||
published=None, title=title,
|
||||
updated=updated, text=None)
|
||||
self.scope = scope
|
||||
self.role = role
|
||||
|
||||
|
||||
def DocumentListAclEntryFromString(xml_string):
|
||||
"""Converts an XML string into a DocumentListAclEntry object.
|
||||
|
||||
Args:
|
||||
xml_string: string The XML describing a Document List ACL feed entry.
|
||||
|
||||
Returns:
|
||||
A DocumentListAclEntry object corresponding to the given XML.
|
||||
"""
|
||||
return atom.CreateClassFromXMLString(DocumentListAclEntry, xml_string)
|
||||
|
||||
|
||||
class DocumentListFeed(gdata.GDataFeed):
|
||||
"""A feed containing a list of Google Documents Items"""
|
||||
|
||||
_tag = gdata.GDataFeed._tag
|
||||
_namespace = atom.ATOM_NAMESPACE
|
||||
_children = gdata.GDataFeed._children.copy()
|
||||
_attributes = gdata.GDataFeed._attributes.copy()
|
||||
_children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry',
|
||||
[DocumentListEntry])
|
||||
|
||||
|
||||
def DocumentListFeedFromString(xml_string):
|
||||
"""Converts an XML string into a DocumentListFeed object.
|
||||
|
||||
Args:
|
||||
xml_string: string The XML describing a DocumentList feed.
|
||||
|
||||
Returns:
|
||||
A DocumentListFeed object corresponding to the given XML.
|
||||
"""
|
||||
return atom.CreateClassFromXMLString(DocumentListFeed, xml_string)
|
||||
|
||||
|
||||
class DocumentListAclFeed(gdata.GDataFeed):
|
||||
"""A DocList ACL feed flavor of a Atom feed"""
|
||||
|
||||
_tag = gdata.GDataFeed._tag
|
||||
_namespace = atom.ATOM_NAMESPACE
|
||||
_children = gdata.GDataFeed._children.copy()
|
||||
_attributes = gdata.GDataFeed._attributes.copy()
|
||||
_children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry',
|
||||
[DocumentListAclEntry])
|
||||
|
||||
|
||||
def DocumentListAclFeedFromString(xml_string):
|
||||
"""Converts an XML string into a DocumentListAclFeed object.
|
||||
|
||||
Args:
|
||||
xml_string: string The XML describing a DocumentList feed.
|
||||
|
||||
Returns:
|
||||
A DocumentListFeed object corresponding to the given XML.
|
||||
"""
|
||||
return atom.CreateClassFromXMLString(DocumentListAclFeed, xml_string)
|
611
python/gdata/docs/client.py
Normal file
611
python/gdata/docs/client.py
Normal file
@@ -0,0 +1,611 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright 2009 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""DocsClient extends gdata.client.GDClient to streamline DocList API calls."""
|
||||
|
||||
|
||||
__author__ = 'e.bidelman (Eric Bidelman)'
|
||||
|
||||
import mimetypes
|
||||
import urllib
|
||||
import atom.data
|
||||
import atom.http_core
|
||||
import gdata.client
|
||||
import gdata.docs.data
|
||||
import gdata.gauth
|
||||
|
||||
|
||||
# Feed URI templates
|
||||
DOCLIST_FEED_URI = '/feeds/default/private/full/'
|
||||
FOLDERS_FEED_TEMPLATE = DOCLIST_FEED_URI + '%s/contents'
|
||||
ACL_FEED_TEMPLATE = DOCLIST_FEED_URI + '%s/acl'
|
||||
REVISIONS_FEED_TEMPLATE = DOCLIST_FEED_URI + '%s/revisions'
|
||||
|
||||
|
||||
class DocsClient(gdata.client.GDClient):
|
||||
"""Client extension for the Google Documents List API."""
|
||||
|
||||
host = 'docs.google.com' # default server for the API
|
||||
api_version = '3.0' # default major version for the service.
|
||||
auth_service = 'writely'
|
||||
auth_scopes = gdata.gauth.AUTH_SCOPES['writely']
|
||||
ssl = True
|
||||
|
||||
def __init__(self, auth_token=None, **kwargs):
|
||||
"""Constructs a new client for the DocList API.
|
||||
|
||||
Args:
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: The other parameters to pass to gdata.client.GDClient constructor.
|
||||
"""
|
||||
gdata.client.GDClient.__init__(self, auth_token=auth_token, **kwargs)
|
||||
|
||||
def get_file_content(self, uri, auth_token=None, **kwargs):
|
||||
"""Fetches the file content from the specified uri.
|
||||
|
||||
This method is useful for downloading/exporting a file within enviornments
|
||||
like Google App Engine, where the user does not have the ability to write
|
||||
the file to a local disk.
|
||||
|
||||
Args:
|
||||
uri: str The full URL to fetch the file contents from.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.request().
|
||||
|
||||
Returns:
|
||||
The binary file content.
|
||||
|
||||
Raises:
|
||||
gdata.client.RequestError: on error response from server.
|
||||
"""
|
||||
server_response = self.request('GET', uri, auth_token=auth_token, **kwargs)
|
||||
if server_response.status != 200:
|
||||
raise gdata.client.RequestError, {'status': server_response.status,
|
||||
'reason': server_response.reason,
|
||||
'body': server_response.read()}
|
||||
return server_response.read()
|
||||
|
||||
GetFileContent = get_file_content
|
||||
|
||||
def _download_file(self, uri, file_path, auth_token=None, **kwargs):
|
||||
"""Downloads a file to disk from the specified URI.
|
||||
|
||||
Note: to download a file in memory, use the GetFileContent() method.
|
||||
|
||||
Args:
|
||||
uri: str The full URL to download the file from.
|
||||
file_path: str The full path to save the file to.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.get_file_content().
|
||||
|
||||
Raises:
|
||||
gdata.client.RequestError: on error response from server.
|
||||
"""
|
||||
f = open(file_path, 'wb')
|
||||
try:
|
||||
f.write(self.get_file_content(uri, auth_token=auth_token, **kwargs))
|
||||
except gdata.client.RequestError, e:
|
||||
f.close()
|
||||
raise e
|
||||
f.flush()
|
||||
f.close()
|
||||
|
||||
_DownloadFile = _download_file
|
||||
|
||||
def get_doclist(self, uri=None, limit=None, auth_token=None, **kwargs):
|
||||
"""Retrieves the main doclist feed containing the user's items.
|
||||
|
||||
Args:
|
||||
uri: str (optional) A URI to query the doclist feed.
|
||||
limit: int (optional) A maximum cap for the number of results to
|
||||
return in the feed. By default, the API returns a maximum of 100
|
||||
per page. Thus, if you set limit=5000, you will get <= 5000
|
||||
documents (guarenteed no more than 5000), and will need to follow the
|
||||
feed's next links (feed.GetNextLink()) to the rest. See
|
||||
get_everything(). Similarly, if you set limit=50, only <= 50
|
||||
documents are returned. Note: if the max-results parameter is set in
|
||||
the uri parameter, it is chosen over a value set for limit.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.get_feed().
|
||||
|
||||
Returns:
|
||||
gdata.docs.data.DocList feed.
|
||||
"""
|
||||
if uri is None:
|
||||
uri = DOCLIST_FEED_URI
|
||||
|
||||
if isinstance(uri, (str, unicode)):
|
||||
uri = atom.http_core.Uri.parse_uri(uri)
|
||||
|
||||
# Add max-results param if it wasn't included in the uri.
|
||||
if limit is not None and not 'max-results' in uri.query:
|
||||
uri.query['max-results'] = limit
|
||||
|
||||
return self.get_feed(uri, desired_class=gdata.docs.data.DocList,
|
||||
auth_token=auth_token, **kwargs)
|
||||
|
||||
GetDocList = get_doclist
|
||||
|
||||
def get_doc(self, resource_id, etag=None, auth_token=None, **kwargs):
|
||||
"""Retrieves a particular document given by its resource id.
|
||||
|
||||
Args:
|
||||
resource_id: str The document/item's resource id. Example spreadsheet:
|
||||
'spreadsheet%3A0A1234567890'.
|
||||
etag: str (optional) The document/item's etag value to be used in a
|
||||
conditional GET. See http://code.google.com/apis/documents/docs/3.0/
|
||||
developers_guide_protocol.html#RetrievingCached.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.get_entry().
|
||||
|
||||
Returns:
|
||||
A gdata.docs.data.DocsEntry object representing the retrieved entry.
|
||||
|
||||
Raises:
|
||||
ValueError if the resource_id is not a valid format.
|
||||
"""
|
||||
match = gdata.docs.data.RESOURCE_ID_PATTERN.match(resource_id)
|
||||
if match is None:
|
||||
raise ValueError, 'Invalid resource id: %s' % resource_id
|
||||
return self.get_entry(
|
||||
DOCLIST_FEED_URI + resource_id, etag=etag,
|
||||
desired_class=gdata.docs.data.DocsEntry,
|
||||
auth_token=auth_token, **kwargs)
|
||||
|
||||
GetDoc = get_doc
|
||||
|
||||
def get_everything(self, uri=None, auth_token=None, **kwargs):
|
||||
"""Retrieves the user's entire doc list.
|
||||
|
||||
The method makes multiple HTTP requests (by following the feed's next links)
|
||||
in order to fetch the user's entire document list.
|
||||
|
||||
Args:
|
||||
uri: str (optional) A URI to query the doclist feed with.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.GetDocList().
|
||||
|
||||
Returns:
|
||||
A list of gdata.docs.data.DocsEntry objects representing the retrieved
|
||||
entries.
|
||||
"""
|
||||
if uri is None:
|
||||
uri = DOCLIST_FEED_URI
|
||||
|
||||
feed = self.GetDocList(uri=uri, auth_token=auth_token, **kwargs)
|
||||
entries = feed.entry
|
||||
|
||||
while feed.GetNextLink() is not None:
|
||||
feed = self.GetDocList(
|
||||
feed.GetNextLink().href, auth_token=auth_token, **kwargs)
|
||||
entries.extend(feed.entry)
|
||||
|
||||
return entries
|
||||
|
||||
GetEverything = get_everything
|
||||
|
||||
def get_acl_permissions(self, resource_id, auth_token=None, **kwargs):
|
||||
"""Retrieves a the ACL sharing permissions for a document.
|
||||
|
||||
Args:
|
||||
resource_id: str The document/item's resource id. Example for pdf:
|
||||
'pdf%3A0A1234567890'.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.get_feed().
|
||||
|
||||
Returns:
|
||||
A gdata.docs.data.AclFeed object representing the document's ACL entries.
|
||||
|
||||
Raises:
|
||||
ValueError if the resource_id is not a valid format.
|
||||
"""
|
||||
match = gdata.docs.data.RESOURCE_ID_PATTERN.match(resource_id)
|
||||
if match is None:
|
||||
raise ValueError, 'Invalid resource id: %s' % resource_id
|
||||
|
||||
return self.get_feed(
|
||||
ACL_FEED_TEMPLATE % resource_id, desired_class=gdata.docs.data.AclFeed,
|
||||
auth_token=auth_token, **kwargs)
|
||||
|
||||
GetAclPermissions = get_acl_permissions
|
||||
|
||||
def get_revisions(self, resource_id, auth_token=None, **kwargs):
|
||||
"""Retrieves the revision history for a document.
|
||||
|
||||
Args:
|
||||
resource_id: str The document/item's resource id. Example for pdf:
|
||||
'pdf%3A0A1234567890'.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.get_feed().
|
||||
|
||||
Returns:
|
||||
A gdata.docs.data.RevisionFeed representing the document's revisions.
|
||||
|
||||
Raises:
|
||||
ValueError if the resource_id is not a valid format.
|
||||
"""
|
||||
match = gdata.docs.data.RESOURCE_ID_PATTERN.match(resource_id)
|
||||
if match is None:
|
||||
raise ValueError, 'Invalid resource id: %s' % resource_id
|
||||
|
||||
return self.get_feed(
|
||||
REVISIONS_FEED_TEMPLATE % resource_id,
|
||||
desired_class=gdata.docs.data.RevisionFeed, auth_token=auth_token,
|
||||
**kwargs)
|
||||
|
||||
GetRevisions = get_revisions
|
||||
|
||||
def create(self, doc_type, title, folder_or_id=None, writers_can_invite=None,
|
||||
auth_token=None, **kwargs):
|
||||
"""Creates a new item in the user's doclist.
|
||||
|
||||
Args:
|
||||
doc_type: str The type of object to create. For example: 'document',
|
||||
'spreadsheet', 'folder', 'presentation'.
|
||||
title: str A title for the document.
|
||||
folder_or_id: gdata.docs.data.DocsEntry or str (optional) Folder entry or
|
||||
the resouce id of a folder to create the object under. Note: A valid
|
||||
resource id for a folder is of the form: folder%3Afolder_id.
|
||||
writers_can_invite: bool (optional) False prevents collaborators from
|
||||
being able to invite others to edit or view the document.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.post().
|
||||
|
||||
Returns:
|
||||
gdata.docs.data.DocsEntry containing information newly created item.
|
||||
"""
|
||||
entry = gdata.docs.data.DocsEntry(title=atom.data.Title(text=title))
|
||||
entry.category.append(gdata.docs.data.make_kind_category(doc_type))
|
||||
|
||||
if isinstance(writers_can_invite, gdata.docs.data.WritersCanInvite):
|
||||
entry.writers_can_invite = writers_can_invite
|
||||
elif isinstance(writers_can_invite, bool):
|
||||
entry.writers_can_invite = gdata.docs.data.WritersCanInvite(
|
||||
value=str(writers_can_invite).lower())
|
||||
|
||||
uri = DOCLIST_FEED_URI
|
||||
|
||||
if folder_or_id is not None:
|
||||
if isinstance(folder_or_id, gdata.docs.data.DocsEntry):
|
||||
# Verify that we're uploading the resource into to a folder.
|
||||
if folder_or_id.get_document_type() == gdata.docs.data.FOLDER_LABEL:
|
||||
uri = folder_or_id.content.src
|
||||
else:
|
||||
raise gdata.client.Error, 'Trying to upload item to a non-folder.'
|
||||
else:
|
||||
uri = FOLDERS_FEED_TEMPLATE % folder_or_id
|
||||
|
||||
return self.post(entry, uri, auth_token=auth_token, **kwargs)
|
||||
|
||||
Create = create
|
||||
|
||||
def copy(self, source_entry, title, auth_token=None, **kwargs):
|
||||
"""Copies a native Google document, spreadsheet, or presentation.
|
||||
|
||||
Note: arbitrary file types and PDFs do not support this feature.
|
||||
|
||||
Args:
|
||||
source_entry: gdata.docs.data.DocsEntry An object representing the source
|
||||
document/folder.
|
||||
title: str A title for the new document.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.post().
|
||||
|
||||
Returns:
|
||||
A gdata.docs.data.DocsEntry of the duplicated document.
|
||||
"""
|
||||
entry = gdata.docs.data.DocsEntry(
|
||||
title=atom.data.Title(text=title),
|
||||
id=atom.data.Id(text=source_entry.GetSelfLink().href))
|
||||
return self.post(entry, DOCLIST_FEED_URI, auth_token=auth_token, **kwargs)
|
||||
|
||||
Copy = copy
|
||||
|
||||
def move(self, source_entry, folder_entry=None,
|
||||
keep_in_folders=False, auth_token=None, **kwargs):
|
||||
"""Moves an item into a different folder (or to the root document list).
|
||||
|
||||
Args:
|
||||
source_entry: gdata.docs.data.DocsEntry An object representing the source
|
||||
document/folder.
|
||||
folder_entry: gdata.docs.data.DocsEntry (optional) An object representing
|
||||
the destination folder. If None, set keep_in_folders to
|
||||
True to remove the item from all parent folders.
|
||||
keep_in_folders: boolean (optional) If True, the source entry
|
||||
is not removed from any existing parent folders it is in.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.post().
|
||||
|
||||
Returns:
|
||||
A gdata.docs.data.DocsEntry of the moved entry or True if just moving the
|
||||
item out of all folders (e.g. Move(source_entry)).
|
||||
"""
|
||||
entry = gdata.docs.data.DocsEntry(id=source_entry.id)
|
||||
|
||||
# Remove the item from any folders it is already in.
|
||||
if not keep_in_folders:
|
||||
for folder in source_entry.InFolders():
|
||||
self.delete(
|
||||
'%s/contents/%s' % (
|
||||
folder.href,
|
||||
urllib.quote(source_entry.resource_id.text)),
|
||||
force=True)
|
||||
|
||||
# If we're moving the resource into a folder, verify it is a folder entry.
|
||||
if folder_entry is not None:
|
||||
if folder_entry.get_document_type() == gdata.docs.data.FOLDER_LABEL:
|
||||
return self.post(entry, folder_entry.content.src,
|
||||
auth_token=auth_token, **kwargs)
|
||||
else:
|
||||
raise gdata.client.Error, 'Trying to move item into a non-folder.'
|
||||
|
||||
return True
|
||||
|
||||
Move = move
|
||||
|
||||
def upload(self, media, title, folder_or_uri=None, content_type=None,
|
||||
auth_token=None, **kwargs):
|
||||
"""Uploads a file to Google Docs.
|
||||
|
||||
Args:
|
||||
media: A gdata.data.MediaSource object containing the file to be
|
||||
uploaded or a string of the filepath.
|
||||
title: str The title of the document on the server after being
|
||||
uploaded.
|
||||
folder_or_uri: gdata.docs.data.DocsEntry or str (optional) An object with
|
||||
a link to the folder or the uri to upload the file to.
|
||||
Note: A valid uri for a folder is of the form:
|
||||
/feeds/default/private/full/folder%3Afolder_id/contents
|
||||
content_type: str (optional) The file's mimetype. If not provided, the
|
||||
one in the media source object is used or the mimetype is inferred
|
||||
from the filename (if media is a string). When media is a filename,
|
||||
it is always recommended to pass in a content type.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.post().
|
||||
|
||||
Returns:
|
||||
A gdata.docs.data.DocsEntry containing information about uploaded doc.
|
||||
"""
|
||||
uri = None
|
||||
if folder_or_uri is not None:
|
||||
if isinstance(folder_or_uri, gdata.docs.data.DocsEntry):
|
||||
# Verify that we're uploading the resource into to a folder.
|
||||
if folder_or_uri.get_document_type() == gdata.docs.data.FOLDER_LABEL:
|
||||
uri = folder_or_uri.content.src
|
||||
else:
|
||||
raise gdata.client.Error, 'Trying to upload item to a non-folder.'
|
||||
else:
|
||||
uri = folder_or_uri
|
||||
else:
|
||||
uri = DOCLIST_FEED_URI
|
||||
|
||||
# Create media source if media is a filepath.
|
||||
if isinstance(media, (str, unicode)):
|
||||
mimetype = mimetypes.guess_type(media)[0]
|
||||
if mimetype is None and content_type is None:
|
||||
raise ValueError, ("Unknown mimetype. Please pass in the file's "
|
||||
"content_type")
|
||||
else:
|
||||
media = gdata.data.MediaSource(file_path=media,
|
||||
content_type=content_type)
|
||||
|
||||
entry = gdata.docs.data.DocsEntry(title=atom.data.Title(text=title))
|
||||
|
||||
return self.post(entry, uri, media_source=media,
|
||||
desired_class=gdata.docs.data.DocsEntry,
|
||||
auth_token=auth_token, **kwargs)
|
||||
|
||||
Upload = upload
|
||||
|
||||
def download(self, entry_or_id_or_url, file_path, extra_params=None,
|
||||
auth_token=None, **kwargs):
|
||||
"""Downloads a file from the Document List to local disk.
|
||||
|
||||
Note: to download a file in memory, use the GetFileContent() method.
|
||||
|
||||
Args:
|
||||
entry_or_id_or_url: gdata.docs.data.DocsEntry 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.
|
||||
extra_params: dict (optional) A map of any further parameters to control
|
||||
how the document is downloaded/exported. For example, exporting a
|
||||
spreadsheet as a .csv: extra_params={'gid': 0, 'exportFormat': 'csv'}
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self._download_file().
|
||||
|
||||
Raises:
|
||||
gdata.client.RequestError if the download URL is malformed or the server's
|
||||
response was not successful.
|
||||
ValueError if entry_or_id_or_url was a resource id for a filetype
|
||||
in which the download link cannot be manually constructed (e.g. pdf).
|
||||
"""
|
||||
if isinstance(entry_or_id_or_url, gdata.docs.data.DocsEntry):
|
||||
url = entry_or_id_or_url.content.src
|
||||
else:
|
||||
if gdata.docs.data.RESOURCE_ID_PATTERN.match(entry_or_id_or_url):
|
||||
url = gdata.docs.data.make_content_link_from_resource_id(
|
||||
entry_or_id_or_url)
|
||||
else:
|
||||
url = entry_or_id_or_url
|
||||
|
||||
if extra_params is not None:
|
||||
if 'exportFormat' in extra_params and url.find('/Export?') == -1:
|
||||
raise gdata.client.Error, ('This entry type cannot be exported '
|
||||
'as a different format.')
|
||||
|
||||
if 'gid' in extra_params and url.find('spreadsheets') == -1:
|
||||
raise gdata.client.Error, 'gid param is not valid for this doc type.'
|
||||
|
||||
url += '&' + urllib.urlencode(extra_params)
|
||||
|
||||
self._download_file(url, file_path, auth_token=auth_token, **kwargs)
|
||||
|
||||
Download = download
|
||||
|
||||
def export(self, entry_or_id_or_url, file_path, gid=None, auth_token=None,
|
||||
**kwargs):
|
||||
"""Exports a document from the Document List in a different format.
|
||||
|
||||
Args:
|
||||
entry_or_id_or_url: gdata.docs.data.DocsEntry 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
|
||||
format is inferred from the the file extension.
|
||||
gid: str (optional) grid id for downloading a single grid of a
|
||||
spreadsheet. The param should only be used for .csv and .tsv
|
||||
spreadsheet exports.
|
||||
auth_token: (optional) gdata.gauth.ClientLoginToken, AuthSubToken, or
|
||||
OAuthToken which authorizes this client to edit the user's data.
|
||||
kwargs: Other parameters to pass to self.download().
|
||||
|
||||
Raises:
|
||||
gdata.client.RequestError if the download URL is malformed or the server's
|
||||
response was not successful.
|
||||
"""
|
||||
extra_params = {}
|
||||
|
||||
match = gdata.docs.data.FILE_EXT_PATTERN.match(file_path)
|
||||
if match:
|
||||
extra_params['exportFormat'] = match.group(1)
|
||||
|
||||
if gid is not None:
|
||||
extra_params['gid'] = gid
|
||||
|
||||
self.download(entry_or_id_or_url, file_path, extra_params,
|
||||
auth_token=auth_token, **kwargs)
|
||||
|
||||
Export = export
|
||||
|
||||
|
||||
class DocsQuery(gdata.client.Query):
|
||||
|
||||
def __init__(self, title=None, title_exact=None, opened_min=None,
|
||||
opened_max=None, edited_min=None, edited_max=None, owner=None,
|
||||
writer=None, reader=None, show_folders=None,
|
||||
show_deleted=None, ocr=None, target_language=None,
|
||||
source_language=None, convert=None, **kwargs):
|
||||
"""Constructs a query URL for the Google Documents List API.
|
||||
|
||||
Args:
|
||||
title: str (optional) Specifies the search terms for the title of a
|
||||
document. This parameter used without title_exact will only
|
||||
submit partial queries, not exact queries.
|
||||
title_exact: str (optional) Meaningless without title. Possible values
|
||||
are 'true' and 'false'. Note: Matches are case-insensitive.
|
||||
opened_min: str (optional) Lower bound on the last time a document was
|
||||
opened by the current user. Use the RFC 3339 timestamp
|
||||
format. For example: opened_min='2005-08-09T09:57:00-08:00'.
|
||||
opened_max: str (optional) Upper bound on the last time a document was
|
||||
opened by the current user. (See also opened_min.)
|
||||
edited_min: str (optional) Lower bound on the last time a document was
|
||||
edited by the current user. This value corresponds to the
|
||||
edited.text value in the doc's entry object, which
|
||||
represents changes to the document's content or metadata.
|
||||
Use the RFC 3339 timestamp format. For example:
|
||||
edited_min='2005-08-09T09:57:00-08:00'
|
||||
edited_max: str (optional) Upper bound on the last time a document was
|
||||
edited by the user. (See also edited_min.)
|
||||
owner: str (optional) Searches for documents with a specific owner. Use
|
||||
the email address of the owner. For example:
|
||||
owner='user@gmail.com'
|
||||
writer: str (optional) Searches for documents which can be written to
|
||||
by specific users. Use a single email address or a comma
|
||||
separated list of email addresses. For example:
|
||||
writer='user1@gmail.com,user@example.com'
|
||||
reader: str (optional) Searches for documents which can be read by
|
||||
specific users. (See also writer.)
|
||||
show_folders: str (optional) Specifies whether the query should return
|
||||
folders as well as documents. Possible values are 'true'
|
||||
and 'false'. Default is false.
|
||||
show_deleted: str (optional) Specifies whether the query should return
|
||||
documents which are in the trash as well as other
|
||||
documents. Possible values are 'true' and 'false'.
|
||||
Default is false.
|
||||
ocr: str (optional) Specifies whether to attempt OCR on a .jpg, .png, or
|
||||
.gif upload. Possible values are 'true' and 'false'. Default is
|
||||
false. See OCR in the Protocol Guide:
|
||||
http://code.google.com/apis/documents/docs/3.0/developers_guide_protocol.html#OCR
|
||||
target_language: str (optional) Specifies the language to translate a
|
||||
document into. See Document Translation in the Protocol
|
||||
Guide for a table of possible values:
|
||||
http://code.google.com/apis/documents/docs/3.0/developers_guide_protocol.html#DocumentTranslation
|
||||
source_language: str (optional) Specifies the source language of the
|
||||
original document. Optional when using the translation
|
||||
service. If not provided, Google will attempt to
|
||||
auto-detect the source language. See Document
|
||||
Translation in the Protocol Guide for a table of
|
||||
possible values (link in target_language).
|
||||
convert: str (optional) Used when uploading arbitrary file types to
|
||||
specity if document-type uploads should convert to a native
|
||||
Google Docs format. Possible values are 'true' and 'false'.
|
||||
The default is 'true'.
|
||||
"""
|
||||
gdata.client.Query.__init__(self, **kwargs)
|
||||
self.convert = convert
|
||||
self.title = title
|
||||
self.title_exact = title_exact
|
||||
self.opened_min = opened_min
|
||||
self.opened_max = opened_max
|
||||
self.edited_min = edited_min
|
||||
self.edited_max = edited_max
|
||||
self.owner = owner
|
||||
self.writer = writer
|
||||
self.reader = reader
|
||||
self.show_folders = show_folders
|
||||
self.show_deleted = show_deleted
|
||||
self.ocr = ocr
|
||||
self.target_language = target_language
|
||||
self.source_language = source_language
|
||||
|
||||
def modify_request(self, http_request):
|
||||
gdata.client._add_query_param('convert', self.convert, http_request)
|
||||
gdata.client._add_query_param('title', self.title, http_request)
|
||||
gdata.client._add_query_param('title-exact', self.title_exact,
|
||||
http_request)
|
||||
gdata.client._add_query_param('opened-min', self.opened_min, http_request)
|
||||
gdata.client._add_query_param('opened-max', self.opened_max, http_request)
|
||||
gdata.client._add_query_param('edited-min', self.edited_min, http_request)
|
||||
gdata.client._add_query_param('edited-max', self.edited_max, http_request)
|
||||
gdata.client._add_query_param('owner', self.owner, http_request)
|
||||
gdata.client._add_query_param('writer', self.writer, http_request)
|
||||
gdata.client._add_query_param('reader', self.reader, http_request)
|
||||
gdata.client._add_query_param('showfolders', self.show_folders,
|
||||
http_request)
|
||||
gdata.client._add_query_param('showdeleted', self.show_deleted,
|
||||
http_request)
|
||||
gdata.client._add_query_param('ocr', self.ocr, http_request)
|
||||
gdata.client._add_query_param('targetLanguage', self.target_language,
|
||||
http_request)
|
||||
gdata.client._add_query_param('sourceLanguage', self.source_language,
|
||||
http_request)
|
||||
gdata.client.Query.modify_request(self, http_request)
|
||||
|
||||
ModifyRequest = modify_request
|
280
python/gdata/docs/data.py
Normal file
280
python/gdata/docs/data.py
Normal file
@@ -0,0 +1,280 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright 2009 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Data model classes for parsing and generating XML for the DocList Data API"""
|
||||
|
||||
__author__ = 'e.bidelman (Eric Bidelman)'
|
||||
|
||||
|
||||
import re
|
||||
import atom.core
|
||||
import atom.data
|
||||
import gdata.acl.data
|
||||
import gdata.data
|
||||
|
||||
DOCUMENTS_NS = 'http://schemas.google.com/docs/2007'
|
||||
DOCUMENTS_TEMPLATE = '{http://schemas.google.com/docs/2007}%s'
|
||||
ACL_FEEDLINK_REL = 'http://schemas.google.com/acl/2007#accessControlList'
|
||||
REVISION_FEEDLINK_REL = DOCUMENTS_NS + '/revisions'
|
||||
|
||||
# XML Namespaces used in Google Documents entities.
|
||||
DATA_KIND_SCHEME = 'http://schemas.google.com/g/2005#kind'
|
||||
DOCUMENT_LABEL = 'document'
|
||||
SPREADSHEET_LABEL = 'spreadsheet'
|
||||
PRESENTATION_LABEL = 'presentation'
|
||||
FOLDER_LABEL = 'folder'
|
||||
PDF_LABEL = 'pdf'
|
||||
|
||||
LABEL_SCHEME = 'http://schemas.google.com/g/2005/labels'
|
||||
STARRED_LABEL_TERM = LABEL_SCHEME + '#starred'
|
||||
TRASHED_LABEL_TERM = LABEL_SCHEME + '#trashed'
|
||||
HIDDEN_LABEL_TERM = LABEL_SCHEME + '#hidden'
|
||||
MINE_LABEL_TERM = LABEL_SCHEME + '#mine'
|
||||
PRIVATE_LABEL_TERM = LABEL_SCHEME + '#private'
|
||||
SHARED_WITH_DOMAIN_LABEL_TERM = LABEL_SCHEME + '#shared-with-domain'
|
||||
VIEWED_LABEL_TERM = LABEL_SCHEME + '#viewed'
|
||||
|
||||
DOCS_PARENT_LINK_REL = DOCUMENTS_NS + '#parent'
|
||||
DOCS_PUBLISH_LINK_REL = DOCUMENTS_NS + '#publish'
|
||||
|
||||
FILE_EXT_PATTERN = re.compile('.*\.([a-zA-Z]{3,}$)')
|
||||
RESOURCE_ID_PATTERN = re.compile('^([a-z]*)(:|%3A)([\w-]*)$')
|
||||
|
||||
# File extension/mimetype pairs of common format.
|
||||
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 make_kind_category(label):
|
||||
"""Builds the appropriate atom.data.Category for the label passed in.
|
||||
|
||||
Args:
|
||||
label: str The value for the category entry.
|
||||
|
||||
Returns:
|
||||
An atom.data.Category or None if label is None.
|
||||
"""
|
||||
if label is None:
|
||||
return None
|
||||
|
||||
return atom.data.Category(
|
||||
scheme=DATA_KIND_SCHEME, term='%s#%s' % (DOCUMENTS_NS, label), label=label)
|
||||
|
||||
MakeKindCategory = make_kind_category
|
||||
|
||||
def make_content_link_from_resource_id(resource_id):
|
||||
"""Constructs export URL for a given resource.
|
||||
|
||||
Args:
|
||||
resource_id: str The document/item's resource id. Example presentation:
|
||||
'presentation%3A0A1234567890'.
|
||||
|
||||
Raises:
|
||||
gdata.client.ValueError if the resource_id is not a valid format.
|
||||
"""
|
||||
match = RESOURCE_ID_PATTERN.match(resource_id)
|
||||
|
||||
if match:
|
||||
label = match.group(1)
|
||||
doc_id = match.group(3)
|
||||
if label == DOCUMENT_LABEL:
|
||||
return '/feeds/download/documents/Export?docId=%s' % doc_id
|
||||
if label == PRESENTATION_LABEL:
|
||||
return '/feeds/download/presentations/Export?docId=%s' % doc_id
|
||||
if label == SPREADSHEET_LABEL:
|
||||
return ('https://spreadsheets.google.com/feeds/download/spreadsheets/'
|
||||
'Export?key=%s' % doc_id)
|
||||
raise ValueError, ('Invalid resource id: %s, or manually creating the '
|
||||
'download url for this type of doc is not possible'
|
||||
% resource_id)
|
||||
|
||||
MakeContentLinkFromResourceId = make_content_link_from_resource_id
|
||||
|
||||
|
||||
class ResourceId(atom.core.XmlElement):
|
||||
"""The DocList gd:resourceId element."""
|
||||
_qname = gdata.data.GDATA_TEMPLATE % 'resourceId'
|
||||
|
||||
|
||||
class LastModifiedBy(atom.data.Person):
|
||||
"""The DocList gd:lastModifiedBy element."""
|
||||
_qname = gdata.data.GDATA_TEMPLATE % 'lastModifiedBy'
|
||||
|
||||
|
||||
class LastViewed(atom.data.Person):
|
||||
"""The DocList gd:lastViewed element."""
|
||||
_qname = gdata.data.GDATA_TEMPLATE % 'lastViewed'
|
||||
|
||||
|
||||
class WritersCanInvite(atom.core.XmlElement):
|
||||
"""The DocList docs:writersCanInvite element."""
|
||||
_qname = DOCUMENTS_TEMPLATE % 'writersCanInvite'
|
||||
value = 'value'
|
||||
|
||||
|
||||
class QuotaBytesUsed(atom.core.XmlElement):
|
||||
"""The DocList gd:quotaBytesUsed element."""
|
||||
_qname = gdata.data.GDATA_TEMPLATE % 'quotaBytesUsed'
|
||||
|
||||
|
||||
class Publish(atom.core.XmlElement):
|
||||
"""The DocList docs:publish element."""
|
||||
_qname = DOCUMENTS_TEMPLATE % 'publish'
|
||||
value = 'value'
|
||||
|
||||
|
||||
class PublishAuto(atom.core.XmlElement):
|
||||
"""The DocList docs:publishAuto element."""
|
||||
_qname = DOCUMENTS_TEMPLATE % 'publishAuto'
|
||||
value = 'value'
|
||||
|
||||
|
||||
class PublishOutsideDomain(atom.core.XmlElement):
|
||||
"""The DocList docs:publishOutsideDomain element."""
|
||||
_qname = DOCUMENTS_TEMPLATE % 'publishOutsideDomain'
|
||||
value = 'value'
|
||||
|
||||
|
||||
class DocsEntry(gdata.data.GDEntry):
|
||||
"""A DocList version of an Atom Entry."""
|
||||
|
||||
last_viewed = LastViewed
|
||||
last_modified_by = LastModifiedBy
|
||||
resource_id = ResourceId
|
||||
writers_can_invite = WritersCanInvite
|
||||
quota_bytes_used = QuotaBytesUsed
|
||||
feed_link = [gdata.data.FeedLink]
|
||||
|
||||
def get_document_type(self):
|
||||
"""Extracts the type of document this DocsEntry is.
|
||||
|
||||
This method returns the type of document the DocsEntry represents. Possible
|
||||
values are document, presentation, spreadsheet, folder, or pdf.
|
||||
|
||||
Returns:
|
||||
A string representing the type of document.
|
||||
"""
|
||||
if self.category:
|
||||
for category in self.category:
|
||||
if category.scheme == DATA_KIND_SCHEME:
|
||||
return category.label
|
||||
else:
|
||||
return None
|
||||
|
||||
GetDocumentType = get_document_type
|
||||
|
||||
def get_acl_feed_link(self):
|
||||
"""Extracts the DocsEntry's ACL feed <gd:feedLink>.
|
||||
|
||||
Returns:
|
||||
A gdata.data.FeedLink object.
|
||||
"""
|
||||
for feed_link in self.feed_link:
|
||||
if feed_link.rel == ACL_FEEDLINK_REL:
|
||||
return feed_link
|
||||
return None
|
||||
|
||||
GetAclFeedLink = get_acl_feed_link
|
||||
|
||||
def get_revisions_feed_link(self):
|
||||
"""Extracts the DocsEntry's revisions feed <gd:feedLink>.
|
||||
|
||||
Returns:
|
||||
A gdata.data.FeedLink object.
|
||||
"""
|
||||
for feed_link in self.feed_link:
|
||||
if feed_link.rel == REVISION_FEEDLINK_REL:
|
||||
return feed_link
|
||||
return None
|
||||
|
||||
GetRevisionsFeedLink = get_revisions_feed_link
|
||||
|
||||
def in_folders(self):
|
||||
"""Returns the parents link(s) (folders) of this entry."""
|
||||
links = []
|
||||
for link in self.link:
|
||||
if link.rel == DOCS_PARENT_LINK_REL and link.href:
|
||||
links.append(link)
|
||||
return links
|
||||
|
||||
InFolders = in_folders
|
||||
|
||||
|
||||
class Acl(gdata.acl.data.AclEntry):
|
||||
"""A document ACL entry."""
|
||||
|
||||
|
||||
class DocList(gdata.data.GDFeed):
|
||||
"""The main DocList feed containing a list of Google Documents."""
|
||||
entry = [DocsEntry]
|
||||
|
||||
|
||||
class AclFeed(gdata.acl.data.AclFeed):
|
||||
"""A DocList ACL feed."""
|
||||
entry = [Acl]
|
||||
|
||||
|
||||
class Revision(gdata.data.GDEntry):
|
||||
"""A document Revision entry."""
|
||||
publish = Publish
|
||||
publish_auto = PublishAuto
|
||||
publish_outside_domain = PublishOutsideDomain
|
||||
|
||||
def find_publish_link(self):
|
||||
"""Get the link that points to the published document on the web.
|
||||
|
||||
Returns:
|
||||
A str for the URL in the link with a rel ending in #publish.
|
||||
"""
|
||||
return self.find_url(DOCS_PUBLISH_LINK_REL)
|
||||
|
||||
FindPublishLink = find_publish_link
|
||||
|
||||
def get_publish_link(self):
|
||||
"""Get the link that points to the published document on the web.
|
||||
|
||||
Returns:
|
||||
A gdata.data.Link for the link with a rel ending in #publish.
|
||||
"""
|
||||
return self.get_link(DOCS_PUBLISH_LINK_REL)
|
||||
|
||||
GetPublishLink = get_publish_link
|
||||
|
||||
|
||||
class RevisionFeed(gdata.data.GDFeed):
|
||||
"""A DocList Revision feed."""
|
||||
entry = [Revision]
|
611
python/gdata/docs/service.py
Normal file
611
python/gdata/docs/service.py
Normal file
@@ -0,0 +1,611 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright 2009 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""DocsService extends the GDataService to streamline Google Documents
|
||||
operations.
|
||||
|
||||
DocsService: Provides methods to query feeds and manipulate items.
|
||||
Extends GDataService.
|
||||
|
||||
DocumentQuery: Queries a Google Document list feed.
|
||||
|
||||
DocumentAclQuery: Queries a Google Document Acl feed.
|
||||
"""
|
||||
|
||||
|
||||
__author__ = ('api.jfisher (Jeff Fisher), '
|
||||
'e.bidelman (Eric Bidelman)')
|
||||
|
||||
import re
|
||||
import atom
|
||||
import gdata.service
|
||||
import gdata.docs
|
||||
import urllib
|
||||
|
||||
# XML Namespaces used in Google Documents entities.
|
||||
DATA_KIND_SCHEME = gdata.GDATA_NAMESPACE + '#kind'
|
||||
DOCUMENT_LABEL = 'document'
|
||||
SPREADSHEET_LABEL = 'spreadsheet'
|
||||
PRESENTATION_LABEL = 'presentation'
|
||||
FOLDER_LABEL = 'folder'
|
||||
PDF_LABEL = 'pdf'
|
||||
|
||||
LABEL_SCHEME = gdata.GDATA_NAMESPACE + '/labels'
|
||||
STARRED_LABEL_TERM = LABEL_SCHEME + '#starred'
|
||||
TRASHED_LABEL_TERM = LABEL_SCHEME + '#trashed'
|
||||
HIDDEN_LABEL_TERM = LABEL_SCHEME + '#hidden'
|
||||
MINE_LABEL_TERM = LABEL_SCHEME + '#mine'
|
||||
PRIVATE_LABEL_TERM = LABEL_SCHEME + '#private'
|
||||
SHARED_WITH_DOMAIN_LABEL_TERM = LABEL_SCHEME + '#shared-with-domain'
|
||||
VIEWED_LABEL_TERM = LABEL_SCHEME + '#viewed'
|
||||
|
||||
FOLDERS_SCHEME_PREFIX = gdata.docs.DOCUMENTS_NAMESPACE + '/folders/'
|
||||
|
||||
# File extensions of documents that are permitted to be uploaded or downloaded.
|
||||
SUPPORTED_FILETYPES = {
|
||||
'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'
|
||||
}
|
||||
|
||||
|
||||
class DocsService(gdata.service.GDataService):
|
||||
|
||||
"""Client extension for the Google Documents service Document List feed."""
|
||||
|
||||
__FILE_EXT_PATTERN = re.compile('.*\.([a-zA-Z]{3,}$)')
|
||||
__RESOURCE_ID_PATTERN = re.compile('^([a-z]*)(:|%3A)([\w-]*)$')
|
||||
|
||||
def __init__(self, email=None, password=None, source=None,
|
||||
server='docs.google.com', additional_headers=None, **kwargs):
|
||||
"""Creates a client for the Google Documents service.
|
||||
|
||||
Args:
|
||||
email: string (optional) The user's email address, used for
|
||||
authentication.
|
||||
password: string (optional) The user's password.
|
||||
source: string (optional) The name of the user's application.
|
||||
server: string (optional) The name of the server to which a connection
|
||||
will be opened. Default value: 'docs.google.com'.
|
||||
**kwargs: The other parameters to pass to gdata.service.GDataService
|
||||
constructor.
|
||||
"""
|
||||
gdata.service.GDataService.__init__(
|
||||
self, email=email, password=password, service='writely', source=source,
|
||||
server=server, additional_headers=additional_headers, **kwargs)
|
||||
|
||||
def _MakeKindCategory(self, label):
|
||||
if label is None:
|
||||
return None
|
||||
return atom.Category(scheme=DATA_KIND_SCHEME,
|
||||
term=gdata.docs.DOCUMENTS_NAMESPACE + '#' + label, label=label)
|
||||
|
||||
def _MakeContentLinkFromId(self, resource_id):
|
||||
match = self.__RESOURCE_ID_PATTERN.match(resource_id)
|
||||
label = match.group(1)
|
||||
doc_id = match.group(3)
|
||||
if label == DOCUMENT_LABEL:
|
||||
return '/feeds/download/documents/Export?docId=%s' % doc_id
|
||||
if label == PRESENTATION_LABEL:
|
||||
return '/feeds/download/presentations/Export?docId=%s' % doc_id
|
||||
if label == SPREADSHEET_LABEL:
|
||||
return ('https://spreadsheets.google.com/feeds/download/spreadsheets/'
|
||||
'Export?key=%s' % doc_id)
|
||||
raise ValueError, 'Invalid resource id: %s' % resource_id
|
||||
|
||||
def _UploadFile(self, media_source, title, category, folder_or_uri=None):
|
||||
"""Uploads a file to the Document List feed.
|
||||
|
||||
Args:
|
||||
media_source: A gdata.MediaSource object containing the file to be
|
||||
uploaded.
|
||||
title: string The title of the document on the server after being
|
||||
uploaded.
|
||||
category: An atom.Category object specifying the appropriate document
|
||||
type.
|
||||
folder_or_uri: DocumentListEntry or string (optional) An object with a
|
||||
link to a folder or a uri to a folder to upload to.
|
||||
Note: A valid uri for a folder is of the form:
|
||||
/feeds/folders/private/full/folder%3Afolder_id
|
||||
|
||||
Returns:
|
||||
A DocumentListEntry containing information about the document created on
|
||||
the Google Documents service.
|
||||
"""
|
||||
if folder_or_uri:
|
||||
try:
|
||||
uri = folder_or_uri.content.src
|
||||
except AttributeError:
|
||||
uri = folder_or_uri
|
||||
else:
|
||||
uri = '/feeds/documents/private/full'
|
||||
|
||||
entry = gdata.docs.DocumentListEntry()
|
||||
entry.title = atom.Title(text=title)
|
||||
if category is not None:
|
||||
entry.category.append(category)
|
||||
entry = self.Post(entry, uri, media_source=media_source,
|
||||
extra_headers={'Slug': media_source.file_name},
|
||||
converter=gdata.docs.DocumentListEntryFromString)
|
||||
return entry
|
||||
|
||||
def _DownloadFile(self, uri, file_path):
|
||||
"""Downloads a file.
|
||||
|
||||
Args:
|
||||
uri: string The full Export URL to download the file from.
|
||||
file_path: string The full path to save the file to.
|
||||
|
||||
Raises:
|
||||
RequestError: on error response from server.
|
||||
"""
|
||||
server_response = self.request('GET', uri)
|
||||
response_body = server_response.read()
|
||||
if server_response.status != 200:
|
||||
raise gdata.service.RequestError, {'status': server_response.status,
|
||||
'reason': server_response.reason,
|
||||
'body': response_body}
|
||||
f = open(file_path, 'wb')
|
||||
f.write(response_body)
|
||||
f.flush()
|
||||
f.close()
|
||||
|
||||
def MoveIntoFolder(self, source_entry, folder_entry):
|
||||
"""Moves a document into a folder in the Document List Feed.
|
||||
|
||||
Args:
|
||||
source_entry: DocumentListEntry An object representing the source
|
||||
document/folder.
|
||||
folder_entry: DocumentListEntry An object with a link to the destination
|
||||
folder.
|
||||
|
||||
Returns:
|
||||
A DocumentListEntry containing information about the document created on
|
||||
the Google Documents service.
|
||||
"""
|
||||
entry = gdata.docs.DocumentListEntry()
|
||||
entry.id = source_entry.id
|
||||
entry = self.Post(entry, folder_entry.content.src,
|
||||
converter=gdata.docs.DocumentListEntryFromString)
|
||||
return entry
|
||||
|
||||
def Query(self, uri, converter=gdata.docs.DocumentListFeedFromString):
|
||||
"""Queries the Document List feed and returns the resulting feed of
|
||||
entries.
|
||||
|
||||
Args:
|
||||
uri: string The full URI to be queried. This can contain query
|
||||
parameters, a hostname, or simply the relative path to a Document
|
||||
List feed. The DocumentQuery object is useful when constructing
|
||||
query parameters.
|
||||
converter: func (optional) A function which will be executed on the
|
||||
retrieved item, generally to render it into a Python object.
|
||||
By default the DocumentListFeedFromString function is used to
|
||||
return a DocumentListFeed object. This is because most feed
|
||||
queries will result in a feed and not a single entry.
|
||||
"""
|
||||
return self.Get(uri, converter=converter)
|
||||
|
||||
def QueryDocumentListFeed(self, uri):
|
||||
"""Retrieves a DocumentListFeed by retrieving a URI based off the Document
|
||||
List feed, including any query parameters. A DocumentQuery object can
|
||||
be used to construct these parameters.
|
||||
|
||||
Args:
|
||||
uri: string The URI of the feed being retrieved possibly with query
|
||||
parameters.
|
||||
|
||||
Returns:
|
||||
A DocumentListFeed object representing the feed returned by the server.
|
||||
"""
|
||||
return self.Get(uri, converter=gdata.docs.DocumentListFeedFromString)
|
||||
|
||||
def GetDocumentListEntry(self, uri):
|
||||
"""Retrieves a particular DocumentListEntry by its unique URI.
|
||||
|
||||
Args:
|
||||
uri: string The unique URI of an entry in a Document List feed.
|
||||
|
||||
Returns:
|
||||
A DocumentListEntry object representing the retrieved entry.
|
||||
"""
|
||||
return self.Get(uri, converter=gdata.docs.DocumentListEntryFromString)
|
||||
|
||||
def GetDocumentListFeed(self, uri=None):
|
||||
"""Retrieves a feed containing all of a user's documents.
|
||||
|
||||
Args:
|
||||
uri: string A full URI to query the Document List feed.
|
||||
"""
|
||||
if not uri:
|
||||
uri = gdata.docs.service.DocumentQuery().ToUri()
|
||||
return self.QueryDocumentListFeed(uri)
|
||||
|
||||
def GetDocumentListAclEntry(self, uri):
|
||||
"""Retrieves a particular DocumentListAclEntry by its unique URI.
|
||||
|
||||
Args:
|
||||
uri: string The unique URI of an entry in a Document List feed.
|
||||
|
||||
Returns:
|
||||
A DocumentListAclEntry object representing the retrieved entry.
|
||||
"""
|
||||
return self.Get(uri, converter=gdata.docs.DocumentListAclEntryFromString)
|
||||
|
||||
def GetDocumentListAclFeed(self, uri):
|
||||
"""Retrieves a feed containing all of a user's documents.
|
||||
|
||||
Args:
|
||||
uri: string The URI of a document's Acl feed to retrieve.
|
||||
|
||||
Returns:
|
||||
A DocumentListAclFeed object representing the ACL feed
|
||||
returned by the server.
|
||||
"""
|
||||
return self.Get(uri, converter=gdata.docs.DocumentListAclFeedFromString)
|
||||
|
||||
def Upload(self, media_source, title, folder_or_uri=None, label=None):
|
||||
"""Uploads a document inside of a MediaSource object to the Document List
|
||||
feed with the given title.
|
||||
|
||||
Args:
|
||||
media_source: MediaSource The gdata.MediaSource object containing a
|
||||
document file to be uploaded.
|
||||
title: string The title of the document on the server after being
|
||||
uploaded.
|
||||
folder_or_uri: DocumentListEntry or string (optional) An object with a
|
||||
link to a folder or a uri to a folder to upload to.
|
||||
Note: A valid uri for a folder is of the form:
|
||||
/feeds/folders/private/full/folder%3Afolder_id
|
||||
label: optional label describing the type of the document to be created.
|
||||
|
||||
Returns:
|
||||
A DocumentListEntry containing information about the document created
|
||||
on the Google Documents service.
|
||||
"""
|
||||
|
||||
return self._UploadFile(media_source, title, self._MakeKindCategory(label),
|
||||
folder_or_uri)
|
||||
|
||||
def Download(self, entry_or_id_or_url, file_path, export_format=None,
|
||||
gid=None, extra_params=None):
|
||||
"""Downloads a document from the Document List.
|
||||
|
||||
Args:
|
||||
entry_or_id_or_url: a DocumentListEntry, or the resource id of an entry,
|
||||
or a url to download from (such as the content src).
|
||||
file_path: string The full path to save the file to.
|
||||
export_format: the format to convert to, if conversion is required.
|
||||
gid: grid id, for downloading a single grid of a spreadsheet
|
||||
extra_params: a map of any further parameters to control how the document
|
||||
is downloaded
|
||||
|
||||
Raises:
|
||||
RequestError if the service does not respond with success
|
||||
"""
|
||||
|
||||
if isinstance(entry_or_id_or_url, gdata.docs.DocumentListEntry):
|
||||
url = entry_or_id_or_url.content.src
|
||||
else:
|
||||
if self.__RESOURCE_ID_PATTERN.match(entry_or_id_or_url):
|
||||
url = self._MakeContentLinkFromId(entry_or_id_or_url)
|
||||
else:
|
||||
url = entry_or_id_or_url
|
||||
|
||||
if export_format is not None:
|
||||
if url.find('/Export?') == -1:
|
||||
raise gdata.service.Error, ('This entry cannot be exported '
|
||||
'as a different format')
|
||||
url += '&exportFormat=%s' % export_format
|
||||
|
||||
if gid is not None:
|
||||
if url.find('spreadsheets') == -1:
|
||||
raise gdata.service.Error, 'grid id param is not valid for this entry'
|
||||
url += '&gid=%s' % gid
|
||||
|
||||
if extra_params:
|
||||
url += '&' + urllib.urlencode(extra_params)
|
||||
|
||||
self._DownloadFile(url, file_path)
|
||||
|
||||
def Export(self, entry_or_id_or_url, file_path, gid=None, extra_params=None):
|
||||
"""Downloads a document from the Document List in a different format.
|
||||
|
||||
Args:
|
||||
entry_or_id_or_url: a DocumentListEntry, or the resource id of an entry,
|
||||
or a url to download from (such as the content src).
|
||||
file_path: string The full path to save the file to. The export
|
||||
format is inferred from the the file extension.
|
||||
gid: grid id, for downloading a single grid of a spreadsheet
|
||||
extra_params: a map of any further parameters to control how the document
|
||||
is downloaded
|
||||
|
||||
Raises:
|
||||
RequestError if the service does not respond with success
|
||||
"""
|
||||
ext = None
|
||||
match = self.__FILE_EXT_PATTERN.match(file_path)
|
||||
if match:
|
||||
ext = match.group(1)
|
||||
self.Download(entry_or_id_or_url, file_path, ext, gid, extra_params)
|
||||
|
||||
def CreateFolder(self, title, folder_or_uri=None):
|
||||
"""Creates a folder in the Document List feed.
|
||||
|
||||
Args:
|
||||
title: string The title of the folder on the server after being created.
|
||||
folder_or_uri: DocumentListEntry or string (optional) An object with a
|
||||
link to a folder or a uri to a folder to upload to.
|
||||
Note: A valid uri for a folder is of the form:
|
||||
/feeds/folders/private/full/folder%3Afolder_id
|
||||
|
||||
Returns:
|
||||
A DocumentListEntry containing information about the folder created on
|
||||
the Google Documents service.
|
||||
"""
|
||||
if folder_or_uri:
|
||||
try:
|
||||
uri = folder_or_uri.content.src
|
||||
except AttributeError:
|
||||
uri = folder_or_uri
|
||||
else:
|
||||
uri = '/feeds/documents/private/full'
|
||||
|
||||
folder_entry = gdata.docs.DocumentListEntry()
|
||||
folder_entry.title = atom.Title(text=title)
|
||||
folder_entry.category.append(self._MakeKindCategory(FOLDER_LABEL))
|
||||
folder_entry = self.Post(folder_entry, uri,
|
||||
converter=gdata.docs.DocumentListEntryFromString)
|
||||
|
||||
return folder_entry
|
||||
|
||||
|
||||
def MoveOutOfFolder(self, source_entry):
|
||||
"""Moves a document into a folder in the Document List Feed.
|
||||
|
||||
Args:
|
||||
source_entry: DocumentListEntry An object representing the source
|
||||
document/folder.
|
||||
|
||||
Returns:
|
||||
True if the entry was moved out.
|
||||
"""
|
||||
return self.Delete(source_entry.GetEditLink().href)
|
||||
|
||||
# Deprecated methods
|
||||
|
||||
#@atom.deprecated('Please use Upload instead')
|
||||
def UploadPresentation(self, media_source, title, folder_or_uri=None):
|
||||
"""Uploads a presentation inside of a MediaSource object to the Document
|
||||
List feed with the given title.
|
||||
|
||||
This method is deprecated, use Upload instead.
|
||||
|
||||
Args:
|
||||
media_source: MediaSource The MediaSource object containing a
|
||||
presentation file to be uploaded.
|
||||
title: string The title of the presentation on the server after being
|
||||
uploaded.
|
||||
folder_or_uri: DocumentListEntry or string (optional) An object with a
|
||||
link to a folder or a uri to a folder to upload to.
|
||||
Note: A valid uri for a folder is of the form:
|
||||
/feeds/folders/private/full/folder%3Afolder_id
|
||||
|
||||
Returns:
|
||||
A DocumentListEntry containing information about the presentation created
|
||||
on the Google Documents service.
|
||||
"""
|
||||
return self._UploadFile(
|
||||
media_source, title, self._MakeKindCategory(PRESENTATION_LABEL),
|
||||
folder_or_uri=folder_or_uri)
|
||||
|
||||
UploadPresentation = atom.deprecated('Please use Upload instead')(
|
||||
UploadPresentation)
|
||||
|
||||
#@atom.deprecated('Please use Upload instead')
|
||||
def UploadSpreadsheet(self, media_source, title, folder_or_uri=None):
|
||||
"""Uploads a spreadsheet inside of a MediaSource object to the Document
|
||||
List feed with the given title.
|
||||
|
||||
This method is deprecated, use Upload instead.
|
||||
|
||||
Args:
|
||||
media_source: MediaSource The MediaSource object containing a spreadsheet
|
||||
file to be uploaded.
|
||||
title: string The title of the spreadsheet on the server after being
|
||||
uploaded.
|
||||
folder_or_uri: DocumentListEntry or string (optional) An object with a
|
||||
link to a folder or a uri to a folder to upload to.
|
||||
Note: A valid uri for a folder is of the form:
|
||||
/feeds/folders/private/full/folder%3Afolder_id
|
||||
|
||||
Returns:
|
||||
A DocumentListEntry containing information about the spreadsheet created
|
||||
on the Google Documents service.
|
||||
"""
|
||||
return self._UploadFile(
|
||||
media_source, title, self._MakeKindCategory(SPREADSHEET_LABEL),
|
||||
folder_or_uri=folder_or_uri)
|
||||
|
||||
UploadSpreadsheet = atom.deprecated('Please use Upload instead')(
|
||||
UploadSpreadsheet)
|
||||
|
||||
#@atom.deprecated('Please use Upload instead')
|
||||
def UploadDocument(self, media_source, title, folder_or_uri=None):
|
||||
"""Uploads a document inside of a MediaSource object to the Document List
|
||||
feed with the given title.
|
||||
|
||||
This method is deprecated, use Upload instead.
|
||||
|
||||
Args:
|
||||
media_source: MediaSource The gdata.MediaSource object containing a
|
||||
document file to be uploaded.
|
||||
title: string The title of the document on the server after being
|
||||
uploaded.
|
||||
folder_or_uri: DocumentListEntry or string (optional) An object with a
|
||||
link to a folder or a uri to a folder to upload to.
|
||||
Note: A valid uri for a folder is of the form:
|
||||
/feeds/folders/private/full/folder%3Afolder_id
|
||||
|
||||
Returns:
|
||||
A DocumentListEntry containing information about the document created
|
||||
on the Google Documents service.
|
||||
"""
|
||||
return self._UploadFile(
|
||||
media_source, title, self._MakeKindCategory(DOCUMENT_LABEL),
|
||||
folder_or_uri=folder_or_uri)
|
||||
|
||||
UploadDocument = atom.deprecated('Please use Upload instead')(
|
||||
UploadDocument)
|
||||
|
||||
"""Calling any of these functions is the same as calling Export"""
|
||||
DownloadDocument = atom.deprecated('Please use Export instead')(Export)
|
||||
DownloadPresentation = atom.deprecated('Please use Export instead')(Export)
|
||||
DownloadSpreadsheet = atom.deprecated('Please use Export instead')(Export)
|
||||
|
||||
"""Calling any of these functions is the same as calling MoveIntoFolder"""
|
||||
MoveDocumentIntoFolder = atom.deprecated(
|
||||
'Please use MoveIntoFolder instead')(MoveIntoFolder)
|
||||
MovePresentationIntoFolder = atom.deprecated(
|
||||
'Please use MoveIntoFolder instead')(MoveIntoFolder)
|
||||
MoveSpreadsheetIntoFolder = atom.deprecated(
|
||||
'Please use MoveIntoFolder instead')(MoveIntoFolder)
|
||||
MoveFolderIntoFolder = atom.deprecated(
|
||||
'Please use MoveIntoFolder instead')(MoveIntoFolder)
|
||||
|
||||
|
||||
class DocumentQuery(gdata.service.Query):
|
||||
|
||||
"""Object used to construct a URI to query the Google Document List feed"""
|
||||
|
||||
def __init__(self, feed='/feeds/documents', visibility='private',
|
||||
projection='full', text_query=None, params=None,
|
||||
categories=None):
|
||||
"""Constructor for Document List Query
|
||||
|
||||
Args:
|
||||
feed: string (optional) The path for the feed. (e.g. '/feeds/documents')
|
||||
visibility: string (optional) The visibility chosen for the current feed.
|
||||
projection: string (optional) The projection chosen for the current feed.
|
||||
text_query: string (optional) The contents of the q query parameter. This
|
||||
string is URL escaped upon conversion to a URI.
|
||||
params: dict (optional) Parameter value string pairs which become URL
|
||||
params when translated to a URI. These parameters are added to
|
||||
the query's items.
|
||||
categories: list (optional) List of category strings which should be
|
||||
included as query categories. See gdata.service.Query for
|
||||
additional documentation.
|
||||
|
||||
Yields:
|
||||
A DocumentQuery object used to construct a URI based on the Document
|
||||
List feed.
|
||||
"""
|
||||
self.visibility = visibility
|
||||
self.projection = projection
|
||||
gdata.service.Query.__init__(self, feed, text_query, params, categories)
|
||||
|
||||
def ToUri(self):
|
||||
"""Generates a URI from the query parameters set in the object.
|
||||
|
||||
Returns:
|
||||
A string containing the URI used to retrieve entries from the Document
|
||||
List feed.
|
||||
"""
|
||||
old_feed = self.feed
|
||||
self.feed = '/'.join([old_feed, self.visibility, self.projection])
|
||||
new_feed = gdata.service.Query.ToUri(self)
|
||||
self.feed = old_feed
|
||||
return new_feed
|
||||
|
||||
def AddNamedFolder(self, email, folder_name):
|
||||
"""Adds a named folder category, qualified by a schema.
|
||||
|
||||
This function lets you query for documents that are contained inside a
|
||||
named folder without fear of collision with other categories.
|
||||
|
||||
Args:
|
||||
email: string The email of the user who owns the folder.
|
||||
folder_name: string The name of the folder.
|
||||
|
||||
Returns:
|
||||
The string of the category that was added to the object.
|
||||
"""
|
||||
|
||||
category = '{%s%s}%s' % (FOLDERS_SCHEME_PREFIX, email, folder_name)
|
||||
self.categories.append(category)
|
||||
return category
|
||||
|
||||
def RemoveNamedFolder(self, email, folder_name):
|
||||
"""Removes a named folder category, qualified by a schema.
|
||||
|
||||
Args:
|
||||
email: string The email of the user who owns the folder.
|
||||
folder_name: string The name of the folder.
|
||||
|
||||
Returns:
|
||||
The string of the category that was removed to the object.
|
||||
"""
|
||||
category = '{%s%s}%s' % (FOLDERS_SCHEME_PREFIX, email, folder_name)
|
||||
self.categories.remove(category)
|
||||
return category
|
||||
|
||||
|
||||
class DocumentAclQuery(gdata.service.Query):
|
||||
|
||||
"""Object used to construct a URI to query a Document's ACL feed"""
|
||||
|
||||
def __init__(self, resource_id, feed='/feeds/acl/private/full'):
|
||||
"""Constructor for Document ACL Query
|
||||
|
||||
Args:
|
||||
resource_id: string The resource id. (e.g. 'document%3Adocument_id',
|
||||
'spreadsheet%3Aspreadsheet_id', etc.)
|
||||
feed: string (optional) The path for the feed.
|
||||
(e.g. '/feeds/acl/private/full')
|
||||
|
||||
Yields:
|
||||
A DocumentAclQuery object used to construct a URI based on the Document
|
||||
ACL feed.
|
||||
"""
|
||||
self.resource_id = resource_id
|
||||
gdata.service.Query.__init__(self, feed)
|
||||
|
||||
def ToUri(self):
|
||||
"""Generates a URI from the query parameters set in the object.
|
||||
|
||||
Returns:
|
||||
A string containing the URI used to retrieve entries from the Document
|
||||
ACL feed.
|
||||
"""
|
||||
return '%s/%s' % (gdata.service.Query.ToUri(self), self.resource_id)
|
Reference in New Issue
Block a user