dotfiles/dot-config/waybar/bin/spotify-info

152 lines
3.6 KiB
Plaintext
Raw Permalink Normal View History

#!/usr/bin/env python3
import gi
gi.require_version('Playerctl', '2.0')
from gi.repository import Playerctl, GLib
from typing import List, Self
from argparse import ArgumentParser
import json
import sys
parser = ArgumentParser()
parser.add_argument("-l", "--main-loop", action="store_true")
parser.add_argument("-p", "--play-pause", action="store_true")
parser.add_argument("-N", "--next", action="store_true")
parser.add_argument("-P", "--previous", action="store_true")
args = parser.parse_args()
PLAY_ICON = " "
PAUSE_ICON = " "
manager = Playerctl.PlayerManager()
class json_data(dict):
def __init__(self) -> None:
super().__init__()
self["text"] = ""
self["alt"] = ""
self["tooltip"] = ""
self["icon"] = ""
def print(self, data=(), **kwargs) -> Self:
super().update(data, **kwargs)
out = {
"text": str(self.get("icon")) + str(self.get("text")),
"alt": self["alt"],
"tooltip": self["tooltip"]
}
sys.stdout.write(json.dumps(out) + '\n')
sys.stdout.flush()
return self
jdata: json_data = json_data()
def on_play(player, status, manager):
global jdata
jdata.print({"icon": PLAY_ICON})
def on_pause(player, status, manager):
global jdata
jdata.print({"icon": PAUSE_ICON})
def on_metadata(player, metadata, manager):
global jdata
keys = metadata.keys()
if 'xesam:artist' in keys and 'xesam:title' in keys:
jdata.print(
{
"text": f'{metadata['xesam:artist'][0]} - {metadata['xesam:title']}',
"alt": metadata['xesam:title'],
"tooltip": f'{', '.join(metadata['xesam:artist'])} - {metadata['xesam:title']}'
}
)
def init_player(name):
if name.name in ['spotify']:
player = Playerctl.Player.new_from_name(name)
player.connect('playback-status::playing', on_play, manager)
player.connect('playback-status::paused', on_pause, manager)
player.connect('metadata', on_metadata, manager)
manager.manage_player(player)
def on_name_appeared(manager, name):
init_player(name)
def on_player_vanished(manager, player):
jdata.print({"text": "", "icon": ""})
def get_spotify() -> Playerctl.Player | None:
for name in manager.props.player_names:
if name.name in ['spotify']:
return Playerctl.Player.new_from_name(name)
def main_loop():
manager.connect('name-appeared', on_name_appeared)
manager.connect('player-vanished', on_player_vanished)
for name in manager.props.player_names:
init_player(name)
if spotify := get_spotify():
jdata.print(
{
"text": f'{spotify.get_artist()} - {spotify.get_title()}',
"alt": spotify.get_title(),
"tooltip": f'{spotify.get_artist()} - {spotify.get_title()}'
}
)
if spotify.props.status == "Playing":
jdata.print({"icon": PLAY_ICON})
else:
jdata.print({"icon": PAUSE_ICON})
else:
jdata.print({"text": "", "percentage": 0})
main = GLib.MainLoop()
main.run()
def play_pause():
if spotify := get_spotify():
spotify.play_pause()
def next():
if spotify := get_spotify():
spotify.next()
def previous():
if spotify := get_spotify():
spotify.previous()
if args.main_loop:
try:
main_loop()
except KeyboardInterrupt:
exit(0)
exit(1)
if args.play_pause:
play_pause()
exit(0)
if args.next:
next()
exit(0)
if args.previous:
previous()
exit(0)