Files
Membarr/run.py
fixebr@gmail.com 359ea8b4e5 fix1
2024-02-04 20:50:48 +03:00

347 lines
18 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from pydoc import describe
import discord
import os
from discord.ext import commands, tasks
from discord.utils import get
from discord.ui import Button, View, Select
from discord import app_commands
import asyncio
import sys
from app.bot.helper.confighelper import MEMBARR_VERSION, switch, Discord_bot_token, plex_roles, jellyfin_roles, DISCORD_SERVER_PERM
import app.bot.helper.confighelper as confighelper
import app.bot.helper.jellyfinhelper as jelly
from app.bot.helper.message import *
from requests import ConnectTimeout
from plexapi.myplex import MyPlexAccount
maxroles = 10
if switch == 0:
print("Потеря конфига.")
sys.exit()
class Bot(commands.Bot):
def __init__(self) -> None:
print("Инициализация дискорд бота")
intents = discord.Intents.all()
intents.members = True
intents.message_content = True
super().__init__(command_prefix=".", intents=intents)
async def on_ready(self):
print("Бот онлайн.")
for guild in self.guilds:
print("Синхронизация команд с " + guild.name)
self.tree.copy_global_to(guild=guild)
await self.tree.sync(guild=guild)
async def on_guild_join(self, guild):
print(f"Зашёл на сервер {guild.name}")
print(f"Синхронизация команд с {guild.name}")
self.tree.copy_global_to(guild=guild)
await self.tree.sync(guild=guild)
async def setup_hook(self):
print("Загрузка подключений медиасервера")
await self.load_extension(f'app.bot.cogs.app')
bot = Bot()
async def reload():
await bot.reload_extension(f'app.bot.cogs.app')
async def getuser(interaction, server, type):
value = None
await interaction.user.send("Пожалуйста, ответьте с вашим {} {}:".format(server, type))
while (value == None):
def check(m):
return m.author == interaction.user and not m.guild
try:
value = await bot.wait_for('message', timeout=200, check=check)
return value.content
except asyncio.TimeoutError:
message = "Тайм-аут. Попробуйте снова."
return None
plex_commands = app_commands.Group(name="plexsettings", description="Membarr Plex команды")
jellyfin_commands = app_commands.Group(name="jellyfinsettings", description="Membarr Jellyfin команды")
@plex_commands.command(name="addrole", description="Роль для автоматического создания пользователя в Plex")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def plexroleadd(interaction: discord.Interaction, role: discord.Role):
if len(plex_roles) <= maxroles:
# Do not add roles multiple times.
if role.name in plex_roles:
await embederror(interaction.response, f"Plex роль \"{role.name}\" добавлена.")
return
plex_roles.append(role.name)
saveroles = ",".join(plex_roles)
confighelper.change_config("plex_roles", saveroles)
await interaction.response.send_message("Обновлены роли Plex. Бот перезапускается. ЖДИТЕ.", ephemeral=True)
print("Обновлены роли Plex. Бот перезапускается. Дайте ему уже поработать!")
await reload()
print("Бот перезапущен. ЖДИТЕ, ему нужно время, чтобы запуститься!")
@plex_commands.command(name="removerole", description="Прекратить создавать пользователй Plex с помощью ролей.")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def plexroleremove(interaction: discord.Interaction, role: discord.Role):
if role.name not in plex_roles:
await embederror(interaction.response, f"\"{role.name}\" больше не связана с Plex.")
return
plex_roles.remove(role.name)
confighelper.change_config("plex_roles", ",".join(plex_roles))
await interaction.response.send_message(f"Membarr больше не будет ассоциировать \"{role.name}\" с Plex", ephemeral=True)
@plex_commands.command(name="listroles", description="Список всех ролей, участники которых будут автоматически добавлены в Plex.")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def plexrolels(interaction: discord.Interaction):
await interaction.response.send_message(
"Следующие роли автоматически добавляются в Plex:\n" +
", ".join(plex_roles), ephemeral=True
)
@plex_commands.command(name="setup", description="Настройка интеграции с Plex")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def setupplex(interaction: discord.Interaction, username: str, password: str, server_name: str,
base_url: str = "", save_token: bool = True):
await interaction.response.defer()
try:
account = MyPlexAccount(username, password)
plex = account.resource(server_name).connect()
except Exception as e:
if str(e).startswith("(429)"):
await embederror(interaction.followup, "Слишком много запросов. Пожалуйста, повторите попытку позже.")
return
await embederror(interaction.followup, "Не удалось подключиться к серверу Plex. Пожалуйста, проверьте свои учетные данные.")
return
if (save_token):
# Save new config entries
confighelper.change_config("plex_base_url", plex._baseurl if base_url == "" else base_url)
confighelper.change_config("plex_token", plex._token)
confighelper.change_config("plex_server_name", server_name)
# Delete old config entries
confighelper.change_config("plex_user", "")
confighelper.change_config("plex_pass", "")
else:
# Save new config entries
confighelper.change_config("plex_user", username)
confighelper.change_config("plex_pass", password)
confighelper.change_config("plex_server_name", server_name)
# Delete old config entries
confighelper.change_config("plex_base_url", "")
confighelper.change_config("plex_token", "")
print("Обновлены сведения об аутентификации в Plex. Перезапуск бота.")
await interaction.followup.send(
"Обновлены сведения об аутентификации в Plex. Перезапуск бота. ЖДИТЕ.\n" +
"Пожалуйста, проверьте журналы и убедитесь, что вы видите эту строку: `Вошел в plex`. Если это не так, выполните эту команду еще раз и убедитесь, что ввели правильные значения.",
ephemeral=True
)
await reload()
print("Бот был перезапущен. Дайте ему несколько секунд.")
@jellyfin_commands.command(name="addrole", description="Добавление роли для автоматического добавления пользователей в Jellyfin")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def jellyroleadd(interaction: discord.Interaction, role: discord.Role):
if len(jellyfin_roles) <= maxroles:
# Do not add roles multiple times.
if role.name in jellyfin_roles:
await embederror(interaction.response, f"Jellyfin роль \"{role.name}\" добавлена.")
return
jellyfin_roles.append(role.name)
saveroles = ",".join(jellyfin_roles)
confighelper.change_config("jellyfin_roles", saveroles)
await interaction.response.send_message("Обновлены роли Jellyfin. Бот перезапускается. Пожалуйста, подождите несколько секунд.",
ephemeral=True)
print("Обновлены роли Jellyfin. Перезапуск бота.")
await reload()
print("Бот был перезапущен. Дайте ему несколько секунд.")
@jellyfin_commands.command(name="removerole", description="Прекращение добавления пользователей с ролью в Jellyfin")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def jellyroleremove(interaction: discord.Interaction, role: discord.Role):
if role.name not in jellyfin_roles:
await embederror(interaction.response, f"\"{role.name}\" больше не связана с Jellyfin.")
return
jellyfin_roles.remove(role.name)
confighelper.change_config("jellyfin_roles", ",".join(jellyfin_roles))
await interaction.response.send_message(f"Membarr больше не будет ассоциировать \"{role.name}\" с Jellyfin",
ephemeral=True)
@jellyfin_commands.command(name="listroles",
description="Список всех ролей, участники которых будут автоматически добавлены в Jellyfin.")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def jellyrolels(interaction: discord.Interaction):
await interaction.response.send_message(
"Следующие роли автоматически добавляются в Jellyfin:\n" +
", ".join(jellyfin_roles), ephemeral=True
)
@jellyfin_commands.command(name="setup", description="Настройка интеграции Jellyfin")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def setupjelly(interaction: discord.Interaction, server_url: str, api_key: str, external_url: str = None):
await interaction.response.defer()
# get rid of training slashes
server_url = server_url.rstrip('/')
try:
server_status = jelly.get_status(server_url, api_key)
if server_status == 200:
pass
elif server_status == 401:
# Unauthorized
await embederror(interaction.followup, "Предоставленный ключ API неправильный.")
return
elif server_status == 403:
# Forbidden
await embederror(interaction.followup, "Предоставленный ключ API не имеет прав доступа")
return
elif server_status == 404:
# page not found
await embederror(interaction.followup, "Указанная конечная точка сервера не найдена")
return
else:
await embederror(interaction.followup,
"При подключении к Jellyfin произошла неизвестная ошибка. Проверьте журналы Membarr.")
except ConnectTimeout as e:
await embederror(interaction.followup,
"Время соединения с сервером истекло. Убедитесь, что Jellyfin онлайн и доступен.")
return
except Exception as e:
print("Исключение при тестировании соединения с Jellyfin")
print(type(e).__name__)
print(e)
await embederror(interaction.followup, "Неизвестное исключение при подключении к Jellyfin. Проверьте журналы Membarr")
return
confighelper.change_config("jellyfin_server_url", str(server_url))
confighelper.change_config("jellyfin_api_key", str(api_key))
if external_url is not None:
confighelper.change_config("jellyfin_external_url", str(external_url))
else:
confighelper.change_config("jellyfin_external_url", "")
print("URL-адрес сервера Jellyfin и ключ API обновлены. Перезапуск бота.")
await interaction.followup.send("URL-адрес сервера Jellyfin и ключ API обновлены. Перезапуск бота.", ephemeral=True)
await reload()
print("Бот был перезапущен. Дайте ему несколько секунд.")
@plex_commands.command(name="setuplibs", description="Библиотеки настройки, к которым могут получить доступ новые пользователи")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def setupplexlibs(interaction: discord.Interaction, libraries: str):
if not libraries:
await embederror(interaction.response, "строка библиотек пуста.")
return
else:
# Do some fancy python to remove spaces from libraries string, but only where wanted.
libraries = ",".join(list(map(lambda lib: lib.strip(), libraries.split(","))))
confighelper.change_config("plex_libs", str(libraries))
print("Обновлены библиотеки Plex. Перезапуск бота. Пожалуйста, подождите.")
await interaction.response.send_message("Обновлены библиотеки Plex. Пожалуйста, подождите несколько секунд, пока бот перезапустится.",
ephemeral=True)
await reload()
print("Бот был перезапущен. Дайте ему несколько секунд.")
@jellyfin_commands.command(name="setuplibs", description="Настройка библиотек, к которым могут получить доступ новые пользователи")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def setupjellylibs(interaction: discord.Interaction, libraries: str):
if not libraries:
await embederror(interaction.response, "строка библиотек пуста.")
return
else:
# Do some fancy python to remove spaces from libraries string, but only where wanted.
libraries = ",".join(list(map(lambda lib: lib.strip(), libraries.split(","))))
confighelper.change_config("jellyfin_libs", str(libraries))
print("Обновлены библиотеки Jellyfin. Перезапуск бота. Пожалуйста, подождите.")
await interaction.response.send_message(
"Обновлены библиотеки Jellyfin. Пожалуйста, подождите несколько секунд, пока бот перезапустится.", ephemeral=True)
await reload()
print("Бот был перезапущен. Дайте ему несколько секунд.")
# Enable / Disable Plex integration
@plex_commands.command(name="enable", description="Включение автоматического добавления пользователей в Plex")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def enableplex(interaction: discord.Interaction):
if confighelper.USE_PLEX:
await interaction.response.send_message("Plex уже включен.", ephemeral=True)
return
confighelper.change_config("plex_enabled", True)
print("Plex включен, перезагрузка сервера")
await reload()
confighelper.USE_PLEX = True
await interaction.response.send_message("Plex включен. Перезапуск сервера. Дайте ему несколько секунд.", ephemeral=True)
print("Бот перезапущен. Дайте ему несколько секунд.")
@plex_commands.command(name="disable", description="Отключение добавления пользователей в Plex")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def disableplex(interaction: discord.Interaction):
if not confighelper.USE_PLEX:
await interaction.response.send_message("Plex уже отключен.", ephemeral=True)
return
confighelper.change_config("plex_enabled", False)
print("Plex отключен, перезагрузка сервера")
await reload()
confighelper.USE_PLEX = False
await interaction.response.send_message("Plex отключен. Перезапуск сервера. Дайте ему несколько секунд.", ephemeral=True)
print("Бот перезапущен. Дайте ему несколько секунд.")
# Enable / Disable Jellyfin integration
@jellyfin_commands.command(name="enable", description="Включение добавления пользователей в Jellyfin")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def enablejellyfin(interaction: discord.Interaction):
if confighelper.USE_JELLYFIN:
await interaction.response.send_message("Jellyfin уже включен.", ephemeral=True)
return
confighelper.change_config("jellyfin_enabled", True)
print("Jellyfin включен, перезагрузка сервера")
confighelper.USE_JELLYFIN = True
await reload()
await interaction.response.send_message("Jellyfin включен. Перезапуск сервера. Дайте ему несколько секунд.",
ephemeral=True)
print("Бот перезапущен. Дайте ему несколько секунд.")
@jellyfin_commands.command(name="disable", description="Отключение добавления пользователей в Jellyfin")
@app_commands.checks.has_role(DISCORD_SERVER_PERM)
async def disablejellyfin(interaction: discord.Interaction):
if not confighelper.USE_JELLYFIN:
await interaction.response.send_message("Jellyfin уже отключен.", ephemeral=True)
return
confighelper.change_config("jellyfin_enabled", False)
print("Jellyfin отключен, перезагрузка сервера")
await reload()
confighelper.USE_JELLYFIN = False
await interaction.response.send_message("Jellyfin отключен. Перезапуск сервера. Дайте ему несколько секунд.",
ephemeral=True)
print("Бот перезапущен. Дайте ему несколько секунд.")
bot.tree.add_command(plex_commands)
bot.tree.add_command(jellyfin_commands)
bot.run(Discord_bot_token)