Skip to content

Commit

Permalink
playerctl, spotify: add self.py3.replace helper
Browse files Browse the repository at this point in the history
  • Loading branch information
lasers committed Dec 23, 2024
1 parent 4feb55b commit 80523e4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 68 deletions.
10 changes: 9 additions & 1 deletion py3status/modules/playerctl.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
r"""
Display song/video and control players supported by playerctl
Playerctl is a command-line utility for controlling media players
Playerctl is a command-line utility for controlling media players
that implement the MPRIS D-Bus Interface Specification. With Playerctl
you can bind player actions to keys and get metadata about the currently
playing song or video.
Expand All @@ -25,6 +25,7 @@
'[\?if=status=Stopped .. ][[{artist}][\?soft - ][{title}|{player}]]]')*
format_player_separator: show separator if more than one player (default ' ')
players: list of players to track. An empty list tracks all players (default [])
replacements: specify a list/dict of string placeholders to modify (default None)
seek_delta: time (in seconds) to change the playback's position by (default 5)
thresholds: specify color thresholds to use for different placeholders
(default {"status": [("Playing", "good"), ("Paused", "degraded"), ("Stopped", "bad")]})
Expand Down Expand Up @@ -100,6 +101,7 @@ class Py3status:
)
format_player_separator = " "
players = []
replacements = None
seek_delta = 5
thresholds = {"status": [("Playing", "good"), ("Paused", "degraded"), ("Stopped", "bad")]}
volume_delta = 10
Expand All @@ -117,6 +119,7 @@ class Meta:

def post_config_hook(self):
self.thresholds_init = self.py3.get_color_names_list(self.format_player)
self.replacements_init = self.py3.get_replacements_list(self.format_player)
self.position = self.py3.format_contains(self.format_player, "position")
self.cache_timeout = getattr(self, "cache_timeout", 1)

Expand Down Expand Up @@ -283,6 +286,11 @@ def playerctl(self):
if self.position and player_data["status"] == "Playing" and player_data["position"]:
cached_until = self.cache_timeout

# Replace the values
for x in self.replacements_init:
if x in player_data:
player_data[x] = self.py3.replace(player_data[x], x)

# Set the color of a player
for key in self.thresholds_init:
if key in player_data:
Expand Down
91 changes: 24 additions & 67 deletions py3status/modules/spotify.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@
(default 'Spotify not running')
format_stopped: define output if spotify is not playing
(default 'Spotify stopped')
sanitize_titles: whether to remove meta data from album/track title
(default True)
sanitize_words: which meta data to remove
*(default ['bonus', 'demo', 'edit', 'explicit', 'extended',
'feat', 'mono', 'remaster', 'stereo', 'version'])*
replacements: specify a list/dict of string placeholders to modify
(default None)
Format placeholders:
{album} album name
Expand All @@ -45,6 +42,12 @@
button_previous = 5
format = "{title} by {artist} -> {time}"
format_down = "no Spotify"
# sanitize
replacements = {
"album": [("\s?[\(\[\-,;/][^)\],;/]*?(bonus|demo|edit|explicit|extended|feat|mono|remaster|stereo|version)[^)\],;/]*[\)\]]?", "")],
"title": [("\s?[\(\[\-,;/][^)\],;/]*?(bonus|demo|edit|explicit|extended|feat|mono|remaster|stereo|version)[^)\],;/]*[\)\]]?", "")]
}
}
```
Expand All @@ -60,7 +63,6 @@
{'color': '#FF0000', 'full_text': 'Spotify stopped'}
"""

import re
from datetime import timedelta
from time import sleep

Expand All @@ -82,47 +84,11 @@ class Py3status:
format = "{artist} : {title}"
format_down = "Spotify not running"
format_stopped = "Spotify stopped"
sanitize_titles = True
sanitize_words = [
"bonus",
"demo",
"edit",
"explicit",
"extended",
"feat",
"mono",
"remaster",
"stereo",
"version",
]
replacements = None

def _spotify_cmd(self, action):
return SPOTIFY_CMD.format(dbus_client=self.dbus_client, cmd=action)

def post_config_hook(self):
""" """
# Match string after hyphen, comma, semicolon or slash containing any metadata word
# examples:
# - Remastered 2012
# / Radio Edit
# ; Remastered
self.after_delimiter = self._compile_re(r"([\-,;/])([^\-,;/])*(META_WORDS_HERE).*")

# Match brackets with their content containing any metadata word
# examples:
# (Remastered 2017)
# [Single]
# (Bonus Track)
self.inside_brackets = self._compile_re(r"([\(\[][^)\]]*?(META_WORDS_HERE)[^)\]]*?[\)\]])")

def _compile_re(self, expression):
"""
Compile given regular expression for current sanitize words
"""
meta_words = "|".join(self.sanitize_words)
expression = expression.replace("META_WORDS_HERE", meta_words)
return re.compile(expression, re.IGNORECASE)

def _get_playback_status(self):
"""
Get the playback status. One of: "Playing", "Paused" or "Stopped".
Expand All @@ -145,10 +111,6 @@ def _get_text(self):
microtime = metadata.get("mpris:length")
rtime = str(timedelta(seconds=microtime // 1_000_000))
title = metadata.get("xesam:title")
if self.sanitize_titles:
album = self._sanitize_title(album)
title = self._sanitize_title(title)

playback_status = self._get_playback_status()
if playback_status == "Playing":
color = self.py3.COLOR_PLAYING or self.py3.COLOR_GOOD
Expand All @@ -160,29 +122,24 @@ def _get_text(self):
self.py3.COLOR_PAUSED or self.py3.COLOR_DEGRADED,
)

return (
self.py3.safe_format(
self.format,
dict(
title=title,
artist=artist,
album=album,
time=rtime,
playback=playback_status,
),
),
color,
)
spotify_data = {
"title": title,
"artist": artist,
"album": album,
"time": rtime,
"playback": playback_status,
}

for x in self.replacements_init:
if x in spotify_data:
spotify_data[x] = self.py3.replace(spotify_data[x], x)

return (self.py3.safe_format(self.format, spotify_data), color)
except Exception:
return (self.format_down, self.py3.COLOR_OFFLINE or self.py3.COLOR_BAD)

def _sanitize_title(self, title):
"""
Remove redundant metadata from title and return it
"""
title = re.sub(self.inside_brackets, "", title)
title = re.sub(self.after_delimiter, "", title)
return title.strip()
def post_config_hook(self):
self.replacements_init = self.py3.get_replacements_list(self.format)

def spotify(self):
"""
Expand Down

0 comments on commit 80523e4

Please sign in to comment.