Added more dynamic button URL placeholders

This commit is contained in:
Phin 2024-02-11 01:50:56 +05:30
parent 31e9628f26
commit eeeb680877
3 changed files with 54 additions and 88 deletions

View file

@ -45,6 +45,7 @@ The config file is stored in a directory named `data`.
* `buttons` (list) - [Information](#buttons) * `buttons` (list) - [Information](#buttons)
* `label` (string) - The label to be displayed on the button. * `label` (string) - The label to be displayed on the button.
* `url` (string) - A web address or a [dynamic URL placeholder](#dynamic-button-urls). * `url` (string) - A web address or a [dynamic URL placeholder](#dynamic-button-urls).
* `mediaTypes` (list, optional) - If set, the button is displayed only for the specified media types. Valid media types are `movie`, `episode` and `track`.
* `users` (list) * `users` (list)
* `token` (string) - An access token associated with your Plex account. ([X-Plex-Token](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/), [Authenticating with Plex](https://forums.plex.tv/t/authenticating-with-plex/609370)) * `token` (string) - An access token associated with your Plex account. ([X-Plex-Token](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/), [Authenticating with Plex](https://forums.plex.tv/t/authenticating-with-plex/609370))
* `servers` (list) * `servers` (list)
@ -69,16 +70,15 @@ Due to a strange Discord bug, these buttons may be unresponsive or exhibit stran
#### Dynamic Button URLs #### Dynamic Button URLs
During runtime, the following dynamic URL placeholders will get replaced with real URLs based on the media being played: During runtime, the following dynamic URL placeholders will get replaced with real URLs based on the media being played:
* `dynamic:imdb` * `dynamic:imdb`
* `dynamic:tmdb` * `dynamic:tmdb`
* `dynamic:thetvdb`
* `dynamic:trakt`
* `dynamic:letterboxd`
* `dynamic:musicbrainz`
### Example ### Example (YAML)
<details>
<summary>YAML</summary>
<br />
```yaml ```yaml
logging: logging:
@ -94,8 +94,10 @@ display:
buttons: buttons:
- label: IMDb - label: IMDb
url: dynamic:imdb url: dynamic:imdb
- label: My YouTube Channel - label: Music Stats
url: https://www.youtube.com/channel/me url: https://github.com
mediaTypes:
- track
users: users:
- token: HPbrz2NhfLRjU888Rrdt - token: HPbrz2NhfLRjU888Rrdt
servers: servers:
@ -105,60 +107,6 @@ users:
- Movies - Movies
``` ```
</details>
<details>
<summary>JSON</summary>
<br />
```json
{
"logging": {
"debug": true,
"writeToFile": false
},
"display": {
"hideTotalTime": false,
"useRemainingTime": false,
"posters": {
"enabled": true,
"imgurClientID": "9e9sf637S8bRp4z",
"maxSize": 256
},
"buttons": [
{
"label": "IMDb",
"url": "dynamic:imdb"
},
{
"label": "My YouTube Channel",
"url": "https://www.youtube.com/channel/me"
}
]
},
"users": [
{
"token": "HPbrz2NhfLRjU888Rrdt",
"servers": [
{
"name": "Bob's Home Media Server"
},
{
"name": "A Friend's Server",
"whitelistedLibraries": [
"Movies"
]
}
]
}
]
}
```
</details>
## Configuration - Discord ## Configuration - Discord
The "Display current activity as a status message" setting must be enabled in Discord Settings → Activity Settings → Activity Privacy. The "Display current activity as a status message" setting must be enabled in Discord Settings → Activity Settings → Activity Privacy.
@ -168,7 +116,7 @@ The "Display current activity as a status message" setting must be enabled in Di
## Configuration - Environment Variables ## Configuration - Environment Variables
* `DRPP_PLEX_SERVER_NAME_INPUT` - This is used only during the initial setup (when there are no users in the config) as the name of the Plex server to be added to the config file after user authentication. If this isn't set, in interactive environments, the user is prompted for an input, and in non-interactive environments, "ServerName" is used as a placeholder, which can later be changed by editing the config file and restarting the script. * `DRPP_PLEX_SERVER_NAME_INPUT` - This is used only during the initial setup (when there are no users in the config) as the name of the Plex server to be added to the config file after user authentication. If this isn't set, in interactive environments, the user is prompted for an input, and in non-interactive environments, "ServerName" is used as a placeholder, which can later be changed by editing the config file and restarting the script.
* `DRPP_NO_PIP_INSTALL` - Automatic invocation of pip to install missing dependencies is skipped if this is set to `true`. * `DRPP_NO_PIP_INSTALL` - Set this to `true` to skip automatic invocation of pip on script startup to install missing dependencies.
## Run with Docker ## Run with Docker

View file

@ -34,6 +34,15 @@ def getAuthToken(id: str, code: str) -> Optional[str]:
}).json() }).json()
return response["authToken"] return response["authToken"]
buttonTypeGuidTypeMap = {
"imdb": "imdb",
"tmdb": "tmdb",
"thetvdb": "tvdb",
"trakt": "tmdb",
"letterboxd": "tmdb",
"musicbrainz": "mbid",
}
class PlexAlertListener(threading.Thread): class PlexAlertListener(threading.Thread):
productName = "Plex Media Server" productName = "Plex Media Server"
@ -242,32 +251,40 @@ class PlexAlertListener(threading.Thread):
}, },
} }
if config["display"]["buttons"]: if config["display"]["buttons"]:
guidTags: list[Guid] = [] guidsRaw: list[Guid] = item.guids if mediaType in ["movie", "track"] else self.server.fetchItem(item.grandparentRatingKey).guids
if mediaType == "movie": guids: dict[str, str] = { guidSplit[0]: guidSplit[1] for guidSplit in [guid.id.split("://") for guid in guidsRaw] if len(guidSplit) > 1 }
guidTags = item.guids
elif mediaType == "episode":
guidTags = self.server.fetchItem(item.grandparentRatingKey).guids
guids: list[str] = [guid.id for guid in guidTags]
buttons: list[models.discord.ActivityButton] = [] buttons: list[models.discord.ActivityButton] = []
for button in config["display"]["buttons"]: for button in config["display"]["buttons"]:
if button["url"].startswith("dynamic:"): if "mediaTypes" in button and mediaType not in button["mediaTypes"]:
if guids: continue
newUrl = button["url"] if not button["url"].startswith("dynamic:"):
if button["url"] == "dynamic:imdb": buttons.append({ "label": button["label"], "url": button["url"] })
for guid in guids: continue
if guid.startswith("imdb://"): buttonType = button["url"][8:]
newUrl = guid.replace("imdb://", "https://www.imdb.com/title/") guidType = buttonTypeGuidTypeMap.get(buttonType)
break if not guidType:
elif button["url"] == "dynamic:tmdb": continue
for guid in guids: guid = guids.get(guidType)
if guid.startswith("tmdb://"): if not guid:
tmdbPathSegment = "movie" if mediaType == "movie" else "tv" continue
newUrl = guid.replace("tmdb://", f"https://www.themoviedb.org/{tmdbPathSegment}/") url = ""
break if buttonType == "imdb":
if newUrl: url = f"https://www.imdb.com/title/{guid}"
buttons.append({ "label": button["label"], "url": newUrl }) elif buttonType == "tmdb":
else: tmdbPathSegment = "movie" if mediaType == "movie" else "tv"
buttons.append(button) url = f"https://www.themoviedb.org/{tmdbPathSegment}/{guid}"
elif buttonType == "thetvdb":
theTvdbPathSegment = "movie" if mediaType == "movie" else "series"
url = f"https://www.thetvdb.com/dereferrer/{theTvdbPathSegment}/{guid}"
elif buttonType == "trakt":
idType = "movie" if mediaType == "movie" else "show"
url = f"https://trakt.tv/search/tmdb/{guid}?id_type={idType}"
elif buttonType == "letterboxd" and mediaType == "movie":
url = f"https://letterboxd.com/tmdb/{guid}"
elif buttonType == "musicbrainz":
url = f"https://musicbrainz.org/track/{guid}"
if url:
buttons.append({ "label": button["label"], "url": url })
if buttons: if buttons:
activity["buttons"] = buttons[:2] activity["buttons"] = buttons[:2]
if state == "playing": if state == "playing":

View file

@ -12,6 +12,7 @@ class Posters(TypedDict):
class Button(TypedDict): class Button(TypedDict):
label: str label: str
url: str url: str
mediaTypes: list[str]
class Display(TypedDict): class Display(TypedDict):
hideTotalTime: bool hideTotalTime: bool