#!/usr/local/bin/python # Copyright (c) 2015 Scott Gasch # # 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 sys import traceback import os from threading import Thread import time import gdata_oauth from datetime import datetime import sets import gdata_oauth import gdata.photos, gdata.photos.service import gdata import secrets class mirror_picasaweb: """A program to mirror my picasaweb photos and make a local webpage out of it.""" album_whitelist = sets.ImmutableSet([ '1-Wire Project', 'Alex 6.0..8.0 years old', 'Barn', 'Bangkok and Phuket, 2003', 'Blue Angels... Seafair', 'Dunn Gardens', 'East Coast, 2011', 'East Coast, 2013', 'Friends', 'Gasches', 'Gasch Wedding', 'Hiking and Ohme Gardens', 'Hiking', 'Kiosk Project', 'Krakow 2009', 'NJ 2015', 'Oahu 2010' 'Ocean Shores 2009', 'Ohme Gardens', 'Olympic Sculpture Park', 'Paintings', 'Puerto Vallarta', 'Photos from posts', 'Random', 'SFO 2014', 'Soccer', 'Skiing with Alex', 'Tuscany 2008', 'Yosemite 2010', 'Zoo', ]) def __init__(self): self.client = oauth.photos_service() self.album = None self.photo = None def write_album_header(self, f, album): f.write(""" %s

Album List | %s

""" % (album.title.text, album.link[0].href, album.title.text)) if album.location.text is not None: f.write("Location: %s
\n" % album.location.text) if album.summary.text is not None: f.write("Summary: %s
\n" % album.summary.text) if album.updated.text is not None: f.write("Updated: %s
\n" % album.updated.text) f.write("""
""") def add_photo_to_album(self, f, photo, url, number): descr = photo.summary.text camera = photo.exif.model.text if photo.exif.model else 'unknown' if photo.timestamp: ts = photo.timestamp.datetime().strftime('%d %b %Y') else: ts = 'unknown' if photo.commentCount and photo.commentCount > 0: comments = self.client.GetFeed( '/data/feed/api/user/default/albumid/%s/photoid/%s?kind=comment' % ( self.album.gphoto_id.text, photo.gphoto_id.text)) else: comments = None thumbnail = photo.media.thumbnail[1].url if number % 2 == 0: f.write('') f.write(""" """) if number % 2 == 1: f.write('') def write_album_footer(self, f): f.write("""
%s
%s
Date: %s
Camera: %s
""" % ( url, thumbnail, descr, descr, ts, camera)) if comments is not None: for comment in comments.entry: print '%s
' % comment.content.text f.write("""
Are you interested in how this page was made?
""") def write_index_header(self, f): f.write(""" Scott's Photo Albums """) def add_album_to_index(self, f, album, count): thumbnail = album.media.thumbnail[0].url if count % 2 == 0: f.write('\n') f.write(""" """) if count % 2 == 1: f.write('\n') def write_index_footer(self, f): f.write("""

Album List

Title: %s
Subtitle: %s
Date: %s
%s photo(s)
%d Mb""" % ( album.name.text, thumbnail, album.title.text, album.summary.text, album.published.text, album.numphotos.text, int(album.bytesUsed) / (1024 * 1024))) f.write("""
""") def run(self): attempts = 0 while attempts < 3: attempts += 1 try: self.run_internal() return except (gdata.service.RequestError, gdata.photos.service.GooglePhotosException): print "******** TRYING TO REFRESH PHOTOS CLIENT *********" oauth.refresh_token() self.client = oauth.photos_service() print "Tried 3x, giving up." def run_internal(self): albums = self.client.GetUserFeed().entry album_count = 0 index = open('./index.html', 'w') self.write_index_header(index) for album in albums: if album.title.text not in mirror_picasaweb.album_whitelist: print '--> Skipping "%s" (%s)' % (album.title.text, album.access.text) continue print '--> Doing "%s" (%s)' % (album.title.text, album.access.text) self.album = album self.add_album_to_index(index, album, album_count) filename = './%s.html' % album.name.text detail = open(filename, 'w') self.write_album_header(detail, album) photos = self.client.GetFeed( '/data/feed/api/user/%s/albumid/%s?kind=photo&imgmax=1024u' % (secrets.account, album.gphoto_id.text)) photo_count = 0 for photo in photos.entry: resolution = 0 for x in photo.media.content: if "video" in x.type and int(x.height) > resolution: url = x.url resolution = int(x.height) elif resolution == 0: url = x.url resolution = int(x.height) self.photo = photo self.add_photo_to_album(detail, photo, url, photo_count) photo_count += 1 self.write_album_footer(detail) detail.close() album_count += 1 self.write_index_footer(index) index.close() if __name__ == "__main__": oauth = gdata_oauth.OAuth(secrets.client_id, secrets.client_secret) if not oauth.has_token(): user_code = oauth.get_user_code() print '------------------------------------------------------------' print 'Go to %s and enter the code "%s" (no quotes, case-sensitive)' % ( oauth.verification_url, user_code) oauth.get_new_token() x = mirror_picasaweb() x.run()