mirror of
https://github.com/spl0k/supysonic.git
synced 2024-11-09 19:52:16 +00:00
Get on my pony
This commit is contained in:
parent
6daedc6919
commit
53fd4865cb
@ -18,15 +18,15 @@
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import binascii
|
||||
import simplejson
|
||||
import uuid
|
||||
import binascii
|
||||
|
||||
from flask import request, current_app as app
|
||||
from pony.orm import db_session, ObjectNotFound
|
||||
from xml.dom import minidom
|
||||
from xml.etree import ElementTree
|
||||
|
||||
from ..web import store
|
||||
from ..managers.user import UserManager
|
||||
|
||||
@app.before_request
|
||||
@ -70,7 +70,7 @@ def authorize():
|
||||
error = request.error_formatter(40, 'Unauthorized'), 401
|
||||
|
||||
if request.authorization:
|
||||
status, user = UserManager.try_auth(store, request.authorization.username, request.authorization.password)
|
||||
status, user = UserManager.try_auth(request.authorization.username, request.authorization.password)
|
||||
if status == UserManager.SUCCESS:
|
||||
request.username = request.authorization.username
|
||||
request.user = user
|
||||
@ -81,7 +81,7 @@ def authorize():
|
||||
return error
|
||||
|
||||
password = decode_password(password)
|
||||
status, user = UserManager.try_auth(store, username, password)
|
||||
status, user = UserManager.try_auth(username, password)
|
||||
if status != UserManager.SUCCESS:
|
||||
return error
|
||||
|
||||
@ -97,13 +97,11 @@ def get_client_prefs():
|
||||
return request.error_formatter(10, 'Missing required parameter')
|
||||
|
||||
client = request.values.get('c')
|
||||
prefs = store.get(ClientPrefs, (request.user.id, client))
|
||||
if not prefs:
|
||||
prefs = ClientPrefs()
|
||||
prefs.user_id = request.user.id
|
||||
prefs.client_name = client
|
||||
store.add(prefs)
|
||||
store.commit()
|
||||
with db_session:
|
||||
try:
|
||||
prefs = ClientPrefs[request.user.id, client]
|
||||
except ObjectNotFound:
|
||||
prefs = ClientPrefs(user = User[request.user.id], client_name = client)
|
||||
|
||||
request.prefs = prefs
|
||||
|
||||
|
@ -23,12 +23,9 @@ import uuid
|
||||
|
||||
from datetime import timedelta
|
||||
from flask import request, current_app as app
|
||||
from storm.expr import Desc, Avg, Min, Max
|
||||
from storm.info import ClassAlias
|
||||
|
||||
from ..db import Folder, Artist, Album, Track, RatingFolder, StarredFolder, StarredArtist, StarredAlbum, StarredTrack, User
|
||||
from ..db import now
|
||||
from ..web import store
|
||||
|
||||
@app.route('/rest/getRandomSongs.view', methods = [ 'GET', 'POST' ])
|
||||
def rand_songs():
|
||||
|
@ -27,7 +27,6 @@ from ..db import Track, Album, Artist, Folder
|
||||
from ..db import StarredTrack, StarredAlbum, StarredArtist, StarredFolder
|
||||
from ..db import RatingTrack, RatingFolder
|
||||
from ..lastfm import LastFm
|
||||
from ..web import store
|
||||
|
||||
from . import get_entity
|
||||
|
||||
|
@ -24,7 +24,6 @@ import uuid
|
||||
from flask import request, current_app as app
|
||||
|
||||
from ..db import Folder, Artist, Album, Track
|
||||
from ..web import store
|
||||
|
||||
from . import get_entity
|
||||
|
||||
|
@ -19,9 +19,9 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from flask import request, current_app as app
|
||||
from pony.orm import db_session
|
||||
|
||||
from ..db import ChatMessage
|
||||
from ..web import store
|
||||
from ..db import ChatMessage, User
|
||||
|
||||
@app.route('/rest/getChatMessages.view', methods = [ 'GET', 'POST' ])
|
||||
def get_chat():
|
||||
@ -31,11 +31,12 @@ def get_chat():
|
||||
except:
|
||||
return request.error_formatter(0, 'Invalid parameter')
|
||||
|
||||
query = store.find(ChatMessage).order_by(ChatMessage.time)
|
||||
if since:
|
||||
query = query.find(ChatMessage.time > since)
|
||||
with db_session:
|
||||
query = ChatMessage.select().order_by(ChatMessage.time)
|
||||
if since:
|
||||
query = query.filter(lambda m: m.time > since)
|
||||
|
||||
return request.formatter({ 'chatMessages': { 'chatMessage': [ msg.responsize() for msg in query ] }})
|
||||
return request.formatter({ 'chatMessages': { 'chatMessage': [ msg.responsize() for msg in query ] }})
|
||||
|
||||
@app.route('/rest/addChatMessage.view', methods = [ 'GET', 'POST' ])
|
||||
def add_chat_message():
|
||||
@ -43,10 +44,8 @@ def add_chat_message():
|
||||
if not msg:
|
||||
return request.error_formatter(10, 'Missing message')
|
||||
|
||||
chat = ChatMessage()
|
||||
chat.user_id = request.user.id
|
||||
chat.message = msg
|
||||
store.add(chat)
|
||||
store.commit()
|
||||
with db_session:
|
||||
ChatMessage(user = User[request.user.id], message = msg)
|
||||
|
||||
return request.formatter({})
|
||||
|
||||
|
@ -29,7 +29,6 @@ from PIL import Image
|
||||
from xml.etree import ElementTree
|
||||
|
||||
from .. import scanner
|
||||
from ..web import store
|
||||
from ..db import Track, Album, Artist, Folder, User, ClientPrefs, now
|
||||
|
||||
from . import get_entity
|
||||
|
@ -21,10 +21,8 @@
|
||||
import uuid
|
||||
|
||||
from flask import request, current_app as app
|
||||
from storm.expr import Or
|
||||
|
||||
from ..db import Playlist, User, Track
|
||||
from ..web import store
|
||||
|
||||
from . import get_entity
|
||||
|
||||
|
@ -20,10 +20,9 @@
|
||||
|
||||
from datetime import datetime
|
||||
from flask import request, current_app as app
|
||||
from storm.info import ClassAlias
|
||||
from pony.orm import db_session, select
|
||||
|
||||
from ..db import Folder, Track, Artist, Album
|
||||
from ..web import store
|
||||
|
||||
@app.route('/rest/search.view', methods = [ 'GET', 'POST' ])
|
||||
def old_search():
|
||||
@ -38,34 +37,36 @@ def old_search():
|
||||
min_date = datetime.fromtimestamp(newer_than)
|
||||
|
||||
if artist:
|
||||
parent = ClassAlias(Folder)
|
||||
query = store.find(parent, Folder.parent_id == parent.id, Track.folder_id == Folder.id, parent.name.contains_string(artist), parent.created > min_date).config(distinct = True)
|
||||
query = select(t.folder.parent for t in Track if artist in t.folder.parent.name and t.folder.parent.created > min_date)
|
||||
elif album:
|
||||
query = store.find(Folder, Track.folder_id == Folder.id, Folder.name.contains_string(album), Folder.created > min_date).config(distinct = True)
|
||||
query = select(t.folder for t in Track if album in t.folder.name and t.folder.created > min_date)
|
||||
elif title:
|
||||
query = store.find(Track, Track.title.contains_string(title), Track.created > min_date)
|
||||
query = Track.select(lambda t: title in t.title and t.created > min_date)
|
||||
elif anyf:
|
||||
folders = store.find(Folder, Folder.name.contains_string(anyf), Folder.created > min_date)
|
||||
tracks = store.find(Track, Track.title.contains_string(anyf), Track.created > min_date)
|
||||
res = list(folders[offset : offset + count])
|
||||
if offset + count > folders.count():
|
||||
toff = max(0, offset - folders.count())
|
||||
tend = offset + count - folders.count()
|
||||
res += list(tracks[toff : tend])
|
||||
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)
|
||||
with db_session:
|
||||
res = folders[offset : offset + count]
|
||||
fcount = folders.count()
|
||||
if offset + count > fcount:
|
||||
toff = max(0, offset - fcount)
|
||||
tend = offset + count - fcount
|
||||
res += tracks[toff : tend]
|
||||
|
||||
return request.formatter({ 'searchResult': {
|
||||
'totalHits': folders.count() + tracks.count(),
|
||||
'offset': offset,
|
||||
'match': [ r.as_subsonic_child(request.user) if isinstance(r, Folder) else r.as_subsonic_child(request.user, request.prefs) for r in res ]
|
||||
}})
|
||||
return request.formatter({ 'searchResult': {
|
||||
'totalHits': folders.count() + tracks.count(),
|
||||
'offset': offset,
|
||||
'match': [ r.as_subsonic_child(request.user) if isinstance(r, Folder) else r.as_subsonic_child(request.user, request.prefs) for r in res ]
|
||||
}})
|
||||
else:
|
||||
return request.error_formatter(10, 'Missing search parameter')
|
||||
|
||||
return request.formatter({ 'searchResult': {
|
||||
'totalHits': query.count(),
|
||||
'offset': offset,
|
||||
'match': [ r.as_subsonic_child(request.user) if isinstance(r, Folder) else r.as_subsonic_child(request.user, request.prefs) for r in query[offset : offset + count] ]
|
||||
}})
|
||||
with db_session:
|
||||
return request.formatter({ 'searchResult': {
|
||||
'totalHits': query.count(),
|
||||
'offset': offset,
|
||||
'match': [ r.as_subsonic_child(request.user) if isinstance(r, Folder) else r.as_subsonic_child(request.user, request.prefs) for r in query[offset : offset + count] ]
|
||||
}})
|
||||
|
||||
@app.route('/rest/search2.view', methods = [ 'GET', 'POST' ])
|
||||
def new_search():
|
||||
@ -85,16 +86,16 @@ def new_search():
|
||||
if not query:
|
||||
return request.error_formatter(10, 'Missing query parameter')
|
||||
|
||||
parent = ClassAlias(Folder)
|
||||
artist_query = store.find(parent, Folder.parent_id == parent.id, Track.folder_id == Folder.id, parent.name.contains_string(query)).config(distinct = True, offset = artist_offset, limit = artist_count)
|
||||
album_query = store.find(Folder, Track.folder_id == Folder.id, Folder.name.contains_string(query)).config(distinct = True, offset = album_offset, limit = album_count)
|
||||
song_query = store.find(Track, Track.title.contains_string(query))[song_offset : song_offset + song_count]
|
||||
with db_session:
|
||||
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)
|
||||
songs = Track.select(lambda t: query in t.title).limit(song_count, song_offset)
|
||||
|
||||
return request.formatter({ 'searchResult2': {
|
||||
'artist': [ { 'id': str(a.id), 'name': a.name } for a in artist_query ],
|
||||
'album': [ f.as_subsonic_child(request.user) for f in album_query ],
|
||||
'song': [ t.as_subsonic_child(request.user, request.prefs) for t in song_query ]
|
||||
}})
|
||||
return request.formatter({ 'searchResult2': {
|
||||
'artist': [ { 'id': str(a.id), 'name': a.name } for a in artists ],
|
||||
'album': [ f.as_subsonic_child(request.user) for f in albums ],
|
||||
'song': [ t.as_subsonic_child(request.user, request.prefs) for t in songs ]
|
||||
}})
|
||||
|
||||
@app.route('/rest/search3.view', methods = [ 'GET', 'POST' ])
|
||||
def search_id3():
|
||||
@ -114,13 +115,14 @@ def search_id3():
|
||||
if not query:
|
||||
return request.error_formatter(10, 'Missing query parameter')
|
||||
|
||||
artist_query = store.find(Artist, Artist.name.contains_string(query))[artist_offset : artist_offset + artist_count]
|
||||
album_query = store.find(Album, Album.name.contains_string(query))[album_offset : album_offset + album_count]
|
||||
song_query = store.find(Track, Track.title.contains_string(query))[song_offset : song_offset + song_count]
|
||||
with db_session:
|
||||
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)
|
||||
songs = Track.select(lambda t: query in t.title).limit(song_count, song_offset)
|
||||
|
||||
return request.formatter({ 'searchResult3': {
|
||||
'artist': [ a.as_subsonic_artist(request.user) for a in artist_query ],
|
||||
'album': [ a.as_subsonic_album(request.user) for a in album_query ],
|
||||
'song': [ t.as_subsonic_child(request.user, request.prefs) for t in song_query ]
|
||||
}})
|
||||
return request.formatter({ 'searchResult3': {
|
||||
'artist': [ a.as_subsonic_artist(request.user) for a in artists ],
|
||||
'album': [ a.as_subsonic_album(request.user) for a in albums ],
|
||||
'song': [ t.as_subsonic_child(request.user, request.prefs) for t in songs ]
|
||||
}})
|
||||
|
||||
|
@ -19,10 +19,10 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from flask import request, current_app as app
|
||||
from pony.orm import db_session
|
||||
|
||||
from ..db import User
|
||||
from ..managers.user import UserManager
|
||||
from ..web import store
|
||||
|
||||
from . import decode_password
|
||||
|
||||
@ -35,7 +35,8 @@ def user_info():
|
||||
if username != request.username and not request.user.admin:
|
||||
return request.error_formatter(50, 'Admin restricted')
|
||||
|
||||
user = store.find(User, User.name == username).one()
|
||||
with db_session:
|
||||
user = User.get(name = username)
|
||||
if user is None:
|
||||
return request.error_formatter(70, 'Unknown user')
|
||||
|
||||
@ -46,7 +47,8 @@ def users_info():
|
||||
if not request.user.admin:
|
||||
return request.error_formatter(50, 'Admin restricted')
|
||||
|
||||
return request.formatter({ 'users': { 'user': [ u.as_subsonic_user() for u in store.find(User) ] } })
|
||||
with db_session:
|
||||
return request.formatter({ 'users': { 'user': [ u.as_subsonic_user() for u in User.select() ] } })
|
||||
|
||||
@app.route('/rest/createUser.view', methods = [ 'GET', 'POST' ])
|
||||
def user_add():
|
||||
@ -59,7 +61,7 @@ def user_add():
|
||||
admin = True if admin in (True, 'True', 'true', 1, '1') else False
|
||||
|
||||
password = decode_password(password)
|
||||
status = UserManager.add(store, username, password, email, admin)
|
||||
status = UserManager.add(username, password, email, admin)
|
||||
if status == UserManager.NAME_EXISTS:
|
||||
return request.error_formatter(0, 'There is already a user with that username')
|
||||
|
||||
@ -74,11 +76,12 @@ def user_del():
|
||||
if not username:
|
||||
return request.error_formatter(10, 'Missing parameter')
|
||||
|
||||
user = store.find(User, User.name == username).one()
|
||||
if not user:
|
||||
with db_session:
|
||||
user = User.get(name = username)
|
||||
if user is None:
|
||||
return request.error_formatter(70, 'Unknown user')
|
||||
|
||||
status = UserManager.delete(store, user.id)
|
||||
status = UserManager.delete(user.id)
|
||||
if status != UserManager.SUCCESS:
|
||||
return request.error_formatter(0, UserManager.error_str(status))
|
||||
|
||||
@ -94,7 +97,7 @@ def user_changepass():
|
||||
return request.error_formatter(50, 'Admin restricted')
|
||||
|
||||
password = decode_password(password)
|
||||
status = UserManager.change_password2(store, username, password)
|
||||
status = UserManager.change_password2(username, password)
|
||||
if status != UserManager.SUCCESS:
|
||||
code = 0
|
||||
if status == UserManager.NO_SUCH_USER:
|
||||
|
@ -130,8 +130,8 @@ class Album(db.Entity):
|
||||
'created': min(self.tracks.created).isoformat()
|
||||
}
|
||||
|
||||
track_with_cover = self.tracks.select(lambda t: t.folder.has_cover_art)[:1][0]
|
||||
if track_with_cover:
|
||||
track_with_cover = self.tracks.select(lambda t: t.folder.has_cover_art).first()
|
||||
if track_with_cover is not None:
|
||||
info['coverArt'] = str(track_with_cover.folder.id)
|
||||
|
||||
try:
|
||||
|
@ -11,7 +11,10 @@
|
||||
|
||||
import unittest
|
||||
|
||||
from . import base, managers, api, frontend
|
||||
from . import base
|
||||
from . import managers
|
||||
from . import api
|
||||
from . import frontend
|
||||
|
||||
def suite():
|
||||
suite = unittest.TestSuite()
|
||||
|
@ -12,6 +12,8 @@
|
||||
import time
|
||||
import unittest
|
||||
|
||||
from pony.orm import db_session, commit
|
||||
|
||||
from supysonic.db import Folder, Artist, Album, Track
|
||||
|
||||
from .apitestbase import ApiTestBase
|
||||
@ -20,53 +22,44 @@ class SearchTestCase(ApiTestBase):
|
||||
def setUp(self):
|
||||
super(SearchTestCase, self).setUp()
|
||||
|
||||
root = Folder()
|
||||
root.root = True
|
||||
root.name = 'Root folder'
|
||||
root.path = 'tests/assets'
|
||||
self.store.add(root)
|
||||
with db_session:
|
||||
root = Folder(root = True, name = 'Root folder', path = 'tests/assets')
|
||||
|
||||
for letter in 'ABC':
|
||||
folder = Folder()
|
||||
folder.name = letter + 'rtist'
|
||||
folder.path = 'tests/assets/{}rtist'.format(letter)
|
||||
folder.parent = root
|
||||
for letter in 'ABC':
|
||||
folder = Folder(name = letter + 'rtist', path = 'tests/assets/{}rtist'.format(letter), parent = root)
|
||||
artist = Artist(name = letter + 'rtist')
|
||||
|
||||
artist = Artist()
|
||||
artist.name = letter + 'rtist'
|
||||
for lether in 'AB':
|
||||
afolder = Folder(
|
||||
name = letter + lether + 'lbum',
|
||||
path = 'tests/assets/{0}rtist/{0}{1}lbum'.format(letter, lether),
|
||||
parent = folder
|
||||
)
|
||||
|
||||
for lether in 'AB':
|
||||
afolder = Folder()
|
||||
afolder.name = letter + lether + 'lbum'
|
||||
afolder.path = 'tests/assets/{0}rtist/{0}{1}lbum'.format(letter, lether)
|
||||
afolder.parent = folder
|
||||
album = Album(name = letter + lether + 'lbum', artist = artist)
|
||||
|
||||
album = Album()
|
||||
album.name = letter + lether + 'lbum'
|
||||
album.artist = artist
|
||||
for num, song in enumerate([ 'One', 'Two', 'Three' ]):
|
||||
track = Track(
|
||||
disc = 1,
|
||||
number = num,
|
||||
title = song,
|
||||
duration = 2,
|
||||
album = album,
|
||||
artist = artist,
|
||||
bitrate = 320,
|
||||
path = 'tests/assets/{0}rtist/{0}{1}lbum/{2}'.format(letter, lether, song),
|
||||
content_type = 'audio/mpeg',
|
||||
last_modification = 0,
|
||||
root_folder = root,
|
||||
folder = afolder
|
||||
)
|
||||
|
||||
for num, song in enumerate([ 'One', 'Two', 'Three' ]):
|
||||
track = Track()
|
||||
track.disc = 1
|
||||
track.number = num
|
||||
track.title = song
|
||||
track.duration = 2
|
||||
track.album = album
|
||||
track.artist = artist
|
||||
track.bitrate = 320
|
||||
track.path = 'tests/assets/{0}rtist/{0}{1}lbum/{2}'.format(letter, lether, song)
|
||||
track.content_type = 'audio/mpeg'
|
||||
track.last_modification = 0
|
||||
track.root_folder = root
|
||||
track.folder = afolder
|
||||
self.store.add(track)
|
||||
commit()
|
||||
|
||||
self.store.commit()
|
||||
|
||||
self.assertEqual(self.store.find(Folder).count(), 10)
|
||||
self.assertEqual(self.store.find(Artist).count(), 3)
|
||||
self.assertEqual(self.store.find(Album).count(), 6)
|
||||
self.assertEqual(self.store.find(Track).count(), 18)
|
||||
self.assertEqual(Folder.select().count(), 10)
|
||||
self.assertEqual(Artist.select().count(), 3)
|
||||
self.assertEqual(Album.select().count(), 6)
|
||||
self.assertEqual(Track.select().count(), 18)
|
||||
|
||||
def __track_as_pseudo_unique_str(self, elem):
|
||||
return elem.get('artist') + elem.get('album') + elem.get('title')
|
||||
|
@ -68,8 +68,8 @@ class TestBase(unittest.TestCase):
|
||||
release_database()
|
||||
|
||||
app = create_application(config)
|
||||
#self.__ctx = app.app_context()
|
||||
#self.__ctx.push()
|
||||
self.__ctx = app.app_context()
|
||||
self.__ctx.push()
|
||||
|
||||
self.client = app.test_client()
|
||||
|
||||
@ -83,7 +83,7 @@ class TestBase(unittest.TestCase):
|
||||
return False
|
||||
|
||||
def tearDown(self):
|
||||
#self.__ctx.pop()
|
||||
self.__ctx.pop()
|
||||
release_database()
|
||||
shutil.rmtree(self.__dir)
|
||||
os.remove(self.__dbfile)
|
||||
|
Loading…
Reference in New Issue
Block a user