2017-11-25 21:21:58 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# vim:fenc=utf-8
|
|
|
|
#
|
|
|
|
# This file is part of Supysonic.
|
|
|
|
# Supysonic is a Python implementation of the Subsonic server API.
|
|
|
|
#
|
|
|
|
# Copyright (C) 2013-2017 Alban 'spl0k' Féron
|
|
|
|
#
|
|
|
|
# Distributed under terms of the GNU AGPLv3 license.
|
|
|
|
|
|
|
|
import io
|
|
|
|
import mutagen
|
|
|
|
import os.path
|
|
|
|
import tempfile
|
|
|
|
import unittest
|
|
|
|
|
|
|
|
from contextlib import contextmanager
|
2017-12-17 22:25:34 +00:00
|
|
|
from pony.orm import db_session, commit
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
from supysonic import db
|
|
|
|
from supysonic.managers.folder import FolderManager
|
|
|
|
from supysonic.scanner import Scanner
|
|
|
|
|
|
|
|
class ScannerTestCase(unittest.TestCase):
|
|
|
|
def setUp(self):
|
2017-12-17 22:25:34 +00:00
|
|
|
self.store = db.get_database('sqlite:', True)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
FolderManager.add('folder', os.path.abspath('tests/assets'))
|
|
|
|
with db_session:
|
|
|
|
folder = db.Folder.select().first()
|
|
|
|
self.assertIsNotNone(folder)
|
|
|
|
self.folderid = folder.id
|
2017-11-25 21:21:58 +00:00
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner = Scanner()
|
|
|
|
self.scanner.scan(folder)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
self.scanner.finish()
|
2017-12-17 22:25:34 +00:00
|
|
|
db.release_database(self.store)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
@contextmanager
|
|
|
|
def __temporary_track_copy(self):
|
2017-12-17 22:25:34 +00:00
|
|
|
track = db.Track.select().first()
|
2017-11-25 21:21:58 +00:00
|
|
|
with tempfile.NamedTemporaryFile(dir = os.path.dirname(track.path)) as tf:
|
|
|
|
with io.open(track.path, 'rb') as f:
|
|
|
|
tf.write(f.read())
|
|
|
|
yield tf
|
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
@db_session
|
2017-11-25 21:21:58 +00:00
|
|
|
def test_scan(self):
|
2017-12-17 22:25:34 +00:00
|
|
|
self.assertEqual(db.Track.select().count(), 1)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
self.assertRaises(TypeError, self.scanner.scan, None)
|
|
|
|
self.assertRaises(TypeError, self.scanner.scan, 'string')
|
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
@db_session
|
2017-11-25 21:21:58 +00:00
|
|
|
def test_progress(self):
|
|
|
|
def progress(processed, total):
|
|
|
|
self.assertIsInstance(processed, int)
|
|
|
|
self.assertIsInstance(total, int)
|
|
|
|
self.assertLessEqual(processed, total)
|
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner.scan(db.Folder[self.folderid], progress)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
@db_session
|
2017-11-25 21:21:58 +00:00
|
|
|
def test_rescan(self):
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner.scan(db.Folder[self.folderid])
|
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 1)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
@db_session
|
2017-11-25 21:21:58 +00:00
|
|
|
def test_force_rescan(self):
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner = Scanner(True)
|
|
|
|
self.scanner.scan(db.Folder[self.folderid])
|
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 1)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
@db_session
|
2017-11-25 21:21:58 +00:00
|
|
|
def test_scan_file(self):
|
2017-12-17 22:25:34 +00:00
|
|
|
track = db.Track.select().first()
|
2017-11-25 21:21:58 +00:00
|
|
|
self.assertRaises(TypeError, self.scanner.scan_file, None)
|
|
|
|
self.assertRaises(TypeError, self.scanner.scan_file, track)
|
|
|
|
|
|
|
|
self.scanner.scan_file('/some/inexistent/path')
|
2017-12-17 22:25:34 +00:00
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 1)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
@db_session
|
2017-11-25 21:21:58 +00:00
|
|
|
def test_remove_file(self):
|
2017-12-17 22:25:34 +00:00
|
|
|
track = db.Track.select().first()
|
2017-11-25 21:21:58 +00:00
|
|
|
self.assertRaises(TypeError, self.scanner.remove_file, None)
|
|
|
|
self.assertRaises(TypeError, self.scanner.remove_file, track)
|
|
|
|
|
|
|
|
self.scanner.remove_file('/some/inexistent/path')
|
2017-12-17 22:25:34 +00:00
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 1)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
self.scanner.remove_file(track.path)
|
|
|
|
self.scanner.finish()
|
2017-12-17 22:25:34 +00:00
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 0)
|
|
|
|
self.assertEqual(db.Album.select().count(), 0)
|
|
|
|
self.assertEqual(db.Artist.select().count(), 0)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
@db_session
|
2017-11-25 21:21:58 +00:00
|
|
|
def test_move_file(self):
|
2017-12-17 22:25:34 +00:00
|
|
|
track = db.Track.select().first()
|
2017-11-25 21:21:58 +00:00
|
|
|
self.assertRaises(TypeError, self.scanner.move_file, None, 'string')
|
|
|
|
self.assertRaises(TypeError, self.scanner.move_file, track, 'string')
|
|
|
|
self.assertRaises(TypeError, self.scanner.move_file, 'string', None)
|
|
|
|
self.assertRaises(TypeError, self.scanner.move_file, 'string', track)
|
|
|
|
|
|
|
|
self.scanner.move_file('/some/inexistent/path', track.path)
|
2017-12-17 22:25:34 +00:00
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 1)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
self.scanner.move_file(track.path, track.path)
|
2017-12-17 22:25:34 +00:00
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 1)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
self.assertRaises(Exception, self.scanner.move_file, track.path, '/some/inexistent/path')
|
|
|
|
|
|
|
|
with self.__temporary_track_copy() as tf:
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner.scan(db.Folder[self.folderid])
|
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 2)
|
2017-11-25 21:21:58 +00:00
|
|
|
self.scanner.move_file(tf.name, track.path)
|
2017-12-17 22:25:34 +00:00
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 1)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
track = db.Track.select().first()
|
2017-11-25 21:21:58 +00:00
|
|
|
new_path = os.path.abspath(os.path.join(os.path.dirname(track.path), '..', 'silence.mp3'))
|
|
|
|
self.scanner.move_file(track.path, new_path)
|
2017-12-17 22:25:34 +00:00
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 1)
|
2017-11-25 21:21:58 +00:00
|
|
|
self.assertEqual(track.path, new_path)
|
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
@db_session
|
2017-11-25 21:21:58 +00:00
|
|
|
def test_rescan_corrupt_file(self):
|
2017-12-17 22:25:34 +00:00
|
|
|
track = db.Track.select().first()
|
|
|
|
self.scanner = Scanner(True)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
with self.__temporary_track_copy() as tf:
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner.scan(db.Folder[self.folderid])
|
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 2)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
tf.seek(0, 0)
|
|
|
|
tf.write('\x00' * 4096)
|
|
|
|
tf.truncate()
|
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner.scan(db.Folder[self.folderid])
|
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 1)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
@db_session
|
2017-11-25 21:21:58 +00:00
|
|
|
def test_rescan_removed_file(self):
|
2017-12-17 22:25:34 +00:00
|
|
|
track = db.Track.select().first()
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
with self.__temporary_track_copy() as tf:
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner.scan(db.Folder[self.folderid])
|
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 2)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner.scan(db.Folder[self.folderid])
|
|
|
|
commit()
|
|
|
|
self.assertEqual(db.Track.select().count(), 1)
|
2017-11-25 21:21:58 +00:00
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
@db_session
|
2017-11-25 21:21:58 +00:00
|
|
|
def test_scan_tag_change(self):
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner = Scanner(True)
|
|
|
|
folder = db.Folder[self.folderid]
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
with self.__temporary_track_copy() as tf:
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner.scan(folder)
|
|
|
|
commit()
|
|
|
|
copy = db.Track.get(path = tf.name)
|
2017-11-25 21:21:58 +00:00
|
|
|
self.assertEqual(copy.artist.name, 'Some artist')
|
|
|
|
self.assertEqual(copy.album.name, 'Awesome album')
|
|
|
|
|
|
|
|
tags = mutagen.File(copy.path, easy = True)
|
|
|
|
tags['artist'] = 'Renamed artist'
|
|
|
|
tags['album'] = 'Crappy album'
|
|
|
|
tags.save()
|
|
|
|
|
2017-12-17 22:25:34 +00:00
|
|
|
self.scanner.scan(folder)
|
2017-11-25 21:21:58 +00:00
|
|
|
self.scanner.finish()
|
|
|
|
self.assertEqual(copy.artist.name, 'Renamed artist')
|
|
|
|
self.assertEqual(copy.album.name, 'Crappy album')
|
2017-12-17 22:25:34 +00:00
|
|
|
self.assertIsNotNone(db.Artist.get(name = 'Some artist'))
|
|
|
|
self.assertIsNotNone(db.Album.get(name = 'Awesome album'))
|
2017-11-25 21:21:58 +00:00
|
|
|
|
|
|
|
def test_stats(self):
|
|
|
|
self.assertEqual(self.scanner.stats(), ((1,1,1),(0,0,0)))
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main()
|
|
|
|
|