1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-22 17:06:17 +00:00

Don't store the mimetype in database

That's useless, it can be deduced from the path
Fixes #150
This commit is contained in:
spl0k 2019-05-18 14:53:26 +02:00
parent deaf17a005
commit 10df0ada07
19 changed files with 56 additions and 28 deletions

View File

@ -3,7 +3,7 @@
# This file is part of Supysonic. # This file is part of Supysonic.
# Supysonic is a Python implementation of the Subsonic server API. # 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
# 2018-2019 Carey 'pR0Ps' Metcalfe # 2018-2019 Carey 'pR0Ps' Metcalfe
# #
# Distributed under terms of the GNU AGPLv3 license. # Distributed under terms of the GNU AGPLv3 license.
@ -65,7 +65,7 @@ def stream_media():
src_suffix = res.suffix() src_suffix = res.suffix()
dst_suffix = res.suffix() dst_suffix = res.suffix()
dst_bitrate = res.bitrate dst_bitrate = res.bitrate
dst_mimetype = res.content_type dst_mimetype = res.mimetype
prefs = request.client prefs = request.client
if prefs.format: if prefs.format:
@ -153,7 +153,7 @@ def download_media():
try: # Track -> direct download try: # Track -> direct download
rv = Track[uid] rv = Track[uid]
return send_file(rv.path, mimetype = rv.content_type, conditional=True) return send_file(rv.path, mimetype = rv.mimetype, conditional=True)
except ObjectNotFound: except ObjectNotFound:
pass pass

View File

@ -3,7 +3,7 @@
# This file is part of Supysonic. # This file is part of Supysonic.
# Supysonic is a Python implementation of the Subsonic server API. # 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. # Distributed under terms of the GNU AGPLv3 license.
@ -31,7 +31,7 @@ try:
except ImportError: except ImportError:
from urlparse import urlparse, parse_qsl from urlparse import urlparse, parse_qsl
SCHEMA_VERSION = '20190324' SCHEMA_VERSION = '20190518'
def now(): def now():
return datetime.now().replace(microsecond = 0) return datetime.now().replace(microsecond = 0)
@ -229,7 +229,6 @@ class Track(PathMixin, db.Entity):
path = Required(str, 4096, autostrip = False) # unique path = Required(str, 4096, autostrip = False) # unique
_path_hash = Required(buffer, column = 'path_hash') _path_hash = Required(buffer, column = 'path_hash')
content_type = Required(str)
created = Required(datetime, precision = 0, default = now) created = Required(datetime, precision = 0, default = now)
last_modification = Required(int) last_modification = Required(int)
@ -254,7 +253,7 @@ class Track(PathMixin, db.Entity):
artist = self.artist.name, artist = self.artist.name,
track = self.number, track = self.number,
size = os.path.getsize(self.path) if os.path.isfile(self.path) else -1, size = os.path.getsize(self.path) if os.path.isfile(self.path) else -1,
contentType = self.content_type, contentType = self.mimetype,
suffix = self.suffix(), suffix = self.suffix(),
duration = self.duration, duration = self.duration,
bitRate = self.bitrate, bitRate = self.bitrate,
@ -296,6 +295,10 @@ class Track(PathMixin, db.Entity):
return info return info
@property
def mimetype(self):
return mimetypes.guess_type(self.path, False)[0] or 'application/octet-stream'
def duration_str(self): def duration_str(self):
ret = '%02i:%02i' % ((self.duration % 3600) / 60, self.duration % 60) ret = '%02i:%02i' % ((self.duration % 3600) / 60, self.duration % 60)
if self.duration >= 3600: if self.duration >= 3600:

View File

