Skip to content

Commit

Permalink
Dockerisation
Browse files Browse the repository at this point in the history
  • Loading branch information
phin05 committed Oct 1, 2023
1 parent 48c7cc6 commit 0194d5c
Show file tree
Hide file tree
Showing 11 changed files with 596 additions and 28 deletions.
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.dockerignore
.git
.github
.gitignore
CONTRIBUTING.md
Dockerfile
pyrightconfig.json
2 changes: 1 addition & 1 deletion .github/workflows/close-pull-requests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
PR_NUMBER: ${{ github.event.number || inputs.prNumber }}
PR_NUMBER: ${{ inputs.prNumber || github.event.number }}
steps:
- name: Comment
run: gh pr comment ${{ env.PR_NUMBER }} --body "This repository does not accept pull requests."
Expand Down
61 changes: 61 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Release
run-name: Release ${{ inputs.version || github.ref_name }}
on:
push:
tags:
- v*
workflow_dispatch:
inputs:
version:
required: true
type: string
description: Version (vX.X.X)
env:
VERSION: ${{ inputs.version || github.ref_name }}
jobs:
release-zip:
runs-on: ubuntu-latest
permissions:
contents: write
env:
RELEASE_ZIP_FILENAME: ${{ github.event.repository.name }}-${{ inputs.version || github.ref_name }}.zip
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Create release ZIP file
run: |
mkdir ${{ github.event.repository.name }}
rm -rf .git .github .gitignore .dockerignore Dockerfile CONTRIBUTING.md pyrightconfig.json
mv * ${{ github.event.repository.name }} || true
zip -r $RELEASE_ZIP_FILENAME ${{ github.event.repository.name }}
- name: Release on GitHub
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844
with:
tag_name: ${{ env.VERSION }}
generate_release_notes: true
files: ${{ env.RELEASE_ZIP_FILENAME }}
release-docker:
runs-on: ubuntu-latest
permissions:
packages: write
env:
DOCKER_IMAGE_NAME: ghcr.io/${{ github.actor }}/${{ github.event.repository.name }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Sign into GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and push Docker images
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
provenance: false
tags: ${{ env.DOCKER_IMAGE_NAME }}:${{ env.VERSION }},${{ env.DOCKER_IMAGE_NAME }}:latest
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
data
Showcase.psd
cache.json
config.json
console.log
lint.bat
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM python:3.10-alpine
ARG USERNAME=app
ARG USER_UID=10000
ARG USER_GID=$USER_UID
RUN addgroup -g $USER_GID $USERNAME && adduser -u $USER_UID -G $USERNAME -D $USERNAME
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt --no-cache-dir
COPY . .
ENV IN_CONTAINER true
CMD ["python", "main.py"]
439 changes: 439 additions & 0 deletions NOTICE

Large diffs are not rendered by default.

55 changes: 39 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,33 @@

![Showcase](https://user-images.githubusercontent.com/59180111/168054648-af0590fd-9bd7-42d0-91b2-d7974643debd.png)

Discord Rich Presence for Plex is 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).
Discord Rich Presence for Plex is a Python script which 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).

