From e210f25bb316743c5eaf7f6bdf5d6c7a834c3e29 Mon Sep 17 00:00:00 2001 From: spl0k Date: Mon, 22 Apr 2019 17:48:44 +0200 Subject: [PATCH] Web UI now scans in background --- supysonic/frontend/__init__.py | 18 +++++++++-- supysonic/frontend/folder.py | 55 +++++++++++++------------------- supysonic/templates/folders.html | 10 +++--- tests/frontend/test_folder.py | 9 ++---- 4 files changed, 47 insertions(+), 45 deletions(-) diff --git a/supysonic/frontend/__init__.py b/supysonic/frontend/__init__.py index f17d49e..30c9d0e 100644 --- a/supysonic/frontend/__init__.py +++ b/supysonic/frontend/__init__.py @@ -3,16 +3,18 @@ # This file is part of Supysonic. # Supysonic is a Python implementation of the Subsonic server API. # -# Copyright (C) 2013-2018 Alban 'spl0k' Féron +# Copyright (C) 2013-2019 Alban 'spl0k' Féron # 2017 Óscar García Amor # # Distributed under terms of the GNU AGPLv3 license. -from flask import redirect, request, session, url_for +from flask import current_app, redirect, request, session, url_for from flask import Blueprint from functools import wraps from pony.orm import ObjectNotFound +from ..daemon.client import DaemonClient +from ..daemon.exceptions import DaemonUnavailableError from ..db import Artist, Album, Track from ..managers.user import UserManager @@ -34,6 +36,18 @@ def login_check(): flash('Please login') return redirect(url_for('frontend.login', returnUrl = request.script_root + request.url[len(request.url_root)-1:])) +@frontend.before_request +def scan_status(): + if not request.user or not request.user.admin: + return + + try: + scanned = DaemonClient(current_app.config['DAEMON']['socket']).get_scanning_progress() + if scanned is not None: + flash('Scanning in progress, {} files scanned.'.format(scanned)) + except DaemonUnavailableError: + pass + @frontend.route('/') def index(): stats = { diff --git a/supysonic/frontend/folder.py b/supysonic/frontend/folder.py index 51803d2..a8be3bb 100644 --- a/supysonic/frontend/folder.py +++ b/supysonic/frontend/folder.py @@ -3,7 +3,7 @@ # This file is part of Supysonic. # Supysonic is a Python implementation of the Subsonic server API. # -# Copyright (C) 2013-2018 Alban 'spl0k' Féron +# Copyright (C) 2013-2019 Alban 'spl0k' Féron # # Distributed under terms of the GNU AGPLv3 license. @@ -13,6 +13,8 @@ import uuid from flask import current_app, flash, redirect, render_template, request, url_for from pony.orm import ObjectNotFound +from ..daemon.client import DaemonClient +from ..daemon.exceptions import DaemonUnavailableError from ..db import Folder from ..managers.folder import FolderManager from ..scanner import Scanner @@ -22,7 +24,13 @@ from . import admin_only, frontend @frontend.route('/folder') @admin_only def folder_index(): - return render_template('folders.html', folders = Folder.select(lambda f: f.root)) + try: + DaemonClient(current_app.config['DAEMON']['socket']).get_scanning_progress() + allow_scan = True + except DaemonUnavailableError: + allow_scan = False + flash("The daemon is unavailable, can't scan from the web interface, use the CLI to do so.", 'warning') + return render_template('folders.html', folders = Folder.select(lambda f: f.root), allow_scan = allow_scan) @frontend.route('/folder/add') @admin_only @@ -69,35 +77,18 @@ def del_folder(id): @frontend.route('/folder/scan/') @admin_only def scan_folder(id = None): - extensions = current_app.config['BASE']['scanner_extensions'] - if extensions: - extensions = extensions.split(' ') + try: + if id is not None: + folders = [ FolderManager.get(id).name ] + else: + folders = [] + DaemonClient(current_app.config['DAEMON']['socket']).scan(folders) + flash('Scanning started') + except ValueError as e: + flash(str(e), 'error') + except ObjectNotFound: + flash('No such folder', 'error') + except DaemonUnavailableError: + flash("Can't start scan", 'error') - scanner = Scanner(extensions = extensions) - - if id is None: - for folder in Folder.select(lambda f: f.root): - scanner.scan(folder) - else: - try: - folder = FolderManager.get(id) - except ValueError as e: - flash(str(e), 'error') - return redirect(url_for('frontend.folder_index')) - except ObjectNotFound: - flash('No such folder', 'error') - return redirect(url_for('frontend.folder_index')) - - scanner.scan(folder) - - scanner.finish() - stats = scanner.stats() - - flash('Added: {0.artists} artists, {0.albums} albums, {0.tracks} tracks'.format(stats.added)) - flash('Deleted: {0.artists} artists, {0.albums} albums, {0.tracks} tracks'.format(stats.deleted)) - if stats.errors: - flash('Errors in:') - for err in stats.errors: - flash('- ' + err) return redirect(url_for('frontend.folder_index')) - diff --git a/supysonic/templates/folders.html b/supysonic/templates/folders.html index 799f4f9..b226f97 100644 --- a/supysonic/templates/folders.html +++ b/supysonic/templates/folders.html @@ -2,7 +2,7 @@ This file is part of Supysonic. Supysonic is a Python implementation of the Subsonic server API. - Copyright (C) 2013-2018 Alban 'spl0k' Féron + Copyright (C) 2013-2019 Alban 'spl0k' Féron 2017 Óscar García Amor Distributed under terms of the GNU AGPLv3 license. @@ -18,7 +18,7 @@ - + {% if allow_scan %}{% endif %} {% for folder in folders %} @@ -26,15 +26,15 @@ - + {%if allow_scan %}{% endif %} {% endfor %}
NamePath
NamePath
{{ folder.name }}{{ folder.path }} - +