@ -3,12 +3,11 @@
# This file is part of Supysonic. # This file is part of Supysonic.
# Supysonic is a Python implementation of the Subsonic server API. # 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. # Distributed under terms of the GNU AGPLv3 license.
import os, os.path import os, os.path
import mimetypes
import mutagen import mutagen
import time import time
@ -145,7 +144,6 @@ class Scanner:
trdict['has_art'] = bool(Track._extract_cover_art(path)) trdict['has_art'] = bool(Track._extract_cover_art(path))
trdict['bitrate'] = int(tag.info.bitrate if hasattr(tag.info, 'bitrate') else os.path.getsize(path) * 8 / tag.info.length) // 1000 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'] = mtime trdict['last_modification'] = mtime
tralbum = self.__find_album(albumartist, album) tralbum = self.__find_album(albumartist, album)

View File

@ -0,0 +1 @@
ALTER TABLE track DROP COLUMN content_type;

View File

@ -0,0 +1 @@
ALTER TABLE track DROP COLUMN content_type;

View File

@ -0,0 +1,43 @@
DROP INDEX index_track_album_id_fk;
DROP INDEX index_track_artist_id_fk;
DROP INDEX index_track_folder_id_fk;
DROP INDEX index_track_root_folder_id_fk;
DROP INDEX index_track_path;
ALTER TABLE track RENAME TO track_old;
CREATE TABLE IF NOT EXISTS track (
id CHAR(36) PRIMARY KEY,
disc INTEGER NOT NULL,
number INTEGER NOT NULL,
title VARCHAR(256) NOT NULL COLLATE NOCASE,
year INTEGER,
genre VARCHAR(256),
duration INTEGER NOT NULL,
has_art BOOLEAN NOT NULL DEFAULT false,
album_id CHAR(36) NOT NULL REFERENCES album,
artist_id CHAR(36) NOT NULL REFERENCES artist,
bitrate INTEGER NOT NULL,
path VARCHAR(4096) NOT NULL,
path_hash BLOB NOT NULL,
created DATETIME NOT NULL,
last_modification INTEGER NOT NULL,
play_count INTEGER NOT NULL,
last_play DATETIME,
root_folder_id CHAR(36) NOT NULL REFERENCES folder,
folder_id CHAR(36) NOT NULL REFERENCES folder
);
CREATE INDEX IF NOT EXISTS index_track_album_id_fk ON track(album_id);
CREATE INDEX IF NOT EXISTS index_track_artist_id_fk ON track(artist_id);
CREATE INDEX IF NOT EXISTS index_track_folder_id_fk ON track(folder_id);
CREATE INDEX IF NOT EXISTS index_track_root_folder_id_fk ON track(root_folder_id);
CREATE UNIQUE INDEX IF NOT EXISTS index_track_path ON track(path_hash);
INSERT INTO track(id, disc, number, title, year, genre, duration, has_art, album_id, artist_id, bitrate, path, path_hash, created, last_modification, play_count, last_play, root_folder_id, folder_id)
SELECT id, disc, number, title, year, genre, duration, has_art, album_id, artist_id, bitrate, path, path_hash, created, last_modification, play_count, last_play, root_folder_id, folder_id
FROM track_old;
DROP TABLE track_old;
COMMIT;
VACUUM;

View File

