# coding: utf-8 # This file is part of Supysonic. # # Supysonic is a Python implementation of the Subsonic server API. # Copyright (C) 2013, 2014 Alban 'spl0k' FĂ©ron # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . import os.path, uuid from db import Folder, Artist, Album, Track class FolderManager: SUCCESS = 0 INVALID_ID = 1 NAME_EXISTS = 2 INVALID_PATH = 3 PATH_EXISTS = 4 NO_SUCH_FOLDER = 5 @staticmethod def get(store, uid): if isinstance(uid, basestring): try: uid = uuid.UUID(uid) except: return FolderManager.INVALID_ID, None elif type(uid) is uuid.UUID: pass else: return FolderManager.INVALID_ID, None folder = store.get(Folder, uid) if not folder: return FolderManager.NO_SUCH_FOLDER, None return FolderManager.SUCCESS, folder @staticmethod def add(store, name, path): if not store.find(Folder, Folder.name == name, Folder.root == True).is_empty(): return FolderManager.NAME_EXISTS path = os.path.abspath(path) if not os.path.isdir(path): return FolderManager.INVALID_PATH if not store.find(Folder, Folder.path == path).is_empty(): return FolderManager.PATH_EXISTS folder = Folder() folder.root = True folder.name = name folder.path = path store.add(folder) store.commit() return FolderManager.SUCCESS @staticmethod def delete(store, uid): status, folder = FolderManager.get(store, uid) if status != FolderManager.SUCCESS: return status if not folder.root: return FolderManager.NO_SUCH_FOLDER # delete associated tracks and prune empty albums/artists potentially_removed_albums = set() for track in store.find(Track, Track.root_folder_id == folder.id): potentially_removed_albums.add(track.album) store.remove(track) potentially_removed_artists = set() for album in filter(lambda album: album.tracks.count() == 0, potentially_removed_albums): potentially_removed_artists.add(album.artist) store.remove(album) for artist in filter(lambda artist: artist.albums.count() == 0, potentially_removed_artists): store.remove(artist) def cleanup_folder(folder): for f in folder.children: cleanup_folder(f) store.remove(folder) cleanup_folder(folder) store.commit() return FolderManager.SUCCESS @staticmethod def delete_by_name(store, name): folder = store.find(Folder, Folder.name == name, Folder.root == True).one() if not folder: return FolderManager.NO_SUCH_FOLDER return FolderManager.delete(store, folder.id) @staticmethod def scan(store, uid, scanner, progress_callback = None): status, folder = FolderManager.get(store, uid) if status != FolderManager.SUCCESS: return status scanner.scan(folder, progress_callback) scanner.prune(folder) scanner.check_cover_art(folder) return FolderManager.SUCCESS @staticmethod def error_str(err): if err == FolderManager.SUCCESS: return 'No error' elif err == FolderManager.INVALID_ID: return 'Invalid folder id' elif err == FolderManager.NAME_EXISTS: return 'There is already a folder with that name. Please pick another one.' elif err == FolderManager.INVALID_PATH: return "The path doesn't exists or isn't a directory" elif err == FolderManager.PATH_EXISTS: return 'This path is already registered' elif err == FolderManager.NO_SUCH_FOLDER: return 'No such folder' return 'Unknown error'