mirror of
https://github.com/spl0k/supysonic.git
synced 2024-12-22 17:06:17 +00:00
Wrapping all request handling in a database transaction
This commit is contained in:
parent
e3ccf0809f
commit
43b197a95e
@ -25,7 +25,7 @@ import uuid
|
|||||||
|
|
||||||
from flask import request
|
from flask import request
|
||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
from pony.orm import db_session, ObjectNotFound
|
from pony.orm import ObjectNotFound
|
||||||
|
|
||||||
from ..managers.user import UserManager
|
from ..managers.user import UserManager
|
||||||
from ..py23 import dict
|
from ..py23 import dict
|
||||||
@ -83,11 +83,10 @@ def get_client_prefs():
|
|||||||
return request.formatter.error(10, 'Missing required parameter')
|
return request.formatter.error(10, 'Missing required parameter')
|
||||||
|
|
||||||
client = request.values.get('c')
|
client = request.values.get('c')
|
||||||
with db_session:
|
try:
|
||||||
try:
|
ClientPrefs[request.user, client]
|
||||||
ClientPrefs[request.user.id, client]
|
except ObjectNotFound:
|
||||||
except ObjectNotFound:
|
ClientPrefs(user = request.user, client_name = client)
|
||||||
ClientPrefs(user = User[request.user.id], client_name = client)
|
|
||||||
|
|
||||||
request.client = client
|
request.client = client
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import uuid
|
|||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from flask import request
|
from flask import request
|
||||||
from pony.orm import db_session, select, desc, avg, max, min, count
|
from pony.orm import select, desc, avg, max, min, count
|
||||||
|
|
||||||
from ..db import Folder, Artist, Album, Track, RatingFolder, StarredFolder, StarredArtist, StarredAlbum, StarredTrack, User
|
from ..db import Folder, Artist, Album, Track, RatingFolder, StarredFolder, StarredArtist, StarredAlbum, StarredTrack, User
|
||||||
from ..db import now
|
from ..db import now
|
||||||
@ -51,16 +51,14 @@ def rand_songs():
|
|||||||
if genre:
|
if genre:
|
||||||
query = query.filter(lambda t: t.genre == genre)
|
query = query.filter(lambda t: t.genre == genre)
|
||||||
if fid:
|
if fid:
|
||||||
with db_session:
|
if not Folder.exists(id = fid, root = True):
|
||||||
if not Folder.exists(id = fid, root = True):
|
return request.formatter.error(70, 'Unknown folder')
|
||||||
return request.formatter.error(70, 'Unknown folder')
|
|
||||||
|
|
||||||
query = query.filter(lambda t: t.root_folder.id == fid)
|
query = query.filter(lambda t: t.root_folder.id == fid)
|
||||||
|
|
||||||
with db_session:
|
return request.formatter('randomSongs', dict(
|
||||||
return request.formatter('randomSongs', dict(
|
song = [ t.as_subsonic_child(request.user, request.client) for t in query.random(size) ]
|
||||||
song = [ t.as_subsonic_child(request.user, request.client) for t in query.random(size) ]
|
))
|
||||||
))
|
|
||||||
|
|
||||||
@api.route('/getAlbumList.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getAlbumList.view', methods = [ 'GET', 'POST' ])
|
||||||
def album_list():
|
def album_list():
|
||||||
@ -75,10 +73,9 @@ def album_list():
|
|||||||
|
|
||||||
query = select(t.folder for t in Track)
|
query = select(t.folder for t in Track)
|
||||||
if ltype == 'random':
|
if ltype == 'random':
|
||||||
with db_session:
|
return request.formatter('albumList', dict(
|
||||||
return request.formatter('albumList', dict(
|
album = [ a.as_subsonic_child(request.user) for a in query.random(size) ]
|
||||||
album = [ a.as_subsonic_child(request.user) for a in query.random(size) ]
|
))
|
||||||
))
|
|
||||||
elif ltype == 'newest':
|
elif ltype == 'newest':
|
||||||
query = query.order_by(desc(Folder.created))
|
query = query.order_by(desc(Folder.created))
|
||||||
elif ltype == 'highest':
|
elif ltype == 'highest':
|
||||||
@ -96,10 +93,9 @@ def album_list():
|
|||||||
else:
|
else:
|
||||||
return request.formatter.error(0, 'Unknown search type')
|
return request.formatter.error(0, 'Unknown search type')
|
||||||
|
|
||||||
with db_session:
|
return request.formatter('albumList', dict(
|
||||||
return request.formatter('albumList', dict(
|
album = [ f.as_subsonic_child(request.user) for f in query.limit(size, offset) ]
|
||||||
album = [ f.as_subsonic_child(request.user) for f in query.limit(size, offset) ]
|
))
|
||||||
))
|
|
||||||
|
|
||||||
@api.route('/getAlbumList2.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getAlbumList2.view', methods = [ 'GET', 'POST' ])
|
||||||
def album_list_id3():
|
def album_list_id3():
|
||||||
@ -114,10 +110,9 @@ def album_list_id3():
|
|||||||
|
|
||||||
query = Album.select()
|
query = Album.select()
|
||||||
if ltype == 'random':
|
if ltype == 'random':
|
||||||
with db_session:
|
return request.formatter('albumList2', dict(
|
||||||
return request.formatter('albumList2', dict(
|
album = [ a.as_subsonic_album(request.user) for a in query.random(size) ]
|
||||||
album = [ a.as_subsonic_album(request.user) for a in query.random(size) ]
|
))
|
||||||
))
|
|
||||||
elif ltype == 'newest':
|
elif ltype == 'newest':
|
||||||
query = query.order_by(lambda a: desc(min(a.tracks.created)))
|
query = query.order_by(lambda a: desc(min(a.tracks.created)))
|
||||||
elif ltype == 'frequent':
|
elif ltype == 'frequent':
|
||||||
@ -133,13 +128,11 @@ def album_list_id3():
|
|||||||
else:
|
else:
|
||||||
return request.formatter.error(0, 'Unknown search type')
|
return request.formatter.error(0, 'Unknown search type')
|
||||||
|
|
||||||
with db_session:
|
return request.formatter('albumList2', dict(
|
||||||
return request.formatter('albumList2', dict(
|
album = [ f.as_subsonic_album(request.user) for f in query.limit(size, offset) ]
|
||||||
album = [ f.as_subsonic_album(request.user) for f in query.limit(size, offset) ]
|
))
|
||||||
))
|
|
||||||
|
|
||||||
@api.route('/getNowPlaying.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getNowPlaying.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def now_playing():
|
def now_playing():
|
||||||
query = User.select(lambda u: u.last_play is not None and u.last_play_date + timedelta(minutes = 3) > now())
|
query = User.select(lambda u: u.last_play is not None and u.last_play_date + timedelta(minutes = 3) > now())
|
||||||
|
|
||||||
@ -151,7 +144,6 @@ def now_playing():
|
|||||||
))
|
))
|
||||||
|
|
||||||
@api.route('/getStarred.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getStarred.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def get_starred():
|
def get_starred():
|
||||||
folders = select(s.starred for s in StarredFolder if s.user.id == request.user.id)
|
folders = select(s.starred for s in StarredFolder if s.user.id == request.user.id)
|
||||||
|
|
||||||
@ -162,7 +154,6 @@ def get_starred():
|
|||||||
))
|
))
|
||||||
|
|
||||||
@api.route('/getStarred2.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getStarred2.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def get_starred_id3():
|
def get_starred_id3():
|
||||||
return request.formatter('starred2', dict(
|
return request.formatter('starred2', dict(
|
||||||
artist = [ sa.as_subsonic_artist(request.user) for sa in select(s.starred for s in StarredArtist if s.user.id == request.user.id) ],
|
artist = [ sa.as_subsonic_artist(request.user) for sa in select(s.starred for s in StarredArtist if s.user.id == request.user.id) ],
|
||||||
|
@ -22,7 +22,7 @@ import time
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from flask import current_app, request
|
from flask import current_app, request
|
||||||
from pony.orm import db_session, delete
|
from pony.orm import delete
|
||||||
from pony.orm import ObjectNotFound
|
from pony.orm import ObjectNotFound
|
||||||
|
|
||||||
from ..db import Track, Album, Artist, Folder, User
|
from ..db import Track, Album, Artist, Folder, User
|
||||||
@ -33,7 +33,6 @@ from ..py23 import dict
|
|||||||
|
|
||||||
from . import api, get_entity
|
from . import api, get_entity
|
||||||
|
|
||||||
@db_session
|
|
||||||
def try_star(cls, starred_cls, eid):
|
def try_star(cls, starred_cls, eid):
|
||||||
""" Stars an entity
|
""" Stars an entity
|
||||||
|
|
||||||
@ -52,15 +51,14 @@ def try_star(cls, starred_cls, eid):
|
|||||||
return dict(code = 70, message = 'Unknown {} id {}'.format(cls.__name__, eid))
|
return dict(code = 70, message = 'Unknown {} id {}'.format(cls.__name__, eid))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
starred_cls[request.user.id, uid]
|
starred_cls[request.user, uid]
|
||||||
return dict(code = 0, message = '{} {} already starred'.format(cls.__name__, eid))
|
return dict(code = 0, message = '{} {} already starred'.format(cls.__name__, eid))
|
||||||
except ObjectNotFound:
|
except ObjectNotFound:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
starred_cls(user = User[request.user.id], starred = e)
|
starred_cls(user = request.user, starred = e)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@db_session
|
|
||||||
def try_unstar(starred_cls, eid):
|
def try_unstar(starred_cls, eid):
|
||||||
""" Unstars an entity
|
""" Unstars an entity
|
||||||
|
|
||||||
@ -153,31 +151,29 @@ def rate():
|
|||||||
if not 0 <= rating <= 5:
|
if not 0 <= rating <= 5:
|
||||||
return request.formatter.error(0, 'rating must be between 0 and 5 (inclusive)')
|
return request.formatter.error(0, 'rating must be between 0 and 5 (inclusive)')
|
||||||
|
|
||||||
with db_session:
|
if rating == 0:
|
||||||
if rating == 0:
|
delete(r for r in RatingTrack if r.user.id == request.user.id and r.rated.id == uid)
|
||||||
delete(r for r in RatingTrack if r.user.id == request.user.id and r.rated.id == uid)
|
delete(r for r in RatingFolder if r.user.id == request.user.id and r.rated.id == uid)
|
||||||
delete(r for r in RatingFolder if r.user.id == request.user.id and r.rated.id == uid)
|
else:
|
||||||
else:
|
try:
|
||||||
|
rated = Track[uid]
|
||||||
|
rating_cls = RatingTrack
|
||||||
|
except ObjectNotFound:
|
||||||
try:
|
try:
|
||||||
rated = Track[uid]
|
rated = Folder[uid]
|
||||||
rating_cls = RatingTrack
|
rating_cls = RatingFolder
|
||||||
except ObjectNotFound:
|
except ObjectNotFound:
|
||||||
try:
|
return request.formatter.error(70, 'Unknown id')
|
||||||
rated = Folder[uid]
|
|
||||||
rating_cls = RatingFolder
|
|
||||||
except ObjectNotFound:
|
|
||||||
return request.formatter.error(70, 'Unknown id')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rating_info = rating_cls[request.user.id, uid]
|
rating_info = rating_cls[request.user, uid]
|
||||||
rating_info.rating = rating
|
rating_info.rating = rating
|
||||||
except ObjectNotFound:
|
except ObjectNotFound:
|
||||||
rating_cls(user = User[request.user.id], rated = rated, rating = rating)
|
rating_cls(user = request.user, rated = rated, rating = rating)
|
||||||
|
|
||||||
return request.formatter.empty
|
return request.formatter.empty
|
||||||
|
|
||||||
@api.route('/scrobble.view', methods = [ 'GET', 'POST' ])
|
@api.route('/scrobble.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def scrobble():
|
def scrobble():
|
||||||
status, res = get_entity(Track)
|
status, res = get_entity(Track)
|
||||||
if not status:
|
if not status:
|
||||||
@ -193,7 +189,7 @@ def scrobble():
|
|||||||
else:
|
else:
|
||||||
t = int(time.time())
|
t = int(time.time())
|
||||||
|
|
||||||
lfm = LastFm(current_app.config['LASTFM'], User[request.user.id], current_app.logger)
|
lfm = LastFm(current_app.config['LASTFM'], request.user, current_app.logger)
|
||||||
|
|
||||||
if submission in (None, '', True, 'true', 'True', 1, '1'):
|
if submission in (None, '', True, 'true', 'True', 1, '1'):
|
||||||
lfm.scrobble(res, t)
|
lfm.scrobble(res, t)
|
||||||
|
@ -22,7 +22,6 @@ import string
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from flask import request
|
from flask import request
|
||||||
from pony.orm import db_session
|
|
||||||
from pony.orm import ObjectNotFound
|
from pony.orm import ObjectNotFound
|
||||||
|
|
||||||
from ..db import Folder, Artist, Album, Track
|
from ..db import Folder, Artist, Album, Track
|
||||||
@ -31,7 +30,6 @@ from ..py23 import dict
|
|||||||
from . import api, get_entity
|
from . import api, get_entity
|
||||||
|
|
||||||
@api.route('/getMusicFolders.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getMusicFolders.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def list_folders():
|
def list_folders():
|
||||||
return request.formatter('musicFolders', dict(
|
return request.formatter('musicFolders', dict(
|
||||||
musicFolder = [ dict(
|
musicFolder = [ dict(
|
||||||
@ -41,7 +39,6 @@ def list_folders():
|
|||||||
))
|
))
|
||||||
|
|
||||||
@api.route('/getIndexes.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getIndexes.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def list_indexes():
|
def list_indexes():
|
||||||
musicFolderId = request.values.get('musicFolderId')
|
musicFolderId = request.values.get('musicFolderId')
|
||||||
ifModifiedSince = request.values.get('ifModifiedSince')
|
ifModifiedSince = request.values.get('ifModifiedSince')
|
||||||
@ -102,7 +99,6 @@ def list_indexes():
|
|||||||
))
|
))
|
||||||
|
|
||||||
@api.route('/getMusicDirectory.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getMusicDirectory.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def show_directory():
|
def show_directory():
|
||||||
status, res = get_entity(Folder)
|
status, res = get_entity(Folder)
|
||||||
if not status:
|
if not status:
|
||||||
@ -119,7 +115,6 @@ def show_directory():
|
|||||||
return request.formatter('directory', directory)
|
return request.formatter('directory', directory)
|
||||||
|
|
||||||
@api.route('/getArtists.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getArtists.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def list_artists():
|
def list_artists():
|
||||||
# According to the API page, there are no parameters?
|
# According to the API page, there are no parameters?
|
||||||
indexes = dict()
|
indexes = dict()
|
||||||
@ -143,7 +138,6 @@ def list_artists():
|
|||||||
))
|
))
|
||||||
|
|
||||||
@api.route('/getArtist.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getArtist.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def artist_info():
|
def artist_info():
|
||||||
status, res = get_entity(Artist)
|
status, res = get_entity(Artist)
|
||||||
if not status:
|
if not status:
|
||||||
@ -157,7 +151,6 @@ def artist_info():
|
|||||||
return request.formatter('artist', info)
|
return request.formatter('artist', info)
|
||||||
|
|
||||||
@api.route('/getAlbum.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getAlbum.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def album_info():
|
def album_info():
|
||||||
status, res = get_entity(Album)
|
status, res = get_entity(Album)
|
||||||
if not status:
|
if not status:
|
||||||
@ -169,7 +162,6 @@ def album_info():
|
|||||||
return request.formatter('album', info)
|
return request.formatter('album', info)
|
||||||
|
|
||||||
@api.route('/getSong.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getSong.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def track_info():
|
def track_info():
|
||||||
status, res = get_entity(Track)
|
status, res = get_entity(Track)
|
||||||
if not status:
|
if not status:
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from flask import request
|
from flask import request
|
||||||
from pony.orm import db_session
|
|
||||||
|
|
||||||
from ..db import ChatMessage, User
|
from ..db import ChatMessage, User
|
||||||
from ..py23 import dict
|
from ..py23 import dict
|
||||||
@ -33,12 +32,11 @@ def get_chat():
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
return request.formatter.error(0, 'Invalid parameter')
|
return request.formatter.error(0, 'Invalid parameter')
|
||||||
|
|
||||||
with db_session:
|
query = ChatMessage.select().order_by(ChatMessage.time)
|
||||||
query = ChatMessage.select().order_by(ChatMessage.time)
|
if since:
|
||||||
if since:
|
query = query.filter(lambda m: m.time > since)
|
||||||
query = query.filter(lambda m: m.time > since)
|
|
||||||
|
|
||||||
return request.formatter('chatMessages', dict(chatMessage = [ msg.responsize() for msg in query ] ))
|
return request.formatter('chatMessages', dict(chatMessage = [ msg.responsize() for msg in query ] ))
|
||||||
|
|
||||||
@api.route('/addChatMessage.view', methods = [ 'GET', 'POST' ])
|
@api.route('/addChatMessage.view', methods = [ 'GET', 'POST' ])
|
||||||
def add_chat_message():
|
def add_chat_message():
|
||||||
@ -46,8 +44,7 @@ def add_chat_message():
|
|||||||
if not msg:
|
if not msg:
|
||||||
return request.formatter.error(10, 'Missing message')
|
return request.formatter.error(10, 'Missing message')
|
||||||
|
|
||||||
with db_session:
|
ChatMessage(user = request.user, message = msg)
|
||||||
ChatMessage(user = User[request.user.id], message = msg)
|
|
||||||
|
|
||||||
return request.formatter.empty
|
return request.formatter.empty
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ import subprocess
|
|||||||
from flask import request, Response, send_file
|
from flask import request, Response, send_file
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from pony.orm import db_session
|
|
||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
from .. import scanner
|
from .. import scanner
|
||||||
@ -47,7 +46,6 @@ def prepare_transcoding_cmdline(base_cmdline, input_file, input_format, output_f
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
@api.route('/stream.view', methods = [ 'GET', 'POST' ])
|
@api.route('/stream.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def stream_media():
|
def stream_media():
|
||||||
status, res = get_entity(Track)
|
status, res = get_entity(Track)
|
||||||
if not status:
|
if not status:
|
||||||
@ -127,7 +125,7 @@ def stream_media():
|
|||||||
|
|
||||||
res.play_count = res.play_count + 1
|
res.play_count = res.play_count + 1
|
||||||
res.last_play = now()
|
res.last_play = now()
|
||||||
user = User[request.user.id]
|
user = request.user
|
||||||
user.last_play = res
|
user.last_play = res
|
||||||
user.last_play_date = now()
|
user.last_play_date = now()
|
||||||
|
|
||||||
@ -135,8 +133,7 @@ def stream_media():
|
|||||||
|
|
||||||
@api.route('/download.view', methods = [ 'GET', 'POST' ])
|
@api.route('/download.view', methods = [ 'GET', 'POST' ])
|
||||||
def download_media():
|
def download_media():
|
||||||
with db_session:
|
status, res = get_entity(Track)
|
||||||
status, res = get_entity(Track)
|
|
||||||
if not status:
|
if not status:
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@ -144,8 +141,7 @@ def download_media():
|
|||||||
|
|
||||||
@api.route('/getCoverArt.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getCoverArt.view', methods = [ 'GET', 'POST' ])
|
||||||
def cover_art():
|
def cover_art():
|
||||||
with db_session:
|
status, res = get_entity(Folder)
|
||||||
status, res = get_entity(Folder)
|
|
||||||
if not status:
|
if not status:
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@ -184,26 +180,25 @@ def lyrics():
|
|||||||
if not title:
|
if not title:
|
||||||
return request.formatter.error(10, 'Missing title parameter')
|
return request.formatter.error(10, 'Missing title parameter')
|
||||||
|
|
||||||
with db_session:
|
query = Track.select(lambda t: title in t.title and artist in t.artist.name)
|
||||||
query = Track.select(lambda t: title in t.title and artist in t.artist.name)
|
for track in query:
|
||||||
for track in query:
|
lyrics_path = os.path.splitext(track.path)[0] + '.txt'
|
||||||
lyrics_path = os.path.splitext(track.path)[0] + '.txt'
|
if os.path.exists(lyrics_path):
|
||||||
if os.path.exists(lyrics_path):
|
current_app.logger.debug('Found lyrics file: ' + lyrics_path)
|
||||||
current_app.logger.debug('Found lyrics file: ' + lyrics_path)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
lyrics = read_file_as_unicode(lyrics_path)
|
lyrics = read_file_as_unicode(lyrics_path)
|
||||||
except UnicodeError:
|
except UnicodeError:
|
||||||
# Lyrics file couldn't be decoded. Rather than displaying an error, try with the potential next files or
|
# Lyrics file couldn't be decoded. Rather than displaying an error, try with the potential next files or
|
||||||
# return no lyrics. Log it anyway.
|
# return no lyrics. Log it anyway.
|
||||||
current_app.logger.warning('Unsupported encoding for lyrics file ' + lyrics_path)
|
current_app.logger.warning('Unsupported encoding for lyrics file ' + lyrics_path)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return request.formatter('lyrics', dict(
|
return request.formatter('lyrics', dict(
|
||||||
artist = track.album.artist.name,
|
artist = track.album.artist.name,
|
||||||
title = track.title,
|
title = track.title,
|
||||||
_value_ = lyrics
|
_value_ = lyrics
|
||||||
))
|
))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = requests.get("http://api.chartlyrics.com/apiv1.asmx/SearchLyricDirect",
|
r = requests.get("http://api.chartlyrics.com/apiv1.asmx/SearchLyricDirect",
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from flask import request
|
from flask import request
|
||||||
from pony.orm import db_session, rollback
|
from pony.orm import rollback
|
||||||
from pony.orm import ObjectNotFound
|
from pony.orm import ObjectNotFound
|
||||||
|
|
||||||
from ..db import Playlist, User, Track
|
from ..db import Playlist, User, Track
|
||||||
@ -38,18 +38,15 @@ def list_playlists():
|
|||||||
if not request.user.admin:
|
if not request.user.admin:
|
||||||
return request.formatter.error(50, 'Restricted to admins')
|
return request.formatter.error(50, 'Restricted to admins')
|
||||||
|
|
||||||
with db_session:
|
user = User.get(name = username)
|
||||||
user = User.get(name = username)
|
|
||||||
if user is None:
|
if user is None:
|
||||||
return request.formatter.error(70, 'No such user')
|
return request.formatter.error(70, 'No such user')
|
||||||
|
|
||||||
query = Playlist.select(lambda p: p.user.name == username).order_by(Playlist.name)
|
query = Playlist.select(lambda p: p.user.name == username).order_by(Playlist.name)
|
||||||
|
|
||||||
with db_session:
|
return request.formatter('playlists', dict(playlist = [ p.as_subsonic_playlist(request.user) for p in query ] ))
|
||||||
return request.formatter('playlists', dict(playlist = [ p.as_subsonic_playlist(request.user) for p in query ] ))
|
|
||||||
|
|
||||||
@api.route('/getPlaylist.view', methods = [ 'GET', 'POST' ])
|
@api.route('/getPlaylist.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def show_playlist():
|
def show_playlist():
|
||||||
status, res = get_entity(Playlist)
|
status, res = get_entity(Playlist)
|
||||||
if not status:
|
if not status:
|
||||||
@ -63,7 +60,6 @@ def show_playlist():
|
|||||||
return request.formatter('playlist', info)
|
return request.formatter('playlist', info)
|
||||||
|
|
||||||
@api.route('/createPlaylist.view', methods = [ 'GET', 'POST' ])
|
@api.route('/createPlaylist.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def create_playlist():
|
def create_playlist():
|
||||||
playlist_id, name = map(request.values.get, [ 'playlistId', 'name' ])
|
playlist_id, name = map(request.values.get, [ 'playlistId', 'name' ])
|
||||||
# songId actually doesn't seem to be required
|
# songId actually doesn't seem to be required
|
||||||
@ -86,7 +82,7 @@ def create_playlist():
|
|||||||
if name:
|
if name:
|
||||||
playlist.name = name
|
playlist.name = name
|
||||||
elif name:
|
elif name:
|
||||||
playlist = Playlist(user = User[request.user.id], name = name)
|
playlist = Playlist(user = request.user, name = name)
|
||||||
else:
|
else:
|
||||||
return request.formatter.error(10, 'Missing playlist id or name')
|
return request.formatter.error(10, 'Missing playlist id or name')
|
||||||
|
|
||||||
@ -105,7 +101,6 @@ def create_playlist():
|
|||||||
return request.formatter.empty
|
return request.formatter.empty
|
||||||
|
|
||||||
@api.route('/deletePlaylist.view', methods = [ 'GET', 'POST' ])
|
@api.route('/deletePlaylist.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def delete_playlist():
|
def delete_playlist():
|
||||||
status, res = get_entity(Playlist)
|
status, res = get_entity(Playlist)
|
||||||
if not status:
|
if not status:
|
||||||
@ -118,7 +113,6 @@ def delete_playlist():
|
|||||||
return request.formatter.empty
|
return request.formatter.empty
|
||||||
|
|
||||||
@api.route('/updatePlaylist.view', methods = [ 'GET', 'POST' ])
|
@api.route('/updatePlaylist.view', methods = [ 'GET', 'POST' ])
|
||||||
@db_session
|
|
||||||
def update_playlist():
|
def update_playlist():
|
||||||
status, res = get_entity(Playlist, 'playlistId')
|
status, res = get_entity(Playlist, 'playlistId')
|
||||||
if not status:
|
if not status:
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from flask import request
|
from flask import request
|
||||||
from pony.orm import db_session, select
|
from pony.orm import select
|
||||||
|
|
||||||
from ..db import Folder, Track, Artist, Album
|
from ..db import Folder, Track, Artist, Album
|
||||||
from ..py23 import dict
|
from ..py23 import dict
|
||||||
@ -48,28 +48,26 @@ def old_search():
|
|||||||
elif anyf:
|
elif anyf:
|
||||||
folders = Folder.select(lambda f: anyf in f.name and f.created > min_date)
|
folders = Folder.select(lambda f: anyf in f.name and f.created > min_date)
|
||||||
tracks = Track.select(lambda t: anyf in t.title and t.created > min_date)
|
tracks = Track.select(lambda t: anyf in t.title and t.created > min_date)
|
||||||
with db_session:
|
res = folders[offset : offset + count]
|
||||||
res = folders[offset : offset + count]
|
fcount = folders.count()
|
||||||
fcount = folders.count()
|
if offset + count > fcount:
|
||||||
if offset + count > fcount:
|
toff = max(0, offset - fcount)
|
||||||
toff = max(0, offset - fcount)
|
tend = offset + count - fcount
|
||||||
tend = offset + count - fcount
|
res += tracks[toff : tend]
|
||||||
res += tracks[toff : tend]
|
|
||||||
|
|
||||||
return request.formatter('searchResult', dict(
|
return request.formatter('searchResult', dict(
|
||||||
totalHits = folders.count() + tracks.count(),
|
totalHits = folders.count() + tracks.count(),
|
||||||
offset = offset,
|
offset = offset,
|
||||||
match = [ r.as_subsonic_child(request.user) if isinstance(r, Folder) else r.as_subsonic_child(request.user, request.client) for r in res ]
|
match = [ r.as_subsonic_child(request.user) if isinstance(r, Folder) else r.as_subsonic_child(request.user, request.client) for r in res ]
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
return request.formatter.error(10, 'Missing search parameter')
|
return request.formatter.error(10, 'Missing search parameter')
|
||||||
|
|
||||||
with db_session:
|
return request.formatter('searchResult', dict(
|
||||||
return request.formatter('searchResult', dict(
|
totalHits = query.count(),
|
||||||
totalHits = query.count(),
|
offset = offset,
|
||||||
offset = offset,
|
match = [ r.as_subsonic_child(request.user) if isinstance(r, Folder) else r.as_subsonic_child(request.user, request.client) for r in query[offset : offset + count] ]
|
||||||
match = [ r.as_subsonic_child(request.user) if isinstance(r, Folder) else r.as_subsonic_child(request.user, request.client) for r in query[offset : offset + count] ]
|
))
|
||||||
))
|
|
||||||
|
|
||||||
@api.route('/search2.view', methods = [ 'GET', 'POST' ])
|
@api.route('/search2.view', methods = [ 'GET', 'POST' ])
|
||||||
def new_search():
|
def new_search():
|
||||||
@ -89,16 +87,15 @@ def new_search():
|
|||||||
if not query:
|
if not query:
|
||||||
return request.formatter.error(10, 'Missing query parameter')
|
return request.formatter.error(10, 'Missing query parameter')
|
||||||
|
|
||||||
with db_session:
|
artists = select(t.folder.parent for t in Track if query in t.folder.parent.name).limit(artist_count, artist_offset)
|
||||||
artists = select(t.folder.parent for t in Track if query in t.folder.parent.name).limit(artist_count, artist_offset)
|
albums = select(t.folder for t in Track if query in t.folder.name).limit(album_count, album_offset)
|
||||||
albums = select(t.folder for t in Track if query in t.folder.name).limit(album_count, album_offset)
|
songs = Track.select(lambda t: query in t.title).limit(song_count, song_offset)
|
||||||
songs = Track.select(lambda t: query in t.title).limit(song_count, song_offset)
|
|
||||||
|
|
||||||
return request.formatter('searchResult2', OrderedDict((
|
return request.formatter('searchResult2', OrderedDict((
|
||||||
('artist', [ dict(id = str(a.id), name = a.name) for a in artists ]),
|
('artist', [ dict(id = str(a.id), name = a.name) for a in artists ]),
|
||||||
('album', [ f.as_subsonic_child(request.user) for f in albums ]),
|
('album', [ f.as_subsonic_child(request.user) for f in albums ]),
|
||||||
('song', [ t.as_subsonic_child(request.user, request.client) for t in songs ])
|
('song', [ t.as_subsonic_child(request.user, request.client) for t in songs ])
|
||||||
)))
|
)))
|
||||||
|
|
||||||
@api.route('/search3.view', methods = [ 'GET', 'POST' ])
|
@api.route('/search3.view', methods = [ 'GET', 'POST' ])
|
||||||
def search_id3():
|
def search_id3():
|
||||||
@ -118,14 +115,13 @@ def search_id3():
|
|||||||
if not query:
|
if not query:
|
||||||
return request.formatter.error(10, 'Missing query parameter')
|
return request.formatter.error(10, 'Missing query parameter')
|
||||||
|
|
||||||
with db_session:
|
artists = Artist.select(lambda a: query in a.name).limit(artist_count, artist_offset)
|
||||||
artists = Artist.select(lambda a: query in a.name).limit(artist_count, artist_offset)
|
albums = Album.select(lambda a: query in a.name).limit(album_count, album_offset)
|
||||||
albums = Album.select(lambda a: query in a.name).limit(album_count, album_offset)
|
songs = Track.select(lambda t: query in t.title).limit(song_count, song_offset)
|
||||||
songs = Track.select(lambda t: query in t.title).limit(song_count, song_offset)
|
|
||||||
|
|
||||||
return request.formatter('searchResult3', OrderedDict((
|
return request.formatter('searchResult3', OrderedDict((
|
||||||
('artist', [ a.as_subsonic_artist(request.user) for a in artists ]),
|
('artist', [ a.as_subsonic_artist(request.user) for a in artists ]),
|
||||||
('album', [ a.as_subsonic_album(request.user) for a in albums ]),
|
('album', [ a.as_subsonic_album(request.user) for a in albums ]),
|
||||||
('song', [ t.as_subsonic_child(request.user, request.client) for t in songs ])
|
('song', [ t.as_subsonic_child(request.user, request.client) for t in songs ])
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from flask import request
|
from flask import request
|
||||||
from pony.orm import db_session
|
|
||||||
|
|
||||||
from ..db import User
|
from ..db import User
|
||||||
from ..managers.user import UserManager
|
from ..managers.user import UserManager
|
||||||
@ -36,8 +35,7 @@ def user_info():
|
|||||||
if username != request.username and not request.user.admin:
|
if username != request.username and not request.user.admin:
|
||||||
return request.formatter.error(50, 'Admin restricted')
|
return request.formatter.error(50, 'Admin restricted')
|
||||||
|
|
||||||
with db_session:
|
user = User.get(name = username)
|
||||||
user = User.get(name = username)
|
|
||||||
if user is None:
|
if user is None:
|
||||||
return request.formatter.error(70, 'Unknown user')
|
return request.formatter.error(70, 'Unknown user')
|
||||||
|
|
||||||
@ -48,8 +46,7 @@ def users_info():
|
|||||||
if not request.user.admin:
|
if not request.user.admin:
|
||||||
return request.formatter.error(50, 'Admin restricted')
|
return request.formatter.error(50, 'Admin restricted')
|
||||||
|
|
||||||
with db_session:
|
return request.formatter('users', dict(user = [ u.as_subsonic_user() for u in User.select() ] ))
|
||||||
return request.formatter('users', dict(user = [ u.as_subsonic_user() for u in User.select() ] ))
|
|
||||||
|
|
||||||
@api.route('/createUser.view', methods = [ 'GET', 'POST' ])
|
@api.route('/createUser.view', methods = [ 'GET', 'POST' ])
|
||||||
def user_add():
|
def user_add():
|
||||||
@ -77,8 +74,7 @@ def user_del():
|
|||||||
if not username:
|
if not username:
|
||||||
return request.formatter.error(10, 'Missing parameter')
|
return request.formatter.error(10, 'Missing parameter')
|
||||||
|
|
||||||
with db_session:
|
user = User.get(name = username)
|
||||||
user = User.get(name = username)
|
|
||||||
if user is None:
|
if user is None:
|
||||||
return request.formatter.error(70, 'Unknown user')
|
return request.formatter.error(70, 'Unknown user')
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
from flask import redirect, request, session, url_for
|
from flask import redirect, request, session, url_for
|
||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from pony.orm import db_session
|
|
||||||
|
|
||||||
from ..db import Artist, Album, Track
|
from ..db import Artist, Album, Track
|
||||||
from ..managers.user import UserManager
|
from ..managers.user import UserManager
|
||||||
@ -36,7 +35,6 @@ def login_check():
|
|||||||
return redirect(url_for('frontend.login', returnUrl = request.script_root + request.url[len(request.url_root)-1:]))
|
return redirect(url_for('frontend.login', returnUrl = request.script_root + request.url[len(request.url_root)-1:]))
|
||||||
|
|
||||||
@frontend.route('/')
|
@frontend.route('/')
|
||||||
@db_session
|
|
||||||
def index():
|
def index():
|
||||||
stats = {
|
stats = {
|
||||||
'artists': Artist.select().count(),
|
'artists': Artist.select().count(),
|
||||||
|
@ -22,7 +22,6 @@ import os.path
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from flask import current_app, flash, redirect, render_template, request, url_for
|
from flask import current_app, flash, redirect, render_template, request, url_for
|
||||||
from pony.orm import db_session
|
|
||||||
|
|
||||||
from ..db import Folder
|
from ..db import Folder
|
||||||
from ..managers.user import UserManager
|
from ..managers.user import UserManager
|
||||||
@ -33,7 +32,6 @@ from . import admin_only, frontend
|
|||||||
|
|
||||||
@frontend.route('/folder')
|
@frontend.route('/folder')
|
||||||
@admin_only
|
@admin_only
|
||||||
@db_session
|
|
||||||
def folder_index():
|
def folder_index():
|
||||||
return render_template('folders.html', folders = Folder.select(lambda f: f.root))
|
return render_template('folders.html', folders = Folder.select(lambda f: f.root))
|
||||||
|
|
||||||
@ -85,7 +83,6 @@ def del_folder(id):
|
|||||||
@frontend.route('/folder/scan')
|
@frontend.route('/folder/scan')
|
||||||
@frontend.route('/folder/scan/<id>')
|
@frontend.route('/folder/scan/<id>')
|
||||||
@admin_only
|
@admin_only
|
||||||
@db_session
|
|
||||||
def scan_folder(id = None):
|
def scan_folder(id = None):
|
||||||
extensions = current_app.config['BASE']['scanner_extensions']
|
extensions = current_app.config['BASE']['scanner_extensions']
|
||||||
if extensions:
|
if extensions:
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from flask import flash, redirect, render_template, request, url_for
|
from flask import flash, redirect, render_template, request, url_for
|
||||||
from pony.orm import db_session
|
|
||||||
from pony.orm import ObjectNotFound
|
from pony.orm import ObjectNotFound
|
||||||
|
|
||||||
from ..db import Playlist
|
from ..db import Playlist
|
||||||
@ -30,14 +29,12 @@ from ..managers.user import UserManager
|
|||||||
from . import frontend
|
from . import frontend
|
||||||
|
|
||||||
@frontend.route('/playlist')
|
@frontend.route('/playlist')
|
||||||
@db_session
|
|
||||||
def playlist_index():
|
def playlist_index():
|
||||||
return render_template('playlists.html',
|
return render_template('playlists.html',
|
||||||
mine = Playlist.select(lambda p: p.user == request.user),
|
mine = Playlist.select(lambda p: p.user == request.user),
|
||||||
others = Playlist.select(lambda p: p.user != request.user and p.public))
|
others = Playlist.select(lambda p: p.user != request.user and p.public))
|
||||||
|
|
||||||
@frontend.route('/playlist/<uid>')
|
@frontend.route('/playlist/<uid>')
|
||||||
@db_session
|
|
||||||
def playlist_details(uid):
|
def playlist_details(uid):
|
||||||
try:
|
try:
|
||||||
uid = uuid.UUID(uid)
|
uid = uuid.UUID(uid)
|
||||||
@ -54,7 +51,6 @@ def playlist_details(uid):
|
|||||||
return render_template('playlist.html', playlist = playlist)
|
return render_template('playlist.html', playlist = playlist)
|
||||||
|
|
||||||
@frontend.route('/playlist/<uid>', methods = [ 'POST' ])
|
@frontend.route('/playlist/<uid>', methods = [ 'POST' ])
|
||||||
@db_session
|
|
||||||
def playlist_update(uid):
|
def playlist_update(uid):
|
||||||
try:
|
try:
|
||||||
uid = uuid.UUID(uid)
|
uid = uuid.UUID(uid)
|
||||||
@ -80,7 +76,6 @@ def playlist_update(uid):
|
|||||||
return playlist_details(str(uid))
|
return playlist_details(str(uid))
|
||||||
|
|
||||||
@frontend.route('/playlist/del/<uid>')
|
@frontend.route('/playlist/del/<uid>')
|
||||||
@db_session
|
|
||||||
def playlist_delete(uid):
|
def playlist_delete(uid):
|
||||||
try:
|
try:
|
||||||
uid = uuid.UUID(uid)
|
uid = uuid.UUID(uid)
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
from flask import flash, redirect, render_template, request, session, url_for
|
from flask import flash, redirect, render_template, request, session, url_for
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from pony.orm import db_session
|
|
||||||
|
|
||||||
from ..db import User, ClientPrefs
|
from ..db import User, ClientPrefs
|
||||||
from ..lastfm import LastFm
|
from ..lastfm import LastFm
|
||||||
@ -31,7 +30,6 @@ from ..py23 import dict
|
|||||||
from . import admin_only, frontend
|
from . import admin_only, frontend
|
||||||
|
|
||||||
def me_or_uuid(f, arg = 'uid'):
|
def me_or_uuid(f, arg = 'uid'):
|
||||||
@db_session
|
|
||||||
@wraps(f)
|
@wraps(f)
|
||||||
def decorated_func(*args, **kwargs):
|
def decorated_func(*args, **kwargs):
|
||||||
if kwargs:
|
if kwargs:
|
||||||
@ -40,7 +38,7 @@ def me_or_uuid(f, arg = 'uid'):
|
|||||||
uid = args[0]
|
uid = args[0]
|
||||||
|
|
||||||
if uid == 'me':
|
if uid == 'me':
|
||||||
user = User[request.user.id] # Refetch user from previous transaction
|
user = request.user
|
||||||
elif not request.user.admin:
|
elif not request.user.admin:
|
||||||
return redirect(url_for('frontend.index'))
|
return redirect(url_for('frontend.index'))
|
||||||
else:
|
else:
|
||||||
@ -60,7 +58,6 @@ def me_or_uuid(f, arg = 'uid'):
|
|||||||
|
|
||||||
@frontend.route('/user')
|
@frontend.route('/user')
|
||||||
@admin_only
|
@admin_only
|
||||||
@db_session
|
|
||||||
def user_index():
|
def user_index():
|
||||||
return render_template('users.html', users = User.select())
|
return render_template('users.html', users = User.select())
|
||||||
|
|
||||||
@ -116,7 +113,6 @@ def change_username_form(uid):
|
|||||||
|
|
||||||
@frontend.route('/user/<uid>/changeusername', methods = [ 'POST' ])
|
@frontend.route('/user/<uid>/changeusername', methods = [ 'POST' ])
|
||||||
@admin_only
|
@admin_only
|
||||||
@db_session
|
|
||||||
def change_username_post(uid):
|
def change_username_post(uid):
|
||||||
code, user = UserManager.get(uid)
|
code, user = UserManager.get(uid)
|
||||||
if code != UserManager.SUCCESS:
|
if code != UserManager.SUCCESS:
|
||||||
|
@ -13,9 +13,10 @@ import mimetypes
|
|||||||
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from os import makedirs, path
|
from os import makedirs, path
|
||||||
|
from pony.orm import db_session
|
||||||
|
|
||||||
from .config import IniConfig
|
from .config import IniConfig
|
||||||
from .db import init_database, release_database
|
from .db import init_database
|
||||||
|
|
||||||
def create_application(config = None):
|
def create_application(config = None):
|
||||||
global app
|
global app
|
||||||
@ -48,6 +49,7 @@ def create_application(config = None):
|
|||||||
|
|
||||||
# Initialize database
|
# Initialize database
|
||||||
init_database(app.config['BASE']['database_uri'])
|
init_database(app.config['BASE']['database_uri'])
|
||||||
|
app.wsgi_app = db_session(app.wsgi_app)
|
||||||
|
|
||||||
# Insert unknown mimetypes
|
# Insert unknown mimetypes
|
||||||
for k, v in app.config['MIMETYPES'].items():
|
for k, v in app.config['MIMETYPES'].items():
|
||||||
|
Loading…
Reference in New Issue
Block a user