diff options
author | Parker <contact@pkrm.dev> | 2024-05-18 20:06:51 -0500 |
---|---|---|
committer | Parker <contact@pkrm.dev> | 2024-05-18 20:06:51 -0500 |
commit | 32ab780b461c1c2b5e3e34c35b5902ed7006b95e (patch) | |
tree | b8717f5d5136b36c3d9bfe9e00346a7747003596 /code/func | |
parent | f0ec1c5a896744e4cdaa377a50b6277562a29f7f (diff) |
Create CordArr
Diffstat (limited to 'code/func')
-rw-r--r-- | code/func/jellyfin.py | 64 | ||||
-rw-r--r-- | code/func/radarr.py | 163 |
2 files changed, 227 insertions, 0 deletions
diff --git a/code/func/jellyfin.py b/code/func/jellyfin.py new file mode 100644 index 0000000..d434c17 --- /dev/null +++ b/code/func/jellyfin.py @@ -0,0 +1,64 @@ +import datetime +import requests +import random +import string +import sqlite3 + +from global_variables import JELLYFIN_URL, JELLYFIN_HEADERS, ACCOUNT_TIME + +""" +Create a new Jellyfin account for the user and return the username and password +""" + + +def create_jellyfin_account(user_id): + username = "".join(random.choices(string.ascii_lowercase + string.digits, k=5)) + password = "".join(random.choices(string.ascii_lowercase + string.digits, k=15)) + + deletion_time = datetime.datetime.now() + datetime.timedelta(hours=ACCOUNT_TIME) + # Create the new Jellyfin account + request_1 = requests.post( + f"{JELLYFIN_URL}/Users/New", + headers=JELLYFIN_HEADERS, + json={"Name": username, "Password": password}, + ) + if request_1.status_code != 200: + return False + + # Get the user ID of the new account + jellyfin_user_id = request_1.json()["Id"] + # Get the account policy and make edits + request_2 = requests.get( + f"{JELLYFIN_URL}/Users/{jellyfin_user_id}", headers=JELLYFIN_HEADERS + ) + if request_2.status_code != 200: + return False + + account_policy = request_2.json() + account_policy["Policy"]["SyncPlayAccess"] = "JoinGroups" + account_policy["Policy"]["EnableContentDownloading"] = False + account_policy["Policy"]["InvalidLoginAttemptCount"] = 3 + account_policy["Policy"]["MaxActiveSessions"] = 1 + # Update the user with the newly edited policy + request_3 = requests.post( + f"{JELLYFIN_URL}/Users?userId={jellyfin_user_id}", + headers=JELLYFIN_HEADERS, + json=account_policy, + ) + if request_3.status_code != 204: + print(request_3.json()) + print(request_3.status_code) + print("BROKEN AT REQUEST 3") + return False + + # Add the information to the database + db = sqlite3.connect("cordarr.db") + cursor = db.cursor() + cursor.execute( + "INSERT INTO jellyfin_accounts (user_id, jellyfin_user_id, deletion_time) VALUES (?, ?, ?)", + (user_id, jellyfin_user_id, deletion_time), + ) + db.commit() + db.close() + + return username, password diff --git a/code/func/radarr.py b/code/func/radarr.py new file mode 100644 index 0000000..463266c --- /dev/null +++ b/code/func/radarr.py @@ -0,0 +1,163 @@ +import requests +import sqlite3 +import discord + +from global_variables import ( + RADARR_HOST_URL, + RADARR_HEADERS, + ROOT_FOLDER_PATH, + QUALITY_PROFILE_ID, +) + +""" +Add a specific movie to the Radarr library +""" + + +def get_movies(name: str): + # Remove leading/trailing whitespace and replace spaces with URL encoding + name = name.strip().replace(" ", "%20") + + # Send a request to the Radarr API to search for the movie + response = requests.get( + f"{RADARR_HOST_URL}/api/v3/movie/lookup?term={name}", headers=RADARR_HEADERS + ).json() + + if len(response) == 0: + return "NO RESULTS" + # If the movie has alreadt been added, then the added date will be + # something other than 0001-01-01T05:51:00Z + if response[0]["added"] != "0001-01-01T05:51:00Z": + return "ALREADY ADDED" + + # Add the top 5 movies and their years to a list of dictionaries and their respective tmdbIds + movies = [ + {"title": response[i]["title"], "year": response[i]["year"]} + for i in range(min(5, len(response))) + ] + tmdb_ids = {} + for i in range(min(5, len(response))): + tmdb_ids[response[i]["tmdbId"]] = {"description": response[i]["overview"]} + # Try to choose from one of the usual 2 poster images available, + # if not, then just set the "poster" to None + try: + try: + tmdb_ids[response[i]["tmdbId"]]["remotePoster"] = response[i]["images"][0]["remoteUrl"] + except IndexError: + tmdb_ids[response[i]["tmdbId"]]["remotePoster"] = response[i]["images"][1]["remoteUrl"] + except IndexError: + tmdb_ids[response[i]["tmdbId"]]["remotePoster"] = None + + return movies, tmdb_ids + + +""" +Send a request to the Radarr API to add the movie +""" + + +def add_movie(tmdb_id: int): + # Get the necessary data for the movie + data = requests.get( + f"{RADARR_HOST_URL}/api/v3/movie/lookup/tmdb?tmdbId={tmdb_id}", + headers=RADARR_HEADERS, + ).json() + + movie_title = data["title"] + # Change the qualityProfileId, monitored, and rootFolderPath values + data["qualityProfileId"] = QUALITY_PROFILE_ID + data["monitored"] = True + data["rootFolderPath"] = ROOT_FOLDER_PATH + # Send the request to add the movie + response = requests.post( + f"{RADARR_HOST_URL}/api/v3/movie", headers=RADARR_HEADERS, json=data + ).json() + movie_id = response["id"] + + # Return the movie_title, movie_id + return movie_title, movie_id + + +class AddMovieView(discord.ui.View): + def __init__(self, movies: list, tmdb_ids: dict, *, timeout=180.0): + super().__init__(timeout=timeout) + self.add_item(AddMovieDropdown(movies, tmdb_ids)) + + +class AddMovieDropdown(discord.ui.Select): + def __init__(self, movies: list, tmdb_ids: dict, *, timeout=180.0): + self.movies = movies + self.tmdb_ids = tmdb_ids + super().__init__( + placeholder="Select from the dropdown", + options=[ + discord.SelectOption(label=f"{movie['title']} ({movie['year']})") + for movie in movies + ], + ) + + async def callback(self, interaction: discord.Interaction): + # Convert the options to a list of strings and get the index of the selected option + string_options = [option.label for option in self.options] + index = string_options.index(interaction.data["values"][0]) + # Convert the tmdbIds dictionary to a list and get the tmdbId of the selected movie + tmdb_id_list = list(self.tmdb_ids.keys()) + tmdb_id = tmdb_id_list[index] + tmdbFull = self.tmdb_ids[tmdb_id] + + embed = discord.Embed( + title="Is this the movie you want to add?", + description=f"**{self.movies[index]['title']}**\n\n{tmdbFull['description']}", + color=0xD01B86 + ) + embed.set_image(url=tmdbFull["remotePoster"]) + view = RequestButtonView(tmdb_id) + await interaction.response.edit_message(embed=embed, view=view) + + +class RequestButtonView(discord.ui.View): + def __init__(self, tmdb_id: int, *, timeout=180.0): + super().__init__(timeout=timeout) + self.tmdb_id = tmdb_id + + @discord.ui.button(label="Request", style=discord.ButtonStyle.success) + async def request_button( + self, interaction: discord.Interaction, button: discord.ui.Button + ): + # Add the movie to the Radarr library + movie_title, movie_id = add_movie(self.tmdb_id) + + # Alert the user that the movie has been added + embed = discord.Embed( + title="Movie Requested", + description=f"**{movie_title}** has been requested and will be added to the Radarr library. You can check the download status of your requested movies by running the `/status` command. Please wait ~5 minutes for Radarr to find a download for the movie.", + color=0xD01B86 + ) + await interaction.response.edit_message(embed=embed, view=None) + # # Add the movie to the Radarr library + # requests.post( + # f"{RADARR_HOST_URL}/api/v3/command", + # headers=RADARR_HEADERS, + # json={"name": "MoviesSearch", "movieIds": movie_id}, + # ) + + # Keep track of the movie for the `/status` command + db = sqlite3.connect("cordarr.db") + cursor = db.cursor() + cursor.execute( + "INSERT INTO movies VALUES (?, ?, ?)", + (interaction.user.id, movie_id, movie_title), + ) + db.commit() + db.close() + + @discord.ui.button(label="Don't Request", style=discord.ButtonStyle.danger) + async def dont_request_button( + self, interaction: discord.Interaction, button: discord.ui.Button + ): + embed = discord.Embed( + title="Request Cancelled", + description="Request has been cancelled. If you would like to request a different movie, run the `/request movie` command again.", + color=0xD01B86 + ) + await interaction.response.edit_message(embed=embed, view=None) |