feat: Jellyfin integration finished
- Finsihed Jellyfin integration with auto-add and auto-remove - Integration toggle in config task: none
This commit is contained in:
26
README.md
26
README.md
@@ -18,10 +18,14 @@ Invitarr is a chatbot that invites discord users to plex. You can also automate
|
|||||||
Commands:
|
Commands:
|
||||||
|
|
||||||
```
|
```
|
||||||
.plexinvite <email>
|
.plexinvite / .plexadd <email>
|
||||||
This command is used to add an email to plex
|
This command is used to add an email to plex
|
||||||
.plexremove <email>
|
.plexremove / .plexrm <email>
|
||||||
This command is used to remove an email from plex
|
This command is used to remove an email from plex
|
||||||
|
.jellyfininvite / .jellyadd <username>
|
||||||
|
This command is used to add a user to Jellyfin.
|
||||||
|
.jellyremove / .jellyrm <username>
|
||||||
|
This command is used to remove a user from Jellyfin.
|
||||||
.dbls
|
.dbls
|
||||||
This command is used to list Invitarrs database
|
This command is used to list Invitarrs database
|
||||||
.dbadd <@user> "<email>" "<jellyfinUsername>"
|
.dbadd <@user> "<email>" "<jellyfinUsername>"
|
||||||
@@ -66,7 +70,7 @@ docker run -d --restart unless-stopped --name invitarr -v /path to config:/app/a
|
|||||||
|
|
||||||
# After bot has started
|
# After bot has started
|
||||||
|
|
||||||
# Setup Commands:
|
# Plex Setup Commands:
|
||||||
|
|
||||||
```
|
```
|
||||||
.setupplex
|
.setupplex
|
||||||
@@ -74,7 +78,21 @@ This command is used to setup plex login.
|
|||||||
.plexroleadd <@role>
|
.plexroleadd <@role>
|
||||||
These role(s) will be used as the role(s) to automatically invite user to plex
|
These role(s) will be used as the role(s) to automatically invite user to plex
|
||||||
.setupplexlibs (optional)
|
.setupplexlibs (optional)
|
||||||
This command is used to setup plex libraries. Default is set to all.
|
This command is used to setup plex libraries. Default is set to all.
|
||||||
|
.plexdisable
|
||||||
|
This command disables the Plex integration (currently only disables auto-add / auto-remove)
|
||||||
|
```
|
||||||
|
|
||||||
|
# Jellyfin Setup Commands:
|
||||||
|
```
|
||||||
|
.setupjelly
|
||||||
|
This command is used to setup Jellyfin API.
|
||||||
|
.jellyroleadd <@role>
|
||||||
|
These role(s) will be used as the role(s) to automatically invite user to Jellyfin
|
||||||
|
.setupjellylibs (optional)
|
||||||
|
This command is used to setup jelly libraries. Default is set to all.
|
||||||
|
.jellydisable
|
||||||
|
this command disables the Jellyfin integration (currently only disables auto-add / auto-remove)
|
||||||
```
|
```
|
||||||
|
|
||||||
Refer to the [Wiki](https://github.com/Sleepingpirates/Invitarr/wiki) for detailed steps.
|
Refer to the [Wiki](https://github.com/Sleepingpirates/Invitarr/wiki) for detailed steps.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from pickle import FALSE
|
||||||
|
import app.bot.helper.jellyfinhelper as jelly
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
import asyncio
|
import asyncio
|
||||||
@@ -5,6 +7,7 @@ from plexapi.myplex import MyPlexAccount
|
|||||||
from discord import Webhook, AsyncWebhookAdapter
|
from discord import Webhook, AsyncWebhookAdapter
|
||||||
import app.bot.helper.db as db
|
import app.bot.helper.db as db
|
||||||
import app.bot.helper.plexhelper as plexhelper
|
import app.bot.helper.plexhelper as plexhelper
|
||||||
|
import app.bot.helper.jellyfinhelper as jelly
|
||||||
import texttable
|
import texttable
|
||||||
import os
|
import os
|
||||||
from os import path
|
from os import path
|
||||||
@@ -19,28 +22,91 @@ PLEXPASS = ""
|
|||||||
PLEX_SERVER_NAME = ""
|
PLEX_SERVER_NAME = ""
|
||||||
Plex_LIBS = None
|
Plex_LIBS = None
|
||||||
|
|
||||||
USE_PLEX = False
|
plex_configured = True
|
||||||
|
jellyfin_configured = True
|
||||||
|
|
||||||
if(path.exists('app/config/config.ini')):
|
if(path.exists(CONFIG_PATH)):
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(CONFIG_PATH)
|
||||||
|
|
||||||
|
# Get Plex config
|
||||||
try:
|
try:
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config.read(CONFIG_PATH)
|
|
||||||
PLEXUSER = config.get(BOT_SECTION, 'plex_user')
|
PLEXUSER = config.get(BOT_SECTION, 'plex_user')
|
||||||
PLEXPASS = config.get(BOT_SECTION, 'plex_pass')
|
PLEXPASS = config.get(BOT_SECTION, 'plex_pass')
|
||||||
PLEX_SERVER_NAME = config.get(BOT_SECTION, 'plex_server_name')
|
PLEX_SERVER_NAME = config.get(BOT_SECTION, 'plex_server_name')
|
||||||
except:
|
except:
|
||||||
pass
|
print("Could not load plex config")
|
||||||
if(path.exists('app/config/config.ini')):
|
plex_configured = False
|
||||||
|
|
||||||
|
# Get Plex roles config
|
||||||
try:
|
try:
|
||||||
plex_roles = config.get(BOT_SECTION, 'plex_roles')
|
plex_roles = config.get(BOT_SECTION, 'plex_roles')
|
||||||
except:
|
except:
|
||||||
pass
|
print("Could not get Plex roles config")
|
||||||
if(path.exists('app/config/config.ini')):
|
plex_roles = None
|
||||||
|
if plex_roles is not None:
|
||||||
|
plex_roles = list(plex_roles.split(','))
|
||||||
|
else:
|
||||||
|
plex_roles = []
|
||||||
|
|
||||||
|
# Get Plex libs config
|
||||||
try:
|
try:
|
||||||
Plex_LIBS = config.get(BOT_SECTION, 'plex_libs')
|
Plex_LIBS = config.get(BOT_SECTION, 'plex_libs')
|
||||||
except:
|
except:
|
||||||
pass
|
print("Could not get Plex libs config. Defaulting to all libraries.")
|
||||||
if USE_PLEX:
|
Plex_LIBS = None
|
||||||
|
if Plex_LIBS is None:
|
||||||
|
Plex_LIBS = ["all"]
|
||||||
|
else:
|
||||||
|
Plex_LIBS = list(Plex_LIBS.split(','))
|
||||||
|
|
||||||
|
# Get Jellyfin config
|
||||||
|
try:
|
||||||
|
JELLYFIN_SERVER_URL = config.get(BOT_SECTION, 'jellyfin_server_url')
|
||||||
|
JELLYFIN_API_KEY = config.get(BOT_SECTION, "jellyfin_api_key")
|
||||||
|
except:
|
||||||
|
print("Could not load Jellyfin config")
|
||||||
|
jellyfin_configured = False
|
||||||
|
|
||||||
|
# Get Jellyfin roles config
|
||||||
|
try:
|
||||||
|
jellyfin_roles = config.get(BOT_SECTION, 'jellyfin_roles')
|
||||||
|
except:
|
||||||
|
print("Could not get Jellyfin roles config")
|
||||||
|
jellyfin_roles = None
|
||||||
|
if jellyfin_roles is not None:
|
||||||
|
jellyfin_roles = list(jellyfin_roles.split(','))
|
||||||
|
else:
|
||||||
|
jellyfin_roles = []
|
||||||
|
|
||||||
|
# Get Jellyfin libs config
|
||||||
|
try:
|
||||||
|
jellyfin_libs = config.get(BOT_SECTION, 'jellyfin_libs')
|
||||||
|
except:
|
||||||
|
print("Could not get Jellyfin libs config. Defaulting to all libraries.")
|
||||||
|
jellyfin_libs = None
|
||||||
|
if jellyfin_libs is None:
|
||||||
|
jellyfin_libs = ["all"]
|
||||||
|
else:
|
||||||
|
jellyfin_libs = list(jellyfin_libs.split(','))
|
||||||
|
|
||||||
|
# Get Enable config
|
||||||
|
try:
|
||||||
|
USE_JELLYFIN = config.get(BOT_SECTION, 'jellyfin_enabled')
|
||||||
|
USE_JELLYFIN = USE_JELLYFIN.lower() == "true"
|
||||||
|
except:
|
||||||
|
print("Could not get Jellyfin enable config. Defaulting to False")
|
||||||
|
USE_JELLYFIN = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
USE_PLEX = config.get(BOT_SECTION, "plex_enabled")
|
||||||
|
USE_PLEX = USE_PLEX.lower() == "true"
|
||||||
|
except:
|
||||||
|
print("Could not get Plex enable config. Defaulting to False")
|
||||||
|
USE_PLEX = False
|
||||||
|
|
||||||
|
|
||||||
|
if USE_PLEX and plex_configured:
|
||||||
try:
|
try:
|
||||||
account = MyPlexAccount(PLEXUSER, PLEXPASS)
|
account = MyPlexAccount(PLEXUSER, PLEXPASS)
|
||||||
plex = account.resource(PLEX_SERVER_NAME).connect() # returns a PlexServer instance
|
plex = account.resource(PLEX_SERVER_NAME).connect() # returns a PlexServer instance
|
||||||
@@ -48,14 +114,9 @@ if USE_PLEX:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('Error with plex login. Please check username and password and Plex server name or setup plex in the bot.')
|
print('Error with plex login. Please check username and password and Plex server name or setup plex in the bot.')
|
||||||
print(f'Error: {e}')
|
print(f'Error: {e}')
|
||||||
|
|
||||||
if plex_roles is not None:
|
|
||||||
plex_roles = list(plex_roles.split(','))
|
|
||||||
|
|
||||||
if Plex_LIBS is None:
|
|
||||||
Plex_LIBS = ["all"]
|
|
||||||
else:
|
else:
|
||||||
Plex_LIBS = list(Plex_LIBS.split(','))
|
print(f"Plex {'disabled' if not USE_PLEX else 'not configured'}. Skipping Plex login.")
|
||||||
|
|
||||||
|
|
||||||
class app(commands.Cog):
|
class app(commands.Cog):
|
||||||
|
|
||||||
@@ -65,6 +126,7 @@ class app(commands.Cog):
|
|||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
print('Made by Sleepingpirate https://github.com/Sleepingpirates/')
|
print('Made by Sleepingpirate https://github.com/Sleepingpirates/')
|
||||||
|
print('Jellyfin implementation by Yoruio https://github.com/Yoruio/')
|
||||||
print(f'Logged in as {self.bot.user} (ID: {self.bot.user.id})')
|
print(f'Logged in as {self.bot.user} (ID: {self.bot.user.id})')
|
||||||
print('------')
|
print('------')
|
||||||
if plex_roles is None:
|
if plex_roles is None:
|
||||||
@@ -77,6 +139,12 @@ class app(commands.Cog):
|
|||||||
async def embedinfo(self, author, message):
|
async def embedinfo(self, author, message):
|
||||||
embed1 = discord.Embed(title=message, color=0x00F500)
|
embed1 = discord.Embed(title=message, color=0x00F500)
|
||||||
await author.send(embed=embed1)
|
await author.send(embed=embed1)
|
||||||
|
|
||||||
|
async def embedcustom(self, recipient, title, fields):
|
||||||
|
embed = discord.Embed(title=title)
|
||||||
|
for k in fields:
|
||||||
|
embed.add_field(name=str(k), value=str(fields[k]), inline=True)
|
||||||
|
await recipient.send(embed=embed)
|
||||||
|
|
||||||
async def getemail(self, after):
|
async def getemail(self, after):
|
||||||
email = None
|
email = None
|
||||||
@@ -98,6 +166,31 @@ class app(commands.Cog):
|
|||||||
message = "Timed Out. Message Server Admin with your email so They Can Add You Manually."
|
message = "Timed Out. Message Server Admin with your email so They Can Add You Manually."
|
||||||
await self.embederror(after, message)
|
await self.embederror(after, message)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
async def getusername(self, after):
|
||||||
|
username = None
|
||||||
|
await self.embedinfo(after, f"Welcome To Jellyfin! Just reply with a username for Jellyfin so we can add you!")
|
||||||
|
await self.embedinfo(after, f"I will wait 24 hours for your message, if you do not send it by then I will cancel the command.")
|
||||||
|
while (username is None):
|
||||||
|
def check(m):
|
||||||
|
return m.author == after and not m.guild
|
||||||
|
try:
|
||||||
|
username = await self.bot.wait_for('message', timeout=86400, check=check)
|
||||||
|
if(jelly.verify_username(JELLYFIN_SERVER_URL, JELLYFIN_API_KEY, str(username.content))):
|
||||||
|
return str(username.content)
|
||||||
|
else:
|
||||||
|
username = None
|
||||||
|
message = "This username is already choosen. Please select another Username."
|
||||||
|
await self.embederror(after, message)
|
||||||
|
continue
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
message = "Timed Out. Message Server Admin with your preferred username so They Can Add You Manually."
|
||||||
|
await self.embederror(after, message)
|
||||||
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
await self.embederror(after, "Something went wrong. Please try again with another username.")
|
||||||
|
print (e)
|
||||||
|
username = None
|
||||||
|
|
||||||
|
|
||||||
async def addtoplex(self, email, channel):
|
async def addtoplex(self, email, channel):
|
||||||
@@ -123,6 +216,30 @@ class app(commands.Cog):
|
|||||||
else:
|
else:
|
||||||
await self.embederror(channel, 'Invalid email.')
|
await self.embederror(channel, 'Invalid email.')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
async def addtojellyfin(self, username, password, channel):
|
||||||
|
if not jelly.verify_username(JELLYFIN_SERVER_URL, JELLYFIN_API_KEY, username):
|
||||||
|
await self.embederror(channel, f'An account with username {username} already exists.')
|
||||||
|
return
|
||||||
|
|
||||||
|
if jelly.add_user(JELLYFIN_SERVER_URL, JELLYFIN_API_KEY, username, password, jellyfin_libs):
|
||||||
|
await self.embedinfo(channel, 'User successfully added to Jellyfin')
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
await self.embederror(channel, 'There was an error adding this user to Jellyfin. Check logs for more info.')
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def removefromjellyfin(self, username, channel):
|
||||||
|
if jelly.verify_username(JELLYFIN_SERVER_URL, JELLYFIN_API_KEY, username):
|
||||||
|
await self.embederror(channel, f'Could not find account with username {username}.')
|
||||||
|
return
|
||||||
|
|
||||||
|
if jelly.remove_user(JELLYFIN_SERVER_URL, JELLYFIN_API_KEY, username):
|
||||||
|
await self.embedinfo(channel, f'Successfully removed user {username} from Jellyfin.')
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
await self.embederror(channel, f'There was an error removing this user from Jellyfin. Check logs for more info.')
|
||||||
|
return False
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_member_update(self, before, after):
|
async def on_member_update(self, before, after):
|
||||||
@@ -130,38 +247,95 @@ class app(commands.Cog):
|
|||||||
return
|
return
|
||||||
roles_in_guild = after.guild.roles
|
roles_in_guild = after.guild.roles
|
||||||
role = None
|
role = None
|
||||||
for role_for_app in plex_roles:
|
|
||||||
for role_in_guild in roles_in_guild:
|
|
||||||
if role_in_guild.name == role_for_app:
|
|
||||||
role = role_in_guild
|
|
||||||
|
|
||||||
if role is not None and (role in after.roles and role not in before.roles):
|
plex_processed = False
|
||||||
email = await self.getemail(after)
|
jellyfin_processed = False
|
||||||
if email is not None:
|
|
||||||
await self.embedinfo(after, "Got it we will be adding your email to plex shortly!")
|
|
||||||
if plexhelper.plexadd(plex,email,Plex_LIBS):
|
|
||||||
db.save_user(str(after.id), email)
|
|
||||||
await asyncio.sleep(5)
|
|
||||||
await self.embedinfo(after, 'You have Been Added To Plex! Login to plex and accept the invite!')
|
|
||||||
else:
|
|
||||||
await self.embedinfo(after, 'There was an error adding this email address. Message Server Admin.')
|
|
||||||
return
|
|
||||||
|
|
||||||
elif role is not None and (role not in after.roles and role in before.roles):
|
# Check Plex roles
|
||||||
try:
|
if plex_configured and USE_PLEX:
|
||||||
user_id = after.id
|
for role_for_app in plex_roles:
|
||||||
email = db.get_useremail(user_id)
|
for role_in_guild in roles_in_guild:
|
||||||
plexhelper.plexremove(plex,email)
|
if role_in_guild.name == role_for_app:
|
||||||
deleted = db.delete_user(user_id)
|
role = role_in_guild
|
||||||
if deleted:
|
|
||||||
print("Removed {} from db".format(email))
|
# Plex role was added
|
||||||
#await secure.send(plexname + ' ' + after.mention + ' was removed from plex')
|
if role is not None and (role in after.roles and role not in before.roles):
|
||||||
else:
|
email = await self.getemail(after)
|
||||||
print("Cannot remove this user from db.")
|
if email is not None:
|
||||||
except Exception as e:
|
await self.embedinfo(after, "Got it we will be adding your email to plex shortly!")
|
||||||
print(e)
|
if plexhelper.plexadd(plex,email,Plex_LIBS):
|
||||||
print("{} Cannot remove this user from plex.".format(email))
|
db.save_user_email(str(after.id), email)
|
||||||
return
|
await asyncio.sleep(5)
|
||||||
|
await self.embedinfo(after, 'You have Been Added To Plex! Login to plex and accept the invite!')
|
||||||
|
else:
|
||||||
|
await self.embedinfo(after, 'There was an error adding this email address. Message Server Admin.')
|
||||||
|
plex_processed = True
|
||||||
|
break
|
||||||
|
|
||||||
|
# Plex role was removed
|
||||||
|
elif role is not None and (role not in after.roles and role in before.roles):
|
||||||
|
try:
|
||||||
|
user_id = after.id
|
||||||
|
email = db.get_useremail(user_id)
|
||||||
|
plexhelper.plexremove(plex,email)
|
||||||
|
deleted = db.remove_email(user_id)
|
||||||
|
if deleted:
|
||||||
|
print("Removed Plex email {} from db".format(after.name))
|
||||||
|
#await secure.send(plexname + ' ' + after.mention + ' was removed from plex')
|
||||||
|
else:
|
||||||
|
print("Cannot remove Plex from this user.")
|
||||||
|
await self.embedinfo(after, "You have been removed from Plex")
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print("{} Cannot remove this user from plex.".format(email))
|
||||||
|
plex_processed = True
|
||||||
|
break
|
||||||
|
if plex_processed:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Check Jellyfin roles
|
||||||
|
if jellyfin_configured and USE_JELLYFIN:
|
||||||
|
for role_for_app in jellyfin_roles:
|
||||||
|
for role_in_guild in roles_in_guild:
|
||||||
|
if role_in_guild.name == role_for_app:
|
||||||
|
role = role_in_guild
|
||||||
|
|
||||||
|
# Jellyfin role was added
|
||||||
|
if role is not None and (role in after.roles and role not in before.roles):
|
||||||
|
username = await self.getusername(after)
|
||||||
|
if username is not None:
|
||||||
|
await self.embedinfo(after, "Got it we will be creating your Jellyfin account shortly!")
|
||||||
|
password = jelly.generate_password(16)
|
||||||
|
if jelly.add_user(JELLYFIN_SERVER_URL, JELLYFIN_API_KEY, username, password, jellyfin_libs):
|
||||||
|
db.save_user_jellyfin(str(after.id), username)
|
||||||
|
await asyncio.sleep(5)
|
||||||
|
await self.embedcustom(after, "You have been added to Jellyfin!", {'Username': username, 'Password': f"||{password}||"})
|
||||||
|
await self.embedinfo(after, f"Go to {JELLYFIN_SERVER_URL} to log in!")
|
||||||
|
else:
|
||||||
|
await self.embedinfo(after, 'There was an error adding this user to Jellyfin. Message Server Admin.')
|
||||||
|
jellyfin_processed = True
|
||||||
|
break
|
||||||
|
|
||||||
|
# Jellyfin role was removed
|
||||||
|
elif role is not None and (role not in after.roles and role in before.roles):
|
||||||
|
try:
|
||||||
|
user_id = after.id
|
||||||
|
username = db.get_jellyfin_username(user_id)
|
||||||
|
jelly.remove_user(JELLYFIN_SERVER_URL, JELLYFIN_API_KEY, username)
|
||||||
|
deleted = db.remove_jellyfin(user_id)
|
||||||
|
if deleted:
|
||||||
|
print("Removed Jellyfin from {}".format(after.name))
|
||||||
|
#await secure.send(plexname + ' ' + after.mention + ' was removed from plex')
|
||||||
|
else:
|
||||||
|
print("Cannot remove Jellyfin from this user")
|
||||||
|
await self.embedinfo(after, "You have been removed from Jellyfin")
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print("{} Cannot remove this user from Jellyfin.".format(username))
|
||||||
|
jellyfin_processed = True
|
||||||
|
break
|
||||||
|
if jellyfin_processed:
|
||||||
|
break
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_member_remove(self, member):
|
async def on_member_remove(self, member):
|
||||||
@@ -181,6 +355,18 @@ class app(commands.Cog):
|
|||||||
async def plexremove(self, ctx, email):
|
async def plexremove(self, ctx, email):
|
||||||
await self.removefromplex(email, ctx.channel)
|
await self.removefromplex(email, ctx.channel)
|
||||||
|
|
||||||
|
@commands.has_permissions(administrator=True)
|
||||||
|
@commands.command(aliases=['jellyadd'])
|
||||||
|
async def jellyfininvite(self, ctx, username):
|
||||||
|
password = jelly.generate_password(16)
|
||||||
|
if await self.addtojellyfin(username, password, ctx.channel):
|
||||||
|
await self.embedcustom(ctx.author, "Jellyfin user created!", {'Username': username, 'Password': f"||{password}||"})
|
||||||
|
|
||||||
|
@commands.has_permissions(administrator=True)
|
||||||
|
@commands.command(aliases=['jellyrm'])
|
||||||
|
async def jellyfinremove(self, ctx, username):
|
||||||
|
await self.removefromjellyfin(username, ctx.channel)
|
||||||
|
|
||||||
@commands.has_permissions(administrator=True)
|
@commands.has_permissions(administrator=True)
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def dbadd(self, ctx, member: discord.Member, email, jellyfin_username):
|
async def dbadd(self, ctx, member: discord.Member, email, jellyfin_username):
|
||||||
@@ -240,32 +426,34 @@ class app(commands.Cog):
|
|||||||
@commands.command()
|
@commands.command()
|
||||||
async def dbrm(self, ctx, position):
|
async def dbrm(self, ctx, position):
|
||||||
embed = discord.Embed(title='Invitarr Database.')
|
embed = discord.Embed(title='Invitarr Database.')
|
||||||
all = db.read_useremail() # TODO: no need to read from DB or make a table here.
|
all = db.read_useremail()
|
||||||
table = texttable.Texttable()
|
table = texttable.Texttable()
|
||||||
table.set_cols_dtype(["t", "t", "t"])
|
table.set_cols_dtype(["t", "t", "t", "t"])
|
||||||
table.set_cols_align(["c", "c", "c"])
|
table.set_cols_align(["c", "c", "c", "c"])
|
||||||
header = ("#", "Name", "Email")
|
header = ("#", "Name", "Email", "Jellyfin")
|
||||||
table.add_row(header)
|
table.add_row(header)
|
||||||
for index, peoples in enumerate(all):
|
for index, peoples in enumerate(all):
|
||||||
index = index + 1
|
index = index + 1
|
||||||
id = int(peoples[1])
|
id = int(peoples[1])
|
||||||
dbuser = self.bot.get_user(id)
|
dbuser = self.bot.get_user(id)
|
||||||
dbemail = peoples[2]
|
dbemail = peoples[2] if peoples[2] else "No Plex"
|
||||||
|
dbjellyfin = peoples[3] if peoples[3] else "No Jellyfin"
|
||||||
try:
|
try:
|
||||||
username = dbuser.name
|
username = dbuser.name
|
||||||
except:
|
except:
|
||||||
username = "User Not Found."
|
username = "User Not Found."
|
||||||
embed.add_field(name=f"**{index}. {username}**", value=dbemail+'\n', inline=False)
|
embed.add_field(name=f"**{index}. {username}**", value=dbemail+'\n'+dbjellyfin+'\n', inline=False)
|
||||||
table.add_row((index, username, dbemail))
|
table.add_row((index, username, dbemail, dbjellyfin))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
position = int(position) - 1
|
position = int(position) - 1
|
||||||
id = all[position][1]
|
id = all[position][1]
|
||||||
email = db.get_useremail(id)
|
discord_user = await self.bot.fetch_user(id)
|
||||||
|
username = discord_user.name
|
||||||
deleted = db.delete_user(id)
|
deleted = db.delete_user(id)
|
||||||
if deleted:
|
if deleted:
|
||||||
print("Removed {} from db".format(email))
|
print("Removed {} from db".format(username))
|
||||||
await self.embedinfo(ctx.channel,"Removed {} from db".format(email))
|
await self.embedinfo(ctx.channel,"Removed {} from db".format(username))
|
||||||
else:
|
else:
|
||||||
await self.embederror(ctx.channel,"Cannot remove this user from db.")
|
await self.embederror(ctx.channel,"Cannot remove this user from db.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ config = configparser.ConfigParser()
|
|||||||
|
|
||||||
CONFIG_KEYS = ['username', 'password', 'discord_bot_token', 'plex_user', 'plex_pass',
|
CONFIG_KEYS = ['username', 'password', 'discord_bot_token', 'plex_user', 'plex_pass',
|
||||||
'plex_roles', 'plex_server_name', 'plex_libs', 'owner_id', 'channel_id',
|
'plex_roles', 'plex_server_name', 'plex_libs', 'owner_id', 'channel_id',
|
||||||
'auto_remove_user']
|
'auto_remove_user', 'jellyfin_api_key', 'jellyfin_server_url', 'jellyfin_roles',
|
||||||
|
'jellyfin_libs', 'plex_enabled', 'jellyfin_enabled']
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
Discord_bot_token = ""
|
Discord_bot_token = ""
|
||||||
@@ -17,6 +18,11 @@ PLEXUSER = ""
|
|||||||
PLEXPASS = ""
|
PLEXPASS = ""
|
||||||
PLEX_SERVER_NAME = ""
|
PLEX_SERVER_NAME = ""
|
||||||
Plex_LIBS = None
|
Plex_LIBS = None
|
||||||
|
JELLYFIN_SERVER_URL = ""
|
||||||
|
JELLYFIN_API_KEY = ""
|
||||||
|
jellyfin_libs = ""
|
||||||
|
jellyfin_roles = None
|
||||||
|
|
||||||
switch = 0
|
switch = 0
|
||||||
|
|
||||||
|
|
||||||
@@ -36,26 +42,63 @@ try:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if(path.exists('app/config/config.ini')):
|
if(path.exists(CONFIG_PATH)):
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(CONFIG_PATH)
|
||||||
|
|
||||||
|
# Get Plex config
|
||||||
try:
|
try:
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config.read(CONFIG_PATH)
|
|
||||||
PLEXUSER = config.get(BOT_SECTION, 'plex_user')
|
PLEXUSER = config.get(BOT_SECTION, 'plex_user')
|
||||||
PLEXPASS = config.get(BOT_SECTION, 'plex_pass')
|
PLEXPASS = config.get(BOT_SECTION, 'plex_pass')
|
||||||
PLEX_SERVER_NAME = config.get(BOT_SECTION, 'plex_server_name')
|
PLEX_SERVER_NAME = config.get(BOT_SECTION, 'plex_server_name')
|
||||||
except:
|
except:
|
||||||
pass
|
print("Could not load plex config")
|
||||||
|
|
||||||
if(path.exists('app/config/config.ini')):
|
# Get Plex roles config
|
||||||
try:
|
try:
|
||||||
roles = config.get(BOT_SECTION, 'plex_roles')
|
plex_roles = config.get(BOT_SECTION, 'plex_roles')
|
||||||
except:
|
except:
|
||||||
pass
|
print("Could not get Plex roles config")
|
||||||
if(path.exists('app/config/config.ini')):
|
|
||||||
|
# Get Plex libs config
|
||||||
try:
|
try:
|
||||||
Plex_LIBS = config.get(BOT_SECTION, 'plex_libs')
|
Plex_LIBS = config.get(BOT_SECTION, 'plex_libs')
|
||||||
except:
|
except:
|
||||||
pass
|
print("Could not get Plex libs config")
|
||||||
|
|
||||||
|
|
||||||
|
# Get Jellyfin config
|
||||||
|
try:
|
||||||
|
JELLYFIN_SERVER_URL = config.get(BOT_SECTION, 'jellyfin_server_url')
|
||||||
|
JELLYFIN_API_KEY = config.get(BOT_SECTION, "jellyfin_api_key")
|
||||||
|
except:
|
||||||
|
print("Could not load Jellyfin config")
|
||||||
|
|
||||||
|
# Get Jellyfin roles config
|
||||||
|
try:
|
||||||
|
jellyfin_roles = config.get(BOT_SECTION, 'jellyfin_roles')
|
||||||
|
except:
|
||||||
|
print("Could not get Jellyfin roles config")
|
||||||
|
|
||||||
|
# Get Jellyfin libs config
|
||||||
|
try:
|
||||||
|
jellyfin_libs = config.get(BOT_SECTION, 'jellyfin_libs')
|
||||||
|
except:
|
||||||
|
print("Could not get Jellyfin libs config")
|
||||||
|
|
||||||
|
# Get Enable config
|
||||||
|
try:
|
||||||
|
USE_JELLYFIN = config.get(BOT_SECTION, 'jellyfin_enabled')
|
||||||
|
except:
|
||||||
|
print("Could not get Jellyfin enable config. Defaulting to False")
|
||||||
|
USE_Jellyfin = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
USE_PLEX = config.get(BOT_SECTION, "plex_enabled")
|
||||||
|
except:
|
||||||
|
print("Could not get Plex enable config. Defaulting to False")
|
||||||
|
USE_PLEX = False
|
||||||
|
|
||||||
def get_config():
|
def get_config():
|
||||||
"""
|
"""
|
||||||
Function to return current config
|
Function to return current config
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ def get_useremail(username):
|
|||||||
if email:
|
if email:
|
||||||
return email
|
return email
|
||||||
else:
|
else:
|
||||||
return "No users found"
|
return "No email found"
|
||||||
except:
|
except:
|
||||||
return "error in fetching from db"
|
return "error in fetching from db"
|
||||||
else:
|
else:
|
||||||
@@ -122,6 +122,32 @@ def get_jellyfin_username(username):
|
|||||||
else:
|
else:
|
||||||
return "username cannot be empty"
|
return "username cannot be empty"
|
||||||
|
|
||||||
|
def remove_email(username):
|
||||||
|
"""
|
||||||
|
Sets email of discord user to null in database
|
||||||
|
"""
|
||||||
|
if username:
|
||||||
|
conn.execute(f"UPDATE clients SET email = null WHERE discord_username = '{username}'")
|
||||||
|
conn.commit()
|
||||||
|
print(f"Email removed from user {username} in database")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"Username cannot be empty.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def remove_jellyfin(username):
|
||||||
|
"""
|
||||||
|
Sets jellyfin username of discord user to null in database
|
||||||
|
"""
|
||||||
|
if username:
|
||||||
|
conn.execute(f"UPDATE clients SET jellyfin_username = null WHERE discord_username = '{username}'")
|
||||||
|
conn.commit()
|
||||||
|
print(f"Jellyfin username removed from user {username} in database")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"Username cannot be empty.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def delete_user(username):
|
def delete_user(username):
|
||||||
if username:
|
if username:
|
||||||
|
|||||||
175
app/bot/helper/jellyfinhelper.py
Normal file
175
app/bot/helper/jellyfinhelper.py
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
import requests
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
|
def add_user(jellyfin_url, jellyfin_api_key, username, password, jellyfin_libs):
|
||||||
|
try:
|
||||||
|
url = f"{jellyfin_url}/Users/New"
|
||||||
|
|
||||||
|
querystring = {"api_key":jellyfin_api_key}
|
||||||
|
payload = {
|
||||||
|
"Name": username,
|
||||||
|
"Password": password
|
||||||
|
}
|
||||||
|
headers = {"Content-Type": "application/json"}
|
||||||
|
response = requests.request("POST", url, json=payload, headers=headers, params=querystring)
|
||||||
|
userId = response.json()["Id"]
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
print(f"Error creating new Jellyfin user: {response.text}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Grant access to User
|
||||||
|
url = f"{jellyfin_url}/Users/{userId}/Policy"
|
||||||
|
|
||||||
|
querystring = {"api_key":jellyfin_api_key}
|
||||||
|
|
||||||
|
enabled_folders = []
|
||||||
|
server_libs = get_libraries(jellyfin_url, jellyfin_api_key)
|
||||||
|
|
||||||
|
if jellyfin_libs[0] != "all":
|
||||||
|
for lib in jellyfin_libs:
|
||||||
|
found = False
|
||||||
|
for server_lib in server_libs:
|
||||||
|
if lib == server_lib['Name']:
|
||||||
|
enabled_folders.append(server_lib['ItemId'])
|
||||||
|
found = True
|
||||||
|
if not found:
|
||||||
|
print(f"Couldn't find Jellyfin Library: {lib}")
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"IsAdministrator": False,
|
||||||
|
"IsHidden": True,
|
||||||
|
"IsDisabled": False,
|
||||||
|
"BlockedTags": [],
|
||||||
|
"EnableUserPreferenceAccess": True,
|
||||||
|
"AccessSchedules": [],
|
||||||
|
"BlockUnratedItems": [],
|
||||||
|
"EnableRemoteControlOfOtherUsers": False,
|
||||||
|
"EnableSharedDeviceControl": True,
|
||||||
|
"EnableRemoteAccess": True,
|
||||||
|
"EnableLiveTvManagement": True,
|
||||||
|
"EnableLiveTvAccess": True,
|
||||||
|
"EnableMediaPlayback": True,
|
||||||
|
"EnableAudioPlaybackTranscoding": True,
|
||||||
|
"EnableVideoPlaybackTranscoding": True,
|
||||||
|
"EnablePlaybackRemuxing": True,
|
||||||
|
"ForceRemoteSourceTranscoding": False,
|
||||||
|
"EnableContentDeletion": False,
|
||||||
|
"EnableContentDeletionFromFolders": [],
|
||||||
|
"EnableContentDownloading": True,
|
||||||
|
"EnableSyncTranscoding": True,
|
||||||
|
"EnableMediaConversion": True,
|
||||||
|
"EnabledDevices": [],
|
||||||
|
"EnableAllDevices": True,
|
||||||
|
"EnabledChannels": [],
|
||||||
|
"EnableAllChannels": False,
|
||||||
|
"EnabledFolders": enabled_folders,
|
||||||
|
"EnableAllFolders": jellyfin_libs[0] == "all",
|
||||||
|
"InvalidLoginAttemptCount": 0,
|
||||||
|
"LoginAttemptsBeforeLockout": -1,
|
||||||
|
"MaxActiveSessions": 0,
|
||||||
|
"EnablePublicSharing": True,
|
||||||
|
"BlockedMediaFolders": [],
|
||||||
|
"BlockedChannels": [],
|
||||||
|
"RemoteClientBitrateLimit": 0,
|
||||||
|
"AuthenticationProviderId": "Jellyfin.Server.Implementations.Users.DefaultAuthenticationProvider",
|
||||||
|
"PasswordResetProviderId": "Jellyfin.Server.Implementations.Users.DefaultPasswordResetProvider",
|
||||||
|
"SyncPlayAccess": "CreateAndJoinGroups"
|
||||||
|
}
|
||||||
|
headers = {"content-type": "application/json"}
|
||||||
|
|
||||||
|
response = requests.request("POST", url, json=payload, headers=headers, params=querystring)
|
||||||
|
|
||||||
|
if response.status_code == 200 or response.status_code == 204:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"Error setting user permissions: {response.text}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_libraries(jellyfin_url, jellyfin_api_key):
|
||||||
|
url = f"{jellyfin_url}/Library/VirtualFolders"
|
||||||
|
querystring = {"api_key":jellyfin_api_key}
|
||||||
|
response = requests.request("GET", url, params=querystring)
|
||||||
|
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
|
||||||
|
def verify_username(jellyfin_url, jellyfin_api_key, username):
|
||||||
|
users = get_users(jellyfin_url, jellyfin_api_key)
|
||||||
|
valid = True
|
||||||
|
for user in users:
|
||||||
|
if user['Name'] == username:
|
||||||
|
valid = False
|
||||||
|
break
|
||||||
|
|
||||||
|
return valid
|
||||||
|
|
||||||
|
def remove_user(jellyfin_url, jellyfin_api_key, jellyfin_username):
|
||||||
|
try:
|
||||||
|
# Get User ID
|
||||||
|
users = get_users(jellyfin_url, jellyfin_api_key)
|
||||||
|
userId = None
|
||||||
|
for user in users:
|
||||||
|
if user['Name'].lower() == jellyfin_username.lower():
|
||||||
|
userId = user['Id']
|
||||||
|
|
||||||
|
if userId is None:
|
||||||
|
# User not found
|
||||||
|
print(f"Error removing user {jellyfin_username} from Jellyfin: Could not find user.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Delete User
|
||||||
|
url = f"{jellyfin_url}/Users/{userId}"
|
||||||
|
|
||||||
|
querystring = {"api_key":jellyfin_api_key}
|
||||||
|
response = requests.request("DELETE", url, params=querystring)
|
||||||
|
|
||||||
|
if response.status_code == 204 or response.status_code == 200:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"Error deleting Jellyfin user: {response.text}")
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_users(jellyfin_url, jellyfin_api_key):
|
||||||
|
url = f"{jellyfin_url}/Users"
|
||||||
|
|
||||||
|
querystring = {"api_key":jellyfin_api_key}
|
||||||
|
response = requests.request("GET", url, params=querystring)
|
||||||
|
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
def generate_password(length, lower=True, upper=True, numbers=True, symbols=True):
|
||||||
|
character_list = []
|
||||||
|
if not (lower or upper or numbers or symbols):
|
||||||
|
raise ValueError("At least one character type must be provided")
|
||||||
|
|
||||||
|
if lower:
|
||||||
|
character_list += string.ascii_lowercase
|
||||||
|
if upper:
|
||||||
|
character_list += string.ascii_uppercase
|
||||||
|
if numbers:
|
||||||
|
character_list += string.digits
|
||||||
|
if symbols:
|
||||||
|
character_list += string.punctuation
|
||||||
|
|
||||||
|
return "".join(random.choice(character_list) for i in range(length))
|
||||||
|
|
||||||
|
def get_config(jellyfin_url, jellyfin_api_key):
|
||||||
|
url = f"{jellyfin_url}/System/Configuration"
|
||||||
|
|
||||||
|
querystring = {"api_key":jellyfin_api_key}
|
||||||
|
response = requests.request("GET", url, params=querystring)
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
def get_status(jellyfin_url, jellyfin_api_key):
|
||||||
|
url = f"{jellyfin_url}/System/Configuration"
|
||||||
|
|
||||||
|
querystring = {"api_key":jellyfin_api_key}
|
||||||
|
response = requests.request("GET", url, params=querystring)
|
||||||
|
return response.status_code
|
||||||
@@ -46,7 +46,4 @@ def plexremoveinvite(plex, plexname):
|
|||||||
def verifyemail(addressToVerify):
|
def verifyemail(addressToVerify):
|
||||||
regex = '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$'
|
regex = '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$'
|
||||||
match = re.match(regex, addressToVerify.lower())
|
match = re.match(regex, addressToVerify.lower())
|
||||||
if match == None:
|
return match != None
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
@@ -3,3 +3,5 @@ plex.py==0.9.0
|
|||||||
PlexAPI==4.0.0
|
PlexAPI==4.0.0
|
||||||
texttable
|
texttable
|
||||||
python-dotenv
|
python-dotenv
|
||||||
|
jellyfin-apiclient-python
|
||||||
|
requests
|
||||||
153
run.py
153
run.py
@@ -4,8 +4,9 @@ from discord.ext import commands, tasks
|
|||||||
from discord.utils import get
|
from discord.utils import get
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
import sys
|
||||||
from app.bot.helper.confighelper import switch, Discord_bot_token, plex_roles
|
from app.bot.helper.confighelper import switch, Discord_bot_token, plex_roles, jellyfin_roles
|
||||||
import app.bot.helper.confighelper as confighelper
|
import app.bot.helper.confighelper as confighelper
|
||||||
|
import app.bot.helper.jellyfinhelper as jelly
|
||||||
maxroles = 10
|
maxroles = 10
|
||||||
|
|
||||||
print(f"Discord Bot Token: {Discord_bot_token}")
|
print(f"Discord Bot Token: {Discord_bot_token}")
|
||||||
@@ -15,11 +16,16 @@ if plex_roles is None:
|
|||||||
else:
|
else:
|
||||||
plex_roles = list(plex_roles.split(','))
|
plex_roles = list(plex_roles.split(','))
|
||||||
|
|
||||||
|
if jellyfin_roles is None:
|
||||||
|
jellyfin_roles = []
|
||||||
|
else:
|
||||||
|
jellyfin_roles = list(jellyfin_roles.split(','))
|
||||||
|
|
||||||
if switch == 0:
|
if switch == 0:
|
||||||
print("Missing Config.")
|
print("Missing Config.")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
print("V 1.0")
|
print("V 1.1")
|
||||||
|
|
||||||
intents = discord.Intents.default()
|
intents = discord.Intents.default()
|
||||||
intents.members = True
|
intents.members = True
|
||||||
@@ -39,12 +45,21 @@ async def on_message(message):
|
|||||||
return
|
return
|
||||||
await bot.process_commands(message)
|
await bot.process_commands(message)
|
||||||
|
|
||||||
|
# these were copied from the app object. They could be made static instead but I'm lazy.
|
||||||
|
async def embederror(author, message):
|
||||||
|
embed1 = discord.Embed(title="ERROR",description=message, color=0xf50000)
|
||||||
|
await author.send(embed=embed1)
|
||||||
|
|
||||||
|
async def embedinfo(author, message):
|
||||||
|
embed1 = discord.Embed(title=message, color=0x00F500)
|
||||||
|
await author.send(embed=embed1)
|
||||||
|
|
||||||
def reload():
|
def reload():
|
||||||
bot.reload_extension(f'app.bot.cogs.app')
|
bot.reload_extension(f'app.bot.cogs.app')
|
||||||
|
|
||||||
async def getplex(ctx, type):
|
async def getuser(ctx, server, type):
|
||||||
value = None
|
value = None
|
||||||
await ctx.author.send("Please reply with your Plex {}:".format(type))
|
await ctx.author.send("Please reply with your {} {}:".format(server, type))
|
||||||
while(value == None):
|
while(value == None):
|
||||||
def check(m):
|
def check(m):
|
||||||
return m.author == ctx.author and not m.guild
|
return m.author == ctx.author and not m.guild
|
||||||
@@ -71,18 +86,18 @@ async def plexroleadd(ctx, role: discord.Role):
|
|||||||
@bot.command()
|
@bot.command()
|
||||||
@commands.has_permissions(administrator=True)
|
@commands.has_permissions(administrator=True)
|
||||||
async def setupplex(ctx):
|
async def setupplex(ctx):
|
||||||
username = ""
|
username = None
|
||||||
pasword = ""
|
password = None
|
||||||
servername = ""
|
servername = None
|
||||||
username = await getplex(ctx, "username")
|
username = await getuser(ctx, "Plex", "username")
|
||||||
if username is None:
|
if username is None:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
password = await getplex(ctx, "password")
|
password = await getuser(ctx, "Plex", "password")
|
||||||
if password is None:
|
if password is None:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
servername = await getplex(ctx, "servername")
|
servername = await getuser(ctx, "Plex", "servername")
|
||||||
if servername is None:
|
if servername is None:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
@@ -95,19 +110,131 @@ async def setupplex(ctx):
|
|||||||
await ctx.author.send("Bot has been restarted. Give it a few seconds. Please check logs and make sure you see the line: `Logged into plex`. If not run this command again and make sure you enter the right values. ")
|
await ctx.author.send("Bot has been restarted. Give it a few seconds. Please check logs and make sure you see the line: `Logged into plex`. If not run this command again and make sure you enter the right values. ")
|
||||||
print("Bot has been restarted. Give it a few seconds.")
|
print("Bot has been restarted. Give it a few seconds.")
|
||||||
|
|
||||||
|
@bot.command()
|
||||||
|
@commands.has_permissions(administrator=True)
|
||||||
|
async def jellyroleadd(ctx, role: discord.Role):
|
||||||
|
if len(jellyfin_roles) <= maxroles:
|
||||||
|
jellyfin_roles.append(role.name)
|
||||||
|
print (f"new jellyfin roles: {jellyfin_roles}")
|
||||||
|
saveroles = ",".join(jellyfin_roles)
|
||||||
|
print (f"saveroles: {saveroles}")
|
||||||
|
confighelper.change_config("jellyfin_roles", saveroles)
|
||||||
|
await ctx.author.send("Updated Jellyfin roles. Bot is restarting. Please wait.")
|
||||||
|
print("Jellyfin roles updated. Restarting bot.")
|
||||||
|
reload()
|
||||||
|
await ctx.author.send("Bot has been restarted. Give it a few seconds.")
|
||||||
|
print("Bot has been restarted. Give it a few seconds.")
|
||||||
|
|
||||||
|
@bot.command()
|
||||||
|
@commands.has_permissions(administrator=True)
|
||||||
|
async def setupjelly(ctx):
|
||||||
|
jellyfin_api_key = None
|
||||||
|
jellyfin_server_url = None
|
||||||
|
|
||||||
|
jellyfin_server_url = await getuser(ctx, "Jellyfin", "Server Url")
|
||||||
|
if jellyfin_server_url is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
jellyfin_api_key = await getuser(ctx, "Jellyfin", "API Key")
|
||||||
|
if jellyfin_api_key is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
server_status = jelly.get_status(jellyfin_server_url, jellyfin_api_key)
|
||||||
|
if server_status == 200:
|
||||||
|
pass
|
||||||
|
elif server_status == 401:
|
||||||
|
# Unauthorized
|
||||||
|
await embederror(ctx.author, "API key provided is invalid")
|
||||||
|
return
|
||||||
|
elif server_status == 403:
|
||||||
|
# Forbidden
|
||||||
|
await embederror(ctx.author, "API key provided does not have permissions")
|
||||||
|
return
|
||||||
|
elif server_status == 404:
|
||||||
|
# page not found
|
||||||
|
await embederror(ctx.author, "Server endpoint provided was not found")
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
print("Exception while testing Jellyfin connection")
|
||||||
|
print(e)
|
||||||
|
await embederror(ctx.author, "Could not connect to server. Check logs for more details.")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
jellyfin_server_url = jellyfin_server_url.rstrip('/')
|
||||||
|
confighelper.change_config("jellyfin_server_url", str(jellyfin_server_url))
|
||||||
|
confighelper.change_config("jellyfin_api_key", str(jellyfin_api_key))
|
||||||
|
print("Jellyfin server URL and API key updated. Restarting bot.")
|
||||||
|
await ctx.author.send("Jellyfin server URL and API key updated. Restarting bot.")
|
||||||
|
reload()
|
||||||
|
await ctx.author.send("Bot has been restarted. Give it a few seconds. Please check logs and make sure you see the line: `Connected to Jellyfin`. If not run this command again and make sure you enter the right values. ")
|
||||||
|
print("Bot has been restarted. Give it a few seconds.")
|
||||||
|
|
||||||
|
|
||||||
@bot.command()
|
@bot.command()
|
||||||
@commands.has_permissions(administrator=True)
|
@commands.has_permissions(administrator=True)
|
||||||
async def setupplexlibs(ctx):
|
async def setupplexlibs(ctx):
|
||||||
libs = ""
|
libs = await getuser(ctx, "Plex", "libs")
|
||||||
libs = await getplex(ctx, "libs")
|
|
||||||
if libs is None:
|
if libs is None:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
confighelper.change_config("plex_libs", str(libs))
|
confighelper.change_config("plex_libs", str(libs))
|
||||||
print("Plex libraries updated. Restarting bot. Please wait.")
|
print("Plex libraries updated. Restarting bot. Please wait.")
|
||||||
reload()
|
reload()
|
||||||
await ctx.author.send("Bot has been restarted. Give it a few seconds. Please check logs and make sure you see the line: `Logged into plex`. If not run this command again and make sure you enter the right values. ")
|
await ctx.author.send("Bot has been restarted. Give it a few seconds.")
|
||||||
print("Bot has been restarted. Give it a few seconds.")
|
print("Bot has been restarted. Give it a few seconds.")
|
||||||
|
|
||||||
|
@bot.command()
|
||||||
|
@commands.has_permissions(administrator=True)
|
||||||
|
async def setupjellylibs(ctx):
|
||||||
|
libs = await getuser(ctx, "Jellyfin", "libs")
|
||||||
|
if libs is None:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
confighelper.change_config("jellyfin_libs", str(libs))
|
||||||
|
print("Jellyfin libraries updated. Restarting bot. Please wait.")
|
||||||
|
reload()
|
||||||
|
await ctx.author.send("Bot has been restarted. Give it a few seconds.")
|
||||||
|
print("Bot has been restarted. Give it a few seconds.")
|
||||||
|
|
||||||
|
# Enable / Disable Plex integration
|
||||||
|
@bot.command(aliases=["plexenable"])
|
||||||
|
@commands.has_permissions(administrator=True)
|
||||||
|
async def enableplex(ctx):
|
||||||
|
confighelper.change_config("plex_enabled", True)
|
||||||
|
print("Plex enabled, reloading server")
|
||||||
|
reload()
|
||||||
|
await ctx.author.send("Bot has restarted. Give it a few seconds.")
|
||||||
|
print("Bot has restarted. Give it a few seconds.")
|
||||||
|
|
||||||
|
@bot.command(aliases=["plexdisable"])
|
||||||
|
@commands.has_permissions(administrator=True)
|
||||||
|
async def disableplex(ctx):
|
||||||
|
confighelper.change_config("plex_enabled", False)
|
||||||
|
print("Plex disabled, reloading server")
|
||||||
|
reload()
|
||||||
|
await ctx.author.send("Bot has restarted. Give it a few seconds.")
|
||||||
|
print("Bot has restarted. Give it a few seconds.")
|
||||||
|
|
||||||
|
# Enable / Disable Jellyfin integration
|
||||||
|
@bot.command(aliases=["jellyenable"])
|
||||||
|
@commands.has_permissions(administrator=True)
|
||||||
|
async def enablejellyfin(ctx):
|
||||||
|
confighelper.change_config("jellyfin_enabled", True)
|
||||||
|
print("Jellyfin enabled, reloading server")
|
||||||
|
reload()
|
||||||
|
await ctx.author.send("Bot has restarted. Give it a few seconds.")
|
||||||
|
print("Bot has restarted. Give it a few seconds.")
|
||||||
|
|
||||||
|
@bot.command(aliases=["jellydisable"])
|
||||||
|
@commands.has_permissions(administrator=True)
|
||||||
|
async def disablejellyfin(ctx):
|
||||||
|
confighelper.change_config("jellyfin_enabled", False)
|
||||||
|
print("Jellyfin disabled, reloading server")
|
||||||
|
reload()
|
||||||
|
await ctx.author.send("Bot has restarted. Give it a few seconds.")
|
||||||
|
print("Bot has restarted. Give it a few seconds.")
|
||||||
|
|
||||||
bot.load_extension(f'app.bot.cogs.app')
|
bot.load_extension(f'app.bot.cogs.app')
|
||||||
bot.run(Discord_bot_token)
|
bot.run(Discord_bot_token)
|
||||||
Reference in New Issue
Block a user