feat: Jellyfin integration finished
- Finsihed Jellyfin integration with auto-add and auto-remove - Integration toggle in config task: none
This commit is contained in:
@@ -8,7 +8,8 @@ config = configparser.ConfigParser()
|
||||
|
||||
CONFIG_KEYS = ['username', 'password', 'discord_bot_token', 'plex_user', 'plex_pass',
|
||||
'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
|
||||
Discord_bot_token = ""
|
||||
@@ -17,6 +18,11 @@ PLEXUSER = ""
|
||||
PLEXPASS = ""
|
||||
PLEX_SERVER_NAME = ""
|
||||
Plex_LIBS = None
|
||||
JELLYFIN_SERVER_URL = ""
|
||||
JELLYFIN_API_KEY = ""
|
||||
jellyfin_libs = ""
|
||||
jellyfin_roles = None
|
||||
|
||||
switch = 0
|
||||
|
||||
|
||||
@@ -36,26 +42,63 @@ try:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
if(path.exists('app/config/config.ini')):
|
||||
if(path.exists(CONFIG_PATH)):
|
||||
config = configparser.ConfigParser()
|
||||
config.read(CONFIG_PATH)
|
||||
|
||||
# Get Plex config
|
||||
try:
|
||||
config = configparser.ConfigParser()
|
||||
config.read(CONFIG_PATH)
|
||||
PLEXUSER = config.get(BOT_SECTION, 'plex_user')
|
||||
PLEXPASS = config.get(BOT_SECTION, 'plex_pass')
|
||||
PLEX_SERVER_NAME = config.get(BOT_SECTION, 'plex_server_name')
|
||||
except:
|
||||
pass
|
||||
print("Could not load plex config")
|
||||
|
||||
if(path.exists('app/config/config.ini')):
|
||||
# Get Plex roles config
|
||||
try:
|
||||
roles = config.get(BOT_SECTION, 'plex_roles')
|
||||
plex_roles = config.get(BOT_SECTION, 'plex_roles')
|
||||
except:
|
||||
pass
|
||||
if(path.exists('app/config/config.ini')):
|
||||
print("Could not get Plex roles config")
|
||||
|
||||
# Get Plex libs config
|
||||
try:
|
||||
Plex_LIBS = config.get(BOT_SECTION, 'plex_libs')
|
||||
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():
|
||||
"""
|
||||
Function to return current config
|
||||
|
||||
@@ -94,7 +94,7 @@ def get_useremail(username):
|
||||
if email:
|
||||
return email
|
||||
else:
|
||||
return "No users found"
|
||||
return "No email found"
|
||||
except:
|
||||
return "error in fetching from db"
|
||||
else:
|
||||
@@ -122,6 +122,32 @@ def get_jellyfin_username(username):
|
||||
else:
|
||||
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):
|
||||
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):
|
||||
regex = '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$'
|
||||
match = re.match(regex, addressToVerify.lower())
|
||||
if match == None:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
return match != None
|
||||
Reference in New Issue
Block a user