@ -37,7 +37,6 @@ CREATE TABLE IF NOT EXISTS track (
bitrate INTEGER NOT NULL, bitrate INTEGER NOT NULL,
path VARCHAR(4096) NOT NULL, path VARCHAR(4096) NOT NULL,
path_hash BINARY(20) UNIQUE NOT NULL, path_hash BINARY(20) UNIQUE NOT NULL,
content_type VARCHAR(32) NOT NULL,
created DATETIME NOT NULL, created DATETIME NOT NULL,
last_modification INTEGER NOT NULL, last_modification INTEGER NOT NULL,
play_count INTEGER NOT NULL, play_count INTEGER NOT NULL,

View File

@ -37,7 +37,6 @@ CREATE TABLE IF NOT EXISTS track (
bitrate INTEGER NOT NULL, bitrate INTEGER NOT NULL,
path VARCHAR(4096) NOT NULL, path VARCHAR(4096) NOT NULL,
path_hash BYTEA UNIQUE NOT NULL, path_hash BYTEA UNIQUE NOT NULL,
content_type VARCHAR(32) NOT NULL,
created TIMESTAMP NOT NULL, created TIMESTAMP NOT NULL,
last_modification INTEGER NOT NULL, last_modification INTEGER NOT NULL,
play_count INTEGER NOT NULL, play_count INTEGER NOT NULL,

View File

@ -38,7 +38,6 @@ CREATE TABLE IF NOT EXISTS track (
bitrate INTEGER NOT NULL, bitrate INTEGER NOT NULL,
path VARCHAR(4096) NOT NULL, path VARCHAR(4096) NOT NULL,
path_hash BLOB NOT NULL, path_hash BLOB NOT NULL,
content_type VARCHAR(32) NOT NULL,
created DATETIME NOT NULL, created DATETIME NOT NULL,
last_modification INTEGER NOT NULL, last_modification INTEGER NOT NULL,
play_count INTEGER NOT NULL, play_count INTEGER NOT NULL,

View File

@ -39,7 +39,6 @@ class AlbumSongsTestCase(ApiTestBase):
root_folder = folder, root_folder = folder,
duration = 2, duration = 2,
bitrate = 320, bitrate = 320,
content_type = 'audio/mpeg',
last_modification = 0 last_modification = 0
) )

View File

@ -37,7 +37,6 @@ class AnnotationTestCase(ApiTestBase):
root_folder = root, root_folder = root,
duration = 2, duration = 2,
bitrate = 320, bitrate = 320,
content_type = 'audio/mpeg',
last_modification = 0 last_modification = 0
) )

View File

@ -54,7 +54,6 @@ class BrowseTestCase(ApiTestBase):
artist = artist, artist = artist,
bitrate = 320, bitrate = 320,
path = 'tests/assets/{0}rtist/{0}{1}lbum/{2}'.format(letter, lether, song), path = 'tests/assets/{0}rtist/{0}{1}lbum/{2}'.format(letter, lether, song),
content_type = 'audio/mpeg',
last_modification = 0, last_modification = 0,
root_folder = root, root_folder = root,
folder = afolder folder = afolder

View File

@ -48,7 +48,6 @@ class MediaTestCase(ApiTestBase):
folder = folder, folder = folder,
duration = 2, duration = 2,
bitrate = 320, bitrate = 320,
content_type = 'audio/mpeg',
last_modification = 0 last_modification = 0
) )
self.trackid = track.id self.trackid = track.id
@ -66,7 +65,6 @@ class MediaTestCase(ApiTestBase):
folder = folder, folder = folder,
duration = 2, duration = 2,
bitrate = 320, bitrate = 320,
content_type = 'audio/{0}'.format(self.formats[i][1]),
last_modification = 0 last_modification = 0
) )
self.formats[i] = track_embeded_art.id self.formats[i] = track_embeded_art.id
@ -82,7 +80,6 @@ class MediaTestCase(ApiTestBase):
rv = self.client.get('/rest/stream.view', query_string = { 'u': 'alice', 'p': 'Alic3', 'c': 'tests', 'id': str(self.trackid) }) rv = self.client.get('/rest/stream.view', query_string = { 'u': 'alice', 'p': 'Alic3', 'c': 'tests', 'id': str(self.trackid) })
self.assertEqual(rv.status_code, 200) self.assertEqual(rv.status_code, 200)
self.assertEqual(rv.mimetype, 'audio/mpeg')
self.assertEqual(len(rv.data), 23) self.assertEqual(len(rv.data), 23)
with db_session: with db_session:
self.assertEqual(Track[self.trackid].play_count, 1) self.assertEqual(Track[self.trackid].play_count, 1)
@ -95,7 +92,6 @@ class MediaTestCase(ApiTestBase):
# download single file # download single file
rv = self.client.get('/rest/download.view', query_string = { 'u': 'alice', 'p': 'Alic3', 'c': 'tests', 'id': str(self.trackid) }) rv = self.client.get('/rest/download.view', query_string = { 'u': 'alice', 'p': 'Alic3', 'c': 'tests', 'id': str(self.trackid) })
self.assertEqual(rv.status_code, 200) self.assertEqual(rv.status_code, 200)
self.assertEqual(rv.mimetype, 'audio/mpeg')
self.assertEqual(len(rv.data), 23) self.assertEqual(len(rv.data), 23)
with db_session: with db_session:
self.assertEqual(Track[self.trackid].play_count, 0) self.assertEqual(Track[self.trackid].play_count, 0)

