Ajout de Compose pour Deluge et Gotify #85
8
Plex Bot Music/README.md
Normal file
8
Plex Bot Music/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Plex Bot Music
|
||||
|
||||
**Plex Bot Music est un bot écrit en Python. Il vous permettra d'écouter votre musique sur Discord au travers d'un bot, tel que Rythme mais vous serez limité à votre Bibliothèque**
|
||||
|
||||
|
||||
## Lien vers le répértoire
|
||||
|
||||
https://gitea.zoz-serv.org/gigidsss/Plex-Bot-Music
|
76
Plex Discord Activity/README.md
Normal file
76
Plex Discord Activity/README.md
Normal file
@ -0,0 +1,76 @@
|
||||
# Plex Discord Activity
|
||||
|
||||
**Plex Discord Activity est un logiciel en Python. Il a été récuperé déjà depuis le dépot d'un utilisateur GitHub mais a été simplifié de sorte a ce que la pré-configuration soit la plus simple possible**
|
||||
|
||||
Il y a eu peu de modifications par rapport à l'original, mais elles vous simplifient grandement la vie.
|
||||
|
||||
## Attention
|
||||
|
||||
Sachez que pour que le script fonctionne, il faut qu'il tourne sur le même PC que votre application Discord. Malheureusement faire tourner ce script sur un serveur en tâche de fond ne donnera aucun résultat...
|
||||
|
||||
## Installation
|
||||
|
||||
Pour cela, commencez déjà par installer Python3 sur votre ordinateur si cela n'est pas déjà fait...
|
||||
|
||||
Ensuite installez ces 2 bibliothèques Python via pip3:
|
||||
|
||||
```bash
|
||||
pip3 install plexapi
|
||||
pip3 install websocket-client==0.48.0
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Éditez le document pma.py et éditez ce paragraphe seulement:
|
||||
```python
|
||||
### SEULEMENT CE QUE VOUS DEVEZ EDITER
|
||||
|
||||
MyDomain = "https://your.plex.dns:32400" #Soit via votre nom de domaine, soit via le domaine de Plex, c'est à dire, https://app.plex.tv
|
||||
Serveur = "MyPlex" #Le nom de votre Serveur Plex, visible dans Paramètres > Général > Nom d'usage
|
||||
NomUser = "username" #Le nom d'utilisateur Plex pour récupérer les métadonnées et les informations de lecture en temps réel
|
||||
MotDePasse = "password" #Votre mot de passe de votre compte Plex
|
||||
MonToken = "your_token" #Votre Token, accessible a la fin de l'url lorsque vous consultez le fichier XML de l'un de vos médias
|
||||
BlackList = ["Musique", "BackingTracks"] #séparée par des virgules avec espace, entourées par des "", entrent 2 balises [], ex: ["bib1", "bib2"]
|
||||
UserOnly = "username" #Si vous avez crée des utilisateurs gérés, pour éviter de partager l'état de lecture d'un autre utilisateur que vous-même, précisez le psuedo du bon utilisateur a priori le même que le 3ème paramètre que vous...
|
||||
InfosSupp = "true" #Ceci partage les métadonnées de votre épisode si c'est sur True, sinon mettez False pour n'afficher que l'état de lecture
|
||||
TempsRestant = "true" #True = Afficher le temps restant de lecture / False = Afficher le nombre de minutes que vous avez déjà consulté depuis le démarrage de l'épisode
|
||||
|
||||
### END DE CE QUE VOUS DEVEZ EDITER
|
||||
```
|
||||
|
||||
Voici un résumé des paramètres:
|
||||
|
||||
**Attention a ne pas supprimer des guillemets ou des crochets... Si vous ne voulez pas préciser de valeur, laissez les guillemets vides ou indiquez-y ``none`` !**
|
||||
|
||||
**Serveur**: C'est le nom de votre serveur Plex. Vous le trouverez dans ``Paramètres > Général > Nom d'usage``
|
||||
|
||||
**NomUser**: Votre nom d'utilisateur Plex associé à votre compte.
|
||||
|
||||
**MotDePasse**: Votre mot de passe de l'utilisateur Plex associé à votre compte.
|
||||
|
||||
**MonToken**: Token que vous pouvez obtenir en consultant le fichier XML d'un de vos média. Allez sur un épisode ou film précis, allez dans ``Voir informations`` puis ``Voir le XML``. Ensuite regardez à la fin de votre URL, vous devriez avoir: **Plex-Token=0x0x0xx0x00xx0x0**
|
||||
|
||||
**BlackList**: Vous pouvez décider de ne pas partager sur Discord les médias d'une bibliothèque définie, indiquez-y entre guillemets et eux-même entre crochets, le nom des Bibliothèques.
|
||||
Exemple:
|
||||
```python
|
||||
BlackList = ["Musique", "BackingTracks"]
|
||||
```
|
||||
**UserOnly**: Si vous avez crée des utilisateurs gérés, pour éviter de partager l'état de lecture d'un autre utilisateur que vous-même, précisez le psuedo du bon utilisateur qui à priori est le même que celui du paramètre ``username``...
|
||||
|
||||
**InfosSupp**: Vous permet de partager davantage d'infos sur le média, à savoir les métadonnées, etc. (Réponse: True / False)
|
||||
|
||||
**TempsRestant**: Vous permet de préciser si vous voulez indiquer le temps restant du média ou la position actuelle (Réponse: True (Il reste 05:00 minutes) / False (Vous êtes à 15:00 minutes sur 20:00 minutes))
|
||||
|
||||
## Utilisation
|
||||
|
||||
```
|
||||
python3 pma.py
|
||||
```
|
||||
*Patientez +/- 20 secondes pour que le script démarre... Le script lancera tout seul la page web Plex*
|
||||
|
||||
## Source
|
||||
https://github.com/Phineas05/discord-rich-presence-plex
|
||||
|
||||
|
||||
## License
|
||||
[MIT](https://choosealicense.com/licenses/mit/)
|
413
Plex Discord Activity/pda.py
Normal file
413
Plex Discord Activity/pda.py
Normal file
@ -0,0 +1,413 @@
|
||||
import asyncio
|
||||
import datetime
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import plexapi.myplex
|
||||
import struct
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
import webbrowser
|
||||
|
||||
### SEULEMENT CE QUE VOUS DEVEZ EDITER
|
||||
|
||||
MyDomain = "https://your.plex.dns:32400" #Soit via votre nom de domaine, soit via le domaine de Plex, c'est à dire, https://app.plex.tv
|
||||
Serveur = "MyPlex" #Le nom de votre Serveur Plex, visible dans Paramètres > Général > Nom d'usage
|
||||
NomUser = "username" #Le nom d'utilisateur Plex pour récupérer les métadonnées et les informations de lecture en temps réel
|
||||
MotDePasse = "password" #Votre mot de passe de votre compte Plex
|
||||
MonToken = "your_token" #Votre Token, accessible a la fin de l'url lorsque vous consultez le fichier XML de l'un de vos médias
|
||||
BlackList = ["Musique", "BackingTracks"] #séparée par des virgules avec espace, entourées par des "", entrent 2 balises [], ex: ["bib1", "bib2"]
|
||||
UserOnly = "username" #Si vous avez crée des utilisateurs gérés, pour éviter de partager l'état de lecture d'un autre utilisateur que vous-même, précisez le psuedo du bon utilisateur a priori le même que le 3ème paramètre que vous...
|
||||
InfosSupp = "true" #Ceci partage les métadonnées de votre épisode si c'est sur True, sinon mettez False pour n'afficher que l'état de lecture
|
||||
TempsRestant = "true" #True = Afficher le temps restant de lecture / False = Afficher le nombre de minutes que vous avez déjà consulté depuis le démarrage de l'épisode
|
||||
|
||||
### END DE CE QUE VOUS DEVEZ EDITER
|
||||
|
||||
webbrowser.open(MyDomain)
|
||||
|
||||
class plexConfig:
|
||||
|
||||
extraLogging = (InfosSupp)
|
||||
timeRemaining = (TempsRestant)
|
||||
|
||||
def __init__(self, serverName = "", username = "", password = "", token = "", listenForUser = "", blacklistedLibraries = None, whitelistedLibraries = None, clientID = "413407336082833418"):
|
||||
self.serverName = serverName
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.token = token
|
||||
self.listenForUser = (username if listenForUser == "" else listenForUser).lower()
|
||||
self.blacklistedLibraries = blacklistedLibraries
|
||||
self.whitelistedLibraries = whitelistedLibraries
|
||||
self.clientID = clientID
|
||||
|
||||
plexConfigs = [
|
||||
plexConfig(serverName = (Serveur), username = (NomUser), password = (MotDePasse), token = (MonToken), blacklistedLibraries = (BlackList), listenForUser = (UserOnly))
|
||||
]
|
||||
|
||||
class discordRichPresence:
|
||||
|
||||
def __init__(self, clientID, child):
|
||||
self.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 isLinux else "\\\\?\\pipe\\discord-ipc-0"
|
||||
self.clientID = clientID
|
||||
self.pipeReader = None
|
||||
self.pipeWriter = None
|
||||
self.process = None
|
||||
self.running = False
|
||||
self.child = child
|
||||
|
||||
async def read(self):
|
||||
try:
|
||||
data = await self.pipeReader.read(1024)
|
||||
self.child.log("[READ] " + str(json.loads(data[8:].decode("utf-8"))))
|
||||
except Exception as e:
|
||||
self.child.log("[READ] " + str(e))
|
||||
self.stop()
|
||||
|
||||
def write(self, op, payload):
|
||||
payload = json.dumps(payload)
|
||||
self.child.log("[WRITE] " + str(payload))
|
||||
data = self.pipeWriter.write(struct.pack("<ii", op, len(payload)) + payload.encode("utf-8"))
|
||||
|
||||
async def handshake(self):
|
||||
try:
|
||||
if (isLinux):
|
||||
self.pipeReader, self.pipeWriter = await asyncio.open_unix_connection(self.IPCPipe, loop = self.loop)
|
||||
else:
|
||||
self.pipeReader = asyncio.StreamReader(loop = self.loop)
|
||||
self.pipeWriter, _ = await self.loop.create_pipe_connection(lambda: asyncio.StreamReaderProtocol(self.pipeReader, loop = self.loop), self.IPCPipe)
|
||||
self.write(0, {"v": 1, "client_id": self.clientID})
|
||||
await self.read()
|
||||
self.running = True
|
||||
except Exception as e:
|
||||
self.child.log("[HANDSHAKE] " + str(e))
|
||||
|
||||
def start(self):
|
||||
self.child.log("Opening Discord IPC Pipe")
|
||||
emptyProcessFilePath = tempfile.gettempdir() + ("/" if isLinux else "\\") + "discordRichPresencePlex-emptyProcess.py"
|
||||
if (not os.path.exists(emptyProcessFilePath)):
|
||||
with open(emptyProcessFilePath, "w") as emptyProcessFile:
|
||||
emptyProcessFile.write("import time\n\ntry:\n\twhile (True):\n\t\ttime.sleep(3600)\nexcept:\n\tpass")
|
||||
self.process = subprocess.Popen(["python3" if isLinux else "pythonw", emptyProcessFilePath])
|
||||
self.loop = asyncio.new_event_loop() if isLinux else asyncio.ProactorEventLoop()
|
||||
self.loop.run_until_complete(self.handshake())
|
||||
|
||||
def stop(self):
|
||||
self.child.log("Closing Discord IPC Pipe")
|
||||
self.child.lastState, self.child.lastSessionKey, self.child.lastRatingKey = None, None, None
|
||||
self.process.kill()
|
||||
if (self.child.stopTimer):
|
||||
self.child.stopTimer.cancel()
|
||||
self.child.stopTimer = None
|
||||
if (self.child.stopTimer2):
|
||||
self.child.stopTimer2.cancel()
|
||||
self.child.stopTimer2 = None
|
||||
if (self.pipeWriter):
|
||||
try:
|
||||
self.pipeWriter.close()
|
||||
except:
|
||||
pass
|
||||
self.pipeWriter = None
|
||||
if (self.pipeReader):
|
||||
try:
|
||||
self.loop.run_until_complete(self.pipeReader.read(1024))
|
||||
except:
|
||||
pass
|
||||
self.pipeReader = None
|
||||
try:
|
||||
self.loop.close()
|
||||
except:
|
||||
pass
|
||||
self.running = False
|
||||
|
||||
def send(self, activity):
|
||||
payload = {
|
||||
"cmd": "SET_ACTIVITY",
|
||||
"args": {
|
||||
"activity": activity,
|
||||
"pid": self.process.pid
|
||||
},
|
||||
"nonce": "{0:.20f}".format(time.time())
|
||||
}
|
||||
self.write(1, payload)
|
||||
self.loop.run_until_complete(self.read())
|
||||
|
||||
class discordRichPresencePlex(discordRichPresence):
|
||||
|
||||
productName = "Plex Media Server"
|
||||
stopTimerInterval = 5
|
||||
stopTimer2Interval = 35
|
||||
checkConnectionTimerInterval = 60
|
||||
maximumIgnores = 3
|
||||
|
||||
def __init__(self, plexConfig):
|
||||
self.plexConfig = plexConfig
|
||||
self.instanceID = hashlib.md5(str(id(self)).encode("UTF-8")).hexdigest()[:5]
|
||||
super().__init__(plexConfig.clientID, self)
|
||||
self.plexAccount = None
|
||||
self.plexServer = None
|
||||
self.isServerOwner = False
|
||||
self.plexAlertListener = None
|
||||
self.lastState = None
|
||||
self.lastSessionKey = None
|
||||
self.lastRatingKey = None
|
||||
self.stopTimer = None
|
||||
self.stopTimer2 = None
|
||||
self.checkConnectionTimer = None
|
||||
self.ignoreCount = 0
|
||||
|
||||
def run(self):
|
||||
self.reset()
|
||||
connected = False
|
||||
while (not connected):
|
||||
try:
|
||||
if (self.plexConfig.token):
|
||||
self.plexAccount = plexapi.myplex.MyPlexAccount(self.plexConfig.username, token = self.plexConfig.token)
|
||||
else:
|
||||
self.plexAccount = plexapi.myplex.MyPlexAccount(self.plexConfig.username, self.plexConfig.password)
|
||||
self.log("Logged in as Plex User \"" + self.plexAccount.username + "\"")
|
||||
self.plexServer = None
|
||||
for resource in self.plexAccount.resources():
|
||||
if (resource.product == self.productName and resource.name == self.plexConfig.serverName):
|
||||
self.plexServer = resource.connect()
|
||||
try:
|
||||
self.plexServer.account()
|
||||
self.isServerOwner = True
|
||||
except:
|
||||
pass
|
||||
self.log("Connected to " + self.productName + " \"" + self.plexConfig.serverName + "\"")
|
||||
self.plexAlertListener = self.plexServer.startAlertListener(self.onPlexServerAlert)
|
||||
self.log("Listening for PlaySessionStateNotification alerts from user \"" + self.plexConfig.listenForUser + "\"")
|
||||
if (self.checkConnectionTimer):
|
||||
self.checkConnectionTimer.cancel()
|
||||
self.checkConnectionTimer = None
|
||||
self.checkConnectionTimer = threading.Timer(self.checkConnectionTimerInterval, self.checkConnection)
|
||||
self.checkConnectionTimer.start()
|
||||
connected = True
|
||||
break
|
||||
if (not self.plexServer):
|
||||
self.log(self.productName + " \"" + self.plexConfig.serverName + "\" not found")
|
||||
break
|
||||
except Exception as e:
|
||||
self.log("Failed to connect to Plex: " + str(e))
|
||||
self.log("Reconnecting in 10 seconds")
|
||||
time.sleep(10)
|
||||
|
||||
def reset(self):
|
||||
if (self.running):
|
||||
self.stop()
|
||||
self.plexAccount, self.plexServer = None, None
|
||||
if (self.plexAlertListener):
|
||||
try:
|
||||
self.plexAlertListener.stop()
|
||||
except:
|
||||
pass
|
||||
self.plexAlertListener = None
|
||||
if (self.stopTimer):
|
||||
self.stopTimer.cancel()
|
||||
self.stopTimer = None
|
||||
if (self.stopTimer2):
|
||||
self.stopTimer2.cancel()
|
||||
self.stopTimer2 = None
|
||||
if (self.checkConnectionTimer):
|
||||
self.checkConnectionTimer.cancel()
|
||||
self.checkConnectionTimer = None
|
||||
|
||||
def checkConnection(self):
|
||||
try:
|
||||
self.log("Request for clients list to check connection: " + str(self.plexServer.clients()), extra = True)
|
||||
self.checkConnectionTimer = threading.Timer(self.checkConnectionTimerInterval, self.checkConnection)
|
||||
self.checkConnectionTimer.start()
|
||||
except Exception as e:
|
||||
self.log("Connection to Plex lost: " + str(e))
|
||||
self.log("Reconnecting")
|
||||
self.run()
|
||||
|
||||
def log(self, text, colour = "", extra = False):
|
||||
timestamp = datetime.datetime.now().strftime("%I:%M:%S %p")
|
||||
prefix = "[" + timestamp + "] [" + self.plexConfig.serverName + "/" + self.instanceID + "] "
|
||||
lock.acquire()
|
||||
if (extra):
|
||||
if (self.plexConfig.extraLogging):
|
||||
print(prefix + colourText(str(text), colour))
|
||||
else:
|
||||
print(prefix + colourText(str(text), colour))
|
||||
lock.release()
|
||||
|
||||
def onPlexServerAlert(self, data):
|
||||
if (not self.plexServer):
|
||||
return
|
||||
try:
|
||||
if (data["type"] == "playing" and "PlaySessionStateNotification" in data):
|
||||
sessionData = data["PlaySessionStateNotification"][0]
|
||||
state = sessionData["state"]
|
||||
sessionKey = int(sessionData["sessionKey"])
|
||||
ratingKey = int(sessionData["ratingKey"])
|
||||
viewOffset = int(sessionData["viewOffset"])
|
||||
self.log("Received Update: " + colourText(sessionData, "yellow").replace("'", "\""), extra = True)
|
||||
metadata = self.plexServer.fetchItem(ratingKey)
|
||||
libraryName = metadata.section().title
|
||||
if (isinstance(self.plexConfig.blacklistedLibraries, list)):
|
||||
if (libraryName in self.plexConfig.blacklistedLibraries):
|
||||
self.log("Library \"" + libraryName + "\" is blacklisted, ignoring", "yellow", True)
|
||||
return
|
||||
if (isinstance(self.plexConfig.whitelistedLibraries, list)):
|
||||
if (libraryName not in self.plexConfig.whitelistedLibraries):
|
||||
self.log("Library \"" + libraryName + "\" is not whitelisted, ignoring", "yellow", True)
|
||||
return
|
||||
if (self.lastSessionKey == sessionKey and self.lastRatingKey == ratingKey):
|
||||
if (self.stopTimer2):
|
||||
self.stopTimer2.cancel()
|
||||
self.stopTimer2 = None
|
||||
if (self.lastState == state):
|
||||
if (self.ignoreCount == self.maximumIgnores):
|
||||
self.ignoreCount = 0
|
||||
else:
|
||||
self.log("Nothing changed, ignoring", "yellow", True)
|
||||
self.ignoreCount += 1
|
||||
self.stopTimer2 = threading.Timer(self.stopTimer2Interval, self.stopOnNoUpdate)
|
||||
self.stopTimer2.start()
|
||||
return
|
||||
elif (state == "stopped"):
|
||||
self.lastState, self.lastSessionKey, self.lastRatingKey = None, None, None
|
||||
self.stopTimer = threading.Timer(self.stopTimerInterval, self.stop)
|
||||
self.stopTimer.start()
|
||||
self.log("Started stopTimer", "yellow", True)
|
||||
return
|
||||
elif (state == "stopped"):
|
||||
self.log("\"stopped\" state update from unknown session key, ignoring", "yellow", True)
|
||||
return
|
||||
if (self.isServerOwner):
|
||||
self.log("Checking Sessions for Session Key " + colourText(sessionKey, "yellow"), extra = True)
|
||||
plexServerSessions = self.plexServer.sessions()
|
||||
if (len(plexServerSessions) < 1):
|
||||
self.log("Empty session list, ignoring", "red", True)
|
||||
return
|
||||
for session in plexServerSessions:
|
||||
self.log(str(session) + ", Session Key: " + colourText(session.sessionKey, "yellow") + ", Users: " + colourText(session.usernames, "yellow").replace("'", "\""), extra = True)
|
||||
sessionFound = False
|
||||
if (session.sessionKey == sessionKey):
|
||||
sessionFound = True
|
||||
self.log("Session found", "green", True)
|
||||
if (session.usernames[0].lower() == self.plexConfig.listenForUser):
|
||||
self.log("Username \"" + session.usernames[0].lower() + "\" matches \"" + self.plexConfig.listenForUser + "\", continuing", "green", True)
|
||||
break
|
||||
else:
|
||||
self.log("Username \"" + session.usernames[0].lower() + "\" doesn't match \"" + self.plexConfig.listenForUser + "\", ignoring", "red", True)
|
||||
return
|
||||
if (not sessionFound):
|
||||
self.log("No matching session found", "red", True)
|
||||
return
|
||||
if (self.stopTimer):
|
||||
self.stopTimer.cancel()
|
||||
self.stopTimer = None
|
||||
if (self.stopTimer2):
|
||||
self.stopTimer2.cancel()
|
||||
self.stopTimer2 = threading.Timer(self.stopTimer2Interval, self.stopOnNoUpdate)
|
||||
self.stopTimer2.start()
|
||||
self.lastState, self.lastSessionKey, self.lastRatingKey = state, sessionKey, ratingKey
|
||||
mediaType = metadata.type
|
||||
if (state != "playing"):
|
||||
extra = secondsToText(viewOffset / 1000, ":") + "/" + secondsToText(metadata.duration / 1000, ":")
|
||||
else:
|
||||
extra = secondsToText(metadata.duration / 1000)
|
||||
if (mediaType == "movie"):
|
||||
title = metadata.title + " (" + str(metadata.year) + ")"
|
||||
extra = extra + " · " + ", ".join([genre.tag for genre in metadata.genres[:3]])
|
||||
largeText = "Watching a Movie"
|
||||
elif (mediaType == "episode"):
|
||||
title = metadata.grandparentTitle
|
||||
extra = extra + " · S" + str(metadata.parentIndex) + " · E" + str(metadata.index) + " - " + metadata.title
|
||||
largeText = "Watching a TV Show"
|
||||
elif (mediaType == "track"):
|
||||
title = metadata.title
|
||||
artist = metadata.originalTitle
|
||||
if (not artist):
|
||||
artist = metadata.grandparentTitle
|
||||
extra = artist + " · " + metadata.parentTitle
|
||||
largeText = "Listening to Music"
|
||||
else:
|
||||
self.log("Unsupported media type \"" + mediaType + "\", ignoring", "red", True)
|
||||
return
|
||||
activity = {
|
||||
"details": title,
|
||||
"state": extra,
|
||||
"assets": {
|
||||
"large_text": largeText,
|
||||
"large_image": "logo",
|
||||
"small_text": state.capitalize(),
|
||||
"small_image": state
|
||||
},
|
||||
}
|
||||
if (state == "playing"):
|
||||
currentTimestamp = int(time.time())
|
||||
if (self.plexConfig.timeRemaining):
|
||||
activity["timestamps"] = {"end": round(currentTimestamp + ((metadata.duration - viewOffset) / 1000))}
|
||||
else:
|
||||
activity["timestamps"] = {"start": round(currentTimestamp - (viewOffset / 1000))}
|
||||
if (not self.running):
|
||||
self.start()
|
||||
if (self.running):
|
||||
self.send(activity)
|
||||
else:
|
||||
self.stop()
|
||||
except Exception as e:
|
||||
self.log("onPlexServerAlert Error: " + str(e))
|
||||
|
||||
def stopOnNoUpdate(self):
|
||||
self.log("No updates from session key " + str(self.lastSessionKey) + ", stopping", "red", True)
|
||||
self.stop()
|
||||
|
||||
isLinux = sys.platform in ["linux", "darwin"]
|
||||
lock = threading.Semaphore(value = 1)
|
||||
|
||||
os.system("clear" if isLinux else "cls")
|
||||
|
||||
if (len(plexConfigs) == 0):
|
||||
print("Error: plexConfigs list is empty")
|
||||
sys.exit()
|
||||
|
||||
colours = {
|
||||
"red": "91",
|
||||
"green": "92",
|
||||
"yellow": "93",
|
||||
"blue": "94",
|
||||
"magenta": "96",
|
||||
"cyan": "97"
|
||||
}
|
||||
|
||||
def colourText(text, colour = ""):
|
||||
prefix = ""
|
||||
suffix = ""
|
||||
colour = colour.lower()
|
||||
if (colour in colours):
|
||||
prefix = "\033[" + colours[colour] + "m"
|
||||
suffix = "\033[0m"
|
||||
return prefix + str(text) + suffix
|
||||
|
||||
def secondsToText(seconds, joiner = ""):
|
||||
seconds = round(seconds)
|
||||
text = {"h": seconds // 3600, "m": seconds // 60 % 60, "s": seconds % 60}
|
||||
if (joiner == ""):
|
||||
text = [str(v) + k for k, v in text.items() if v > 0]
|
||||
else:
|
||||
if (text["h"] == 0):
|
||||
del text["h"]
|
||||
text = [str(v).rjust(2, "0") for k, v in text.items()]
|
||||
return joiner.join(text)
|
||||
|
||||
discordRichPresencePlexInstances = []
|
||||
for config in plexConfigs:
|
||||
discordRichPresencePlexInstances.append(discordRichPresencePlex(config))
|
||||
try:
|
||||
for discordRichPresencePlexInstance in discordRichPresencePlexInstances:
|
||||
discordRichPresencePlexInstance.run()
|
||||
while (True):
|
||||
time.sleep(3600)
|
||||
except KeyboardInterrupt:
|
||||
for discordRichPresencePlexInstance in discordRichPresencePlexInstances:
|
||||
discordRichPresencePlexInstance.reset()
|
||||
except Exception as e:
|
||||
print("Error: " + str(e))
|
19
docker-compose/deluge/docker-compose.yml
Normal file
19
docker-compose/deluge/docker-compose.yml
Normal file
@ -0,0 +1,19 @@
|
||||
## Discord Plex FR : https://discord.gg/ERpYMqS
|
||||
## Version 2021-08-12
|
||||
|
||||
version: "2.1"
|
||||
services:
|
||||
deluge:
|
||||
image: ghcr.io/linuxserver/deluge:latest
|
||||
container_name: deluge
|
||||
environment:
|
||||
- PUID=1000 # Utiliser la commande (en SSH) : id NOM_UTILISATEUR
|
||||
- PGID=1000 # Utiliser la commande (en SSH) : id NOM_UTILISATEUR
|
||||
ports:
|
||||
- 8112:8112
|
||||
volumes:
|
||||
- /volume1/docker/deluge/config:/config
|
||||
- /volume1/torrent:/downloads
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- com.centurylinklabs.watchtower.enable=true
|
23
docker-compose/gotify/docker-compose.yml
Normal file
23
docker-compose/gotify/docker-compose.yml
Normal file
@ -0,0 +1,23 @@
|
||||
## Discord Plex FR : https://discord.gg/ERpYMqS
|
||||
## Version 2021-08-12
|
||||
version: "2.1"
|
||||
services:
|
||||
gotify:
|
||||
image: gotify/server
|
||||
container_name: gotify
|
||||
labels:
|
||||
- "autoheal=true" # Voir autoheal pour relance automatique de container instable
|
||||
- com.centurylinklabs.watchtower.enable=true # Le label ci-dessous permet à Watchtower de faire les mises à jour automatiquement
|
||||
ports:
|
||||
- 2222:80 # Choisir un port de connexion libre sur votre machine, ce sera la port de connexion
|
||||
environment:
|
||||
- GOTIFY_DEFAULTUSER_PASS=custom
|
||||
- GOTIFY_DATABASE_DIALECT=sqlite3
|
||||
- GOTIFY_DATABASE_CONNECTION=data/gotify.db
|
||||
- GOTIFY_DEFAULTUSER_NAME=admin
|
||||
- GOTIFY_DEFAULTUSER_PASS=admin
|
||||
- GOTIFY_PASSSTRENGTH=10
|
||||
- GOTIFY_UPLOADEDIMAGESDIR=data/images
|
||||
- GOTIFY_PLUGINSDIR=data/plugins
|
||||
volumes:
|
||||
- /volume1/docker/gotify/data:/app/data
|
Loading…
Reference in New Issue
Block a user