Reformat code

This commit is contained in:
badaix 2021-05-17 22:04:27 +02:00
parent 64448e4fa2
commit cc25f1d937

View file

@ -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: