diff --git a/bin/mopidy-scan b/bin/mopidy-scan index 84cfee57..869aa662 100755 --- a/bin/mopidy-scan +++ b/bin/mopidy-scan @@ -1,31 +1,38 @@ #!/usr/bin/env python -if __name__ == '__main__': - import sys +import sys +import logging - from mopidy import settings - from mopidy.scanner import Scanner, translator - from mopidy.frontends.mpd.translator import tracks_to_tag_cache_format +from mopidy import settings +from mopidy.utils.log import setup_console_logging, setup_root_logger +from mopidy.scanner import Scanner, translator +from mopidy.frontends.mpd.translator import tracks_to_tag_cache_format - tracks = [] +setup_root_logger() +setup_console_logging(2) - def store(data): - track = translator(data) - tracks.append(track) - print >> sys.stderr, 'Added %s' % track.uri +tracks = [] - def debug(uri, error): - print >> sys.stderr, 'Failed %s: %s' % (uri, error) +def store(data): + track = translator(data) + tracks.append(track) + logging.debug(u'Added %s', track.uri) - print >> sys.stderr, 'Scanning %s' % settings.LOCAL_MUSIC_PATH +def debug(uri, error, debug): + logging.error(u'Failed %s: %s - %s', uri, error, debug) - scanner = Scanner(settings.LOCAL_MUSIC_PATH, store, debug) +logging.info(u'Scanning %s', settings.LOCAL_MUSIC_PATH) + +scanner = Scanner(settings.LOCAL_MUSIC_PATH, store, debug) +try: scanner.start() +except KeyboardInterrupt: + scanner.stop() - print >> sys.stderr, 'Done' +logging.info(u'Done') - for a in tracks_to_tag_cache_format(tracks): - if len(a) == 1: - print (u'%s' % a).encode('utf-8') - else: - print (u'%s: %s' % a).encode('utf-8') +for a in tracks_to_tag_cache_format(tracks): + if len(a) == 1: + print (u'%s' % a).encode('utf-8') + else: + print (u'%s: %s' % a).encode('utf-8') diff --git a/docs/changes.rst b/docs/changes.rst index a3a8f1ce..a01ff931 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -59,6 +59,17 @@ Please note that 0.5.0 requires some updated dependencies, as listed under authentication is turned on, but the connected user has not been authenticated yet. +- Tag cache generator: + + - Made it possible to CTRL^c mopidy-scan. + + - Fixed bug with bad dates. + + - Use logging not print statements. + + - Found and worked around strange WMA metadata behaviour, should be fixed + properly. + v0.4.1 (2011-05-06) =================== diff --git a/mopidy/scanner.py b/mopidy/scanner.py index c603c578..3bcf03d9 100644 --- a/mopidy/scanner.py +++ b/mopidy/scanner.py @@ -24,7 +24,7 @@ def translator(data): _retrieve(gst.TAG_TRACK_COUNT, 'num_tracks', album_kwargs) _retrieve(gst.TAG_ARTIST, 'name', artist_kwargs) - if gst.TAG_DATE in data: + if gst.TAG_DATE in data and data[gst.TAG_DATE]: date = data[gst.TAG_DATE] date = datetime.date(date.year, date.month, date.day) track_kwargs['date'] = date @@ -57,17 +57,16 @@ class Scanner(object): self.error_callback = error_callback self.loop = gobject.MainLoop() - caps = gst.Caps('audio/x-raw-int') fakesink = gst.element_factory_make('fakesink') - pad = fakesink.get_pad('sink') self.uribin = gst.element_factory_make('uridecodebin') - self.uribin.connect('pad-added', self.process_new_pad, pad) - self.uribin.set_property('caps', caps) + self.uribin.set_property('caps', gst.Caps('audio/x-raw-int')) + self.uribin.connect('pad-added', self.process_new_pad, + fakesink.get_pad('sink')) self.pipe = gst.element_factory_make('pipeline') - self.pipe.add(fakesink) self.pipe.add(self.uribin) + self.pipe.add(fakesink) bus = self.pipe.get_bus() bus.add_signal_watch() @@ -78,22 +77,36 @@ class Scanner(object): pad.link(target_pad) def process_tags(self, bus, message): - data = message.parse_tag() - data = dict([(k, data[k]) for k in data.keys()]) - data['uri'] = unicode(self.uribin.get_property('uri')) - data['duration'] = self.get_duration() - self.data_callback(data) - self.next_uri() + taglist = message.parse_tag() + data = { + 'uri': unicode(self.uribin.get_property('uri')), + gst.TAG_DURATION: self.get_duration(), + } + + for key in taglist.keys(): + # XXX: For some crazy reason some wma files spit out lists here, + # not sure if this is due to better data in headers or wma being + # stupid. So ugly hack for now :/ + if type(taglist[key]) is list: + data[key] = taglist[key][0] + else: + data[key] = taglist[key] + + try: + self.data_callback(data) + self.next_uri() + except KeyboardInterrupt: + self.stop() def process_error(self, bus, message): if self.error_callback: uri = self.uribin.get_property('uri') - errors = message.parse_error() - self.error_callback(uri, errors) + error, debug = message.parse_error() + self.error_callback(uri, error, debug) self.next_uri() def get_duration(self): - self.pipe.get_state() + self.pipe.get_state() # Block until state change is done. try: return self.pipe.query_duration( gst.FORMAT_TIME, None)[0] // gst.MSECOND diff --git a/tests/scanner_test.py b/tests/scanner_test.py index b98c5aa9..f403a221 100644 --- a/tests/scanner_test.py +++ b/tests/scanner_test.py @@ -4,7 +4,7 @@ from datetime import date from mopidy.scanner import Scanner, translator from mopidy.models import Track, Artist, Album -from tests import path_to_data_dir +from tests import path_to_data_dir, SkipTest class FakeGstDate(object): def __init__(self, year, month, day): @@ -144,9 +144,9 @@ class ScannerTest(unittest.TestCase): uri = data['uri'][len('file://'):] self.data[uri] = data - def error_callback(self, uri, errors): + def error_callback(self, uri, error, debug): uri = uri[len('file://'):] - self.errors[uri] = errors + self.errors[uri] = (error, debug) def test_data_is_set(self): self.scan('scanner/simple') @@ -184,3 +184,7 @@ class ScannerTest(unittest.TestCase): def test_other_media_is_ignored(self): self.scan('scanner/image') self.assert_(self.errors) + + @SkipTest + def test_song_without_time_is_handeled(self): + pass