From f26cfbbb767623f44df0a4bc7d207fc433589789 Mon Sep 17 00:00:00 2001 From: spl0k Date: Sun, 16 Mar 2014 18:51:19 +0100 Subject: [PATCH] Converting... --- README.md | 2 +- db.py | 8 +++--- frontend/__init__.py | 14 +++++----- frontend/folder.py | 10 +++---- frontend/user.py | 62 ++++++++++++++++++++++++++------------------ lastfm.py | 4 --- managers/user.py | 2 +- web.py | 28 +++++++++++++------- 8 files changed, 75 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index c3b7233..4bb6fed 100644 --- a/README.md +++ b/README.md @@ -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`) diff --git a/db.py b/db.py index 6874f4e..b2914ca 100644 --- a/db.py +++ b/db.py @@ -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() diff --git a/frontend/__init__.py b/frontend/__init__.py index ea1a21f..cd6aef0 100644 --- a/frontend/__init__.py +++ b/frontend/__init__.py @@ -18,7 +18,9 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -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 * diff --git a/frontend/folder.py b/frontend/folder.py index da13830..bc53c0a 100644 --- a/frontend/folder.py +++ b/frontend/folder.py @@ -18,12 +18,12 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -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])) diff --git a/frontend/user.py b/frontend/user.py index ed8c937..ee5fa08 100644 --- a/frontend/user.py +++ b/frontend/user.py @@ -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/') 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 diff --git a/lastfm.py b/lastfm.py index 5c09743..c49d67d 100644 --- a/lastfm.py +++ b/lastfm.py @@ -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 diff --git a/managers/user.py b/managers/user.py index 610035b..f1ac41b 100644 --- a/managers/user.py +++ b/managers/user.py @@ -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) diff --git a/web.py b/web.py index 1ce3beb..1be9527 100644 --- a/web.py +++ b/web.py @@ -19,15 +19,28 @@ # along with this program. If not, see . 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