diff --git a/supysonic/api/__init__.py b/supysonic/api/__init__.py
index 0d603f2..1db12b0 100644
--- a/supysonic/api/__init__.py
+++ b/supysonic/api/__init__.py
@@ -18,15 +18,16 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-from flask import request, current_app as app
-from xml.etree import ElementTree
-from xml.dom import minidom
import simplejson
import uuid
import binascii
-from supysonic.web import store
-from supysonic.managers.user import UserManager
+from flask import request, current_app as app
+from xml.dom import minidom
+from xml.etree import ElementTree
+
+from ..web import store
+from ..managers.user import UserManager
@app.before_request
def set_formatter():
diff --git a/supysonic/api/albums_songs.py b/supysonic/api/albums_songs.py
index 0c0dcf5..90f22ab 100644
--- a/supysonic/api/albums_songs.py
+++ b/supysonic/api/albums_songs.py
@@ -18,16 +18,17 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-from flask import request, current_app as app
-from storm.expr import Desc, Avg, Min, Max
-from storm.info import ClassAlias
-from datetime import timedelta
import random
import uuid
-from supysonic.web import store
-from supysonic.db import Folder, Artist, Album, Track, RatingFolder, StarredFolder, StarredArtist, StarredAlbum, StarredTrack, User
-from supysonic.db import now
+from datetime import timedelta
+from flask import request, current_app as app
+from storm.expr import Desc, Avg, Min, Max
+from storm.info import ClassAlias
+
+from ..db import Folder, Artist, Album, Track, RatingFolder, StarredFolder, StarredArtist, StarredAlbum, StarredTrack, User
+from ..db import now
+from ..web import store
@app.route('/rest/getRandomSongs.view', methods = [ 'GET', 'POST' ])
def rand_songs():
diff --git a/supysonic/api/annotation.py b/supysonic/api/annotation.py
index 9d84d82..215c52b 100644
--- a/supysonic/api/annotation.py
+++ b/supysonic/api/annotation.py
@@ -20,14 +20,16 @@
import time
import uuid
+
from flask import request, current_app as app
-from supysonic.web import store
+from ..db import Track, Album, Artist, Folder
+from ..db import StarredTrack, StarredAlbum, StarredArtist, StarredFolder
+from ..db import RatingTrack, RatingFolder
+from ..lastfm import LastFm
+from ..web import store
+
from . import get_entity
-from supysonic.lastfm import LastFm
-from supysonic.db import Track, Album, Artist, Folder
-from supysonic.db import StarredTrack, StarredAlbum, StarredArtist, StarredFolder
-from supysonic.db import RatingTrack, RatingFolder
def try_star(ent, starred_ent, eid):
""" Stars an entity
diff --git a/supysonic/api/browse.py b/supysonic/api/browse.py
index 138ee13..eed9db7 100644
--- a/supysonic/api/browse.py
+++ b/supysonic/api/browse.py
@@ -3,7 +3,7 @@
# This file is part of Supysonic.
#
# Supysonic is a Python implementation of the Subsonic server API.
-# Copyright (C) 2013 Alban 'spl0k' Féron
+# Copyright (C) 2013-2017 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
@@ -18,11 +18,15 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
+import string
+import uuid
+
from flask import request, current_app as app
-from supysonic.web import store
-from supysonic.db import Folder, Artist, Album, Track
+
+from ..db import Folder, Artist, Album, Track
+from ..web import store
+
from . import get_entity
-import uuid, string
@app.route('/rest/getMusicFolders.view', methods = [ 'GET', 'POST' ])
def list_folders():
diff --git a/supysonic/api/chat.py b/supysonic/api/chat.py
index 9384e72..bab6c1d 100644
--- a/supysonic/api/chat.py
+++ b/supysonic/api/chat.py
@@ -3,7 +3,7 @@
# This file is part of Supysonic.
#
# Supysonic is a Python implementation of the Subsonic server API.
-# Copyright (C) 2013 Alban 'spl0k' Féron
+# Copyright (C) 2013-2017 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
@@ -19,8 +19,9 @@
# along with this program. If not, see .
from flask import request, current_app as app
-from supysonic.web import store
-from supysonic.db import ChatMessage
+
+from ..db import ChatMessage
+from ..web import store
@app.route('/rest/getChatMessages.view', methods = [ 'GET', 'POST' ])
def get_chat():
diff --git a/supysonic/api/media.py b/supysonic/api/media.py
index dc05c0b..53beca5 100644
--- a/supysonic/api/media.py
+++ b/supysonic/api/media.py
@@ -28,9 +28,10 @@ from flask import request, send_file, Response, current_app as app
from PIL import Image
from xml.etree import ElementTree
-from supysonic import scanner
-from supysonic.web import store
-from supysonic.db import Track, Album, Artist, Folder, User, ClientPrefs, now
+from .. import scanner
+from ..web import store
+from ..db import Track, Album, Artist, Folder, User, ClientPrefs, now
+
from . import get_entity
def prepare_transcoding_cmdline(base_cmdline, input_file, input_format, output_format, output_bitrate):
diff --git a/supysonic/api/playlists.py b/supysonic/api/playlists.py
index fcb9935..78c7c0d 100644
--- a/supysonic/api/playlists.py
+++ b/supysonic/api/playlists.py
@@ -18,11 +18,14 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
+import uuid
+
from flask import request, current_app as app
from storm.expr import Or
-import uuid
-from supysonic.web import store
-from supysonic.db import Playlist, User, Track
+
+from ..db import Playlist, User, Track
+from ..web import store
+
from . import get_entity
@app.route('/rest/getPlaylists.view', methods = [ 'GET', 'POST' ])
diff --git a/supysonic/api/search.py b/supysonic/api/search.py
index 9eb365e..49d0c1d 100644
--- a/supysonic/api/search.py
+++ b/supysonic/api/search.py
@@ -21,8 +21,9 @@
from datetime import datetime
from flask import request, current_app as app
from storm.info import ClassAlias
-from supysonic.web import store
-from supysonic.db import Folder, Track, Artist, Album
+
+from ..db import Folder, Track, Artist, Album
+from ..web import store
@app.route('/rest/search.view', methods = [ 'GET', 'POST' ])
def old_search():
diff --git a/supysonic/api/user.py b/supysonic/api/user.py
index cfd07b7..00e45d1 100644
--- a/supysonic/api/user.py
+++ b/supysonic/api/user.py
@@ -19,9 +19,11 @@
# along with this program. If not, see .
from flask import request, current_app as app
-from supysonic.web import store
-from supysonic.db import User
-from supysonic.managers.user import UserManager
+
+from ..db import User
+from ..managers.user import UserManager
+from ..web import store
+
from . import decode_password
@app.route('/rest/getUser.view', methods = [ 'GET', 'POST' ])
diff --git a/supysonic/cli.py b/supysonic/cli.py
index 8def64e..116e184 100755
--- a/supysonic/cli.py
+++ b/supysonic/cli.py
@@ -25,10 +25,10 @@ import getpass
import sys
import time
-from supysonic.db import get_store, Folder, User
-from supysonic.managers.folder import FolderManager
-from supysonic.managers.user import UserManager
-from supysonic.scanner import Scanner
+from .db import get_store, Folder, User
+from .managers.folder import FolderManager
+from .managers.user import UserManager
+from .scanner import Scanner
class TimedProgressDisplay:
def __init__(self, name, stdout, interval = 5):
diff --git a/supysonic/frontend/__init__.py b/supysonic/frontend/__init__.py
index 6c7a208..3db8481 100644
--- a/supysonic/frontend/__init__.py
+++ b/supysonic/frontend/__init__.py
@@ -10,11 +10,12 @@
# Distributed under terms of the GNU AGPLv3 license.
from flask import session, request, redirect, url_for, current_app as app
-from supysonic.web import store
-from supysonic.db import Artist, Album, Track
-from supysonic.managers.user import UserManager
from functools import wraps
+from ..web import store
+from ..db import Artist, Album, Track
+from ..managers.user import UserManager
+
@app.before_request
def login_check():
if request.path.startswith('/rest/'):
diff --git a/supysonic/frontend/folder.py b/supysonic/frontend/folder.py
index e375862..f36cc81 100644
--- a/supysonic/frontend/folder.py
+++ b/supysonic/frontend/folder.py
@@ -18,15 +18,16 @@
# 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, current_app as app
import os.path
import uuid
-from supysonic.web import store
-from supysonic.db import Folder
-from supysonic.scanner import Scanner
-from supysonic.managers.user import UserManager
-from supysonic.managers.folder import FolderManager
+from flask import request, flash, render_template, redirect, url_for, current_app as app
+
+from ..db import Folder
+from ..managers.user import UserManager
+from ..managers.folder import FolderManager
+from ..scanner import Scanner
+from ..web import store
from . import admin_only
diff --git a/supysonic/frontend/playlist.py b/supysonic/frontend/playlist.py
index 9f81ddd..00e4692 100644
--- a/supysonic/frontend/playlist.py
+++ b/supysonic/frontend/playlist.py
@@ -18,11 +18,13 @@
# 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, current_app as app
import uuid
-from supysonic.web import store
-from supysonic.db import Playlist
-from supysonic.managers.user import UserManager
+
+from flask import request, flash, render_template, redirect, url_for, current_app as app
+
+from ..web import store
+from ..db import Playlist
+from ..managers.user import UserManager
@app.route('/playlist')
def playlist_index():
diff --git a/supysonic/frontend/user.py b/supysonic/frontend/user.py
index 6ebb0fc..573aa71 100644
--- a/supysonic/frontend/user.py
+++ b/supysonic/frontend/user.py
@@ -21,10 +21,10 @@
from flask import request, session, flash, render_template, redirect, url_for, current_app as app
from functools import wraps
-from supysonic.web import store
-from supysonic.managers.user import UserManager
-from supysonic.db import User, ClientPrefs
-from supysonic.lastfm import LastFm
+from ..db import User, ClientPrefs
+from ..lastfm import LastFm
+from ..managers.user import UserManager
+from ..web import store
from . import admin_only
diff --git a/supysonic/managers/folder.py b/supysonic/managers/folder.py
index d5ca32f..547a711 100644
--- a/supysonic/managers/folder.py
+++ b/supysonic/managers/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, 2014 Alban 'spl0k' Féron
+# Copyright (C) 2013-2017 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
@@ -18,9 +18,11 @@
# 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 supysonic.db import Folder, Artist, Album, Track, StarredFolder, RatingFolder
-from supysonic.scanner import Scanner
+import os.path
+import uuid
+
+from ..db import Folder, Artist, Album, Track, StarredFolder, RatingFolder
+from ..scanner import Scanner
class FolderManager:
SUCCESS = 0
diff --git a/supysonic/managers/user.py b/supysonic/managers/user.py
index 5e43d44..2431c68 100644
--- a/supysonic/managers/user.py
+++ b/supysonic/managers/user.py
@@ -9,14 +9,14 @@
#
# Distributed under terms of the GNU AGPLv3 license.
-import string
-import random
import hashlib
+import random
+import string
import uuid
-from supysonic.db import User, ChatMessage, Playlist
-from supysonic.db import StarredFolder, StarredArtist, StarredAlbum, StarredTrack
-from supysonic.db import RatingFolder, RatingTrack
+from ..db import User, ChatMessage, Playlist
+from ..db import StarredFolder, StarredArtist, StarredAlbum, StarredTrack
+from ..db import RatingFolder, RatingTrack
class UserManager:
SUCCESS = 0
diff --git a/supysonic/scanner.py b/supysonic/scanner.py
index 789bdbc..9edff22 100644
--- a/supysonic/scanner.py
+++ b/supysonic/scanner.py
@@ -3,7 +3,7 @@
# This file is part of Supysonic.
#
# Supysonic is a Python implementation of the Subsonic server API.
-# Copyright (C) 2013, 2014 Alban 'spl0k' Féron
+# Copyright (C) 2013-2017 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
@@ -26,9 +26,9 @@ import time
from storm.expr import ComparableExpr, compile, Like
from storm.exceptions import NotSupportedError
-from supysonic.db import Folder, Artist, Album, Track, User
-from supysonic.db import StarredFolder, StarredArtist, StarredAlbum, StarredTrack
-from supysonic.db import RatingFolder, RatingTrack
+from .db import Folder, Artist, Album, Track, User
+from .db import StarredFolder, StarredArtist, StarredAlbum, StarredTrack
+from .db import RatingFolder, RatingTrack
# Hacking in support for a concatenation expression
class Concat(ComparableExpr):
diff --git a/supysonic/watcher.py b/supysonic/watcher.py
index b24aa35..d50a45b 100644
--- a/supysonic/watcher.py
+++ b/supysonic/watcher.py
@@ -18,16 +18,17 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-import time
import logging
+import time
+
+from logging.handlers import TimedRotatingFileHandler
from signal import signal, SIGTERM, SIGINT
from threading import Thread, Condition, Timer
-from logging.handlers import TimedRotatingFileHandler
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
-from supysonic import db
-from supysonic.scanner import Scanner
+from . import db
+from .scanner import Scanner
OP_SCAN = 1
OP_REMOVE = 2
diff --git a/supysonic/web.py b/supysonic/web.py
index 7890037..266a227 100644
--- a/supysonic/web.py
+++ b/supysonic/web.py
@@ -15,8 +15,8 @@ from flask import Flask, g, current_app
from os import makedirs, path
from werkzeug.local import LocalProxy
-from supysonic.config import IniConfig
-from supysonic.db import get_store
+from .config import IniConfig
+from .db import get_store
# Supysonic database open
def get_db():
@@ -77,9 +77,9 @@ def create_application(config = None):
# Import app sections
with app.app_context():
if app.config['WEBAPP']['mount_webui']:
- from supysonic import frontend
+ from . import frontend
if app.config['WEBAPP']['mount_api']:
- from supysonic import api
+ from . import api
return app
diff --git a/tests/__init__.py b/tests/__init__.py
index 7c7e71c..80a348f 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -11,7 +11,7 @@
import unittest
-import base, managers, api, frontend
+from . import base, managers, api, frontend
def suite():
suite = unittest.TestSuite()