mirror of
https://github.com/phin05/discord-rich-presence-plex
synced 2024-11-22 01:23:02 +00:00
Added Plex authorisation flow to retrieve token
This commit is contained in:
parent
86d59fa16a
commit
8a29fb5aff
6 changed files with 48 additions and 26 deletions
|
@ -11,7 +11,7 @@ A Python script that displays your [Plex](https://www.plex.tv) status on [Discor
|
|||
5. Install the required Python modules by running `python -m pip install -r requirements.txt`
|
||||
6. Start the script by running `python main.py`
|
||||
|
||||
When the script runs for the first time, a `config.json` file will be created in the working directory and you will be prompted to complete the authentication flow to allow the script to retrieve your username and an access token.
|
||||
When the script runs for the first time, a `config.json` file will be created in the working directory and you will be prompted to complete the authentication flow to allow the script to retrieve an access token for your Plex account.
|
||||
|
||||
The script must be running on the same machine as your Discord client.
|
||||
|
||||
|
@ -24,10 +24,9 @@ The script must be running on the same machine as your Discord client.
|
|||
* `display`
|
||||
* `useRemainingTime` - Display remaining time in your Rich Presence instead of elapsed time
|
||||
* `users` (list)
|
||||
* `username` - Username or e-mail
|
||||
* `token` - A [X-Plex-Token](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token)
|
||||
* `servers` (list)
|
||||
* `name` - Friendly name of the Plex Media Server you wish to connect to.
|
||||
* `name` - Name of the Plex Media Server you wish to connect to.
|
||||
* `blacklistedLibraries` (optional list) - Alerts originating from libraries in this list are ignored.
|
||||
* `whitelistedLibraries` (optional list) - If set, alerts originating from libraries that are not in this list are ignored.
|
||||
|
||||
|
@ -43,7 +42,6 @@ The script must be running on the same machine as your Discord client.
|
|||
},
|
||||
"users": [
|
||||
{
|
||||
"username": "bob",
|
||||
"token": "HPbrz2NhfLRjU888Rrdt",
|
||||
"servers": [
|
||||
{
|
||||
|
@ -68,4 +66,5 @@ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file
|
|||
* [Discord](https://discord.com)
|
||||
* [Plex](https://www.plex.tv)
|
||||
* [plexapi](https://github.com/pkkid/python-plexapi)
|
||||
* [requests](https://github.com/psf/requests)
|
||||
* [websocket-client](https://github.com/websocket-client/websocket-client)
|
||||
|
|
33
main.py
33
main.py
|
@ -1,28 +1,49 @@
|
|||
from services import ConfigService, PlexAlertListener
|
||||
from store.constants import isUnix
|
||||
from store.constants import isUnix, name, plexClientID, version
|
||||
from utils.logs import logger
|
||||
import logging
|
||||
import os
|
||||
import requests
|
||||
import time
|
||||
import urllib.parse
|
||||
|
||||
os.system("clear" if isUnix else "cls")
|
||||
|
||||
logger.info("%s - v%s", name, version)
|
||||
configService = ConfigService("config.json")
|
||||
config = configService.config
|
||||
|
||||
if config["logging"]["debug"]:
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
PlexAlertListener.useRemainingTime = config["display"]["useRemainingTime"]
|
||||
|
||||
if len(config["users"]) == 0:
|
||||
logger.info("No users found in the config file. Initiating authorisation flow. ! TBD !") # TODO
|
||||
logger.info("No users found in the config file. Initiating authorisation flow.")
|
||||
response = requests.post("https://plex.tv/api/v2/pins.json?strong=true", headers = {
|
||||
"X-Plex-Product": name,
|
||||
"X-Plex-Client-Identifier": plexClientID,
|
||||
}).json()
|
||||
logger.info("Open the below URL in your web browser and sign in:")
|
||||
logger.info("https://app.plex.tv/auth#?clientID=%s&code=%s&context%%5Bdevice%%5D%%5Bproduct%%5D=%s", plexClientID, response["code"], urllib.parse.quote(name))
|
||||
for _ in range(10):
|
||||
time.sleep(5)
|
||||
logger.info("Checking whether authorisation was successful...")
|
||||
authCheckResponse = requests.get(f"https://plex.tv/api/v2/pins/{response['id']}.json?code={response['code']}", headers = {
|
||||
"X-Plex-Client-Identifier": plexClientID,
|
||||
}).json()
|
||||
if authCheckResponse["authToken"]:
|
||||
logger.info("Authorisation successful.")
|
||||
serverName = input("Enter the name of the Plex Media Server you wish to connect to: ")
|
||||
config["users"].append({ "token": authCheckResponse["authToken"], "servers": [{ "name": serverName }] })
|
||||
configService.saveConfig()
|
||||
break
|
||||
else:
|
||||
logger.info("Authorisation failed.")
|
||||
exit()
|
||||
|
||||
plexAlertListeners: list[PlexAlertListener] = []
|
||||
try:
|
||||
for user in config["users"]:
|
||||
for server in user["servers"]:
|
||||
plexAlertListeners.append(PlexAlertListener(user["username"], user["token"], server))
|
||||
plexAlertListeners.append(PlexAlertListener(user["token"], server))
|
||||
while True:
|
||||
userInput = input()
|
||||
if userInput in ["exit", "quit"]:
|
||||
|
|
|
@ -6,13 +6,12 @@ class Logging(TypedDict):
|
|||
class Display(TypedDict):
|
||||
useRemainingTime: bool
|
||||
|
||||
class Server(TypedDict):
|
||||
class Server(TypedDict, total = False):
|
||||
name: str
|
||||
blacklistedLibraries: list[str]
|
||||
whitelistedLibraries: list[str]
|
||||
|
||||
class User(TypedDict):
|
||||
username: str
|
||||
token: str
|
||||
servers: list[Server]
|
||||
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
plexapi
|
||||
requests
|
||||
websocket-client
|
||||
|
|
|
@ -17,8 +17,7 @@ class PlexAlertListener:
|
|||
maximumIgnores = 2
|
||||
useRemainingTime = False
|
||||
|
||||
def __init__(self, username, token, serverConfig):
|
||||
self.username = username
|
||||
def __init__(self, token, serverConfig):
|
||||
self.token = token
|
||||
self.serverConfig = serverConfig
|
||||
self.logger = LoggerWithPrefix(f"[{self.serverConfig['name']}/{hashlib.md5(str(id(self)).encode('UTF-8')).hexdigest()[:5].upper()}] ")
|
||||
|
@ -33,20 +32,20 @@ class PlexAlertListener:
|
|||
self.plexServer = None
|
||||
self.isServerOwner = False
|
||||
self.plexAlertListener = None
|
||||
self.lastState = None
|
||||
self.lastSessionKey = None
|
||||
self.lastRatingKey = None
|
||||
self.lastState = ""
|
||||
self.lastSessionKey = 0
|
||||
self.lastRatingKey = 0
|
||||
self.ignoreCount = 0
|
||||
|
||||
def connect(self):
|
||||
connected = False
|
||||
while not connected:
|
||||
try:
|
||||
self.plexAccount = MyPlexAccount(self.username, token = self.token)
|
||||
self.plexAccount = MyPlexAccount(token = self.token)
|
||||
self.logger.info("Logged in as Plex User \"%s\"", self.plexAccount.username)
|
||||
self.plexServer = None
|
||||
for resource in self.plexAccount.resources():
|
||||
if resource.product == self.productName and resource.name == self.serverConfig["name"]:
|
||||
if resource.product == self.productName and resource.name.lower() == self.serverConfig["name"].lower():
|
||||
self.logger.info("Connecting to %s \"%s\"", self.productName, self.serverConfig["name"])
|
||||
self.plexServer = resource.connect()
|
||||
try:
|
||||
|
@ -54,10 +53,10 @@ class PlexAlertListener:
|
|||
self.isServerOwner = True
|
||||
except:
|
||||
pass
|
||||
self.logger.info("Connected to %s \"%s\"", self.productName, self.serverConfig["name"])
|
||||
self.logger.info("Connected to %s \"%s\"", self.productName, resource.name)
|
||||
self.plexAlertListener = AlertListener(self.plexServer, self.handlePlexAlert, self.reconnect)
|
||||
self.plexAlertListener.start()
|
||||
self.logger.info("Listening for alerts from user \"%s\"", self.username)
|
||||
self.logger.info("Listening for alerts from user \"%s\"", self.plexAccount.username)
|
||||
self.connectionTimeoutTimer = threading.Timer(self.connectionTimeoutTimerInterval, self.connectionTimeout)
|
||||
self.connectionTimeoutTimer.start()
|
||||
connected = True
|
||||
|
@ -156,11 +155,11 @@ class PlexAlertListener:
|
|||
if session.sessionKey == sessionKey:
|
||||
self.logger.debug("Session found")
|
||||
sessionUsername = session.usernames[0].lower()
|
||||
if sessionUsername == self.username:
|
||||
self.logger.debug("Username \"%s\" matches \"%s\", continuing", sessionUsername, self.username)
|
||||
if sessionUsername == self.plexAccount.username:
|
||||
self.logger.debug("Username \"%s\" matches \"%s\", continuing", sessionUsername, self.plexAccount.username)
|
||||
break
|
||||
else:
|
||||
self.logger.debug("Username \"%s\" doesn't match \"%s\", ignoring", sessionUsername, self.username)
|
||||
self.logger.debug("Username \"%s\" doesn't match \"%s\", ignoring", sessionUsername, self.plexAccount.username)
|
||||
return
|
||||
else:
|
||||
self.logger.debug("No matching session found, ignoring")
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import sys
|
||||
import os
|
||||
|
||||
name = "Discord Rich Presence for Plex"
|
||||
version = "2.0.0"
|
||||
plexClientID = "discord-rich-presence-plex"
|
||||
isUnix = sys.platform in ["linux", "darwin"]
|
||||
processID = os.getpid()
|
||||
|
|
Loading…
Reference in a new issue