[![Latest Release](https://shields.io/badge/Latest%20Release-v2.3.2-informational)](https://github.com/phin05/discord-rich-presence-plex/archive/refs/heads/master.zip)
[![Latest Release](https://img.shields.io/github/v/release/phin05/discord-rich-presence-plex?label=Latest%20Release)](https://github.com/phin05/discord-rich-presence-plex/releases/latest)
[![Build Status](https://img.shields.io/github/actions/workflow/status/phin05/discord-rich-presence-plex/release.yml?label=Build&logo=github)](https://github.com/phin05/discord-rich-presence-plex/actions/workflows/release.yml)

## Usage

When the script runs for the first time, a `data` directory will be created in the current working directory along with a `config.json` file inside of it. 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.

### Instructions

1. Install [Python 3.10](https://www.python.org/downloads/) - Make sure to tick "Add Python 3.10 to PATH" during the installation.
2. Download [this repository's contents](https://github.com/phin05/discord-rich-presence-plex/archive/refs/heads/master.zip).
3. Extract the folder contained in the above ZIP file.
2. Download the [latest release](https://github.com/phin05/discord-rich-presence-plex/releases/latest) of this script.
3. Extract the directory contained in the above ZIP file.
4. Navigate a command-line interface (cmd.exe, PowerShell, bash, etc.) into the above-extracted directory.
5. Install the required Python modules by running `python -m pip install -U -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 an access token for your Plex account.

The script must be running on the same machine as your Discord client.
Alternatively, you can [run with Docker](#run-with-docker) if you're using a Linux-based operating system.

## Configuration - `config.json`

* `logging`
* `debug` (boolean, default: `true`) - Outputs additional debug-helpful information to the console if enabled.
* `writeToFile` (boolean, default: `false`) - Writes everything outputted to the console to a `console.log` file if enabled.
* `writeToFile` (boolean, default: `false`) - Writes console output to a `console.log` file in the `data` directory if enabled.
* `display` - Display settings for Rich Presence
* `hideTotalTime` (boolean, default: `false`) - Hides the total duration of the media if enabled.
* `useRemainingTime` (boolean, default: `false`) - Displays the media's remaining time instead of elapsed time if enabled.
Expand Down Expand Up @@ -109,14 +114,32 @@ The "Display current activity as a status message" setting must be enabled in Di

![Discord Settings](https://user-images.githubusercontent.com/59180111/186830889-35af3895-ece0-4a7d-9efb-f68640116884.png)

## License
## Run with Docker

### Image

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
[ghcr.io/phin05/discord-rich-presence-plex](https://ghcr.io/phin05/discord-rich-presence-plex)

## Credits
### Volumes

* [Discord](https://discord.com)
* [Plex](https://www.plex.tv)
* [Python-PlexAPI](https://github.com/pkkid/python-plexapi)
* [Requests](https://github.com/psf/requests)
* [websocket-client](https://github.com/websocket-client/websocket-client)
Mount a directory for persistent data (config file, cache file and log file) at `/app/data`.

The directory where Discord stores its inter-process communication Unix socket file needs to be mounted into the container at `/run/app`. The path for this would be the first non-null value from the values of the following environment variables: ([source](https://github.com/discord/discord-rpc/blob/963aa9f3e5ce81a4682c6ca3d136cddda614db33/src/connection_unix.cpp#L29C33-L29C33))

* XDG_RUNTIME_DIR
* TMPDIR
* TMP
* TEMP
* Fallback path: /tmp

### Example

```
docker run \
-v ./data:/app/data \
-v /run/user/1000:/run/app:ro \
--detach \
--restart unless-stopped \
--name discord-rich-presence-plex \
ghcr.io/phin05/discord-rich-presence-plex:latest
```
16 changes: 14 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
from store.constants import isUnix
import os

if isUnix and os.environ.get("IN_CONTAINER", "") == "true":
uid = 10000
os.system(f"chown -R {uid}:{uid} /app")
os.setuid(uid)

from services import PlexAlertListener
from services.cache import loadCache
from services.config import config, loadConfig, saveConfig
from store.constants import isUnix, logFilePath, name, plexClientID, version
from store.constants import dataFolderPath, logFilePath, name, plexClientID, version
from utils.logging import formatter, logger
import logging
import os
import requests
import sys
import time
Expand All @@ -13,6 +20,11 @@
plexAlertListeners: list[PlexAlertListener] = []

try:
if not os.path.exists(dataFolderPath):
os.mkdir(dataFolderPath)
for oldFilePath in ["config.json", "cache.json", "console.log"]:
if os.path.isfile(oldFilePath):
os.rename(oldFilePath, os.path.join(dataFolderPath, oldFilePath))
loadConfig()
if config["logging"]["debug"]:
logger.setLevel(logging.DEBUG)
Expand Down
2 changes: 1 addition & 1 deletion services/DiscordRpcService.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class DiscordRpcService:

ipcPipe = ((os.environ.get("XDG_RUNTIME_DIR", None) or os.environ.get("TMPDIR", None) or os.environ.get("TMP", None) or os.environ.get("TEMP", None) or "/tmp") + "/discord-ipc-0") if isUnix else r"\\?\pipe\discord-ipc-0"
ipcPipe = (((os.path.isdir("/run/app") and "/run/app") or os.environ.get("XDG_RUNTIME_DIR", None) or os.environ.get("TMPDIR", None) or os.environ.get("TMP", None) or os.environ.get("TEMP", None) or "/tmp") + "/discord-ipc-0") if isUnix else r"\\?\pipe\discord-ipc-0"

def __init__(self) -> None:
self.loop: Optional[asyncio.AbstractEventLoop] = None
Expand Down
10 changes: 6 additions & 4 deletions store/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
import sys

name = "Discord Rich Presence for Plex"
version = "2.3.2"
version = "2.3.3"

plexClientID = "discord-rich-presence-plex"
discordClientID = "413407336082833418"
configFilePath = "config.json"
cacheFilePath = "cache.json"
logFilePath = "console.log"

dataFolderPath = "data"
configFilePath = os.path.join(dataFolderPath, "config.json")
cacheFilePath = os.path.join(dataFolderPath, "cache.json")
logFilePath = os.path.join(dataFolderPath, "console.log")

isUnix = sys.platform in ["linux", "darwin"]
processID = os.getpid()
16 changes: 16 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from services import DiscordRpcService
import time

discordRpcService = DiscordRpcService()
discordRpcService.connect()
discordRpcService.setActivity({
"details": "details",
"state": "state",
"assets": {
"large_text": "large_text",
"large_image": "logo",
"small_text": "small_text",
"small_image": "playing",
},
})
time.sleep(60)

0 comments on commit 0194d5c

Please sign in to comment.