diff --git a/supysonic/scanner.py b/supysonic/scanner.py index a4c0022..d00b76c 100644 --- a/supysonic/scanner.py +++ b/supysonic/scanner.py @@ -12,6 +12,7 @@ import mimetypes import mutagen import time +from datetime import datetime from pony.orm import db_session from .covers import find_cover_in_folder, CoverFile @@ -114,8 +115,9 @@ class Scanner: raise TypeError('Expecting string, got ' + str(type(path))) tr = Track.get(path = path) + mtime = int(os.path.getmtime(path)) if os.path.exists(path) else 0 # condition for some tests if tr is not None: - if not self.__force and not int(os.path.getmtime(path)) > tr.last_modification: + if not self.__force and not mtime > tr.last_modification: return tag = self.__try_load_tag(path) @@ -144,7 +146,7 @@ class Scanner: trdict['bitrate'] = int(tag.info.bitrate if hasattr(tag.info, 'bitrate') else os.path.getsize(path) * 8 / tag.info.length) // 1000 trdict['content_type'] = mimetypes.guess_type(path, False)[0] or 'application/octet-stream' - trdict['last_modification'] = int(os.path.getmtime(path)) + trdict['last_modification'] = mtime tralbum = self.__find_album(albumartist, album) trartist = self.__find_artist(artist) @@ -154,6 +156,7 @@ class Scanner: trdict['folder'] = self.__find_folder(path) trdict['album'] = tralbum trdict['artist'] = trartist + trdict['created'] = datetime.fromtimestamp(mtime) Track(**trdict) self.__stats.added.tracks += 1 @@ -284,7 +287,8 @@ class Scanner: if folder is not None: break - children.append(dict(root = False, name = os.path.basename(path), path = path)) + created = datetime.fromtimestamp(os.path.getmtime(path)) + children.append(dict(root = False, name = os.path.basename(path), path = path, created = created)) path = os.path.dirname(path) assert folder is not None diff --git a/supysonic/utils.py b/supysonic/utils.py new file mode 100644 index 0000000..01b8f28 --- /dev/null +++ b/supysonic/utils.py @@ -0,0 +1,23 @@ +# coding: utf-8 +# +# This file is part of Supysonic. +# Supysonic is a Python implementation of the Subsonic server API. +# +# Copyright (C) 2019 Alban 'spl0k' FĂ©ron +# +# Distributed under terms of the GNU AGPLv3 license. + +from base64 import b64encode, b64decode +from os import urandom +from pony.orm import db_session, ObjectNotFound + +from supysonic.db import Meta + +@db_session +def get_secret_key(keyname): + try: + key = b64decode(Meta[keyname].value) + except ObjectNotFound: + key = urandom(128) + Meta(key = keyname, value = b64encode(key).decode()) + return key diff --git a/supysonic/web.py b/supysonic/web.py index 9120504..e773c99 100644 --- a/supysonic/web.py +++ b/supysonic/web.py @@ -14,12 +14,13 @@ import logging import mimetypes from flask import Flask -from os import makedirs, path, urandom +from os import makedirs, path from pony.orm import db_session from .config import IniConfig from .cache import Cache from .db import init_database +from .utils import get_secret_key logger = logging.getLogger(__package__) @@ -69,15 +70,7 @@ def create_application(config = None): makedirs(cache_path) # pragma: nocover # Read or create secret key - secret_path = path.join(cache_path, 'secret') - if path.exists(secret_path): - with io.open(secret_path, 'rb') as f: - app.secret_key = f.read() - else: - secret = urandom(128) - with io.open(secret_path, 'wb') as f: - f.write(secret) - app.secret_key = secret + app.secret_key = get_secret_key('cookies_secret') # Import app sections if app.config['WEBAPP']['mount_webui']: