2 messages in com.googlegroups.google-picasa-data-apicontribution - picasa web album suppo...| From | Sent On | Attachments |
|---|---|---|
| Jason R. Coombs | 23 Oct 2007 11:39 | |
| Ryan Boyd (Google) | 24 Oct 2007 17:19 |
| Subject: | contribution - picasa web album support for gdata-python-client![]() |
|---|---|
| From: | Jason R. Coombs (jar...@gmail.com) |
| Date: | 10/23/2007 11:39:43 AM |
| List: | com.googlegroups.google-picasa-data-api |
I put this code together so I could upload photos from a different web service (ngallery in particular) into picasa web albums. There wasn't already API support for PWA, so I wrote it. The following patch, applied to the trunk, would provide a basic web album interface for creating albums and photos.
I'm providing it hoping that it can be included in a future release so that others can re-use the work I did. I tried to follow the style and syntax of the other objects in the library.
If there is a better mechanism for providing contributions like this one, please advise.
If anyone is interested in the ngallery code, e-mail me, and I can provide it.
Regards, Jason
---
Index: samples/picasa/pwa_sample.py =================================================================== --- samples/picasa/pwa_sample.py (revision 0) +++ samples/picasa/pwa_sample.py (revision 0) @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +from gdata.photo import * +from getpass import getpass +import time, datetime + +def run_example( ): + global svc + svc = PicasaWebService() + svc.email = raw_input( 'google username: ' ) + svc.password = getpass('password: ') + svc.source='jaraco-picasatools-1.0' + svc.ProgrammaticLogin() + AddSampleAlbum() + +def AddSampleAlbum(): + album = AlbumEntry() + now = datetime.datetime.utcnow() + album.title = atom.Title(text='Trip to Italy '+str(now)) + album.summary = atom.Summary(text='This was my <a href="mailto:f....@example.com">recent</a> trip to Italy') + album.location = Location( 'Italy' ) + album.access = Access( 'public' ) + album.commentingEnabled = CommentingEnabled('true') + timestamp = str(int(time.mktime(now.utctimetuple()))*1000) + album.timestamp = Timestamp( timestamp ) + + print album.ToString() + + new_album = svc.CreateAlbum(album) + photo = PhotoEntry() + photo.title = atom.Title(text="some title") + photo.summary = atom.Summary(text="some summary") + source = gdata.MediaSource(file_path='sample.png', content_type='image/png') + added_photo = svc.AddPhoto(new_album, photo, source) + +if __name__ == '__main__': + run_example() \ No newline at end of file
Property changes on: samples\picasa\pwa_sample.py
___________________________________________________________________ Name: svn:keywords + Id
Index: samples/picasa/sample.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
Property changes on: samples\picasa\sample.png
___________________________________________________________________ Name: svn:mime-type + application/octet-stream
Index: samples/picasa/pwa_sample.py =================================================================== --- samples/picasa/pwa_sample.py (revision 0) +++ samples/picasa/pwa_sample.py (revision 0) @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +from gdata.photo import * +from getpass import getpass +import time, datetime + +def run_example( ): + global svc + svc = PicasaWebService() + svc.email = raw_input( 'google username: ' ) + svc.password = getpass('password: ') + svc.source='jaraco-picasatools-1.0' + svc.ProgrammaticLogin() + AddSampleAlbum() + +def AddSampleAlbum(): + album = AlbumEntry() + now = datetime.datetime.utcnow() + album.title = atom.Title(text='Trip to Italy '+str(now)) + album.summary = atom.Summary(text='This was my <a href="mailto:f....@example.com">recent</a> trip to Italy') + album.location = Location( 'Italy' ) + album.access = Access( 'public' ) + album.commentingEnabled = CommentingEnabled('true') + timestamp = str(int(time.mktime(now.utctimetuple()))*1000) + album.timestamp = Timestamp( timestamp ) + + print album.ToString() + + new_album = svc.CreateAlbum(album) + photo = PhotoEntry() + photo.title = atom.Title(text="some title") + photo.summary = atom.Summary(text="some summary") + source = gdata.MediaSource(file_path='sample.png', content_type='image/png') + added_photo = svc.AddPhoto(new_album, photo, source) + +if __name__ == '__main__': + run_example() \ No newline at end of file
Property changes on: samples\picasa\pwa_sample.py
___________________________________________________________________ Name: svn:keywords + Id
Index: samples/picasa/sample.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
Property changes on: samples\picasa\sample.png
___________________________________________________________________ Name: svn:mime-type + application/octet-stream
Index: setup.py =================================================================== --- setup.py (revision 214) +++ setup.py (working copy) @@ -43,6 +43,8 @@ license='Apache 2.0', url='http://code.google.com/p/gdata-python-client/', packages=['atom', 'gdata', 'gdata.calendar', 'gdata.base', - 'gdata.spreadsheet', 'gdata.apps', 'gdata.docs'], + 'gdata.spreadsheet', 'gdata.apps', 'gdata.docs', + 'gdata.photo', + ], package_dir = {'gdata':'src/gdata', 'atom':'src/atom'} ) Index: src/gdata/photo/__init__.py =================================================================== --- src/gdata/photo/__init__.py (revision 0) +++ src/gdata/photo/__init__.py (revision 0) @@ -0,0 +1,21 @@ +#!/usr/bin/python +# +# Copyright (C) 2007 Caffeine Computer Innovations +# +# 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 Picasa Web Albums.""" + +__author__ = 'jar...@jaraco.com (Jason R. Coombs)' + +from gphoto import * \ No newline at end of file
Property changes on: src\gdata\photo\__init__.py
___________________________________________________________________ Name: svn:keywords + Id
Index: src/gdata/photo/gphoto.py =================================================================== --- src/gdata/photo/gphoto.py (revision 0) +++ src/gdata/photo/gphoto.py (revision 0) @@ -0,0 +1,140 @@ +#!/usr/bin/env python + +# Copyright (C) 2007 Caffeine Computer Innovations +# +# 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. + +import gdata +from gdata import atom +from gdata.service import GDataService + +class GPhotoBase( atom.AtomBase ): + "An abstract base class for Google Photo namespace objects" + + _namespace = 'http://schemas.google.com/photos/2007' + _children = atom.AtomBase._children.copy() + _attributes = atom.AtomBase._attributes.copy() + + def __init__(self, text=None, extension_elements=None, + extension_attributes=None): + self.text = text + self.extension_elements = extension_elements or [] + self.extension_attributes = extension_attributes or {} + + def _TransferToElementTree(self, element_tree): + element_tree.tag = '{%s}%s' % ( self._namespace, self._tag ) + atom.AtomBase._TransferToElementTree(self, element_tree) + return element_tree + +class Name(GPhotoBase): + """The Google Photo name element""" + _tag = 'name' + _children = GPhotoBase._children.copy() + _attributes = GPhotoBase._attributes.copy() + +class Location(GPhotoBase): + """The Google Photo location element""" + _tag = 'location' + _children = GPhotoBase._children.copy() + _attributes = GPhotoBase._attributes.copy() + +class Access(GPhotoBase): + """The Google Photo access element""" + _tag = 'access' + _children = GPhotoBase._children.copy() + _attributes = GPhotoBase._attributes.copy() + +class CommentingEnabled(GPhotoBase): + """The Google Photo commentingEnabled element""" + _tag = 'commentingEnabled' + _children = GPhotoBase._children.copy() + _attributes = GPhotoBase._attributes.copy() + +class Timestamp(GPhotoBase): + """The Google Photo timestamp element""" + _tag = 'timestamp' + _children = GPhotoBase._children.copy() + _attributes = GPhotoBase._attributes.copy() + +class AlbumEntry( gdata.GDataEntry ): + _tag = 'entry' + _namespace = atom.ATOM_NAMESPACE + _children = gdata.GDataEntry._children.copy() + _attributes = gdata.GDataEntry._attributes.copy() + for cls in ( Location, Access, CommentingEnabled, Timestamp, Name ): + fmt = '{%s}%s' + key = fmt % (GPhotoBase._namespace, cls._tag) + _children[key] = (cls._tag,cls) + + def __init__( self, *args, **kargs ): + gdata.GDataEntry.__init__( self, *kargs, **kargs ) + self.category.append( + atom.Category( scheme="http://schemas.google.com/g/2005#kind", + term="http://schemas.google.com/photos/2007#album" ) ) + self.name = None + self.location = None + + def _TransferToElementTree(self, element_tree): + element_tree.tag = '{%s}%s' % ( self._namespace, self._tag ) + gdata.GDataEntry._TransferToElementTree(self, element_tree) + return element_tree + + @classmethod + def FromString( cls, xml_string ): + "Factory method to instantiate one of these from a string" + return atom.CreateClassFromXMLString(cls, xml_string) + +class PhotoEntry( gdata.GDataEntry ): + _tag = 'entry' + _namespace = atom.ATOM_NAMESPACE + _children = gdata.GDataEntry._children.copy() + _attributes = gdata.GDataEntry._attributes.copy() + + def __init__( self, *args, **kargs ): + gdata.GDataEntry.__init__( self, *kargs, **kargs ) + self.category.append( + atom.Category( scheme="http://schemas.google.com/g/2005#kind", + term="http://schemas.google.com/photos/2007#photo" ) ) + + def _TransferToElementTree(self, element_tree): + element_tree.tag = '{%s}%s' % ( self._namespace, self._tag ) + gdata.GDataEntry._TransferToElementTree(self, element_tree) + return element_tree + + @classmethod + def FromString( cls, xml_string ): + "Factory method to instantiate one of these from a string" + return atom.CreateClassFromXMLString(cls, xml_string) + +class PicasaWebService( GDataService ): + path = '/data/feed/api' + def __init__( self, email=None, password=None, source=None, + server='picasaweb.google.com', + additional_headers=None ): + GDataService.__init__(self, email=email, password=password, + service='lh2', source=source, + server=server, + additional_headers=additional_headers) + + def CreateAlbum( self, album ): + path = self.path + '/user/%s' % self.email + print 'posting album to', path + response = self.Post( album, path ) + if isinstance(response, atom.Entry): + response = AlbumEntry.FromString(response.ToString()) + return response + + def AddPhoto( self, album, photo, source ): + album_name = album.name.text + path = self.path + '/user/%s/album/%s' % (self.email, album_name) + return self.Post( photo, path, media_source=source )
Property changes on: src\gdata\photo\gphoto.py
___________________________________________________________________ Name: svn:keywords + Id
Index: src/gdata/photo/__init__.py =================================================================== --- src/gdata/photo/__init__.py (revision 0) +++ src/gdata/photo/__init__.py (revision 0) @@ -0,0 +1,21 @@ +#!/usr/bin/python +# +# Copyright (C) 2007 Caffeine Computer Innovations +# +# 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 Picasa Web Albums.""" + +__author__ = 'jar...@jaraco.com (Jason R. Coombs)' + +from gphoto import * \ No newline at end of file
Property changes on: src\gdata\photo\__init__.py
___________________________________________________________________ Name: svn:keywords + Id
Index: src/gdata/photo/gphoto.py =================================================================== --- src/gdata/photo/gphoto.py (revision 0) +++ src/gdata/photo/gphoto.py (revision 0) @@ -0,0 +1,140 @@ +#!/usr/bin/env python + +# Copyright (C) 2007 Caffeine Computer Innovations +# +# 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. + +import gdata +from gdata import atom +from gdata.service import GDataService + +class GPhotoBase( atom.AtomBase ): + "An abstract base class for Google Photo namespace objects" + + _namespace = 'http://schemas.google.com/photos/2007' + _children = atom.AtomBase._children.copy() + _attributes = atom.AtomBase._attributes.copy() + + def __init__(self, text=None, extension_elements=None, + extension_attributes=None): + self.text = text + self.extension_elements = extension_elements or [] + self.extension_attributes = extension_attributes or {} + + def _TransferToElementTree(self, element_tree): + element_tree.tag = '{%s}%s' % ( self._namespace, self._tag ) + atom.AtomBase._TransferToElementTree(self, element_tree) + return element_tree + +class Name(GPhotoBase): + """The Google Photo name element""" + _tag = 'name' + _children = GPhotoBase._children.copy() + _attributes = GPhotoBase._attributes.copy() + +class Location(GPhotoBase): + """The Google Photo location element""" + _tag = 'location' + _children = GPhotoBase._children.copy() + _attributes = GPhotoBase._attributes.copy() + +class Access(GPhotoBase): + """The Google Photo access element""" + _tag = 'access' + _children = GPhotoBase._children.copy() + _attributes = GPhotoBase._attributes.copy() + +class CommentingEnabled(GPhotoBase): + """The Google Photo commentingEnabled element""" + _tag = 'commentingEnabled' + _children = GPhotoBase._children.copy() + _attributes = GPhotoBase._attributes.copy() + +class Timestamp(GPhotoBase): + """The Google Photo timestamp element""" + _tag = 'timestamp' + _children = GPhotoBase._children.copy() + _attributes = GPhotoBase._attributes.copy() + +class AlbumEntry( gdata.GDataEntry ): + _tag = 'entry' + _namespace = atom.ATOM_NAMESPACE + _children = gdata.GDataEntry._children.copy() + _attributes = gdata.GDataEntry._attributes.copy() + for cls in ( Location, Access, CommentingEnabled, Timestamp, Name ): + fmt = '{%s}%s' + key = fmt % (GPhotoBase._namespace, cls._tag) + _children[key] = (cls._tag,cls) + + def __init__( self, *args, **kargs ): + gdata.GDataEntry.__init__( self, *kargs, **kargs ) + self.category.append( + atom.Category( scheme="http://schemas.google.com/g/2005#kind", + term="http://schemas.google.com/photos/2007#album" ) ) + self.name = None + self.location = None + + def _TransferToElementTree(self, element_tree): + element_tree.tag = '{%s}%s' % ( self._namespace, self._tag ) + gdata.GDataEntry._TransferToElementTree(self, element_tree) + return element_tree + + @classmethod + def FromString( cls, xml_string ): + "Factory method to instantiate one of these from a string" + return atom.CreateClassFromXMLString(cls, xml_string) + +class PhotoEntry( gdata.GDataEntry ): + _tag = 'entry' + _namespace = atom.ATOM_NAMESPACE + _children = gdata.GDataEntry._children.copy() + _attributes = gdata.GDataEntry._attributes.copy() + + def __init__( self, *args, **kargs ): + gdata.GDataEntry.__init__( self, *kargs, **kargs ) + self.category.append( + atom.Category( scheme="http://schemas.google.com/g/2005#kind", + term="http://schemas.google.com/photos/2007#photo" ) ) + + def _TransferToElementTree(self, element_tree): + element_tree.tag = '{%s}%s' % ( self._namespace, self._tag ) + gdata.GDataEntry._TransferToElementTree(self, element_tree) + return element_tree + + @classmethod + def FromString( cls, xml_string ): + "Factory method to instantiate one of these from a string" + return atom.CreateClassFromXMLString(cls, xml_string) + +class PicasaWebService( GDataService ): + path = '/data/feed/api' + def __init__( self, email=None, password=None, source=None, + server='picasaweb.google.com', + additional_headers=None ): + GDataService.__init__(self, email=email, password=password, + service='lh2', source=source, + server=server, + additional_headers=additional_headers) + + def CreateAlbum( self, album ): + path = self.path + '/user/%s' % self.email + print 'posting album to', path + response = self.Post( album, path ) + if isinstance(response, atom.Entry): + response = AlbumEntry.FromString(response.ToString()) + return response + + def AddPhoto( self, album, photo, source ): + album_name = album.name.text + path = self.path + '/user/%s/album/%s' % (self.email, album_name) + return self.Post( photo, path, media_source=source )
Property changes on: src\gdata\photo\gphoto.py
___________________________________________________________________ Name: svn:keywords + Id




