1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-11-09 11:42:16 +00:00

Converting...

This commit is contained in:
spl0k 2014-03-16 18:51:19 +01:00
parent 3a06107fd6
commit f26cfbbb76
8 changed files with 75 additions and 55 deletions

View File

@ -23,7 +23,7 @@ or as a WSGI application (on Apache for instance). But first:
### Prerequisites
* 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`)
* Python Imaging Library (`apt-get install python-imaging`)
* simplejson (`apt-get install python-simplejson`)

8
db.py
View File

@ -261,7 +261,7 @@ class User(object):
class ClientPrefs(object):
__storm_table__ = 'client_prefs'
__storm_primary__ = 'user_id, client_name'
__storm_primary__ = 'user_id', 'client_name'
user_id = UUID()
client_name = Unicode()
@ -269,7 +269,7 @@ class ClientPrefs(object):
bitrate = Int() # nullable
class BaseStarred(object):
__storm_primary__ = 'user_id, starred_id'
__storm_primary__ = 'user_id', 'starred_id'
user_id = UUID()
starred_id = UUID()
@ -298,7 +298,7 @@ class StarredTrack(BaseStarred):
starred = Reference(BaseStarred.starred_id, Track.id)
class BaseRating(object):
__storm_primary__ = 'user_id, rated_id'
__storm_primary__ = 'user_id', 'rated_id'
user_id = UUID()
rated_id = UUID()
@ -361,7 +361,7 @@ class Playlist(object):
class PlaylistTrack(object):
__storm_table__ = 'playlist_track'
__storm_primary__ = 'playlist_id, track_id'
__storm_primary__ = 'playlist_id', 'track_id'
playlist_id = UUID()
track_id = UUID()

View File

@ -18,7 +18,9 @@
# 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/>.
from web import app
from flask import session
from web import app, store
from db import Artist, Album, Track
from managers.user import UserManager
app.add_template_filter(str)
@ -32,7 +34,7 @@ def login_check():
should_login = False
if not session.get('userid'):
should_login = True
elif UserManager.get(session.get('userid'))[0] != UserManager.SUCCESS:
elif UserManager.get(store, session.get('userid'))[0] != UserManager.SUCCESS:
session.clear()
should_login = True
@ -43,11 +45,11 @@ def login_check():
@app.route('/')
def index():
stats = {
'artists': db.Artist.query.count(),
'albums': db.Album.query.count(),
'tracks': db.Track.query.count()
'artists': store.find(Artist).count(),
'albums': store.find(Album).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 .folder import *

View File

@ -18,12 +18,12 @@
# 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/>.
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 uuid
from web import app
from db import session, Folder
from web import app, store
from db import Folder
from scanner import Scanner
from managers.user import UserManager
from managers.folder import FolderManager
@ -33,7 +33,7 @@ def check_admin():
if not request.path.startswith('/folder'):
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'))
@app.route('/folder')
@ -95,7 +95,7 @@ def scan_folder(id = None):
return redirect(url_for('folder_index'))
added, deleted = s.stats()
session.commit()
store.commit()
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]))

View File

@ -20,9 +20,9 @@
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 db import User, ClientPrefs, session as db_sess
from db import User, ClientPrefs
import uuid, csv
import config
from lastfm import LastFm
@ -32,46 +32,46 @@ def check_admin():
if not request.path.startswith('/user'):
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'))
@app.route('/user')
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')
def user_profile():
prefs = ClientPrefs.query.filter(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)
prefs = store.find(ClientPrefs, ClientPrefs.user_id == uuid.UUID(session.get('userid')))
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' ])
def update_clients():
clients_opts = {}
for client in set(map(lambda k: k.rsplit('_', 1)[0],request.form.keys())):
for client in set(map(lambda k: k.rsplit('_', 1)[0], request.form.keys())):
clients_opts[client] = { k.rsplit('_', 1)[1]: v for k, v in filter(lambda (k, v): k.startswith(client), request.form.iteritems()) }
app.logger.debug(clients_opts)
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' ]:
db_sess.delete(prefs)
store.remove(prefs)
continue
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
db_sess.commit()
store.commit()
flash('Clients preferences updated.')
return user_profile()
@app.route('/user/changemail', methods = [ 'GET', 'POST' ])
def change_mail():
user = UserManager.get(session.get('userid'))[1]
user = UserManager.get(store, session.get('userid'))[1]
if request.method == 'POST':
mail = request.form.get('mail')
# No validation, lol.
user.mail = mail
db_sess.commit()
store.commit()
return redirect(url_for('user_profile'))
return render_template('change_mail.html', user = user)
@ -92,14 +92,14 @@ def change_password():
error = True
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:
flash(UserManager.error_str(status))
else:
flash('Password changed')
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' ])
def add_user():
@ -119,12 +119,12 @@ def add_user():
error = True
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:
admin = True
if not error:
status = UserManager.add(name, passwd, mail, admin)
status = UserManager.add(store, name, passwd, mail, admin)
if status == UserManager.SUCCESS:
flash("User '%s' successfully added" % name)
return redirect(url_for('user_index'))
@ -136,7 +136,7 @@ def add_user():
@app.route('/user/del/<uid>')
def del_user(uid):
status = UserManager.delete(uid)
status = UserManager.delete(store, uid)
if status == UserManager.SUCCESS:
flash('Deleted user')
else:
@ -147,7 +147,7 @@ def del_user(uid):
@app.route('/user/export')
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)
for u in User.query.all() ]))
for u in store.find(User) ]))
resp.headers['Content-disposition'] = 'attachment;filename=users.csv'
resp.headers['Content-type'] = 'text/csv'
return resp
@ -168,12 +168,22 @@ def do_user_import():
admin = admin == 'True'
lfmsess = None if lfmsess == 'None' else lfmsess
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:
db_sess.add(u)
db_sess.commit()
store.add(u)
store.commit()
return redirect(url_for('user_index'))
@ -184,16 +194,18 @@ def lastfm_reg():
flash('Missing LastFM auth token')
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)
store.commit()
flash(error if not status else 'Successfully linked LastFM account')
return redirect(url_for('user_profile'))
@app.route('/user/lastfm/unlink')
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()
store.commit()
flash('Unliked LastFM account')
return redirect(url_for('user_profile'))
@ -217,7 +229,7 @@ def login():
error = True
if not error:
status, user = UserManager.try_auth(name, password)
status, user = UserManager.try_auth(store, name, password)
if status == UserManager.SUCCESS:
session['userid'] = str(user.id)
session['username'] = user.name

View File

@ -20,7 +20,6 @@
import requests, hashlib
import config
from db import session
class LastFm:
def __init__(self, user, logger):
@ -40,13 +39,11 @@ class LastFm:
else:
self.__user.lastfm_session = res['session']['key']
self.__user.lastfm_status = True
session.commit()
return True, 'OK'
def unlink_account(self):
self.__user.lastfm_session = None
self.__user.lastfm_status = True
session.commit()
def now_playing(self, track):
if not self.__enabled:
@ -92,7 +89,6 @@ class LastFm:
if 'error' in r.json:
if r.json['error'] in (9, '9'):
self.__user.lastfm_status = False
session.commit()
self.__logger.warn('LastFM error %i: %s' % (r.json['error'], r.json['message']))
return r.json

View File

@ -31,7 +31,7 @@ class UserManager:
WRONG_PASS = 4
@staticmethod
def get(stotre, uid):
def get(store, uid):
if type(uid) in (str, unicode):
try:
uid = uuid.UUID(uid)

28
web.py
View File

@ -19,15 +19,28 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
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
from db import get_store
def teardown(exception):
db.session.remove()
def get_db_store():
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():
global app, db, UserManager
global app
if not config.check():
return None
@ -35,12 +48,11 @@ def create_application():
if not os.path.exists(config.get('base', 'cache_dir')):
os.makedirs(config.get('base', 'cache_dir'))
import db
db.init_db()
app = Flask(__name__)
app.secret_key = '?9huDM\\H'
app.teardown_appcontext(teardown_db)
if config.get('base', 'log_file'):
import logging
from logging.handlers import TimedRotatingFileHandler
@ -48,8 +60,6 @@ def create_application():
handler.setLevel(logging.WARNING)
app.logger.addHandler(handler)
app.teardown_request(teardown)
import frontend
import api