Source code for coherence.backends.picasa_storage

# Licensed under the MIT license
# http://opensource.org/licenses/mit-license.php

# Copyright 2009, Jean-Michel Sizun
# Copyright 2009 Frank Scholz <coherence@beebits.net>

import gdata.geo
import gdata.media
import gdata.photos.service
from twisted.internet import threads

from coherence.backend import BackendItem, Container, \
    LazyContainer, \
    AbstractBackendStore
from coherence.upnp.core import DIDLLite
from coherence.upnp.core.utils import ReverseProxyUriResource


[docs]class PicasaProxy(ReverseProxyUriResource): def __init__(self, uri): ReverseProxyUriResource.__init__(self, uri)
[docs] def render(self, request): if 'referer' in request.received_headers: del request.received_headers['referer'] return ReverseProxyUriResource.render(self, request)
[docs]class PicasaPhotoItem(BackendItem): def __init__(self, photo): BackendItem.__init__(self) # print photo self.photo = photo self.name = photo.summary.text if self.name is None: self.name = photo.title.text self.duration = None self.size = None self.mimetype = photo.content.type self.description = photo.summary.text self.date = None self.item = None self.photo_url = photo.content.src self.thumbnail_url = photo.media.thumbnail[0].url self.url = None self.location = PicasaProxy(self.photo_url)
[docs] def replace_by(self, item): # print photo self.photo = item.photo self.name = self.photo.summary.text if self.name is None: self.name = self.photo.title.text self.mimetype = self.photo.content.type self.description = self.photo.summary.text self.photo_url = self.photo.content.src self.thumbnail_url = self.photo.media.thumbnail[0].url self.location = PicasaProxy(self.photo_url) return True
[docs] def get_item(self): if self.item is None: upnp_id = self.get_id() upnp_parent_id = self.parent.get_id() self.item = DIDLLite.Photo( upnp_id, upnp_parent_id, self.name) res = DIDLLite.Resource( self.url, f'http-get:*:{self.mimetype}:*') self.item.res.append(res) self.item.childCount = 0 return self.item
[docs] def get_path(self): return self.url
[docs] def get_id(self): return self.storage_id
[docs]class PicasaStore(AbstractBackendStore): logCategory = 'picasa_store' implements = ['MediaServer'] description = ( 'Picasa Web Albums', 'connects to the Picasa Web Albums service and exposes the ' 'featured photos and albums for a given user.', None) options = [ {'option': 'name', 'text': 'Server Name:', 'type': 'string', 'default': 'my media', 'help': 'the name under this MediaServer shall ' 'show up with on other UPnP clients'}, {'option': 'version', 'text': 'UPnP Version:', 'type': 'int', 'default': 2, 'enum': (2, 1), 'help': 'the highest UPnP version this MediaServer shall support', 'level': 'advance'}, {'option': 'uuid', 'text': 'UUID Identifier:', 'type': 'string', 'help': 'the unique (UPnP) identifier for this MediaServer, ' 'usually automatically set', 'level': 'advance'}, {'option': 'refresh', 'text': 'Refresh period', 'type': 'string'}, {'option': 'login', 'text': 'User ID:', 'type': 'string', 'group': 'User Account'}, {'option': 'password', 'text': 'Password:', 'type': 'string', 'group': 'User Account'}, ] def __init__(self, server, **kwargs): AbstractBackendStore.__init__(self, server, **kwargs) self.name = kwargs.get('name', 'Picasa Web Albums') self.refresh = int(kwargs.get('refresh', 60)) * 60 self.login = kwargs.get('userid', kwargs.get('login', '')) self.password = kwargs.get('password', '') rootContainer = Container(None, self.name) self.set_root_item(rootContainer) self.AlbumsContainer = LazyContainer( rootContainer, 'My Albums', None, self.refresh, self.retrieveAlbums) rootContainer.add_child(self.AlbumsContainer) self.FeaturedContainer = LazyContainer( rootContainer, 'Featured photos', None, self.refresh, self.retrieveFeaturedPhotos) rootContainer.add_child(self.FeaturedContainer) self.init_completed() def __repr__(self): return self.__class__.__name__
[docs] def upnp_init(self): self.current_connection_id = None if self.server: self.server.connection_manager_server.set_variable( 0, 'SourceProtocolInfo', 'http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=01;' 'DLNA.ORG_FLAGS=00f00000000000000000000000000000,' 'http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=01;' 'DLNA.ORG_FLAGS=00f00000000000000000000000000000,' 'http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=01;' 'DLNA.ORG_FLAGS=00f00000000000000000000000000000,' 'http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=01;' 'DLNA.ORG_FLAGS=00f00000000000000000000000000000,' 'http-get:*:image/jpeg:*,' 'http-get:*:image/gif:*,' 'http-get:*:image/png:*', default=True) self.wmc_mapping = {'16': self.get_root_id()} self.gd_client = gdata.photos.service.PhotosService() self.gd_client.email = self.login self.gd_client.password = self.password self.gd_client.source = 'Coherence UPnP backend' if len(self.login) > 0: d = threads.deferToThread(self.gd_client.ProgrammaticLogin)
[docs] def retrieveAlbums(self, parent=None): albums = threads.deferToThread(self.gd_client.GetUserFeed) def gotAlbums(albums): if albums is None: print('Unable to retrieve albums') return for album in albums.entry: title = album.title.text album_id = album.gphoto_id.text item = LazyContainer(parent, title, album_id, self.refresh, self.retrieveAlbumPhotos, album_id=album_id) parent.add_child(item, external_id=album_id) def gotError(error): print(f'ERROR: {error}') albums.addCallbacks(gotAlbums, gotError) return albums
[docs] def retrieveFeedPhotos(self, parent=None, feed_uri=''): # print feed_uri photos = threads.deferToThread(self.gd_client.GetFeed, feed_uri) def gotPhotos(photos): if photos is None: print(f'Unable to retrieve photos for feed {feed_uri}') return for photo in photos.entry: photo_id = photo.gphoto_id.text item = PicasaPhotoItem(photo) item.parent = parent parent.add_child(item, external_id=photo_id) def gotError(error): print(f'ERROR: {error}') photos.addCallbacks(gotPhotos, gotError) return photos
[docs] def retrieveAlbumPhotos(self, parent=None, album_id=''): album_feed_uri = \ f'/data/feed/api/user/{self.login}/albumid/{album_id}?kind=photo' return self.retrieveFeedPhotos(parent, album_feed_uri)
[docs] def retrieveFeaturedPhotos(self, parent=None): feed_uri = 'http://picasaweb.google.com/data/feed/api/featured' return self.retrieveFeedPhotos(parent, feed_uri)