Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 379 lines (293 sloc) 10.949 kb
0462037 David Gray headphones module
N3MIS15 authored
1 from flask import jsonify, render_template, json, send_file
2 from maraschino import app, logger, WEBROOT, RUNDIR
3 from maraschino.tools import requires_auth, get_setting_value
4 from threading import Thread
5 import StringIO
6 import urllib
7 import urllib2
8 import base64
9
a2a3d59 Jeroen van Emden Headphones https enabled
Jeroenve authored
10 def headphones_http():
11 if get_setting_value('headphones_https') == '1':
12 return 'https://'
13 else:
14 return 'http://'
0462037 David Gray headphones module
N3MIS15 authored
15
a2a3d59 Jeroen van Emden Headphones https enabled
Jeroenve authored
16 def headphones_url():
0462037 David Gray headphones module
N3MIS15 authored
17 port = get_setting_value('headphones_port')
a2a3d59 Jeroen van Emden Headphones https enabled
Jeroenve authored
18 url_base = get_setting_value('headphones_host')
19
20 if port:
21 url_base = '%s:%s' % (url_base, port)
22
23 return headphones_http() + url_base
24
25 def headphones_api(command, use_json=True, dev=False):
0462037 David Gray headphones module
N3MIS15 authored
26 username = get_setting_value('headphones_user')
27 password = get_setting_value('headphones_password')
b996541 David Gray use urllib2 for headphones images
N3MIS15 authored
28 apikey = get_setting_value('headphones_api')
0462037 David Gray headphones module
N3MIS15 authored
29
b996541 David Gray use urllib2 for headphones images
N3MIS15 authored
30 url = '%s/api?apikey=%s&cmd=%s' % (headphones_url(), apikey, command)
a2a3d59 Jeroen van Emden Headphones https enabled
Jeroenve authored
31
0462037 David Gray headphones module
N3MIS15 authored
32 request = urllib2.Request(url)
33 base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
34 request.add_header("Authorization", "Basic %s" % base64string)
35 data = urllib2.urlopen(request).read()
36
37 if use_json:
38 data = json.JSONDecoder().decode(data)
39
40 if dev:
41 print 'DEVELOPER :: %s' % url
42 print 'DEVELOPER :: %s' % data
43
44 return data
45
46
47 def convert_track_duration(milliseconds):
48 if milliseconds is None:
49 return "00:00"
50 seconds = milliseconds / 1000
51 hours = seconds / 3600
52 seconds -= 3600 * hours
53 minutes = seconds / 60
54 seconds -= 60 * minutes
55 if hours == 0:
56 return "%02d:%02d" % (minutes, seconds)
57 return "%02d:%02d:%02d" % (hours, minutes, seconds)
58
59
60 def hp_compact():
61 return get_setting_value('headphones_compact') == '1'
62
63 def headphones_exception(e):
64 logger.log('HEADPHONES :: EXCEPTION -- %s' % e, 'DEBUG')
65 return render_template('headphones-base.html', headphones=True, message=e)
66
67
68 def hp_artistart(id):
69 return '%s/xhr/headphones/img/artist/%s' % (WEBROOT, id)
70
71
72 def hp_albumart(id):
ff53281 Jeroen van Emden % was missing
Jeroenve authored
73 return '%s/xhr/headphones/img/album/%s' % (WEBROOT, id)
0462037 David Gray headphones module
N3MIS15 authored
74
75 @app.route('/xhr/headphones/img/<type>/<id>/')
76 @requires_auth
77 def xhr_headphones_image(type, id):
78 if type == 'artist':
79 cache_url = headphones_api('getArtistThumb&id=' + id)
80 else:
81 cache_url = headphones_api('getAlbumThumb&id=' + id)
82
83 if cache_url:
b996541 David Gray use urllib2 for headphones images
N3MIS15 authored
84 url = '%s/%s' % (headphones_url(), cache_url)
0462037 David Gray headphones module
N3MIS15 authored
85 else:
86 img = RUNDIR + '/static/images/applications/HeadPhones.png'
87 return send_file(img, mimetype='image/jpeg')
88
b996541 David Gray use urllib2 for headphones images
N3MIS15 authored
89 username = get_setting_value('headphones_user')
90 password = get_setting_value('headphones_password')
91
92 request = urllib2.Request(url)
93 base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
94 request.add_header("Authorization", "Basic %s" % base64string)
95
96 img = StringIO.StringIO(urllib2.urlopen(request).read())
0462037 David Gray headphones module
N3MIS15 authored
97 return send_file(img, mimetype='image/jpeg')
98
99
100 @app.route('/xhr/headphones/')
101 @requires_auth
102 def xhr_headphones():
8f86d25 David Gray Use upcoming view as default for headphones
N3MIS15 authored
103 return xhr_headphones_upcoming()
0462037 David Gray headphones module
N3MIS15 authored
104
105
106 @app.route('/xhr/headphones/artists/')
107 @requires_auth
108 def xhr_headphones_artists():
109 logger.log('HEADPHONES :: Fetching artists list', 'INFO')
110
111 try:
b1faacb David Gray code cleanup
N3MIS15 authored
112 headphones = headphones_api('getIndex')
0462037 David Gray headphones module
N3MIS15 authored
113 updates = headphones_api('getVersion')
114 except Exception as e:
115 return headphones_exception(e)
116
117 artists = []
118
119 for artist in headphones:
120 if not 'Fetch failed' in artist['ArtistName']:
121 try:
122 artist['Percent'] = int(100 * float(artist['HaveTracks']) / float(artist['TotalTracks']))
123 except:
124 artist['Percent'] = 0
125
126 if not hp_compact():
b1faacb David Gray code cleanup
N3MIS15 authored
127 try:
128 artist['ThumbURL'] = hp_artistart(artist['ArtistID'])
129 except:
130 pass
0462037 David Gray headphones module
N3MIS15 authored
131 artists.append(artist)
132
8f86d25 David Gray Use upcoming view as default for headphones
N3MIS15 authored
133 return render_template('headphones-artists.html',
0462037 David Gray headphones module
N3MIS15 authored
134 headphones=True,
135 artists=artists,
136 updates=updates,
137 compact=hp_compact(),
138 )
139
140
141 @app.route('/xhr/headphones/artist/<artistid>/')
142 @requires_auth
143 def xhr_headphones_artist(artistid):
144 logger.log('HEADPHONES :: Fetching artist', 'INFO')
145
146 try:
b1faacb David Gray code cleanup
N3MIS15 authored
147 albums = headphones_api('getArtist&id=%s' % artistid)
0462037 David Gray headphones module
N3MIS15 authored
148 except Exception as e:
149 return headphones_exception(e)
150
151 if not hp_compact():
b1faacb David Gray code cleanup
N3MIS15 authored
152 for album in albums['albums']:
0462037 David Gray headphones module
N3MIS15 authored
153 try:
154 album['ThumbURL'] = hp_albumart(album['AlbumID'])
155 except:
156 pass
157
158 return render_template('headphones-artist.html',
b1faacb David Gray code cleanup
N3MIS15 authored
159 albums=albums,
0462037 David Gray headphones module
N3MIS15 authored
160 headphones=True,
161 compact=hp_compact(),
162 )
163
164
165 @app.route('/xhr/headphones/album/<albumid>/')
166 @requires_auth
167 def xhr_headphones_album(albumid):
168 logger.log('HEADPHONES :: Fetching album', 'INFO')
169
170 try:
b1faacb David Gray code cleanup
N3MIS15 authored
171 headphones = headphones_api('getAlbum&id=%s' % albumid)
0462037 David Gray headphones module
N3MIS15 authored
172 except Exception as e:
173 return headphones_exception(e)
174
175 album = headphones['album'][0]
176
177 try:
178 album['ThumbURL'] = hp_albumart(album['AlbumID'])
179 except:
180 pass
181
182 album['TotalDuration'] = 0
183
184 for track in headphones['tracks']:
185 if track['TrackDuration'] == None:
186 track['TrackDuration'] = 0
187 album['TotalDuration'] = album['TotalDuration'] + int(track['TrackDuration'])
188 track['TrackDuration'] = convert_track_duration(track['TrackDuration'])
189
190 album['TotalDuration'] = convert_track_duration(album['TotalDuration'])
191 album['Tracks'] = len(headphones['tracks'])
192
193 return render_template('headphones-album.html',
194 album=headphones,
195 headphones=True,
196 compact=hp_compact(),
197 )
198
199
200 @app.route('/xhr/headphones/upcoming/')
201 @requires_auth
202 def xhr_headphones_upcoming():
203 logger.log('HEADPHONES :: Fetching upcoming albums', 'INFO')
204
205 try:
b1faacb David Gray code cleanup
N3MIS15 authored
206 upcoming = headphones_api('getUpcoming')
4e28d0b David Gray added wanted albums to upcoming
N3MIS15 authored
207 except Exception as e:
208 return headphones_exception(e)
209
210 if upcoming == []:
211 upcoming = 'empty'
212
213 for album in upcoming:
214 try:
215 album['ThumbURL'] = hp_albumart(album['AlbumID'])
216 except:
217 pass
218
219 try:
220 wanted = headphones_api('getWanted')
0462037 David Gray headphones module
N3MIS15 authored
221 except Exception as e:
222 return headphones_exception(e)
223
4e28d0b David Gray added wanted albums to upcoming
N3MIS15 authored
224 if wanted == []:
225 wanted = 'empty'
0462037 David Gray headphones module
N3MIS15 authored
226
4e28d0b David Gray added wanted albums to upcoming
N3MIS15 authored
227 for album in wanted:
0462037 David Gray headphones module
N3MIS15 authored
228 try:
4e28d0b David Gray added wanted albums to upcoming
N3MIS15 authored
229 album['ThumbURL'] = hp_albumart(album['AlbumID'])
0462037 David Gray headphones module
N3MIS15 authored
230 except:
231 pass
232
8f86d25 David Gray Use upcoming view as default for headphones
N3MIS15 authored
233 return render_template('headphones.html',
4e28d0b David Gray added wanted albums to upcoming
N3MIS15 authored
234 upcoming=upcoming,
235 wanted=wanted,
0462037 David Gray headphones module
N3MIS15 authored
236 headphones=True,
237 compact=hp_compact(),
238 )
239
240
241 @app.route('/xhr/headphones/similar/')
242 @requires_auth
243 def xhr_headphones_similar():
244 logger.log('HEADPHONES :: Fetching similar artists', 'INFO')
245
246 try:
b1faacb David Gray code cleanup
N3MIS15 authored
247 headphones = headphones_api('getSimilar')
0462037 David Gray headphones module
N3MIS15 authored
248 except Exception as e:
249 return headphones_exception(e)
250
251 return render_template('headphones-similar.html',
252 similar=headphones,
253 headphones=True,
254 )
255
256
bc52717 David Gray added simple history view to headphones module
N3MIS15 authored
257 @app.route('/xhr/headphones/history/')
258 @requires_auth
259 def xhr_headphones_history():
260 logger.log('HEADPHONES :: Fetching history', 'INFO')
261
262 try:
263 headphones = headphones_api('getHistory')
264 except Exception as e:
265 return headphones_exception(e)
266
267 return render_template('headphones-history.html',
268 history=headphones,
269 headphones=True,
270 )
271
272
0462037 David Gray headphones module
N3MIS15 authored
273 @app.route('/xhr/headphones/search/<type>/<query>/')
274 @requires_auth
275 def xhr_headphones_search(type, query):
276 if type == 'artist':
277 logger.log('HEADPHONES :: Searching for artist', 'INFO')
278 command = 'findArtist&name=%s' % urllib.quote(query)
279 else:
280 logger.log('HEADPHONES :: Searching for album', 'INFO')
281 command = 'findAlbum&name=%s' % urllib.quote(query)
282
283 try:
284 headphones = headphones_api(command)
285 except Exception as e:
286 return headphones_exception(e)
287
288 for artist in headphones:
289 artist['url'].replace('\/', '/')
290
291 return render_template('headphones-search_dialog.html',
292 headphones=True,
293 search=headphones,
294 query=query
295 )
296
297
298 @app.route('/xhr/headphones/artist/<artistid>/<action>/')
299 @requires_auth
300 def xhr_headphones_artist_action(artistid, action):
301 if action == 'pause':
302 logger.log('HEADPHONES :: Pausing artist', 'INFO')
303 command = 'pauseArtist&id=%s' % artistid
304 elif action == 'resume':
305 logger.log('HEADPHONES :: Resuming artist', 'INFO')
306 command = 'resumeArtist&id=%s' % artistid
307 elif action == 'refresh':
308 logger.log('HEADPHONES :: Refreshing artist', 'INFO')
309 command = 'refreshArtist&id=%s' % artistid
310 elif action == 'remove':
311 logger.log('HEADPHONES :: Removing artist', 'INFO')
312 command = 'delArtist&id=%s' % artistid
313 elif action == 'add':
314 logger.log('HEADPHONES :: Adding artist', 'INFO')
315 command = 'addArtist&id=%s' % artistid
316
317 try:
a6a04bb David Gray added some animation to artist action buttons
N3MIS15 authored
318 if command == 'remove':
319 headphones_api(command, False)
320 elif command == 'pause':
321 headphones_api(command, False)
322 elif command == 'resume':
0462037 David Gray headphones module
N3MIS15 authored
323 headphones_api(command, False)
324 else:
325 Thread(target=headphones_api, args=(command, False)).start()
326 except Exception as e:
327 return headphones_exception(e)
328
329 return jsonify(status='successful')
330
331
332 @app.route('/xhr/headphones/album/<albumid>/<status>/')
333 @requires_auth
334 def xhr_headphones_album_status(albumid, status):
335 if status == 'wanted':
336 logger.log('HEADPHONES :: Marking album as wanted', 'INFO')
337 command = 'queueAlbum&id=%s' % albumid
338 if status == 'wanted_new':
339 logger.log('HEADPHONES :: Marking album as wanted (new)', 'INFO')
340 command = 'queueAlbum&new=True&id=%s' % albumid
341 if status == 'skipped':
342 logger.log('HEADPHONES :: Marking album as skipped', 'INFO')
343 command = 'unqueueAlbum&id=%s' % albumid
344
345 try:
346 Thread(target=headphones_api, args=(command, False)).start()
347 except Exception as e:
348 return headphones_exception(e)
349
350 return jsonify(status='successful')
351
352
353 @app.route('/xhr/headphones/control/<command>/')
354 @requires_auth
355 def xhr_headphones_control(command):
356 if command == 'shutdown':
357 logger.log('HEADPHONES :: Shutting down', 'INFO')
358
359 elif command == 'restart':
360 logger.log('HEADPHONES :: Restarting', 'INFO')
361
362 elif command == 'update':
363 logger.log('HEADPHONES :: Updating', 'INFO')
364
365 elif command == 'force_search':
366 logger.log('HEADPHONES :: Forcing wanted album search', 'INFO')
367 command = 'forceSearch'
368
369 elif command == 'force_process':
370 logger.log('HEADPHONES :: Forcing post process', 'INFO')
371 command = 'forceProcess'
372
373 try:
374 Thread(target=headphones_api, args=(command, False)).start()
375 except Exception as e:
376 return headphones_exception(e)
377
378 return jsonify(status='successful')
Something went wrong with that request. Please try again.