1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-11-12 21:22:17 +00:00

Wrapping all request handling in a database transaction

This commit is contained in:
spl0k 2018-02-14 22:48:44 +01:00
parent e3ccf0809f
commit 43b197a95e
14 changed files with 112 additions and 168 deletions

View File

@ -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

View File

@ -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) ],

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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",

View File

@ -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:

View File

@ -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 ])
))) )))

View File

@ -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')

View File

@ -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(),

View File

@ -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:

View File

@ -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)

View File

@ -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:

View File

@ -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():