Merge branch 'master' of ssh://wwwjail.house/usr/local/git/base/kiosk
[kiosk.git] / picasa_renderer.py
1 import http.client
2 import gdata_oauth
3 import file_writer
4 import renderer
5 import gdata
6 import secrets
7 import sets
8 import random
9 from oauth2client.client import AccessTokenRefreshError
10
11
12 class picasa_renderer(renderer.debuggable_abstaining_renderer):
13     """A renderer to fetch photos from picasaweb.google.com"""
14
15     album_whitelist = sets.ImmutableSet(
16         [
17             "Alex",
18             "Alex 6.0..8.0 years old",
19             "Alex 3.0..4.0 years old",
20             "Barn",
21             "Bangkok and Phukey, 2003",
22             "Blue Angels... Seafair",
23             "Carol Ann and Owen",
24             "Chahuly Glass",
25             "Dunn Gardens",
26             "East Coast, 2011",
27             "East Coast, 2013",
28             "Friends",
29             "Gasches",
30             "Gasch Wedding",
31             "Hiking and Ohme Gardens",
32             "Hiking",
33             "Karen's Wedding",
34             "Key West 2019",
35             "Krakow 2009",
36             "Munich, July 2018",
37             "NJ 2015",
38             "NW Trek",
39             "Oahu 2010" "Ocean Shores 2009",
40             "Ohme Gardens",
41             "Olympic Sculpture Park",
42             "Paintings",
43             "Puerto Vallarta",
44             "Photos from posts",
45             "Random",
46             "SFO 2014",
47             "Soccer",
48             "Skiing with Alex",
49             "Tuscany 2008",
50             "Trip to California '16",
51             "Trip to East Coast '16",
52             "Yosemite 2010",
53             "Zoo",
54         ]
55     )
56
57     def __init__(self, name_to_timeout_dict, oauth):
58         super(picasa_renderer, self).__init__(name_to_timeout_dict, False)
59         self.oauth = oauth
60         self.photo_urls = {}
61         self.width = {}
62         self.height = {}
63         self.is_video = {}
64
65     def debug_prefix(self):
66         return "picasa"
67
68     def periodic_render(self, key):
69         if key == "Fetch Photos":
70             return self.fetch_photos()
71         elif key == "Shuffle Cached Photos":
72             return self.shuffle_cached()
73         else:
74             raise error("Unexpected operation")
75
76     # Just fetch and cache the photo URLs in memory.
77     def fetch_photos(self):
78         try:
79             temp_photo_urls = {}
80             temp_width = {}
81             temp_height = {}
82             temp_is_video = {}
83             conn = http.client.HTTPSConnection("photoslibrary.googleapis.com")
84             conn.request(
85                 "GET",
86                 "/v1/albums",
87                 None,
88                 {
89                     "Authorization": "%s %s"
90                     % (self.oauth.token["token_type"], self.oauth.token["access_token"])
91                 },
92             )
93             response = conn.getresponse()
94             if response.status != 200:
95                 print(("Failed to fetch albums, status %d\n" % response.status))
96             print(response.read())
97             albums = self.pws.GetUserFeed().entry
98             for album in albums:
99                 if album.title.text not in picasa_renderer.album_whitelist:
100                     continue
101                 photos = self.pws.GetFeed(
102                     "/data/feed/api/user/%s/albumid/%s?kind=photo&imgmax=1024u"
103                     % (secrets.google_username, album.gphoto_id.text)
104                 )
105                 for photo in photos.entry:
106                     id = "%s/%s" % (photo.albumid.text, photo.gphoto_id.text)
107                     temp_is_video[id] = False
108                     resolution = 999999
109                     for x in photo.media.content:
110                         if "video" in x.type and int(x.height) < resolution:
111                             url = x.url
112                             resolution = int(x.height)
113                             temp_width[id] = x.width
114                             temp_height[id] = x.height
115                             temp_is_video[id] = True
116                         else:
117                             if resolution == 999999:
118                                 url = x.url
119                                 temp_width[id] = x.width
120                                 temp_height[id] = x.height
121                                 temp_is_video[id] = False
122                     temp_photo_urls[id] = url
123             self.photo_urls = temp_photo_urls
124             self.width = temp_width
125             self.height = temp_height
126             self.is_video = temp_is_video
127             return True
128         except (
129             gdata.service.RequestError,
130             gdata.photos.service.GooglePhotosException,
131             AccessTokenRefreshError,
132         ):
133             print("******** TRYING TO REFRESH PHOTOS CLIENT *********")
134             self.oauth.refresh_token()
135             self.client = self.oauth.photos_service()
136             return False
137
138     # Pick one of the cached URLs and build a page.
139     def shuffle_cached(self):
140         if len(self.photo_urls) == 0:
141             print("No photos!")
142             return False
143         pid = random.sample(self.photo_urls, 1)
144         id = pid[0]
145         refresh = 15
146         if self.is_video[id]:
147             refresh = 60
148
149         f = file_writer.file_writer("photo_23_none.html")
150         f.write(
151             """
152 <style>
153 body{background-color:#303030;}
154 div#time{color:#dddddd;}
155 div#date{color:#dddddd;}
156 </style>
157 <center>"""
158         )
159         if self.is_video[id]:
160             f.write(
161                 '<iframe src="%s" seamless width=%s height=%s></iframe>'
162                 % (self.photo_urls[id], self.width[id], self.height[id])
163             )
164         else:
165             f.write(
166                 '<img src="%s" width=%s alt="%s">'
167                 % (self.photo_urls[id], self.width[id], self.photo_urls[id])
168             )
169         f.write("</center>")
170         f.close()
171         return True
172
173
174 # Test code
175 oauth = gdata_oauth.OAuth(secrets.google_client_id, secrets.google_client_secret)
176 oauth.get_new_token()
177 if not oauth.has_token():
178     user_code = oauth.get_user_code()
179     print("------------------------------------------------------------")
180     print(
181         (
182             'Go to %s and enter the code "%s" (no quotes, case-sensitive)'
183             % (oauth.verification_url, user_code)
184         )
185     )
186     oauth.get_new_token()
187 x = picasa_renderer(
188     {"Fetch Photos": (60 * 60 * 12), "Shuffle Cached Photos": (1)}, oauth
189 )
190 x.fetch_photos()