Skip to content

Instantly share code, notes, and snippets.

@pipe01
Created December 13, 2021 00:29
Show Gist options
  • Select an option

  • Save pipe01/ae5caf2ec50c4446a5c1f7bcabe47cdf to your computer and use it in GitHub Desktop.

Select an option

Save pipe01/ae5caf2ec50c4446a5c1f7bcabe47cdf to your computer and use it in GitHub Desktop.
Spotify song name indicator for GNOME
import argparse
from gi import require_version
require_version('Gtk', '3.0')
require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, GLib
from gi.repository import AppIndicator3 as appindicator
from dbus.mainloop.glib import DBusGMainLoop
import textwrap, threading
import dbus
APPINDICATOR_ID = 'spotify-song-name'
global ind
ind = None
DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
props: dbus.Interface = None
player: dbus.Interface = None
def set_stopped():
global props, player
props = None
player = None
ind.set_label("Not playing", "")
ind.set_icon_full("media-playback-stop", "Not playing")
def connect_spotify():
global props, player, ind
if props == None:
if "org.mpris.MediaPlayer2.spotify" in bus.list_names():
spotify = bus.get_object("org.mpris.MediaPlayer2.spotify", "/org/mpris/MediaPlayer2")
props = dbus.Interface(spotify, "org.freedesktop.DBus.Properties")
player = dbus.Interface(spotify, "org.mpris.MediaPlayer2.Player")
props.connect_to_signal("PropertiesChanged", lambda *_: update())
update()
else:
set_stopped()
else:
try:
props.Get("org.mpris.MediaPlayer2.Player", "Position")
except:
set_stopped()
threading.Timer(5, connect_spotify).start()
glib_loop = GLib.MainLoop()
threading.Thread(target=glib_loop.run).start()
def get_metadata():
md = props.Get("org.mpris.MediaPlayer2.Player", "Metadata")
return {
"artist": ", ".join(md["xesam:artist"]),
"title": md["xesam:title"]
}
def is_playing():
return props.Get("org.mpris.MediaPlayer2.Player", "PlaybackStatus") == "Playing"
def quit_app(_):
Gtk.main_quit()
glib_loop.quit()
def trim(s: str, width: int):
return s[:width] + "…" if len(s) > width else s
def update():
data = get_metadata()
artist = trim(data["artist"], 20)
title = trim(data["title"], 30)
label = "%s - %s" % (artist, title)
ind.set_label(label, "")
ind.set_icon_full(*(("media-playback-start", "Playing") if is_playing() else ("media-playback-pause", "Paused")))
if __name__ == "__main__":
ind = appindicator.Indicator.new(
APPINDICATOR_ID,
"media-playback-pause",
appindicator.IndicatorCategory.APPLICATION_STATUS)
ind.set_status(appindicator.IndicatorStatus.ACTIVE)
connect_spotify()
menu = Gtk.Menu()
prev_item = Gtk.MenuItem(label="Previous")
prev_item.connect("activate", lambda: player.Previous())
prev_item.show_all()
menu.append(prev_item)
next_item = Gtk.MenuItem(label="Next")
next_item.connect("activate", lambda: player.Next())
next_item.show_all()
menu.append(next_item)
exit_item = Gtk.MenuItem(label="Exit")
exit_item.connect("activate", quit_app)
exit_item.show_all()
menu.append(exit_item)
ind.set_menu(menu)
Gtk.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment