Skip to content

Commit 50ac76d

Browse files
committed
Added config property display.posters.fit, release v2.12.0
1 parent 09c3857 commit 50ac76d

File tree

7 files changed

+49
-17
lines changed

7 files changed

+49
-17
lines changed

.github/release-notes/v2.12.0.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
### Release Notes
2+
3+
- Added config property `display.posters.fit` to make posters fit inside a square while maintaining the original aspect ratio. This is set to `true` by default. Otherwise, Discord crops posters into a square.
4+
5+
### Installation Instructions
6+
7+
- [Regular](https://github.com/phin05/discord-rich-presence-plex/blob/v2.12.0/README.md#installation)
8+
- [Docker](https://github.com/phin05/discord-rich-presence-plex/blob/v2.12.0/README.md#run-with-docker)

README.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,21 @@ The config file is stored in a directory named `data`.
3636
- `debug` (boolean, default: `true`) - Outputs additional debug-helpful information to the console.
3737
- `writeToFile` (boolean, default: `false`) - Writes console output to a `console.log` file in the `data` directory.
3838
- `display` - Display settings for Rich Presence
39-
- `duration` (boolean, default: `true`) - Displays the total duration. Applicable to movies and TV shows only.
39+
- `duration` (boolean, default: `false`) - Displays the total duration. Applicable to movies and TV shows only.
4040
- `genres` (boolean, default: `true`) - Displays the genre. Applicable to movies only.
4141
- `album` (boolean, default: `true`) - Displays the album name. Applicable to music only.
4242
- `albumImage` (boolean, default: `true`) - Displays the album image. Applicable to music only.
4343
- `artist` (boolean, default: `true`) - Displays the artist name. Applicable to music only.
4444
- `artistImage` (boolean, default: `true`) - Displays the artist image. Applicable to music only.
4545
- `year` (boolean, default: `true`) - Displays the release year.
46-
- `statusIcon` (boolean, default: `false`) - Displays a status icon (playing, paused, buffering) at the bottom-right corner of the poster. Applicable to movies and TV shows only. Posters get cropped to a square if this is enabled (Discord bug/limitation).
46+
- `statusIcon` (boolean, default: `false`) - Displays a status icon (playing, paused, buffering) at the bottom-right corner of the poster. Applicable to movies and TV shows only.
4747
- `progressMode` (string, default: `bar`) - Progress/timestamp display mode. Valid modes are `off`, `elapsed` (displays elapsed time), `remaining` (displays remaining time) and `bar` (displays a progress bar). The `off` and `remaining` modes are currently broken due to a Discord bug/limitation.
4848
- `paused` (boolean, default: `false`) - Displays Rich Presence even while media is paused. Progress/timestamp display while paused is currently broken due to a Discord bug/limitation.
4949
- `posters`
5050
- `enabled` (boolean, default: `false`) - Displays media posters (including album art and artist images). Requires `imgurClientID`.
5151
- `imgurClientID` (string, default: `""`) - [Obtention Instructions](#obtaining-an-imgur-client-id)
5252
- `maxSize` (int, default: `256`) - Maximum width and maximum height to use while downscaling posters before uploading them.
53+
- `fit` (boolean, default: `true`) - Fits posters inside a square while maintaining the original aspect ratio. Otherwise, Discord crops posters into a square.
5354
- `buttons` (list) - [Information](#buttons)
5455
- `label` (string) - The label to be displayed on the button.
5556
- `url` (string) - A web address or a [dynamic URL placeholder](#dynamic-button-urls).
@@ -95,9 +96,12 @@ logging:
9596
debug: true
9697
writeToFile: false
9798
display:
98-
duration: true
99+
duration: false
99100
genres: true
100101
album: true
102+
albumImage: true
103+
artist: true
104+
artistImage: true
101105
year: true
102106
statusIcon: false
103107
progressMode: bar
@@ -106,6 +110,7 @@ display:
106110
enabled: true
107111
imgurClientID: 9e9sf637S8bRp4z
108112
maxSize: 256
113+
fit: true
109114
buttons:
110115
- label: "{title} on IMDb"
111116
url: dynamic:imdb

config/constants.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import sys
33

44
name = "Discord Rich Presence for Plex"
5-
version = "2.11.0"
5+
version = "2.12.0"
66

77
plexClientID = "discord-rich-presence-plex"
88
discordClientID = "413407336082833418"

core/config.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import json
55
import models.config
66
import os
7-
import time
7+
import sys
88
import yaml
99

1010
config: models.config.Config = {
@@ -13,7 +13,7 @@
1313
"writeToFile": False,
1414
},
1515
"display": {
16-
"duration": True,
16+
"duration": False,
1717
"genres": True,
1818
"album": True,
1919
"albumImage": True,
@@ -27,6 +27,7 @@
2727
"enabled": False,
2828
"imgurClientID": "",
2929
"maxSize": 256,
30+
"fit": True,
3031
},
3132
"buttons": [],
3233
},
@@ -61,8 +62,8 @@ def loadConfig() -> None:
6162
else:
6263
loadedConfig = json.load(configFile) or {} # pyright: ignore[reportUnknownVariableType]
6364
except:
64-
os.rename(configFilePath, f"{configFilePathBase}-{time.time():.0f}.{configFileExtension}")
65-
logger.exception("Failed to parse the config file. A new one will be created.")
65+
logger.exception("Failed to parse the config file")
66+
sys.exit(1)
6667
else:
6768
copyDict(loadedConfig, config)
6869
if "hideTotalTime" in config["display"]:

core/imgur.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .config import config
2-
from PIL import Image
2+
from PIL import Image, ImageOps
33
from typing import Optional
44
from utils.logging import logger
55
import io
@@ -9,14 +9,17 @@
99
def uploadToImgur(url: str) -> Optional[str]:
1010
try:
1111
originalImageBytesIO = io.BytesIO(requests.get(url).content)
12-
originalImage = Image.open(originalImageBytesIO).convert("RGB")
13-
newImage = Image.new("RGB", originalImage.size)
12+
originalImage = Image.open(originalImageBytesIO).convert("RGBA")
13+
newImage = Image.new("RGBA", originalImage.size)
1414
newImage.putdata(originalImage.getdata()) # pyright: ignore[reportArgumentType]
15+
if newImage.width != newImage.height and config["display"]["posters"]["fit"]:
16+
longestSideLength = max(newImage.width, newImage.height)
17+
newImage = ImageOps.pad(newImage, (longestSideLength, longestSideLength), color = (0, 0, 0, 0))
1518
maxSize = config["display"]["posters"]["maxSize"]
1619
if maxSize:
1720
newImage.thumbnail((maxSize, maxSize))
1821
newImageBytesIO = io.BytesIO()
19-
newImage.save(newImageBytesIO, subsampling = 0, quality = 90, format = "JPEG")
22+
newImage.save(newImageBytesIO, subsampling = 0, quality = 90, format = "PNG")
2023
response = requests.post(
2124
"https://api.imgur.com/3/image",
2225
headers = { "Authorization": f"Client-ID {config['display']['posters']['imgurClientID']}" },

main.py

+19-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from config.constants import isInContainer, runtimeDirectory, uid, gid, containerCwd, noRuntimeDirChown
22
from utils.logging import logger
33
import os
4+
import sys
45

56
if isInContainer:
67
if not os.path.isdir(runtimeDirectory):
78
logger.error(f"Runtime directory does not exist. Ensure that it is mounted into the container at {runtimeDirectory}")
8-
exit(1)
9+
sys.exit(1)
910
if os.geteuid() == 0: # pyright: ignore[reportAttributeAccessIssue,reportUnknownMemberType]
1011
if uid == -1 or gid == -1:
1112
logger.warning(f"Environment variable(s) DRPP_UID and/or DRPP_GID are/is not set. Manually ensure appropriate ownership of {runtimeDirectory}")
@@ -24,7 +25,6 @@
2425
logger.warning("Not running as the superuser. Manually ensure appropriate ownership of mounted contents")
2526

2627
from config.constants import noPipInstall
27-
import sys
2828

2929
if not noPipInstall:
3030
try:
@@ -40,13 +40,15 @@ def parsePipPackages(packagesStr: str) -> dict[str, str]:
4040
if installedPackageVersion != requiredPackageVersion:
4141
logger.info(f"Installing dependency: {packageName} (required: {requiredPackageVersion}, installed: {installedPackageVersion})")
4242
subprocess.run([sys.executable, "-m", "pip", "install", "-U", f"{packageName}=={requiredPackageVersion}"], check = True)
43-
except Exception as e:
43+
except:
4444
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")
4545

4646
from config.constants import dataDirectoryPath, logFilePath, name, version, isInteractive, plexServerNameInput
4747
from core.config import config, loadConfig, saveConfig
4848
from core.discord import DiscordIpcService
49+
from core.imgur import uploadToImgur
4950
from core.plex import PlexAlertListener, initiateAuth, getAuthToken
51+
from models.discord import ActivityType
5052
from typing import Optional
5153
from utils.cache import loadCache
5254
from utils.logging import formatter
@@ -76,7 +78,7 @@ def main() -> None:
7678
logger.info("No users found in the config file")
7779
user = authNewUser()
7880
if not user:
79-
exit(1)
81+
sys.exit(1)
8082
config["users"].append(user)
8183
saveConfig()
8284
plexAlertListeners = [PlexAlertListener(user["token"], server) for user in config["users"] for server in user["servers"]]
@@ -125,17 +127,29 @@ def authNewUser() -> Optional[models.config.User]:
125127
def testIpc(pipeNumber: int) -> None:
126128
init()
127129
logger.info("Testing Discord IPC connection")
130+
currentTimestamp = int(time.time() * 1000)
128131
discordIpcService = DiscordIpcService(pipeNumber)
129132
discordIpcService.connect()
130133
discordIpcService.setActivity({
134+
"type": ActivityType.WATCHING,
131135
"details": "details",
132136
"state": "state",
133137
"assets": {
134138
"large_text": "large_text",
135-
"large_image": "logo",
139+
"large_image": uploadToImgur("https://placehold.co/256x256/EEE/333.png") or "large_text",
136140
"small_text": "small_text",
137141
"small_image": "playing",
138142
},
143+
"timestamps": {
144+
"start": currentTimestamp,
145+
"end": currentTimestamp + 15000,
146+
},
147+
"buttons": [
148+
{
149+
"label": "Label",
150+
"url": "https://placehold.co/"
151+
},
152+
],
139153
})
140154
time.sleep(15)
141155
discordIpcService.disconnect()

models/config.py

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class Posters(TypedDict):
88
enabled: bool
99
imgurClientID: str
1010
maxSize: int
11+
fit: bool
1112

1213
class Button(TypedDict):
1314
label: str

0 commit comments

Comments
 (0)