1 #!/usr/local/bin/python
3 # Copyright (c) 2015 Scott Gasch
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
20 from threading import Thread
23 from datetime import datetime
26 import gdata.photos, gdata.photos.service
30 class mirror_picasaweb:
31 """A program to mirror my picasaweb photos and make a local webpage out of it."""
33 album_whitelist = sets.ImmutableSet([
35 'Alex 6.0..8.0 years old',
37 'Bangkok and Phuket, 2003',
38 'Blue Angels... Seafair',
45 'Hiking and Ohme Gardens',
53 'Olympic Sculpture Park',
67 self.client = oauth.photos_service()
71 def write_album_header(self, f, album):
76 <H2><A HREF="/scott/photos">Album List</A> | <A HREF="%s">%s</A></H2>
77 """ % (album.title.text,
80 if album.location.text is not None:
81 f.write("<B>Location:</B> %s <BR>\n" % album.location.text)
82 if album.summary.text is not None:
83 f.write("<B>Summary:</B> %s <BR>\n" % album.summary.text)
84 if album.updated.text is not None:
85 f.write("<B>Updated:</B> %s <BR>\n" % album.updated.text)
88 <TABLE STYLE="float:left; margin:0 5px 20px 0;" WIDTH=100%%>""")
90 def add_photo_to_album(self, f, photo, url, number):
91 descr = photo.summary.text
92 camera = photo.exif.model.text if photo.exif.model else 'unknown'
94 ts = photo.timestamp.datetime().strftime('%d %b %Y')
97 if photo.commentCount and photo.commentCount > 0:
98 comments = self.client.GetFeed(
99 '/data/feed/api/user/default/albumid/%s/photoid/%s?kind=comment' % (
100 self.album.gphoto_id.text, photo.gphoto_id.text))
103 thumbnail = photo.media.thumbnail[1].url
108 <TD ALIGN="center" WIDTH=33%%>
114 <DIV CLASS="img-shadow"><IMG SRC="%s" ALT="%s"></DIV>
122 <B STYLE="font-size: 60%%; color: #406b38">%s</B> <BR>
124 <B>Camera</B>: %s <BR>""" % (
131 if comments is not None:
132 for comment in comments.entry:
133 print '%s <BR>' % comment.content.text
142 def write_album_footer(self, f):
146 <FONT style="font-size:60%;color:#406b38">
147 Are you interested in <A HREF="/svn/picasa/trunk">how this page was made</A>?
153 def write_index_header(self, f):
156 <TITLE>Scott's Photo Albums</TITLE>
162 <H2><A HREF="/scott/photos">Album List</A></H2>
167 def add_album_to_index(self, f, album, count):
168 thumbnail = album.media.thumbnail[0].url
178 <IMG ALIGN=CENTER WIDTH=160 HEIGHT=160 SRC="%s">
183 <B>Title</B>: %s <BR>
184 <B>Subtitle</B>: %s <BR>
186 <B>%s</B> photo(s) <BR>
192 album.published.text,
193 album.numphotos.text,
194 int(album.bytesUsed) / (1024 * 1024)))
203 def write_index_footer(self, f):
215 except (gdata.service.RequestError,
216 gdata.photos.service.GooglePhotosException):
217 print "******** TRYING TO REFRESH PHOTOS CLIENT *********"
218 oauth.refresh_token()
219 self.client = oauth.photos_service()
220 print "Tried 3x, giving up."
222 def run_internal(self):
223 albums = self.client.GetUserFeed().entry
225 index = open('./index.html', 'w')
226 self.write_index_header(index)
228 if album.title.text not in mirror_picasaweb.album_whitelist:
229 print '--> Skipping "%s" (%s)' % (album.title.text, album.access.text)
231 print '--> Doing "%s" (%s)' % (album.title.text, album.access.text)
233 self.add_album_to_index(index, album, album_count)
234 filename = './%s.html' % album.name.text
235 detail = open(filename, 'w')
236 self.write_album_header(detail, album)
237 photos = self.client.GetFeed(
238 '/data/feed/api/user/%s/albumid/%s?kind=photo&imgmax=1024u' %
239 (secrets.account, album.gphoto_id.text))
241 for photo in photos.entry:
243 for x in photo.media.content:
244 if "video" in x.type and int(x.height) > resolution:
246 resolution = int(x.height)
247 elif resolution == 0:
249 resolution = int(x.height)
251 self.add_photo_to_album(detail, photo, url, photo_count)
253 self.write_album_footer(detail)
256 self.write_index_footer(index)
259 if __name__ == "__main__":
260 oauth = gdata_oauth.OAuth(secrets.client_id,
261 secrets.client_secret)
262 if not oauth.has_token():
263 user_code = oauth.get_user_code()
264 print '------------------------------------------------------------'
265 print 'Go to %s and enter the code "%s" (no quotes, case-sensitive)' % (
266 oauth.verification_url, user_code)
267 oauth.get_new_token()
268 x = mirror_picasaweb()