Last active
January 3, 2023 12:11
-
-
Save Dan6erbond/d712aab1ab67cb2aa24939eab5ede3b6 to your computer and use it in GitHub Desktop.
Organizarr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
import PTN | |
import requests | |
from dotenv import load_dotenv | |
from sanitize_filename import sanitize | |
load_dotenv() | |
api_root = "https://api.themoviedb.org/3/" | |
params = {"api_key": os.getenv("TMDB_API_KEY")} | |
def main(movies_folder: str, dry_run: bool): | |
searched_titles = list() | |
for file in os.listdir(movies_folder): | |
if os.path.isdir(file): | |
continue | |
file_info = PTN.parse(file) | |
if not file_info["title"]: | |
print("No title found for:", file) | |
continue | |
movie_title = "" | |
year = "" | |
for title in searched_titles: | |
if title["file_info_title"] == file_info["title"]: | |
movie_title = title["original_title"] | |
year = title["year"] | |
if not movie_title: | |
r = requests.get( | |
api_root + "/search/movie", | |
params={**params, "query": file_info["title"]}, | |
) | |
res = r.json() | |
if len(movies := res["results"]) > 0: | |
movie_title = movies[0]["original_title"] | |
year = movies[0]["release_date"].split("-")[0] | |
searched_titles.append( | |
{ | |
"file_info_title": file_info["title"], | |
"original_title": movie_title, | |
"year": movies[0]["release_date"].split("-")[0], | |
} | |
) | |
else: | |
print("No results found for:", file, file_info) | |
continue | |
filename_friendly_movie_title = sanitize(movie_title) | |
folder_name = f"{filename_friendly_movie_title} ({year})" | |
movie_folder = os.path.join(movies_folder, folder_name) | |
if not os.path.exists(movie_folder): | |
os.mkdir(movie_folder) | |
file_name = f"{filename_friendly_movie_title} ({year})" | |
if "resolution" in file_info and "quality" in file_info: | |
file_name += f" {file_info['quality']}-{file_info['resolution']}" | |
elif "quality" in file_info: | |
file_name += f" {file_info['quality']}" | |
elif "resolution" in file_info: | |
file_name += f" {file_info['resolution']}" | |
file_name += os.path.splitext(file)[1] | |
file_path = os.path.join(movie_folder, file_name) | |
if os.path.exists(file_path): | |
print("File already exists:", file_path) | |
continue | |
if dry_run: | |
print(f"Moving {file} to {file_path}") | |
else: | |
os.rename(os.path.join(movies_folder, file), file_path) | |
if __name__ == "__main__": | |
main( | |
sys.argv[1], | |
True if len(sys.argv) > 2 and sys.argv[2] in ("--dry-run", "-p") else False, | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
def main(show_folder: str, dry_run: bool): | |
show = os.path.basename(show_folder) or os.path.basename(os.path.dirname(show_folder)) | |
for season in os.listdir(show_folder): | |
if not os.path.isdir(os.path.join(show_folder, season)): | |
continue | |
if season.startswith("Season "): | |
try: | |
season_nr = int(season.split(" ")[1]) | |
for episode in os.listdir(os.path.join(show_folder, season)): | |
if episode.startswith("Episode "): | |
try: | |
if len(episode.split(" ")) > 2: | |
episode_nr = int(episode.split(" ")[1]) | |
episode_name = " ".join(episode.split(" ")[3:]) | |
filename = f"{show} - S{season_nr:02d}E{episode_nr:02d} - {episode_name}" | |
else: | |
episode_nr = int( | |
os.path.splitext(episode)[0].split(" ")[1] | |
) | |
filename = f"{show} - S{season_nr:02d}E{episode_nr:02d}{os.path.splitext(episode)[1]}" | |
filepath = os.path.join(show_folder, season, filename) | |
if dry_run: | |
print(f"Moving {episode} to {filepath}") | |
else: | |
os.rename( | |
os.path.join(show_folder, season, episode), | |
filepath, | |
) | |
except: | |
print("Error parsing episode:", episode) | |
continue | |
except: | |
print("Error parsing season:", season) | |
continue | |
if __name__ == "__main__": | |
main( | |
sys.argv[1], | |
True if len(sys.argv) > 2 and sys.argv[2] in ("--dry-run", "-p") else False, | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment