Merge pull request #106 from adamcik/feature/improve-scanner

feature/improve-scanner
This commit is contained in:
Stein Magnus Jodal 2011-06-09 04:56:35 -07:00
commit 02ff811770
4 changed files with 73 additions and 38 deletions

View File

@ -1,31 +1,38 @@
#!/usr/bin/env python #!/usr/bin/env python
if __name__ == '__main__': import sys
import sys import logging
from mopidy import settings from mopidy import settings
from mopidy.scanner import Scanner, translator from mopidy.utils.log import setup_console_logging, setup_root_logger
from mopidy.frontends.mpd.translator import tracks_to_tag_cache_format 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): tracks = []
track = translator(data)
tracks.append(track)
print >> sys.stderr, 'Added %s' % track.uri
def debug(uri, error): def store(data):
print >> sys.stderr, 'Failed %s: %s' % (uri, error) 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() scanner.start()
except KeyboardInterrupt:
scanner.stop()
print >> sys.stderr, 'Done' logging.info(u'Done')
for a in tracks_to_tag_cache_format(tracks): for a in tracks_to_tag_cache_format(tracks):
if len(a) == 1: if len(a) == 1:
print (u'%s' % a).encode('utf-8') print (u'%s' % a).encode('utf-8')
else: else:
print (u'%s: %s' % a).encode('utf-8') print (u'%s: %s' % a).encode('utf-8')

View File

@ -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 authentication is turned on, but the connected user has not been
authenticated yet. 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) v0.4.1 (2011-05-06)
=================== ===================

View File

@ -24,7 +24,7 @@ def translator(data):
_retrieve(gst.TAG_TRACK_COUNT, 'num_tracks', album_kwargs) _retrieve(gst.TAG_TRACK_COUNT, 'num_tracks', album_kwargs)
_retrieve(gst.TAG_ARTIST, 'name', artist_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 = data[gst.TAG_DATE]
date = datetime.date(date.year, date.month, date.day) date = datetime.date(date.year, date.month, date.day)
track_kwargs['date'] = date track_kwargs['date'] = date
@ -57,17 +57,16 @@ class Scanner(object):
self.error_callback = error_callback self.error_callback = error_callback
self.loop = gobject.MainLoop() self.loop = gobject.MainLoop()
caps = gst.Caps('audio/x-raw-int')
fakesink = gst.element_factory_make('fakesink') fakesink = gst.element_factory_make('fakesink')
pad = fakesink.get_pad('sink')
self.uribin = gst.element_factory_make('uridecodebin') self.uribin = gst.element_factory_make('uridecodebin')
self.uribin.connect('pad-added', self.process_new_pad, pad) self.uribin.set_property('caps', gst.Caps('audio/x-raw-int'))
self.uribin.set_property('caps', caps) self.uribin.connect('pad-added', self.process_new_pad,
fakesink.get_pad('sink'))
self.pipe = gst.element_factory_make('pipeline') self.pipe = gst.element_factory_make('pipeline')
self.pipe.add(fakesink)
self.pipe.add(self.uribin) self.pipe.add(self.uribin)
self.pipe.add(fakesink)
bus = self.pipe.get_bus() bus = self.pipe.get_bus()
bus.add_signal_watch() bus.add_signal_watch()
@ -78,22 +77,36 @@ class Scanner(object):
pad.link(target_pad) pad.link(target_pad)
def process_tags(self, bus, message): def process_tags(self, bus, message):
data = message.parse_tag() taglist = message.parse_tag()
data = dict([(k, data[k]) for k in data.keys()]) data = {
data['uri'] = unicode(self.uribin.get_property('uri')) 'uri': unicode(self.uribin.get_property('uri')),
data['duration'] = self.get_duration() gst.TAG_DURATION: self.get_duration(),
self.data_callback(data) }
self.next_uri()
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): def process_error(self, bus, message):
if self.error_callback: if self.error_callback:
uri = self.uribin.get_property('uri') uri = self.uribin.get_property('uri')
errors = message.parse_error() error, debug = message.parse_error()
self.error_callback(uri, errors) self.error_callback(uri, error, debug)
self.next_uri() self.next_uri()
def get_duration(self): def get_duration(self):
self.pipe.get_state() self.pipe.get_state() # Block until state change is done.
try: try:
return self.pipe.query_duration( return self.pipe.query_duration(
gst.FORMAT_TIME, None)[0] // gst.MSECOND gst.FORMAT_TIME, None)[0] // gst.MSECOND

View File

@ -4,7 +4,7 @@ from datetime import date
from mopidy.scanner import Scanner, translator from mopidy.scanner import Scanner, translator
from mopidy.models import Track, Artist, Album 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): class FakeGstDate(object):
def __init__(self, year, month, day): def __init__(self, year, month, day):
@ -144,9 +144,9 @@ class ScannerTest(unittest.TestCase):
uri = data['uri'][len('file://'):] uri = data['uri'][len('file://'):]
self.data[uri] = data self.data[uri] = data
def error_callback(self, uri, errors): def error_callback(self, uri, error, debug):
uri = uri[len('file://'):] uri = uri[len('file://'):]
self.errors[uri] = errors self.errors[uri] = (error, debug)
def test_data_is_set(self): def test_data_is_set(self):
self.scan('scanner/simple') self.scan('scanner/simple')
@ -184,3 +184,7 @@ class ScannerTest(unittest.TestCase):
def test_other_media_is_ignored(self): def test_other_media_is_ignored(self):
self.scan('scanner/image') self.scan('scanner/image')
self.assert_(self.errors) self.assert_(self.errors)
@SkipTest
def test_song_without_time_is_handeled(self):
pass