mirror of
https://github.com/badaix/snapcast.git
synced 2025-06-06 04:41:44 +02:00
Reformat code
This commit is contained in:
parent
64448e4fa2
commit
cc25f1d937
1 changed files with 75 additions and 47 deletions
|
@ -37,6 +37,8 @@ import time
|
||||||
import tempfile
|
import tempfile
|
||||||
import base64
|
import base64
|
||||||
import musicbrainzngs
|
import musicbrainzngs
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
__version__ = "@version@"
|
__version__ = "@version@"
|
||||||
__git_version__ = "@gitversion@"
|
__git_version__ = "@gitversion@"
|
||||||
|
@ -339,7 +341,7 @@ class MPDWrapper(object):
|
||||||
self._dbus_service = MPRISInterface(self._params)
|
self._dbus_service = MPRISInterface(self._params)
|
||||||
else:
|
else:
|
||||||
# Add our service to the session bus
|
# Add our service to the session bus
|
||||||
#self._dbus_service.add_to_connection(dbus.SessionBus(),
|
# self._dbus_service.add_to_connection(dbus.SessionBus(),
|
||||||
# '/org/mpris/MediaPlayer2')
|
# '/org/mpris/MediaPlayer2')
|
||||||
self._dbus_service.acquire_name()
|
self._dbus_service.acquire_name()
|
||||||
|
|
||||||
|
@ -383,7 +385,7 @@ class MPDWrapper(object):
|
||||||
# Release the DBus name and disconnect from bus
|
# Release the DBus name and disconnect from bus
|
||||||
if self._dbus_service is not None:
|
if self._dbus_service is not None:
|
||||||
self._dbus_service.release_name()
|
self._dbus_service.release_name()
|
||||||
#self._dbus_service.remove_from_connection()
|
# self._dbus_service.remove_from_connection()
|
||||||
|
|
||||||
# Stop monitoring
|
# Stop monitoring
|
||||||
if self._poll_id:
|
if self._poll_id:
|
||||||
|
@ -412,7 +414,7 @@ class MPDWrapper(object):
|
||||||
|
|
||||||
def init_state(self):
|
def init_state(self):
|
||||||
# Get current state
|
# Get current state
|
||||||
self._status = self.status()
|
self._status = self.client.status()
|
||||||
# Invalid some fields to throw events at start
|
# Invalid some fields to throw events at start
|
||||||
self._status['state'] = 'invalid'
|
self._status['state'] = 'invalid'
|
||||||
self._status['songid'] = '-1'
|
self._status['songid'] = '-1'
|
||||||
|
@ -444,7 +446,7 @@ class MPDWrapper(object):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
## Events
|
# Events
|
||||||
|
|
||||||
def timer_callback(self):
|
def timer_callback(self):
|
||||||
try:
|
try:
|
||||||
|
@ -483,17 +485,17 @@ class MPDWrapper(object):
|
||||||
logger.debug('Got GNOME mmkey "%s" for "%s"' % (key, appname))
|
logger.debug('Got GNOME mmkey "%s" for "%s"' % (key, appname))
|
||||||
if key == 'Play':
|
if key == 'Play':
|
||||||
if self._status['state'] == 'play':
|
if self._status['state'] == 'play':
|
||||||
self.pause(1)
|
self.client.pause(1)
|
||||||
self.notify_about_state('pause')
|
self.notify_about_state('pause')
|
||||||
else:
|
else:
|
||||||
self.play()
|
self.play()
|
||||||
self.notify_about_state('play')
|
self.notify_about_state('play')
|
||||||
elif key == 'Next':
|
elif key == 'Next':
|
||||||
self.next()
|
self.client.next()
|
||||||
elif key == 'Previous':
|
elif key == 'Previous':
|
||||||
self.previous()
|
self.client.previous()
|
||||||
elif key == 'Stop':
|
elif key == 'Stop':
|
||||||
self.stop()
|
self.client.stop()
|
||||||
self.notify_about_state('stop')
|
self.notify_about_state('stop')
|
||||||
|
|
||||||
def last_currentsong(self):
|
def last_currentsong(self):
|
||||||
|
@ -510,6 +512,7 @@ class MPDWrapper(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
mpd_meta = self.last_currentsong()
|
mpd_meta = self.last_currentsong()
|
||||||
|
print(mpd_meta)
|
||||||
self._metadata = {}
|
self._metadata = {}
|
||||||
|
|
||||||
for tag in ('album', 'title'):
|
for tag in ('album', 'title'):
|
||||||
|
@ -592,9 +595,10 @@ class MPDWrapper(object):
|
||||||
|
|
||||||
if 'xesam:title' in self._metadata and 'xesam:album' in self._metadata:
|
if 'xesam:title' in self._metadata and 'xesam:album' in self._metadata:
|
||||||
result = musicbrainzngs.search_releases(artist=self._metadata['xesam:title'], release=self._metadata['xesam:album'],
|
result = musicbrainzngs.search_releases(artist=self._metadata['xesam:title'], release=self._metadata['xesam:album'],
|
||||||
limit=1)
|
limit=1)
|
||||||
if result['release-list']:
|
if result['release-list']:
|
||||||
self._metadata['mpris:artUrl'] = f"http://coverartarchive.org/release/{result['release-list'][0]['id']}/front-250"
|
self._metadata[
|
||||||
|
'mpris:artUrl'] = f"http://coverartarchive.org/release/{result['release-list'][0]['id']}/front-250"
|
||||||
print(self._metadata['mpris:artUrl'])
|
print(self._metadata['mpris:artUrl'])
|
||||||
|
|
||||||
def notify_about_track(self, meta, state='play'):
|
def notify_about_track(self, meta, state='play'):
|
||||||
|
@ -619,10 +623,14 @@ class MPDWrapper(object):
|
||||||
body += ' (%s)' % _('Paused')
|
body += ' (%s)' % _('Paused')
|
||||||
|
|
||||||
notification.notify(title, body, uri)
|
notification.notify(title, body, uri)
|
||||||
|
r = requests.post('http://127.0.0.1:1780/jsonrpc', json={"id": 4, "jsonrpc": "2.0", "method": "Stream.SetMeta", "params": {
|
||||||
|
"id": "Spotify", "meta": meta}})
|
||||||
|
print(r)
|
||||||
|
|
||||||
def notify_about_state(self, state):
|
def notify_about_state(self, state):
|
||||||
if state == 'stop':
|
if state == 'stop':
|
||||||
notification.notify(identity, _('Stopped'), 'media-playback-stop-symbolic')
|
notification.notify(identity, _('Stopped'),
|
||||||
|
'media-playback-stop-symbolic')
|
||||||
else:
|
else:
|
||||||
self.notify_about_track(self.metadata, state)
|
self.notify_about_track(self.metadata, state)
|
||||||
|
|
||||||
|
@ -634,10 +642,12 @@ class MPDWrapper(object):
|
||||||
# Try existing temporary file
|
# Try existing temporary file
|
||||||
if self._temp_cover:
|
if self._temp_cover:
|
||||||
if song_url == self._temp_song_url:
|
if song_url == self._temp_song_url:
|
||||||
logger.debug("find_cover: Reusing old image at %r" % self._temp_cover.name)
|
logger.debug("find_cover: Reusing old image at %r" %
|
||||||
|
self._temp_cover.name)
|
||||||
return 'file://' + self._temp_cover.name
|
return 'file://' + self._temp_cover.name
|
||||||
else:
|
else:
|
||||||
logger.debug("find_cover: Cleaning up old image at %r" % self._temp_cover.name)
|
logger.debug(
|
||||||
|
"find_cover: Cleaning up old image at %r" % self._temp_cover.name)
|
||||||
self._temp_song_url = None
|
self._temp_song_url = None
|
||||||
self._temp_cover.close()
|
self._temp_cover.close()
|
||||||
|
|
||||||
|
@ -647,7 +657,8 @@ class MPDWrapper(object):
|
||||||
try:
|
try:
|
||||||
song = mutagen.File(song_path)
|
song = mutagen.File(song_path)
|
||||||
except mutagen.MutagenError as e:
|
except mutagen.MutagenError as e:
|
||||||
logger.error("Can't extract covers from %r: %r" % (song_path, e))
|
logger.error("Can't extract covers from %r: %r" %
|
||||||
|
(song_path, e))
|
||||||
if song is not None:
|
if song is not None:
|
||||||
if song.tags:
|
if song.tags:
|
||||||
# present but null for some file types
|
# present but null for some file types
|
||||||
|
@ -655,8 +666,8 @@ class MPDWrapper(object):
|
||||||
if tag.startswith("APIC:"):
|
if tag.startswith("APIC:"):
|
||||||
for pic in song.tags.getall(tag):
|
for pic in song.tags.getall(tag):
|
||||||
if pic.type == mutagen.id3.PictureType.COVER_FRONT:
|
if pic.type == mutagen.id3.PictureType.COVER_FRONT:
|
||||||
self._temp_song_url = song_url
|
self._temp_song_url = song_url
|
||||||
return self._create_temp_cover(pic)
|
return self._create_temp_cover(pic)
|
||||||
if hasattr(song, "pictures"):
|
if hasattr(song, "pictures"):
|
||||||
# FLAC
|
# FLAC
|
||||||
for pic in song.pictures:
|
for pic in song.pictures:
|
||||||
|
@ -704,10 +715,12 @@ class MPDWrapper(object):
|
||||||
'image/png': '.png',
|
'image/png': '.png',
|
||||||
'image/gif': '.gif'}
|
'image/gif': '.gif'}
|
||||||
|
|
||||||
self._temp_cover = tempfile.NamedTemporaryFile(prefix='cover-', suffix=extension.get(pic.mime, '.jpg'))
|
self._temp_cover = tempfile.NamedTemporaryFile(
|
||||||
|
prefix='cover-', suffix=extension.get(pic.mime, '.jpg'))
|
||||||
self._temp_cover.write(pic.data)
|
self._temp_cover.write(pic.data)
|
||||||
self._temp_cover.flush()
|
self._temp_cover.flush()
|
||||||
logger.debug("find_cover: Storing embedded image at %r" % self._temp_cover.name)
|
logger.debug("find_cover: Storing embedded image at %r" %
|
||||||
|
self._temp_cover.name)
|
||||||
return 'file://' + self._temp_cover.name
|
return 'file://' + self._temp_cover.name
|
||||||
|
|
||||||
def last_status(self):
|
def last_status(self):
|
||||||
|
@ -719,8 +732,8 @@ class MPDWrapper(object):
|
||||||
old_status = self._status
|
old_status = self._status
|
||||||
old_position = self._position
|
old_position = self._position
|
||||||
old_time = self._time
|
old_time = self._time
|
||||||
self._currentsong = self.currentsong()
|
self._currentsong = self.client.currentsong()
|
||||||
new_status = self.status()
|
new_status = self.client.status()
|
||||||
self._time = new_time = int(time.time())
|
self._time = new_time = int(time.time())
|
||||||
|
|
||||||
if not new_status:
|
if not new_status:
|
||||||
|
@ -728,7 +741,8 @@ class MPDWrapper(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
self._status = new_status
|
self._status = new_status
|
||||||
logger.debug("_update_properties: current song = %r" % self._currentsong)
|
logger.debug("_update_properties: current song = %r" %
|
||||||
|
self._currentsong)
|
||||||
logger.debug("_update_properties: current status = %r" % self._status)
|
logger.debug("_update_properties: current status = %r" % self._status)
|
||||||
|
|
||||||
if 'elapsed' in new_status:
|
if 'elapsed' in new_status:
|
||||||
|
@ -772,9 +786,9 @@ class MPDWrapper(object):
|
||||||
|
|
||||||
if self._params['notify'] and new_status['state'] != 'stop':
|
if self._params['notify'] and new_status['state'] != 'stop':
|
||||||
if old_meta.get('xesam:artist', None) != new_meta.get('xesam:artist', None) \
|
if old_meta.get('xesam:artist', None) != new_meta.get('xesam:artist', None) \
|
||||||
or old_meta.get('xesam:album', None) != new_meta.get('xesam:album', None) \
|
or old_meta.get('xesam:album', None) != new_meta.get('xesam:album', None) \
|
||||||
or old_meta.get('xesam:title', None) != new_meta.get('xesam:title', None) \
|
or old_meta.get('xesam:title', None) != new_meta.get('xesam:title', None) \
|
||||||
or old_meta.get('xesam:url', None) != new_meta.get('xesam:url', None):
|
or old_meta.get('xesam:url', None) != new_meta.get('xesam:url', None):
|
||||||
self.notify_about_track(new_meta, new_status['state'])
|
self.notify_about_track(new_meta, new_status['state'])
|
||||||
|
|
||||||
# "mixer" subsystem
|
# "mixer" subsystem
|
||||||
|
@ -798,15 +812,15 @@ class MPDWrapper(object):
|
||||||
self._dbus_service.update_property('org.mpris.MediaPlayer2.Player',
|
self._dbus_service.update_property('org.mpris.MediaPlayer2.Player',
|
||||||
'CanGoNext')
|
'CanGoNext')
|
||||||
|
|
||||||
## Media keys
|
# Media keys
|
||||||
|
|
||||||
def setup_mediakeys(self):
|
def setup_mediakeys(self):
|
||||||
self.register_mediakeys()
|
self.register_mediakeys()
|
||||||
self._dbus_obj = self._bus.get_object("org.freedesktop.DBus",
|
self._dbus_obj = self._bus.get_object("org.freedesktop.DBus",
|
||||||
"/org/freedesktop/DBus")
|
"/org/freedesktop/DBus")
|
||||||
self._dbus_obj.connect_to_signal("NameOwnerChanged",
|
self._dbus_obj.connect_to_signal("NameOwnerChanged",
|
||||||
self.gsd_name_owner_changed_callback,
|
self.gsd_name_owner_changed_callback,
|
||||||
arg0="org.gnome.SettingsDaemon")
|
arg0="org.gnome.SettingsDaemon")
|
||||||
|
|
||||||
def register_mediakeys(self):
|
def register_mediakeys(self):
|
||||||
try:
|
try:
|
||||||
|
@ -820,21 +834,24 @@ class MPDWrapper(object):
|
||||||
gsd_object.GrabMediaPlayerKeys("mpDris2", 0,
|
gsd_object.GrabMediaPlayerKeys("mpDris2", 0,
|
||||||
dbus_interface="org.gnome.SettingsDaemon.MediaKeys")
|
dbus_interface="org.gnome.SettingsDaemon.MediaKeys")
|
||||||
except:
|
except:
|
||||||
logger.warning("Failed to connect to GNOME Settings Daemon. Media keys won't work.")
|
logger.warning(
|
||||||
|
"Failed to connect to GNOME Settings Daemon. Media keys won't work.")
|
||||||
else:
|
else:
|
||||||
self._bus.remove_signal_receiver(self.mediakey_callback)
|
self._bus.remove_signal_receiver(self.mediakey_callback)
|
||||||
gsd_object.connect_to_signal("MediaPlayerKeyPressed", self.mediakey_callback)
|
gsd_object.connect_to_signal(
|
||||||
|
"MediaPlayerKeyPressed", self.mediakey_callback)
|
||||||
|
|
||||||
def gsd_name_owner_changed_callback(self, bus_name, old_owner, new_owner):
|
def gsd_name_owner_changed_callback(self, bus_name, old_owner, new_owner):
|
||||||
if bus_name == "org.gnome.SettingsDaemon" and new_owner != "":
|
if bus_name == "org.gnome.SettingsDaemon" and new_owner != "":
|
||||||
def reregister():
|
def reregister():
|
||||||
logger.debug("Re-registering with GNOME Settings Daemon (owner %s)" % new_owner)
|
logger.debug(
|
||||||
|
"Re-registering with GNOME Settings Daemon (owner %s)" % new_owner)
|
||||||
self.register_mediakeys()
|
self.register_mediakeys()
|
||||||
return False
|
return False
|
||||||
# Timeout is necessary since g-s-d takes some time to load all plugins.
|
# Timeout is necessary since g-s-d takes some time to load all plugins.
|
||||||
GLib.timeout_add(600, reregister)
|
GLib.timeout_add(600, reregister)
|
||||||
|
|
||||||
## Compatibility functions
|
# Compatibility functions
|
||||||
|
|
||||||
# Fedora 17 still has python-mpd 0.2, which lacks fileno().
|
# Fedora 17 still has python-mpd 0.2, which lacks fileno().
|
||||||
if hasattr(mpd.MPDClient, "fileno"):
|
if hasattr(mpd.MPDClient, "fileno"):
|
||||||
|
@ -846,7 +863,7 @@ class MPDWrapper(object):
|
||||||
raise mpd.ConnectionError("Not connected")
|
raise mpd.ConnectionError("Not connected")
|
||||||
return self.client._sock.fileno()
|
return self.client._sock.fileno()
|
||||||
|
|
||||||
## Access to python-mpd internal APIs
|
# Access to python-mpd internal APIs
|
||||||
|
|
||||||
# We use _write_command("idle") to manually enter idle mode, as it has no
|
# We use _write_command("idle") to manually enter idle mode, as it has no
|
||||||
# immediate response to fetch.
|
# immediate response to fetch.
|
||||||
|
@ -899,7 +916,8 @@ class MPDWrapper(object):
|
||||||
fn = getattr(self.client, command)
|
fn = getattr(self.client, command)
|
||||||
try:
|
try:
|
||||||
was_idle = self.idle_leave()
|
was_idle = self.idle_leave()
|
||||||
logger.debug("Sending command %r (was idle? %r)" % (command, was_idle))
|
logger.debug("Sending command %r (was idle? %r)" %
|
||||||
|
(command, was_idle))
|
||||||
r = fn(*args)
|
r = fn(*args)
|
||||||
if was_idle:
|
if was_idle:
|
||||||
self.idle_enter()
|
self.idle_enter()
|
||||||
|
@ -919,7 +937,8 @@ class NotifyWrapper(object):
|
||||||
if params["notify"]:
|
if params["notify"]:
|
||||||
self._notification = self._bootstrap_notifications()
|
self._notification = self._bootstrap_notifications()
|
||||||
if not self._notification:
|
if not self._notification:
|
||||||
logger.error("No notification service provider could be found; disabling notifications")
|
logger.error(
|
||||||
|
"No notification service provider could be found; disabling notifications")
|
||||||
else:
|
else:
|
||||||
self._enabled = False
|
self._enabled = False
|
||||||
|
|
||||||
|
@ -941,7 +960,8 @@ class NotifyWrapper(object):
|
||||||
notif.set_hint("desktop-entry", GLib.Variant("s", "mpdris2"))
|
notif.set_hint("desktop-entry", GLib.Variant("s", "mpdris2"))
|
||||||
notif.set_hint("transient", GLib.Variant("b", True))
|
notif.set_hint("transient", GLib.Variant("b", True))
|
||||||
else:
|
else:
|
||||||
logger.error("Failed to init libnotify; disabling notifications")
|
logger.error(
|
||||||
|
"Failed to init libnotify; disabling notifications")
|
||||||
elif using_old_notify:
|
elif using_old_notify:
|
||||||
logger.debug("Initializing old pynotify")
|
logger.debug("Initializing old pynotify")
|
||||||
if pynotify.init(identity):
|
if pynotify.init(identity):
|
||||||
|
@ -949,22 +969,24 @@ class NotifyWrapper(object):
|
||||||
notif.set_hint("desktop-entry", "mpdris2")
|
notif.set_hint("desktop-entry", "mpdris2")
|
||||||
notif.set_hint("transient", True)
|
notif.set_hint("transient", True)
|
||||||
else:
|
else:
|
||||||
logger.error("Failed to init libnotify; disabling notifications")
|
logger.error(
|
||||||
|
"Failed to init libnotify; disabling notifications")
|
||||||
|
|
||||||
return notif
|
return notif
|
||||||
|
|
||||||
def notify(self, title, body, uri=''):
|
def notify(self, title, body, uri=''):
|
||||||
if not self._enabled:
|
if not self._enabled:
|
||||||
return
|
return
|
||||||
|
|
||||||
# If we did not yet manage to get a notification service,
|
# If we did not yet manage to get a notification service,
|
||||||
# try again
|
# try again
|
||||||
if not self._notification:
|
if not self._notification:
|
||||||
logger.info('Retrying to acquire a notification service provider...')
|
logger.info(
|
||||||
|
'Retrying to acquire a notification service provider...')
|
||||||
self._notification = self._bootstrap_notifications()
|
self._notification = self._bootstrap_notifications()
|
||||||
if self._notification:
|
if self._notification:
|
||||||
logger.info('Notification service provider acquired!')
|
logger.info('Notification service provider acquired!')
|
||||||
|
|
||||||
if self._notification:
|
if self._notification:
|
||||||
try:
|
try:
|
||||||
self._notification.set_urgency(params['notify_urgency'])
|
self._notification.set_urgency(params['notify_urgency'])
|
||||||
|
@ -987,7 +1009,8 @@ class MPRISInterface(dbus.service.Object):
|
||||||
self._params = params or {}
|
self._params = params or {}
|
||||||
self._name = self._params["bus_name"] or "org.mpris.MediaPlayer2.mpd"
|
self._name = self._params["bus_name"] or "org.mpris.MediaPlayer2.mpd"
|
||||||
if not self._name.startswith("org.mpris.MediaPlayer2."):
|
if not self._name.startswith("org.mpris.MediaPlayer2."):
|
||||||
logger.warn("Configured bus name %r is outside MPRIS2 namespace" % self._name)
|
logger.warn(
|
||||||
|
"Configured bus name %r is outside MPRIS2 namespace" % self._name)
|
||||||
|
|
||||||
self._bus = dbus.SessionBus()
|
self._bus = dbus.SessionBus()
|
||||||
self._uname = self._bus.get_unique_name()
|
self._uname = self._bus.get_unique_name()
|
||||||
|
@ -1005,7 +1028,8 @@ class MPRISInterface(dbus.service.Object):
|
||||||
pid = self._dbus_obj.GetConnectionUnixProcessID(new_owner)
|
pid = self._dbus_obj.GetConnectionUnixProcessID(new_owner)
|
||||||
except:
|
except:
|
||||||
pid = None
|
pid = None
|
||||||
logger.info("Replaced by %s (PID %s)" % (new_owner, pid or "unknown"))
|
logger.info("Replaced by %s (PID %s)" %
|
||||||
|
(new_owner, pid or "unknown"))
|
||||||
loop.quit()
|
loop.quit()
|
||||||
|
|
||||||
def acquire_name(self):
|
def acquire_name(self):
|
||||||
|
@ -1252,6 +1276,7 @@ class MPRISInterface(dbus.service.Object):
|
||||||
# TODO
|
# TODO
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def each_xdg_config(suffix):
|
def each_xdg_config(suffix):
|
||||||
"""
|
"""
|
||||||
Return each location matching XDG_CONFIG_DIRS/suffix in descending
|
Return each location matching XDG_CONFIG_DIRS/suffix in descending
|
||||||
|
@ -1325,6 +1350,7 @@ Environment variables MPD_HOST and MPD_PORT can be used.
|
||||||
|
|
||||||
Report bugs to https://github.com/eonpatapon/mpDris2/issues""" % params)
|
Report bugs to https://github.com/eonpatapon/mpDris2/issues""" % params)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
DBusGMainLoop(set_as_default=True)
|
DBusGMainLoop(set_as_default=True)
|
||||||
|
|
||||||
|
@ -1458,7 +1484,8 @@ if __name__ == '__main__':
|
||||||
if music_dir.startswith('file://'):
|
if music_dir.startswith('file://'):
|
||||||
music_dir = music_dir[:7] + os.path.expanduser(music_dir[7:])
|
music_dir = music_dir[:7] + os.path.expanduser(music_dir[7:])
|
||||||
if not os.path.exists(music_dir[7:]):
|
if not os.path.exists(music_dir[7:]):
|
||||||
logger.error('Music library path %s does not exist!' % music_dir)
|
logger.error(
|
||||||
|
'Music library path %s does not exist!' % music_dir)
|
||||||
# Non-local URLs can still be useful to MPRIS clients, so accept them.
|
# Non-local URLs can still be useful to MPRIS clients, so accept them.
|
||||||
params['music_dir'] = music_dir
|
params['music_dir'] = music_dir
|
||||||
logger.info('Using %s as music library path.' % music_dir)
|
logger.info('Using %s as music library path.' % music_dir)
|
||||||
|
@ -1477,7 +1504,8 @@ if __name__ == '__main__':
|
||||||
if mutagen:
|
if mutagen:
|
||||||
logger.info('Using Mutagen to read covers from music files.')
|
logger.info('Using Mutagen to read covers from music files.')
|
||||||
else:
|
else:
|
||||||
logger.info('Mutagen not available, covers in music files will be ignored.')
|
logger.info(
|
||||||
|
'Mutagen not available, covers in music files will be ignored.')
|
||||||
|
|
||||||
# Set up the main loop
|
# Set up the main loop
|
||||||
if using_gi_glib:
|
if using_gi_glib:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue