mirror of
https://github.com/phin05/discord-rich-presence-plex
synced 2024-11-10 13:04:18 +00:00
Improved automatic installation of dependencies
This commit is contained in:
parent
e819adb12f
commit
31e9628f26
4 changed files with 22 additions and 15 deletions
|
@ -7,4 +7,5 @@ COPY requirements.txt .
|
||||||
RUN pip install -U -r requirements.txt --no-cache-dir
|
RUN pip install -U -r requirements.txt --no-cache-dir
|
||||||
COPY . .
|
COPY . .
|
||||||
ENV DRPP_IS_IN_CONTAINER=true
|
ENV DRPP_IS_IN_CONTAINER=true
|
||||||
|
ENV DRPP_NO_PIP_INSTALL=true
|
||||||
ENTRYPOINT ["python", "main.py"]
|
ENTRYPOINT ["python", "main.py"]
|
||||||
|
|
16
README.md
16
README.md
|
@ -41,7 +41,7 @@ The config file is stored in a directory named `data`.
|
||||||
* `posters`
|
* `posters`
|
||||||
* `enabled` (boolean, default: `false`) - Displays media posters if enabled. Requires `imgurClientID`.
|
* `enabled` (boolean, default: `false`) - Displays media posters if enabled. Requires `imgurClientID`.
|
||||||
* `imgurClientID` (string, default: `""`) - [Obtention Instructions](#obtaining-an-imgur-client-id)
|
* `imgurClientID` (string, default: `""`) - [Obtention Instructions](#obtaining-an-imgur-client-id)
|
||||||
* `maxSize` (int, default: `256`)
|
* `maxSize` (int, default: `256`) - Maximum width and maximum height to use while downscaling posters before uploading them.
|
||||||
* `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).
|
||||||
|
@ -64,7 +64,7 @@ The config file is stored in a directory named `data`.
|
||||||
|
|
||||||
Discord can display up to 2 buttons in your Rich Presence.
|
Discord can display up to 2 buttons in your Rich Presence.
|
||||||
|
|
||||||
Due to a strange Discord bug, these buttons are unresponsive or exhibit strange behaviour towards your own clicks, but other users are able to click on them to open their corresponding URLs.
|
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 URLs
|
#### Dynamic Button URLs
|
||||||
|
|
||||||
|
@ -90,8 +90,9 @@ display:
|
||||||
posters:
|
posters:
|
||||||
enabled: true
|
enabled: true
|
||||||
imgurClientID: 9e9sf637S8bRp4z
|
imgurClientID: 9e9sf637S8bRp4z
|
||||||
|
maxSize: 256
|
||||||
buttons:
|
buttons:
|
||||||
- label: IMDb Link
|
- label: IMDb
|
||||||
url: dynamic:imdb
|
url: dynamic:imdb
|
||||||
- label: My YouTube Channel
|
- label: My YouTube Channel
|
||||||
url: https://www.youtube.com/channel/me
|
url: https://www.youtube.com/channel/me
|
||||||
|
@ -123,11 +124,12 @@ users:
|
||||||
"useRemainingTime": false,
|
"useRemainingTime": false,
|
||||||
"posters": {
|
"posters": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"imgurClientID": "9e9sf637S8bRp4z"
|
"imgurClientID": "9e9sf637S8bRp4z",
|
||||||
|
"maxSize": 256
|
||||||
},
|
},
|
||||||
"buttons": [
|
"buttons": [
|
||||||
{
|
{
|
||||||
"label": "IMDb Link",
|
"label": "IMDb",
|
||||||
"url": "dynamic:imdb"
|
"url": "dynamic:imdb"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -145,7 +147,6 @@ users:
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "A Friend's Server",
|
"name": "A Friend's Server",
|
||||||
"listenForUser": "xyz",
|
|
||||||
"whitelistedLibraries": [
|
"whitelistedLibraries": [
|
||||||
"Movies"
|
"Movies"
|
||||||
]
|
]
|
||||||
|
@ -167,6 +168,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`.
|
||||||
|
|
||||||
## Run with Docker
|
## Run with Docker
|
||||||
|
|
||||||
|
@ -247,7 +249,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ./kasmcord:/run/user/1000
|
- ./kasmcord:/run/user/1000
|
||||||
user: "0"
|
user: "0"
|
||||||
entrypoint: sh -c "chown -R kasm-user:kasm-user /run/user/1000 && su kasm-user -c '/dockerstartup/kasm_default_profile.sh /dockerstartup/vnc_startup.sh /dockerstartup/kasm_startup.sh'"
|
entrypoint: sh -c "chmod 700 /run/user/1000 && chown -R kasm-user:kasm-user /run/user/1000 && su kasm-user -c '/dockerstartup/kasm_default_profile.sh /dockerstartup/vnc_startup.sh /dockerstartup/kasm_startup.sh'"
|
||||||
drpp:
|
drpp:
|
||||||
container_name: drpp
|
container_name: drpp
|
||||||
image: ghcr.io/phin05/discord-rich-presence-plex:latest
|
image: ghcr.io/phin05/discord-rich-presence-plex:latest
|
||||||
|
|
|
@ -15,6 +15,7 @@ logFilePath = os.path.join(dataDirectoryPath, "console.log")
|
||||||
isUnix = sys.platform in ["linux", "darwin"]
|
isUnix = sys.platform in ["linux", "darwin"]
|
||||||
processID = os.getpid()
|
processID = os.getpid()
|
||||||
isInteractive = sys.stdin and sys.stdin.isatty()
|
isInteractive = sys.stdin and sys.stdin.isatty()
|
||||||
|
noPipInstall = os.environ.get("DRPP_NO_PIP_INSTALL", "") == "true"
|
||||||
isInContainer = os.environ.get("DRPP_IS_IN_CONTAINER", "") == "true"
|
isInContainer = os.environ.get("DRPP_IS_IN_CONTAINER", "") == "true"
|
||||||
runtimeDirectory = "/run/app" if isInContainer else os.environ.get("XDG_RUNTIME_DIR", os.environ.get("TMPDIR", os.environ.get("TMP", os.environ.get("TEMP", "/tmp"))))
|
runtimeDirectory = "/run/app" if isInContainer else os.environ.get("XDG_RUNTIME_DIR", os.environ.get("TMPDIR", os.environ.get("TMP", os.environ.get("TEMP", "/tmp"))))
|
||||||
ipcPipeBase = runtimeDirectory if isUnix else r"\\?\pipe"
|
ipcPipeBase = runtimeDirectory if isUnix else r"\\?\pipe"
|
||||||
|
|
19
main.py
19
main.py
|
@ -1,7 +1,6 @@
|
||||||
from config.constants import isInContainer, runtimeDirectory, uid, gid, containerCwd, noRuntimeDirChown
|
from config.constants import isInContainer, runtimeDirectory, uid, gid, containerCwd, noRuntimeDirChown
|
||||||
from utils.logging import logger
|
from utils.logging import logger
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
|
|
||||||
if isInContainer:
|
if isInContainer:
|
||||||
if not os.path.isdir(runtimeDirectory):
|
if not os.path.isdir(runtimeDirectory):
|
||||||
|
@ -23,20 +22,24 @@ if isInContainer:
|
||||||
os.setuid(uid) # pyright: ignore[reportAttributeAccessIssue,reportUnknownMemberType]
|
os.setuid(uid) # pyright: ignore[reportAttributeAccessIssue,reportUnknownMemberType]
|
||||||
else:
|
else:
|
||||||
logger.warning(f"Not running as the superuser. Manually ensure appropriate ownership of mounted contents")
|
logger.warning(f"Not running as the superuser. Manually ensure appropriate ownership of mounted contents")
|
||||||
else:
|
|
||||||
|
from config.constants import noPipInstall
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if not noPipInstall:
|
||||||
try:
|
try:
|
||||||
import subprocess
|
import subprocess
|
||||||
def parsePipPackages(packagesStr: str) -> dict[str, str]:
|
def parsePipPackages(packagesStr: str) -> dict[str, str]:
|
||||||
return { packageSplit[0]: packageSplit[1] if len(packageSplit) > 1 else "" for packageSplit in [package.split("==") for package in packagesStr.splitlines()] }
|
return { packageSplit[0].lower(): packageSplit[1] if len(packageSplit) > 1 else "" for packageSplit in [package.split("==") for package in packagesStr.splitlines()] }
|
||||||
pipFreezeResult = subprocess.run([sys.executable, "-m", "pip", "freeze"], stdout = subprocess.PIPE, text = True, check = True)
|
pipFreezeResult = subprocess.run([sys.executable, "-m", "pip", "freeze"], stdout = subprocess.PIPE, text = True, check = True)
|
||||||
installedPackages = parsePipPackages(pipFreezeResult.stdout)
|
installedPackages = parsePipPackages(pipFreezeResult.stdout)
|
||||||
with open("requirements.txt", "r", encoding = "UTF-8") as requirementsFile:
|
with open("requirements.txt", "r", encoding = "UTF-8") as requirementsFile:
|
||||||
requiredPackages = parsePipPackages(requirementsFile.read())
|
requiredPackages = parsePipPackages(requirementsFile.read())
|
||||||
for packageName, packageVersion in requiredPackages.items():
|
for packageName, requiredPackageVersion in requiredPackages.items():
|
||||||
if packageName not in installedPackages:
|
installedPackageVersion = installedPackages.get(packageName, "none")
|
||||||
package = f"{packageName}{f'=={packageVersion}' if packageVersion else ''}"
|
if installedPackageVersion != requiredPackageVersion:
|
||||||
logger.info(f"Installing missing dependency: {package}")
|
logger.info(f"Installing dependency: {packageName} (required: {requiredPackageVersion}, installed: {installedPackageVersion})")
|
||||||
subprocess.run([sys.executable, "-m", "pip", "install", "-U", package], check = True)
|
subprocess.run([sys.executable, "-m", "pip", "install", "-U", f"{packageName}=={requiredPackageVersion}"], check = True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("An unexpected error occured during automatic installation of dependencies. Install them manually by running the following command: python -m pip install -U -r requirements.txt")
|
logger.exception("An unexpected error occured during automatic installation of dependencies. Install them manually by running the following command: python -m pip install -U -r requirements.txt")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue