From 7477e549f78bb52bcad82cbefda28b100a251e0b Mon Sep 17 00:00:00 2001 From: Alban Date: Sun, 2 Dec 2012 16:42:25 +0100 Subject: [PATCH] Some factoring... --- api/__init__.py | 17 ++++++++++ api/browse.py | 84 +++++++++++++++---------------------------------- api/media.py | 65 +++++++++++++++----------------------- 3 files changed, 67 insertions(+), 99 deletions(-) diff --git a/api/__init__.py b/api/__init__.py index fd8a89e..e464b32 100755 --- a/api/__init__.py +++ b/api/__init__.py @@ -3,6 +3,7 @@ from flask import request import simplejson import cgi +import uuid from web import app from user_manager import UserManager @@ -171,3 +172,19 @@ def hexdecode(enc): enc = enc[2:] return ret +def get_entity(req, ent, param = 'id'): + eid = req.args.get(param) + if not eid: + return False, req.error_formatter(10, 'Missing %s id' % ent.__name__) + + try: + eid = uuid.UUID(eid) + except: + return False, req.error_formatter(0, 'Invalid %s id' % ent.__name__) + + entity = ent.query.get(eid) + if not entity: + return False, (req.error_formatter(70, '%s not found' % ent.__name__), 404) + + return True, entity + diff --git a/api/browse.py b/api/browse.py index fc6ec46..593360f 100755 --- a/api/browse.py +++ b/api/browse.py @@ -3,6 +3,7 @@ from flask import request from web import app from db import Folder, Artist, Album, Track +from api import get_entity import uuid, time, string @app.route('/rest/getMusicFolders.view', methods = [ 'GET', 'POST' ]) @@ -85,31 +86,23 @@ def list_indexes(): @app.route('/rest/getMusicDirectory.view', methods = [ 'GET', 'POST' ]) def show_directory(): - did = request.args.get('id') - if not did: - return request.error_formatter(10, 'Missing directory id') - try: - fid = uuid.UUID(did) - except: - return request.error_formatter(0, 'Invalid directory id') - - folder = Folder.query.get(fid) - if not folder: - return request.error_formatter(70, 'Directory not found') + status, res = get_entity(request, Folder) + if not status: + return res directory = { - 'id': str(folder.id), - 'name': folder.name, - 'child': [ f.as_subsonic_child() for f in sorted(folder.children, key = lambda c: c.name) ] + [ t.as_subsonic_child() for t in sorted(folder.tracks, key = lambda t: t.sort_key()) ] + 'id': str(res.id), + 'name': res.name, + 'child': [ f.as_subsonic_child() for f in sorted(res.children, key = lambda c: c.name.lower()) ] + [ t.as_subsonic_child() for t in sorted(res.tracks, key = lambda t: t.sort_key()) ] } - if not folder.root: - directory['parent'] = str(folder.parent_id) + if not res.root: + directory['parent'] = str(res.parent_id) return request.formatter({ 'directory': directory }) @app.route('/rest/getArtists.view', methods = [ 'GET', 'POST' ]) def list_artists(): - # According to the API page, there are no parameter? + # According to the API page, there are no parameters? indexes = {} for artist in Artist.query.all(): index = artist.name[0].upper() @@ -134,60 +127,33 @@ def list_artists(): @app.route('/rest/getArtist.view', methods = [ 'GET', 'POST' ]) def artist_info(): - id = request.args.get('id') - if not id: - return request.error_formatter(10, 'Missing artist id') + status, res = get_entity(request, Artist) + if not status: + return res - try: - aid = uuid.UUID(id) - except: - return request.error_formatter(0, 'Invalid artist id') - - artist = Artist.query.get(aid) - if not artist: - return request.error_formatter(70, 'Artist not found'), 404 - - info = artist.as_subsonic_artist() - info['album'] = [ a.as_subsonic_album() for a in sorted(artist.albums, key = lambda a: a.sort_key()) ] + info = res.as_subsonic_artist() + info['album'] = [ a.as_subsonic_album() for a in sorted(res.albums, key = lambda a: a.sort_key()) ] return request.formatter({ 'artist': info }) @app.route('/rest/getAlbum.view', methods = [ 'GET', 'POST' ]) def album_info(): - id = request.args.get('id') - if not id: - return request.error_formatter(10, 'Missing album id') + status, res = get_entity(request, Album) + if not status: + return res - try: - aid = uuid.UUID(id) - except: - return request.error_formatter(0, 'Invalid album id') + info = res.as_subsonic_album() + info['song'] = [ t.as_subsonic_child() for t in sorted(res.tracks, key = lambda t: t.sort_key()) ] - album = Album.query.get(aid) - if not album: - return request.error_formatter(70, 'Album not found'), 404 - - info = album.as_subsonic_album() - info['song'] = [ t.as_subsonic_child() for t in sorted(album.tracks, key = lambda t: t.sort_key()) ] - - return request.formatter({ 'artist': info }) + return request.formatter({ 'album': info }) @app.route('/rest/getSong.view', methods = [ 'GET', 'POST' ]) def track_info(): - id = request.args.get('id') - if not id: - return request.error_formatter(10, 'Missing media id') + status, res = get_entity(request, Track) + if not status: + return res - try: - tid = uuid.UUID(id) - except: - return request.error_formatter(0, 'Invalid media id') - - track = Track.query.get(tid) - if not track: - return request.error_formatter(70, 'Media not found'), 404 - - return request.formatter({ 'song': track.as_subsonic_child() }) + return request.formatter({ 'song': res.as_subsonic_child() }) @app.route('/rest/getVideos.view', methods = [ 'GET', 'POST' ]) def list_videos(): diff --git a/api/media.py b/api/media.py index 561e2e5..e540fbc 100755 --- a/api/media.py +++ b/api/media.py @@ -1,29 +1,23 @@ # coding: utf-8 from flask import request, send_file -import os.path, uuid +import os.path import Image from time import time as now import config from web import app from db import Track, Folder, User +from api import get_entity from lastfm import LastFm @app.route('/rest/stream.view', methods = [ 'GET', 'POST' ]) def stream_media(): - id, maxBitRate, format, timeOffset, size, estimateContentLength = map(request.args.get, [ 'id', 'maxBitRate', 'format', 'timeOffset', 'size', 'estimateContentLength' ]) - if not id: - return request.error_formatter(10, 'Missing media id') + status, res = get_entity(request, Track) + if not status: + return res - try: - tid = uuid.UUID(id) - except: - return request.error_formatter(0, 'Invalid media id') - - track = Track.query.get(tid) - if not track: - return request.error_formatter(70, 'Media not found'), 404 + maxBitRate, format, timeOffset, size, estimateContentLength = map(request.args.get, [ 'maxBitRate', 'format', 'timeOffset', 'size', 'estimateContentLength' ]) if maxBitRate: try: @@ -31,7 +25,7 @@ def stream_media(): except: return request.error_formatter(0, 'Invalid bitrate value') - if track.bitrate > maxBitRate: + if res.bitrate > maxBitRate: # TODO transcode pass @@ -40,21 +34,17 @@ def stream_media(): pass if estimateContentLength == 'true': - return send_file(track.path), 200, { 'Content-Length': os.path.getsize(track.path) } + return send_file(res.path), 200, { 'Content-Length': os.path.getsize(res.path) } - return send_file(track.path) + return send_file(res.path) @app.route('/rest/getCoverArt.view', methods = [ 'GET', 'POST' ]) def cover_art(): - id = request.args.get('id') - if not id: - return request.error_formatter(10, 'Missing cover art id') - try: - fid = uuid.UUID(id) - except: - return request.error_formatter(0, 'Invalid cover art id') - folder = Folder.query.get(fid) - if not folder or not folder.has_cover_art or not os.path.isfile(os.path.join(folder.path, 'cover.jpg')): + status, res = get_entity(request, Folder) + if not status: + return res + + if not res.has_cover_art or not os.path.isfile(os.path.join(res.path, 'cover.jpg')): return request.error_formatter(70, 'Cover art not found') size = request.args.get('size') @@ -64,14 +54,14 @@ def cover_art(): except: return request.error_formatter(0, 'Invalid size value') else: - return send_file(os.path.join(folder.path, 'cover.jpg')) + return send_file(os.path.join(res.path, 'cover.jpg')) - im = Image.open(os.path.join(folder.path, 'cover.jpg')) + im = Image.open(os.path.join(res.path, 'cover.jpg')) if size > im.size[0] and size > im.size[1]: - return send_file(os.path.join(folder.path, 'cover.jpg')) + return send_file(os.path.join(res.path, 'cover.jpg')) size_path = os.path.join(config.get('CACHE_DIR'), str(size)) - path = os.path.join(size_path, id) + path = os.path.join(size_path, str(res.id)) if os.path.exists(path): return send_file(path) if not os.path.exists(size_path): @@ -83,16 +73,11 @@ def cover_art(): @app.route('/rest/scrobble.view', methods = [ 'GET', 'POST' ]) def scrobble(): - tid, time, submission, u = map(request.args.get, [ 'id', 'time', 'submission', 'u' ]) - if not tid: - return request.error_formatter(10, 'Missing file id') - try: - tid = uuid.UUID(tid) - except: - return request.error_formatter(0, 'Invalid file id') - track = Track.query.get(tid) - if not track: - return request.error_formatter(70, 'File not found') + status, res = get_entity(request, Track) + if not status: + return res + + time, submission, u = map(request.args.get, [ 'time', 'submission', 'u' ]) if time: try: @@ -106,9 +91,9 @@ def scrobble(): lfm = LastFm(user, app.logger) if submission in (None, '', True, 'true', 'True', 1, '1'): - lfm.scrobble(track, time) + lfm.scrobble(res, time) else: - lfm.now_playing(track) + lfm.now_playing(res) return request.formatter({})