mirror of
https://github.com/phin05/discord-rich-presence-plex
synced 2024-11-25 02:50:17 +00:00
Added support for buttons in Rich Presence
This commit is contained in:
parent
f6ca9fc7e7
commit
510db5f0dc
6 changed files with 73 additions and 6 deletions
31
README.md
31
README.md
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
A Python script that displays your [Plex](https://www.plex.tv) status on [Discord](https://discord.com) using [Rich Presence](https://discord.com/developers/docs/rich-presence/how-to).
|
A Python script that displays your [Plex](https://www.plex.tv) status on [Discord](https://discord.com) using [Rich Presence](https://discord.com/developers/docs/rich-presence/how-to).
|
||||||
|
|
||||||
Current Version: 2.2.5
|
Current Version: 2.3.0
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
|
@ -30,9 +30,12 @@ The script must be running on the same machine as your Discord client.
|
||||||
* `useRemainingTime` (boolean, default: `false`) - Displays your media's remaining time instead of elapsed time in your Rich Presence if enabled.
|
* `useRemainingTime` (boolean, default: `false`) - Displays your media's remaining time instead of elapsed time in your Rich Presence if enabled.
|
||||||
* `posters`
|
* `posters`
|
||||||
* `enabled` (boolean, default: `false`) - Displays media posters in Rich Presence if enabled. Requires `imgurClientID`.
|
* `enabled` (boolean, default: `false`) - Displays media posters in Rich Presence if enabled. Requires `imgurClientID`.
|
||||||
* `imgurClientID` (string, default: `""`) - [Instructions](#obtaining-an-imgur-client-id)
|
* `imgurClientID` (string, default: `""`) - [Obtention Instructions](#obtaining-an-imgur-client-id)
|
||||||
|
* `buttons` (list) - [Information](#buttons)
|
||||||
|
* `label` (string) - The label to be displayed on the button.
|
||||||
|
* `url` (string) - A web address or a [dynamic URL placeholder](#dynamic-button-urls).
|
||||||
* `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)
|
||||||
* `name` (string) - Name of the Plex Media Server you wish to connect to.
|
* `name` (string) - Name of the Plex Media Server you wish to connect to.
|
||||||
* `listenForUser` (string, optional) - The script will respond to alerts originating only from this username. Defaults to the parent user's username if not set.
|
* `listenForUser` (string, optional) - The script will respond to alerts originating only from this username. Defaults to the parent user's username if not set.
|
||||||
|
@ -45,6 +48,18 @@ The script must be running on the same machine as your Discord client.
|
||||||
2. Enter any name for the application and pick OAuth2 without a callback URL as the authorisation type
|
2. Enter any name for the application and pick OAuth2 without a callback URL as the authorisation type
|
||||||
3. Submit the form to obtain your application's client ID
|
3. Submit the form to obtain your application's client ID
|
||||||
|
|
||||||
|
### Buttons
|
||||||
|
|
||||||
|
A maximum of 2 buttons can be displayed in your Rich Presence.
|
||||||
|
|
||||||
|
Due to a strange Discord bug, buttons displayed in your Rich Presence are unresponsive to your own clicks, but other users are able to click on them to open their corresponding URLs.
|
||||||
|
|
||||||
|
#### Dynamic Button URLs
|
||||||
|
|
||||||
|
During runtime, the following dynamic URL placeholders will get replaced with real URLs based on the media being played:
|
||||||
|
* `dynamic:imdb`
|
||||||
|
* `dynamic:tmdb`
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
@ -58,7 +73,17 @@ The script must be running on the same machine as your Discord client.
|
||||||
"posters": {
|
"posters": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"imgurClientID": "9e9sf637S8bRp4z"
|
"imgurClientID": "9e9sf637S8bRp4z"
|
||||||
|
},
|
||||||
|
"buttons": [
|
||||||
|
{
|
||||||
|
"label": "IMDb Link",
|
||||||
|
"url": "dynamic:imdb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "My YouTube Channel",
|
||||||
|
"url": "https://www.youtube.com/"
|
||||||
}
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"users": [
|
"users": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,9 +8,14 @@ class Posters(TypedDict):
|
||||||
enabled: bool
|
enabled: bool
|
||||||
imgurClientID: str
|
imgurClientID: str
|
||||||
|
|
||||||
|
class Button(TypedDict):
|
||||||
|
label: str
|
||||||
|
url: str
|
||||||
|
|
||||||
class Display(TypedDict):
|
class Display(TypedDict):
|
||||||
useRemainingTime: bool
|
useRemainingTime: bool
|
||||||
posters: Posters
|
posters: Posters
|
||||||
|
buttons: list[Button]
|
||||||
|
|
||||||
class Server(TypedDict, total = False):
|
class Server(TypedDict, total = False):
|
||||||
name: str
|
name: str
|
||||||
|
|
|
@ -10,8 +10,13 @@ class ActivityTimestamps(TypedDict, total = False):
|
||||||
start: int
|
start: int
|
||||||
end: int
|
end: int
|
||||||
|
|
||||||
|
class ActivityButton(TypedDict):
|
||||||
|
label: str
|
||||||
|
url: str
|
||||||
|
|
||||||
class Activity(TypedDict, total = False):
|
class Activity(TypedDict, total = False):
|
||||||
details: str
|
details: str
|
||||||
state: str
|
state: str
|
||||||
assets: ActivityAssets
|
assets: ActivityAssets
|
||||||
timestamps: ActivityTimestamps
|
timestamps: ActivityTimestamps
|
||||||
|
buttons: list[ActivityButton]
|
||||||
|
|
|
@ -6,6 +6,7 @@ from .config import config
|
||||||
from .imgur import uploadImage
|
from .imgur import uploadImage
|
||||||
from plexapi.alert import AlertListener
|
from plexapi.alert import AlertListener
|
||||||
from plexapi.base import Playable, PlexPartialObject
|
from plexapi.base import Playable, PlexPartialObject
|
||||||
|
from plexapi.media import Genre, GuidTag
|
||||||
from plexapi.myplex import MyPlexAccount, PlexServer
|
from plexapi.myplex import MyPlexAccount, PlexServer
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from utils.logging import LoggerWithPrefix
|
from utils.logging import LoggerWithPrefix
|
||||||
|
@ -183,7 +184,8 @@ class PlexAlertListener(threading.Thread):
|
||||||
stateStrings: list[str] = [formatSeconds(item.duration / 1000)]
|
stateStrings: list[str] = [formatSeconds(item.duration / 1000)]
|
||||||
if mediaType == "movie":
|
if mediaType == "movie":
|
||||||
title = f"{item.title} ({item.year})"
|
title = f"{item.title} ({item.year})"
|
||||||
stateStrings.append(f"{', '.join(genre.tag for genre in item.genres[:3])}")
|
genres: list[Genre] = item.genres[:3]
|
||||||
|
stateStrings.append(f"{', '.join(genre.tag for genre in genres)}")
|
||||||
largeText = "Watching a movie"
|
largeText = "Watching a movie"
|
||||||
thumb = item.thumb
|
thumb = item.thumb
|
||||||
else:
|
else:
|
||||||
|
@ -220,6 +222,35 @@ class PlexAlertListener(threading.Thread):
|
||||||
"small_image": state,
|
"small_image": state,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if config["display"]["buttons"]:
|
||||||
|
guidTags: list[GuidTag] = []
|
||||||
|
if mediaType == "movie":
|
||||||
|
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] = []
|
||||||
|
for button in config["display"]["buttons"]:
|
||||||
|
if button["url"].startswith("dynamic:"):
|
||||||
|
if guids:
|
||||||
|
newUrl = button["url"]
|
||||||
|
if button["url"] == "dynamic:imdb":
|
||||||
|
for guid in guids:
|
||||||
|
if guid.startswith("imdb://"):
|
||||||
|
newUrl = guid.replace("imdb://", "https://www.imdb.com/title/")
|
||||||
|
break
|
||||||
|
elif button["url"] == "dynamic:tmdb":
|
||||||
|
for guid in guids:
|
||||||
|
if guid.startswith("tmdb://"):
|
||||||
|
tmdbPathSegment = "movie" if mediaType == "movie" else "tv"
|
||||||
|
newUrl = guid.replace("tmdb://", f"https://www.themoviedb.org/{tmdbPathSegment}/")
|
||||||
|
break
|
||||||
|
if newUrl:
|
||||||
|
buttons.append({ "label": button["label"], "url": newUrl })
|
||||||
|
else:
|
||||||
|
buttons.append(button)
|
||||||
|
if buttons:
|
||||||
|
activity["buttons"] = buttons[:2]
|
||||||
if state == "playing":
|
if state == "playing":
|
||||||
currentTimestamp = int(time.time())
|
currentTimestamp = int(time.time())
|
||||||
if config["display"]["useRemainingTime"]:
|
if config["display"]["useRemainingTime"]:
|
||||||
|
|
|
@ -17,6 +17,7 @@ config: models.config.Config = {
|
||||||
"enabled": False,
|
"enabled": False,
|
||||||
"imgurClientID": "",
|
"imgurClientID": "",
|
||||||
},
|
},
|
||||||
|
"buttons": [],
|
||||||
},
|
},
|
||||||
"users": [],
|
"users": [],
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
name = "Discord Rich Presence for Plex"
|
name = "Discord Rich Presence for Plex"
|
||||||
version = "2.2.5"
|
version = "2.3.0"
|
||||||
|
|
||||||
plexClientID = "discord-rich-presence-plex"
|
plexClientID = "discord-rich-presence-plex"
|
||||||
discordClientID = "413407336082833418"
|
discordClientID = "413407336082833418"
|
||||||
|
|
Loading…
Reference in a new issue