diff --git a/README.md b/README.md index f9fe08c..417784b 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,10 @@ Discord can display up to 2 buttons in your Rich Presence. Due to a strange Discord bug, these buttons may be unresponsive or exhibit strange behaviour towards your own clicks, but other users are able to click on them to open their corresponding URLs. +#### Dynamic Button Labels + +Instances of `{title}` in button labels will be replaced with the top-level title of the media being played. + #### Dynamic Button URLs During runtime, the following dynamic URL placeholders will get replaced with real URLs based on the media being played: @@ -92,7 +96,7 @@ display: imgurClientID: 9e9sf637S8bRp4z maxSize: 256 buttons: - - label: IMDb + - label: '{title} on IMDb' url: dynamic:imdb - label: Music Stats url: https://github.com diff --git a/core/plex.py b/core/plex.py index eb468ff..7082c7e 100644 --- a/core/plex.py +++ b/core/plex.py @@ -11,7 +11,7 @@ from plexapi.myplex import MyPlexAccount, PlexServer from typing import Optional from utils.cache import getCacheKey, setCacheKey from utils.logging import LoggerWithPrefix -from utils.text import formatSeconds +from utils.text import formatSeconds, truncate import models.config import models.discord import models.plex @@ -131,8 +131,9 @@ class PlexAlertListener(threading.Thread): def connectionCheck(self) -> None: try: + self.logger.debug("Running periodic connection check") assert self.server - self.logger.debug("Request for list of clients to check connection: %s", self.server.clients()) + self.server.clients() except Exception as e: self.reconnect(e) else: @@ -220,7 +221,7 @@ class PlexAlertListener(threading.Thread): if not config["display"]["hideTotalTime"] and item.duration and mediaType != "track": stateStrings.append(formatSeconds(item.duration / 1000)) if mediaType == "movie": - title = item.title + title = shortTitle = item.title if item.year: title += f" ({item.year})" if item.genres: @@ -229,19 +230,22 @@ class PlexAlertListener(threading.Thread): largeText = "Watching a movie" thumb = item.thumb elif mediaType == "episode": - title = item.grandparentTitle + title = shortTitle = item.grandparentTitle + grandparent = self.server.fetchItem(item.grandparentRatingKey) + if grandparent.year: + title += f" ({grandparent.year})" stateStrings.append(f"S{item.parentIndex:02}E{item.index:02}") stateStrings.append(item.title) largeText = "Watching a TV show" thumb = item.grandparentThumb elif mediaType == "livetv": - title = item.grandparentTitle + title = shortTitle = item.grandparentTitle if item.title != item.grandparentTitle: stateStrings.append(item.title) largeText = "Watching live TV" thumb = item.grandparentThumb elif mediaType == "track": - title = item.title + title = shortTitle = item.title artistAlbum = f"{item.originalTitle or item.grandparentTitle} - {item.parentTitle}" parent = self.server.fetchItem(item.parentRatingKey) if parent.year: @@ -250,7 +254,7 @@ class PlexAlertListener(threading.Thread): largeText = "Listening to music" thumb = item.thumb else: - title = item.title + title = shortTitle = item.title largeText = "Watching a video" thumb = item.thumb if state != "playing" and mediaType != "track": @@ -267,7 +271,7 @@ class PlexAlertListener(threading.Thread): thumbUrl = uploadToImgur(self.server.url(thumb, True), config["display"]["posters"]["maxSize"]) setCacheKey(thumb, thumbUrl) activity: models.discord.Activity = { - "details": title[:128], + "details": truncate(title, 128), "assets": { "large_text": largeText, "large_image": thumbUrl or "logo", @@ -276,7 +280,7 @@ class PlexAlertListener(threading.Thread): }, } if stateText: - activity["state"] = stateText[:128] + activity["state"] = truncate(stateText, 128) if config["display"]["buttons"]: guidsRaw: list[Guid] = [] if mediaType in ["movie", "track"]: @@ -288,8 +292,9 @@ class PlexAlertListener(threading.Thread): for button in config["display"]["buttons"]: if "mediaTypes" in button and mediaType not in button["mediaTypes"]: continue + label = truncate(button["label"].format(title = shortTitle), 32) if not button["url"].startswith("dynamic:"): - buttons.append({ "label": button["label"], "url": button["url"] }) + buttons.append({ "label": label, "url": button["url"] }) continue buttonType = button["url"][8:] guidType = buttonTypeGuidTypeMap.get(buttonType) @@ -315,7 +320,7 @@ class PlexAlertListener(threading.Thread): elif buttonType == "musicbrainz": url = f"https://musicbrainz.org/track/{guid}" if url: - buttons.append({ "label": button["label"], "url": url }) + buttons.append({ "label": label, "url": url }) if buttons: activity["buttons"] = buttons[:2] if state == "playing": diff --git a/utils/text.py b/utils/text.py index 961ca5e..3b4f726 100644 --- a/utils/text.py +++ b/utils/text.py @@ -8,3 +8,8 @@ def formatSeconds(seconds: int | float, joiner: Optional[str] = None) -> str: if timeValues["h"] == 0: del timeValues["h"] return joiner.join(str(v).rjust(2, "0") for v in timeValues.values()) + +def truncate(text: str, maxLength: int) -> str: + if len(text) > maxLength: + text = text[:maxLength-3] + "..." + return text