1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-09-20 03:11:04 +00:00
supysonic/api/albums_songs.py
spl0k d9caa025fd getNowPlaying.view
Code is specific to a SQLite database
2013-06-10 20:58:51 +02:00

137 lines
4.5 KiB
Python
Executable File

# coding: utf-8
from flask import request
from sqlalchemy import desc, func, Interval
from sqlalchemy.orm import aliased
import random
import uuid
from web import app
from db import Track, Folder, Album, Artist, User, now
@app.route('/rest/getRandomSongs.view', methods = [ 'GET', 'POST' ])
def rand_songs():
size = request.args.get('size', '10')
genre, fromYear, toYear, musicFolderId = map(request.args.get, [ 'genre', 'fromYear', 'toYear', 'musicFolderId' ])
try:
size = int(size) if size else 10
fromYear = int(fromYear) if fromYear else None
toYear = int(toYear) if toYear else None
fid = uuid.UUID(musicFolderId) if musicFolderId else None
except:
return request.error_formatter(0, 'Invalid parameter format')
query = Track.query
if fromYear:
query = query.filter(Track.year >= fromYear)
if toYear:
query = query.filter(Track.year <= toYear)
if genre:
query = query.filter(Track.genre == genre)
if fid:
query = query.filter(Track.root_folder_id == fid)
tracks = query.all()
if not tracks:
return request.formatter({ 'randomSongs': {} })
return request.formatter({
'randomSongs': {
'song': [ random.choice(tracks).as_subsonic_child() for x in xrange(size) ]
}
})
@app.route('/rest/getAlbumList.view', methods = [ 'GET', 'POST' ])
def album_list():
ltype, size, offset = map(request.args.get, [ 'type', 'size', 'offset' ])
try:
size = int(size) if size else 10
offset = int(offset) if offset else 0
except:
return request.error_formatter(0, 'Invalid parameter format')
query = Folder.query.filter(Folder.tracks.any())
if ltype == 'random':
albums = query.all()
return request.formatter({
'albumList': {
'album': [ random.choice(albums).as_subsonic_child() for x in xrange(size) ]
}
})
elif ltype == 'newest':
query = query.order_by(desc(Folder.created))
elif ltype == 'highest':
return request.error_formatter(0, 'Not implemented')
elif ltype == 'frequent':
query = query.join(Track, Folder.tracks).group_by(Folder.id).order_by(desc(func.sum(Track.play_count) / func.count()))
elif ltype == 'recent':
query = query.join(Track, Folder.tracks).group_by(Folder.id).order_by(desc(func.max(Track.last_play)))
elif ltype == 'starred':
return request.error_formatter(0, 'Not implemented')
elif ltype == 'alphabeticalByName':
query = query.order_by(Folder.name)
elif ltype == 'alphabeticalByArtist':
parent = aliased(Folder)
query = query.join(parent, Folder.parent).order_by(parent.name).order_by(Folder.name)
else:
return request.error_formatter(0, 'Unknown search type')
return request.formatter({
'albumList': {
'album': [ f.as_subsonic_child() for f in query.limit(size).offset(offset) ]
}
})
@app.route('/rest/getAlbumList2.view', methods = [ 'GET', 'POST' ])
def album_list():
ltype, size, offset = map(request.args.get, [ 'type', 'size', 'offset' ])
try:
size = int(size) if size else 10
offset = int(offset) if offset else 0
except:
return request.error_formatter(0, 'Invalid parameter format')
query = Album.query
if ltype == 'random':
albums = query.all()
return request.formatter({
'albumList2': {
'album': [ random.choice(albums).as_subsonic_album() for x in xrange(size) ]
}
})
elif ltype == 'newest':
query = query.join(Track, Album.tracks).group_by(Album.id).order_by(desc(func.min(Track.created)))
elif ltype == 'frequent':
query = query.join(Track, Album.tracks).group_by(Album.id).order_by(desc(func.sum(Track.play_count) / func.count()))
elif ltype == 'recent':
query = query.join(Track, Album.tracks).group_by(Album.id).order_by(desc(func.max(Track.last_play)))
elif ltype == 'starred':
return request.error_formatter(0, 'Not implemented')
elif ltype == 'alphabeticalByName':
query = query.order_by(Album.name)
elif ltype == 'alphabeticalByArtist':
query = query.join(Artist).order_by(Artist.name).order_by(Album.name)
else:
return request.error_formatter(0, 'Unknown search type')
return request.formatter({
'albumList2': {
'album': [ f.as_subsonic_album() for f in query.limit(size).offset(offset) ]
}
})
@app.route('/rest/getNowPlaying.view', methods = [ 'GET', 'POST' ])
def now_playing():
# SQLite specific
query = User.query.join(Track).filter(func.strftime('%s', now()) - func.strftime('%s', User.last_play_date) < Track.duration * 2)
return request.formatter({
'nowPlaying': {
'entry': [ dict(
u.last_play.as_subsonic_child().items() +
{ 'username': u.name, 'minutesAgo': (now() - u.last_play_date).seconds / 60, 'playerId': 0 }.items()
) for u in query ]
}
})