View File

@ -36,7 +36,6 @@ class PlaylistTestCase(ApiTestBase):
artist = artist, artist = artist,
bitrate = 320, bitrate = 320,
path = 'tests/assets/' + song, path = 'tests/assets/' + song,
content_type = 'audio/mpeg',
last_modification = 0, last_modification = 0,
root_folder = root, root_folder = root,
folder = root folder = root

View File

@ -47,7 +47,6 @@ class SearchTestCase(ApiTestBase):
artist = artist, artist = artist,
bitrate = 320, bitrate = 320,
path = 'tests/assets/{0}rtist/{0}{1}lbum/{2}'.format(letter, lether, song), path = 'tests/assets/{0}rtist/{0}{1}lbum/{2}'.format(letter, lether, song),
content_type = 'audio/mpeg',
last_modification = 0, last_modification = 0,
root_folder = root, root_folder = root,
folder = afolder folder = afolder

View File

@ -74,7 +74,6 @@ class DbTestCase(unittest.TestCase):
has_art = True, has_art = True,
bitrate = 320, bitrate = 320,
path = 'tests/assets/formats/silence.ogg', path = 'tests/assets/formats/silence.ogg',
content_type = 'audio/ogg',
last_modification = 1234, last_modification = 1234,
root_folder = root, root_folder = root,
folder = child folder = child
@ -89,7 +88,6 @@ class DbTestCase(unittest.TestCase):
duration = 5, duration = 5,
bitrate = 96, bitrate = 96,
path = 'tests/assets/23bytes', path = 'tests/assets/23bytes',
content_type = 'audio/mpeg',
last_modification = 1234, last_modification = 1234,
root_folder = root, root_folder = root,
folder = child folder = child
@ -110,7 +108,6 @@ class DbTestCase(unittest.TestCase):
has_art = has_art, has_art = has_art,
bitrate = 96, bitrate = 96,
path = 'tests/assets/formats/silence.flac', path = 'tests/assets/formats/silence.flac',
content_type = 'audio/flac',
last_modification = 1234, last_modification = 1234,
root_folder = root, root_folder = root,
folder = folder folder = folder

View File

@ -35,7 +35,6 @@ class PlaylistTestCase(FrontendTestBase):
duration = 2, duration = 2,
disc = 1, disc = 1,
number = 1, number = 1,
content_type = 'audio/mpeg',
bitrate = 320, bitrate = 320,
last_modification = 0 last_modification = 0
) )

View File

@ -59,7 +59,6 @@ class FolderManagerTestCase(unittest.TestCase):
folder = root, folder = root,
root_folder = root, root_folder = root,
duration = 2, duration = 2,
content_type = 'audio/mpeg',
bitrate = 320, bitrate = 320,
last_modification = 0 last_modification = 0
) )

View File

@ -48,7 +48,6 @@ class UserManagerTestCase(unittest.TestCase):
path = 'tests/assets/empty', path = 'tests/assets/empty',
folder = folder, folder = folder,
root_folder = folder, root_folder = folder,
content_type = 'audio/mpeg',
bitrate = 320, bitrate = 320,
last_modification = 0 last_modification = 0
) )