mirror of
https://github.com/spl0k/supysonic.git
synced 2024-12-23 01:16:18 +00:00
Converting...
This commit is contained in:
parent
3a06107fd6
commit
f26cfbbb76
@ -23,7 +23,7 @@ or as a WSGI application (on Apache for instance). But first:
|
|||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
* Python 2.7
|
* Python 2.7
|
||||||
* [Flask](http://flask.pocoo.org/) >= 0.7 (`pip install flask`)
|
* [Flask](http://flask.pocoo.org/) >= 0.9 (`pip install flask`)
|
||||||
* [SQLAlchemy](http://www.sqlalchemy.org/) (`apt-get install python-sqlalchemy`)
|
* [SQLAlchemy](http://www.sqlalchemy.org/) (`apt-get install python-sqlalchemy`)
|
||||||
* Python Imaging Library (`apt-get install python-imaging`)
|
* Python Imaging Library (`apt-get install python-imaging`)
|
||||||
* simplejson (`apt-get install python-simplejson`)
|
* simplejson (`apt-get install python-simplejson`)
|
||||||
|
8
db.py
8
db.py
@ -261,7 +261,7 @@ class User(object):
|
|||||||
|
|
||||||
class ClientPrefs(object):
|
class ClientPrefs(object):
|
||||||
__storm_table__ = 'client_prefs'
|
__storm_table__ = 'client_prefs'
|
||||||
__storm_primary__ = 'user_id, client_name'
|
__storm_primary__ = 'user_id', 'client_name'
|
||||||
|
|
||||||
user_id = UUID()
|
user_id = UUID()
|
||||||
client_name = Unicode()
|
client_name = Unicode()
|
||||||
@ -269,7 +269,7 @@ class ClientPrefs(object):
|
|||||||
bitrate = Int() # nullable
|
bitrate = Int() # nullable
|
||||||
|
|
||||||
class BaseStarred(object):
|
class BaseStarred(object):
|
||||||
__storm_primary__ = 'user_id, starred_id'
|
__storm_primary__ = 'user_id', 'starred_id'
|
||||||
|
|
||||||
user_id = UUID()
|
user_id = UUID()
|
||||||
starred_id = UUID()
|
starred_id = UUID()
|
||||||
@ -298,7 +298,7 @@ class StarredTrack(BaseStarred):
|
|||||||
starred = Reference(BaseStarred.starred_id, Track.id)
|
starred = Reference(BaseStarred.starred_id, Track.id)
|
||||||
|
|
||||||
class BaseRating(object):
|
class BaseRating(object):
|
||||||
__storm_primary__ = 'user_id, rated_id'
|
__storm_primary__ = 'user_id', 'rated_id'
|
||||||
|
|
||||||
user_id = UUID()
|
user_id = UUID()
|
||||||
rated_id = UUID()
|
rated_id = UUID()
|
||||||
@ -361,7 +361,7 @@ class Playlist(object):
|
|||||||
|
|
||||||
class PlaylistTrack(object):
|
class PlaylistTrack(object):
|
||||||
__storm_table__ = 'playlist_track'
|
__storm_table__ = 'playlist_track'
|
||||||
__storm_primary__ = 'playlist_id, track_id'
|
__storm_primary__ = 'playlist_id', 'track_id'
|
||||||
|
|
||||||
playlist_id = UUID()
|
playlist_id = UUID()
|
||||||
track_id = UUID()
|
track_id = UUID()
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from web import app
|
from flask import session
|
||||||
|
from web import app, store
|
||||||
|
from db import Artist, Album, Track
|
||||||
from managers.user import UserManager
|
from managers.user import UserManager
|
||||||
|
|
||||||
app.add_template_filter(str)
|
app.add_template_filter(str)
|
||||||
@ -32,7 +34,7 @@ def login_check():
|
|||||||
should_login = False
|
should_login = False
|
||||||
if not session.get('userid'):
|
if not session.get('userid'):
|
||||||
should_login = True
|
should_login = True
|
||||||
elif UserManager.get(session.get('userid'))[0] != UserManager.SUCCESS:
|
elif UserManager.get(store, session.get('userid'))[0] != UserManager.SUCCESS:
|
||||||
session.clear()
|
session.clear()
|
||||||
should_login = True
|
should_login = True
|
||||||
|
|
||||||
@ -43,11 +45,11 @@ def login_check():
|
|||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
stats = {
|
stats = {
|
||||||
'artists': db.Artist.query.count(),
|
'artists': store.find(Artist).count(),
|
||||||
'albums': db.Album.query.count(),
|
'albums': store.find(Album).count(),
|
||||||
'tracks': db.Track.query.count()
|
'tracks': store.find(Track).count()
|
||||||
}
|
}
|
||||||
return render_template('home.html', stats = stats, admin = UserManager.get(session.get('userid'))[1].admin)
|
return render_template('home.html', stats = stats, admin = UserManager.get(store, session.get('userid'))[1].admin)
|
||||||
|
|
||||||
from .user import *
|
from .user import *
|
||||||
from .folder import *
|
from .folder import *
|
||||||
|
@ -18,12 +18,12 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from flask import request, flash, render_template, redirect, url_for, session as fl_sess
|
from flask import request, flash, render_template, redirect, url_for, session
|
||||||
import os.path
|
import os.path
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from web import app
|
from web import app, store
|
||||||
from db import session, Folder
|
from db import Folder
|
||||||
from scanner import Scanner
|
from scanner import Scanner
|
||||||
from managers.user import UserManager
|
from managers.user import UserManager
|
||||||
from managers.folder import FolderManager
|
from managers.folder import FolderManager
|
||||||
@ -33,7 +33,7 @@ def check_admin():
|
|||||||
if not request.path.startswith('/folder'):
|
if not request.path.startswith('/folder'):
|
||||||
return
|
return
|
||||||
|
|
||||||
if not UserManager.get(fl_sess.get('userid'))[1].admin:
|
if not UserManager.get(store, session.get('userid'))[1].admin:
|
||||||
return redirect(url_for('index'))
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
@app.route('/folder')
|
@app.route('/folder')
|
||||||
@ -95,7 +95,7 @@ def scan_folder(id = None):
|
|||||||
return redirect(url_for('folder_index'))
|
return redirect(url_for('folder_index'))
|
||||||
|
|
||||||
added, deleted = s.stats()
|
added, deleted = s.stats()
|
||||||
session.commit()
|
store.commit()
|
||||||
|
|
||||||
flash('Added: %i artists, %i albums, %i tracks' % (added[0], added[1], added[2]))
|
flash('Added: %i artists, %i albums, %i tracks' % (added[0], added[1], added[2]))
|
||||||
flash('Deleted: %i artists, %i albums, %i tracks' % (deleted[0], deleted[1], deleted[2]))
|
flash('Deleted: %i artists, %i albums, %i tracks' % (deleted[0], deleted[1], deleted[2]))
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
from flask import request, session, flash, render_template, redirect, url_for, make_response
|
from flask import request, session, flash, render_template, redirect, url_for, make_response
|
||||||
|
|
||||||
from web import app
|
from web import app, store
|
||||||
from managers.user import UserManager
|
from managers.user import UserManager
|
||||||
from db import User, ClientPrefs, session as db_sess
|
from db import User, ClientPrefs
|
||||||
import uuid, csv
|
import uuid, csv
|
||||||
import config
|
import config
|
||||||
from lastfm import LastFm
|
from lastfm import LastFm
|
||||||
@ -32,17 +32,17 @@ def check_admin():
|
|||||||
if not request.path.startswith('/user'):
|
if not request.path.startswith('/user'):
|
||||||
return
|
return
|
||||||
|
|
||||||
if request.endpoint in ('user_index', 'add_user', 'del_user', 'export_users', 'import_users', 'do_user_import') and not UserManager.get(session.get('userid'))[1].admin:
|
if request.endpoint in ('user_index', 'add_user', 'del_user', 'export_users', 'import_users', 'do_user_import') and not UserManager.get(store, session.get('userid'))[1].admin:
|
||||||
return redirect(url_for('index'))
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
@app.route('/user')
|
@app.route('/user')
|
||||||
def user_index():
|
def user_index():
|
||||||
return render_template('users.html', users = User.query.all())
|
return render_template('users.html', users = store.find(User))
|
||||||
|
|
||||||
@app.route('/user/me')
|
@app.route('/user/me')
|
||||||
def user_profile():
|
def user_profile():
|
||||||
prefs = ClientPrefs.query.filter(ClientPrefs.user_id == uuid.UUID(session.get('userid')))
|
prefs = store.find(ClientPrefs, ClientPrefs.user_id == uuid.UUID(session.get('userid')))
|
||||||
return render_template('profile.html', user = UserManager.get(session.get('userid'))[1], api_key = config.get('lastfm', 'api_key'), clients = prefs)
|
return render_template('profile.html', user = UserManager.get(store, session.get('userid'))[1], api_key = config.get('lastfm', 'api_key'), clients = prefs)
|
||||||
|
|
||||||
@app.route('/user/me', methods = [ 'POST' ])
|
@app.route('/user/me', methods = [ 'POST' ])
|
||||||
def update_clients():
|
def update_clients():
|
||||||
@ -52,26 +52,26 @@ def update_clients():
|
|||||||
app.logger.debug(clients_opts)
|
app.logger.debug(clients_opts)
|
||||||
|
|
||||||
for client, opts in clients_opts.iteritems():
|
for client, opts in clients_opts.iteritems():
|
||||||
prefs = ClientPrefs.query.get((uuid.UUID(session.get('userid')), client))
|
prefs = store.get(ClientPrefs, (uuid.UUID(session.get('userid')), client))
|
||||||
if 'delete' in opts and opts['delete'] in [ 'on', 'true', 'checked', 'selected', '1' ]:
|
if 'delete' in opts and opts['delete'] in [ 'on', 'true', 'checked', 'selected', '1' ]:
|
||||||
db_sess.delete(prefs)
|
store.remove(prefs)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
prefs.format = opts['format'] if 'format' in opts and opts['format'] else None
|
prefs.format = opts['format'] if 'format' in opts and opts['format'] else None
|
||||||
prefs.bitrate = int(opts['bitrate']) if 'bitrate' in opts and opts['bitrate'] else None
|
prefs.bitrate = int(opts['bitrate']) if 'bitrate' in opts and opts['bitrate'] else None
|
||||||
|
|
||||||
db_sess.commit()
|
store.commit()
|
||||||
flash('Clients preferences updated.')
|
flash('Clients preferences updated.')
|
||||||
return user_profile()
|
return user_profile()
|
||||||
|
|
||||||
@app.route('/user/changemail', methods = [ 'GET', 'POST' ])
|
@app.route('/user/changemail', methods = [ 'GET', 'POST' ])
|
||||||
def change_mail():
|
def change_mail():
|
||||||
user = UserManager.get(session.get('userid'))[1]
|
user = UserManager.get(store, session.get('userid'))[1]
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
mail = request.form.get('mail')
|
mail = request.form.get('mail')
|
||||||
# No validation, lol.
|
# No validation, lol.
|
||||||
user.mail = mail
|
user.mail = mail
|
||||||
db_sess.commit()
|
store.commit()
|
||||||
return redirect(url_for('user_profile'))
|
return redirect(url_for('user_profile'))
|
||||||
|
|
||||||
return render_template('change_mail.html', user = user)
|
return render_template('change_mail.html', user = user)
|
||||||
@ -92,14 +92,14 @@ def change_password():
|
|||||||
error = True
|
error = True
|
||||||
|
|
||||||
if not error:
|
if not error:
|
||||||
status = UserManager.change_password(session.get('userid'), current, new)
|
status = UserManager.change_password(store, session.get('userid'), current, new)
|
||||||
if status != UserManager.SUCCESS:
|
if status != UserManager.SUCCESS:
|
||||||
flash(UserManager.error_str(status))
|
flash(UserManager.error_str(status))
|
||||||
else:
|
else:
|
||||||
flash('Password changed')
|
flash('Password changed')
|
||||||
return redirect(url_for('user_profile'))
|
return redirect(url_for('user_profile'))
|
||||||
|
|
||||||
return render_template('change_pass.html', user = UserManager.get(session.get('userid'))[1].name)
|
return render_template('change_pass.html', user = UserManager.get(store, session.get('userid'))[1].name)
|
||||||
|
|
||||||
@app.route('/user/add', methods = [ 'GET', 'POST' ])
|
@app.route('/user/add', methods = [ 'GET', 'POST' ])
|
||||||
def add_user():
|
def add_user():
|
||||||
@ -119,12 +119,12 @@ def add_user():
|
|||||||
error = True
|
error = True
|
||||||
|
|
||||||
if admin is None:
|
if admin is None:
|
||||||
admin = True if User.query.filter(User.admin == True).count() == 0 else False
|
admin = True if store.find(User, User.admin == True).count() == 0 else False
|
||||||
else:
|
else:
|
||||||
admin = True
|
admin = True
|
||||||
|
|
||||||
if not error:
|
if not error:
|
||||||
status = UserManager.add(name, passwd, mail, admin)
|
status = UserManager.add(store, name, passwd, mail, admin)
|
||||||
if status == UserManager.SUCCESS:
|
if status == UserManager.SUCCESS:
|
||||||
flash("User '%s' successfully added" % name)
|
flash("User '%s' successfully added" % name)
|
||||||
return redirect(url_for('user_index'))
|
return redirect(url_for('user_index'))
|
||||||
@ -136,7 +136,7 @@ def add_user():
|
|||||||
|
|
||||||
@app.route('/user/del/<uid>')
|
@app.route('/user/del/<uid>')
|
||||||
def del_user(uid):
|
def del_user(uid):
|
||||||
status = UserManager.delete(uid)
|
status = UserManager.delete(store, uid)
|
||||||
if status == UserManager.SUCCESS:
|
if status == UserManager.SUCCESS:
|
||||||
flash('Deleted user')
|
flash('Deleted user')
|
||||||
else:
|
else:
|
||||||
@ -147,7 +147,7 @@ def del_user(uid):
|
|||||||
@app.route('/user/export')
|
@app.route('/user/export')
|
||||||
def export_users():
|
def export_users():
|
||||||
resp = make_response('\n'.join([ '%s,%s,%s,%s,"%s",%s,%s,%s' % (u.id, u.name, u.mail, u.password, u.salt, u.admin, u.lastfm_session, u.lastfm_status)
|
resp = make_response('\n'.join([ '%s,%s,%s,%s,"%s",%s,%s,%s' % (u.id, u.name, u.mail, u.password, u.salt, u.admin, u.lastfm_session, u.lastfm_status)
|
||||||
for u in User.query.all() ]))
|
for u in store.find(User) ]))
|
||||||
resp.headers['Content-disposition'] = 'attachment;filename=users.csv'
|
resp.headers['Content-disposition'] = 'attachment;filename=users.csv'
|
||||||
resp.headers['Content-type'] = 'text/csv'
|
resp.headers['Content-type'] = 'text/csv'
|
||||||
return resp
|
return resp
|
||||||
@ -168,12 +168,22 @@ def do_user_import():
|
|||||||
admin = admin == 'True'
|
admin = admin == 'True'
|
||||||
lfmsess = None if lfmsess == 'None' else lfmsess
|
lfmsess = None if lfmsess == 'None' else lfmsess
|
||||||
lfmstatus = lfmstatus == 'True'
|
lfmstatus = lfmstatus == 'True'
|
||||||
users.append(User(id = uuid.UUID(id), name = name, password = password, salt = salt, admin = admin, lastfm_session = lfmsess, lastfm_status = lfmstatus))
|
|
||||||
|
|
||||||
User.query.delete()
|
user = User()
|
||||||
|
user.id = uuid.UUID(id)
|
||||||
|
user.name = name
|
||||||
|
user.password = password
|
||||||
|
user.salt = salt
|
||||||
|
user.admin = admin
|
||||||
|
user.lastfm_session = lfmsess
|
||||||
|
user.lastfm_status = lfmstatus
|
||||||
|
|
||||||
|
users.append(user)
|
||||||
|
|
||||||
|
store.find(User).remove()
|
||||||
for u in users:
|
for u in users:
|
||||||
db_sess.add(u)
|
store.add(u)
|
||||||
db_sess.commit()
|
store.commit()
|
||||||
|
|
||||||
return redirect(url_for('user_index'))
|
return redirect(url_for('user_index'))
|
||||||
|
|
||||||
@ -184,16 +194,18 @@ def lastfm_reg():
|
|||||||
flash('Missing LastFM auth token')
|
flash('Missing LastFM auth token')
|
||||||
return redirect(url_for('user_profile'))
|
return redirect(url_for('user_profile'))
|
||||||
|
|
||||||
lfm = LastFm(UserManager.get(session.get('userid'))[1], app.logger)
|
lfm = LastFm(UserManager.get(store, session.get('userid'))[1], app.logger)
|
||||||
status, error = lfm.link_account(token)
|
status, error = lfm.link_account(token)
|
||||||
|
store.commit()
|
||||||
flash(error if not status else 'Successfully linked LastFM account')
|
flash(error if not status else 'Successfully linked LastFM account')
|
||||||
|
|
||||||
return redirect(url_for('user_profile'))
|
return redirect(url_for('user_profile'))
|
||||||
|
|
||||||
@app.route('/user/lastfm/unlink')
|
@app.route('/user/lastfm/unlink')
|
||||||
def lastfm_unreg():
|
def lastfm_unreg():
|
||||||
lfm = LastFm(UserManager.get(session.get('userid'))[1], app.logger)
|
lfm = LastFm(UserManager.get(store, session.get('userid'))[1], app.logger)
|
||||||
lfm.unlink_account()
|
lfm.unlink_account()
|
||||||
|
store.commit()
|
||||||
flash('Unliked LastFM account')
|
flash('Unliked LastFM account')
|
||||||
return redirect(url_for('user_profile'))
|
return redirect(url_for('user_profile'))
|
||||||
|
|
||||||
@ -217,7 +229,7 @@ def login():
|
|||||||
error = True
|
error = True
|
||||||
|
|
||||||
if not error:
|
if not error:
|
||||||
status, user = UserManager.try_auth(name, password)
|
status, user = UserManager.try_auth(store, name, password)
|
||||||
if status == UserManager.SUCCESS:
|
if status == UserManager.SUCCESS:
|
||||||
session['userid'] = str(user.id)
|
session['userid'] = str(user.id)
|
||||||
session['username'] = user.name
|
session['username'] = user.name
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
import requests, hashlib
|
import requests, hashlib
|
||||||
import config
|
import config
|
||||||
from db import session
|
|
||||||
|
|
||||||
class LastFm:
|
class LastFm:
|
||||||
def __init__(self, user, logger):
|
def __init__(self, user, logger):
|
||||||
@ -40,13 +39,11 @@ class LastFm:
|
|||||||
else:
|
else:
|
||||||
self.__user.lastfm_session = res['session']['key']
|
self.__user.lastfm_session = res['session']['key']
|
||||||
self.__user.lastfm_status = True
|
self.__user.lastfm_status = True
|
||||||
session.commit()
|
|
||||||
return True, 'OK'
|
return True, 'OK'
|
||||||
|
|
||||||
def unlink_account(self):
|
def unlink_account(self):
|
||||||
self.__user.lastfm_session = None
|
self.__user.lastfm_session = None
|
||||||
self.__user.lastfm_status = True
|
self.__user.lastfm_status = True
|
||||||
session.commit()
|
|
||||||
|
|
||||||
def now_playing(self, track):
|
def now_playing(self, track):
|
||||||
if not self.__enabled:
|
if not self.__enabled:
|
||||||
@ -92,7 +89,6 @@ class LastFm:
|
|||||||
if 'error' in r.json:
|
if 'error' in r.json:
|
||||||
if r.json['error'] in (9, '9'):
|
if r.json['error'] in (9, '9'):
|
||||||
self.__user.lastfm_status = False
|
self.__user.lastfm_status = False
|
||||||
session.commit()
|
|
||||||
self.__logger.warn('LastFM error %i: %s' % (r.json['error'], r.json['message']))
|
self.__logger.warn('LastFM error %i: %s' % (r.json['error'], r.json['message']))
|
||||||
|
|
||||||
return r.json
|
return r.json
|
||||||
|
@ -31,7 +31,7 @@ class UserManager:
|
|||||||
WRONG_PASS = 4
|
WRONG_PASS = 4
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get(stotre, uid):
|
def get(store, uid):
|
||||||
if type(uid) in (str, unicode):
|
if type(uid) in (str, unicode):
|
||||||
try:
|
try:
|
||||||
uid = uuid.UUID(uid)
|
uid = uuid.UUID(uid)
|
||||||
|
28
web.py
28
web.py
@ -19,15 +19,28 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
from flask import Flask, request, session, flash, render_template, redirect, url_for
|
from flask import Flask, g
|
||||||
|
from werkzeug.local import LocalProxy
|
||||||
|
|
||||||
import config
|
import config
|
||||||
|
from db import get_store
|
||||||
|
|
||||||
def teardown(exception):
|
def get_db_store():
|
||||||
db.session.remove()
|
store = getattr(g, 'store', None)
|
||||||
|
if store:
|
||||||
|
return store
|
||||||
|
g.store = get_store(config.get('base', 'database_uri'))
|
||||||
|
return g.store
|
||||||
|
|
||||||
|
store = LocalProxy(get_db_store)
|
||||||
|
|
||||||
|
def teardown_db(exception):
|
||||||
|
store = getattr(g, 'store', None)
|
||||||
|
if store:
|
||||||
|
store.close()
|
||||||
|
|
||||||
def create_application():
|
def create_application():
|
||||||
global app, db, UserManager
|
global app
|
||||||
|
|
||||||
if not config.check():
|
if not config.check():
|
||||||
return None
|
return None
|
||||||
@ -35,12 +48,11 @@ def create_application():
|
|||||||
if not os.path.exists(config.get('base', 'cache_dir')):
|
if not os.path.exists(config.get('base', 'cache_dir')):
|
||||||
os.makedirs(config.get('base', 'cache_dir'))
|
os.makedirs(config.get('base', 'cache_dir'))
|
||||||
|
|
||||||
import db
|
|
||||||
db.init_db()
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = '?9huDM\\H'
|
app.secret_key = '?9huDM\\H'
|
||||||
|
|
||||||
|
app.teardown_appcontext(teardown_db)
|
||||||
|
|
||||||
if config.get('base', 'log_file'):
|
if config.get('base', 'log_file'):
|
||||||
import logging
|
import logging
|
||||||
from logging.handlers import TimedRotatingFileHandler
|
from logging.handlers import TimedRotatingFileHandler
|
||||||
@ -48,8 +60,6 @@ def create_application():
|
|||||||
handler.setLevel(logging.WARNING)
|
handler.setLevel(logging.WARNING)
|
||||||
app.logger.addHandler(handler)
|
app.logger.addHandler(handler)
|
||||||
|
|
||||||
app.teardown_request(teardown)
|
|
||||||
|
|
||||||
import frontend
|
import frontend
|
||||||
import api
|
import api
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user