Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve series detection #16

Merged
merged 3 commits into from
Jul 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

*.mkv
*.mp4
*.ini
.google-cookie
**/*.pyc
42 changes: 34 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,33 @@

## What it does

## Getting Started
Running `./organizer.py` will show possible commands and flags:
```
Usage: organizer.py [OPTIONS] COMMAND [ARGS]...

### Prerequisites
What things you need to run the program:
- At least Python 3.8
- Install requirements `pip install -r requirements.txt`
Rename Media Files

Options:
--help Show this message and exit.

Commands:
movies Rename Movies
series Rename TV Series
```
Currently renaming movies and series is supported.

Help for series:
```
Usage: organizer.py series [OPTIONS]

Rename TV Series

Options:
-p, --path TEXT Path
-f, --force Automatically rename
--help Show this message and exit.
```

### Features
- Movies are renamed and organized in format:
```
<Movie_name> (<year>)/<Movie_name> (<year>)
Expand All @@ -28,13 +47,20 @@ What things you need to run the program:
<TV_Series_name>/S<Season_number>/S<Season_number>E<Episode_Number>
```

## Getting Started

### Prerequisites
What things you need to run the program:
- At least Python 3.8
- Install requirements `pip install -r requirements.txt`

### Development

- `pre-commit install --hook-type commit-msg`

<p align="center">
Made with ❤️ by <a href="https://github.com/3h4x">3h4x</a>
Based on work of <a href="https://github.com/bearlike">bearlike</a>
Made with ❤️ by <a href="https://github.com/3h4x">3h4x</a></br>
Loosely based on work of <a href="https://github.com/bearlike/Media-Library-Organiser">bearlike</a>
</p>

![wave](http://cdn.thekrishna.in/img/common/border.png)
Binary file removed src/__pycache__/rename_movies.cpython-39.pyc
Binary file not shown.
Binary file removed src/__pycache__/rename_series.cpython-39.pyc
Binary file not shown.
18 changes: 11 additions & 7 deletions src/main.py → src/organizer.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/usr/bin/env python3
import os
import sys
import click

from imdb import IMDb

from rename_movies import rename_movies
from rename_series import rename_series

Expand All @@ -11,22 +12,25 @@
@click.pass_context
def main(ctx):
ctx.ensure_object(dict)
ctx.obj["imdb_client"] = IMDb()


@main.command(help="Rename Movies")
@click.pass_context
@click.option("--path", "-p", help="Path", default=".")
@click.option(
"--default", help="Should default answer for renaming be True",
default=True
"--default", help="Should default answer for renaming be True", default=True
)
def movies(path, default):
rename_movies(path, default)
def movies(ctx, path, default):
rename_movies(ctx, path, default)


@main.command(help="Rename TV Series")
@click.pass_context
@click.option("--path", "-p", help="Path", default=".")
def series(path):
rename_series(path)
@click.option("--force", "-f", help="Automatically rename", is_flag=True, default=False)
def series(ctx, path, force):
rename_series(ctx, path, force)


if __name__ == "__main__":
Expand Down
10 changes: 4 additions & 6 deletions src/rename_movies.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import click
import ipdb
import re
from imdb import IMDb
from similarity.damerau import Damerau

damerau = Damerau()
Expand Down Expand Up @@ -32,9 +31,8 @@ def find_url_in_string(file_name: str) -> str:


# Returns a List Movie name and release year using imDB from Old_FileName
def main_imdb(str21):
ia = IMDb()
s_result = ia.search_movie(str21)
def get_imdb_title(imdb_client, name):
s_result = imdb_client.search_movie(name)
movies = []
for movie in s_result:
if movie["kind"] == "movie":
Expand Down Expand Up @@ -87,7 +85,7 @@ def FormatStr(file_new_name):
return rest.strip()


def rename_movies(path, default):
def rename_movies(ctx, path, default):
files = os.listdir(path)
for file in files:
file_new_name = file
Expand All @@ -104,7 +102,7 @@ def rename_movies(path, default):
)
file_new_name = file_new_name[0 : len(file_new_name) - 4]
Final = file_new_name + year_str
movies = main_imdb(file_new_name + year_str)
movies = get_imdb_title(ctx.obj["imdb_client"], file_new_name + year_str)
if not movies:
click.secho(f'No Match Found for "{file_new_name}"', bg="yellow")
click.echo()
Expand Down
168 changes: 81 additions & 87 deletions src/rename_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import re
import subprocess
import click
from imdb import IMDb
from similarity.damerau import Damerau


Expand All @@ -21,14 +20,12 @@ def find_most_apt(name, series):


# Retrieves name from imDB
def main_imdb(str21):
ia = IMDb()
s_result = ia.search_movie(str21)
def get_imdb_title(imdb_client, name, season, episode):
results = imdb_client.search_movie(name)
series = []
for ss in s_result:
if ss["kind"] == "tv series":
str2 = ss["title"]
series.append(str2)
for result in results:
if result["kind"] == "tv series":
series.append(result["title"])
return series


Expand All @@ -47,100 +44,97 @@ def removeIllegal(str):
return str


RE_X = r"(\d)+\s+x\s+(\d+)"
RE_X = re.compile("(\d)+\s+x\s+(\d+)", re.IGNORECASE)
RE_SE = re.compile("SE?(\d+)EP?(\d+)", re.IGNORECASE)
RE_E = re.compile("EP?(\d+)", re.IGNORECASE)


def hasX(inputString):
return bool(re.search(RE_X, inputString, re.IGNORECASE))


RE_SE = r"SE?(\d+)EP?(\d+)"


def hasSE(inputString):
return bool(re.search(RE_SE, inputString, re.IGNORECASE))
RE_XA = re.compile("(\d)+\s+x\s+(\d+).*", re.IGNORECASE)
RE_SEA = re.compile("SE?(\d+)EP?(\d+).*", re.IGNORECASE)
RE_EA = re.compile("EP?(\d+).*", re.IGNORECASE)


def get_season_episode(file_name: str):
if hasSE(file_name):
season, episode = re.search(RE_SE, file_name, re.IGNORECASE).groups()
if re.search(RE_SE, file_name):
season, episode = re.search(RE_SE, file_name).groups()
return AddZero(season), AddZero(episode)
elif hasX(file_name):
season, episode = re.search(RE_X, file_name, re.IGNORECASE).groups()
elif re.search(RE_X, file_name):
season, episode = re.search(RE_X, file_name).groups()
return AddZero(season), AddZero(episode)
elif re.search(RE_E, file_name):
episode = re.search(RE_E, file_name).groups()[0]
return AddZero(1), AddZero(episode)

return "", ""


def sanitize_name(file_name):
file_name = re.sub(RE_X, "", file_name)
file_name = re.sub(RE_SE, "", file_name)
file_name = re.sub(RE_XA, "", file_name)
file_name = re.sub(RE_SEA, "", file_name)
file_name = re.sub(RE_EA, "", file_name)
return file_name.replace("-", " ").replace(".", " ").strip()


def AddZero(inputString):
if int(inputString) < 10:
return str("0" + str(int(inputString)))
return inputString
def AddZero(input):
if int(input) < 10:
return str("0" + str(int(input)))
return input


def rename_series(path):
def rename_series(ctx, path, force):
click.echo("Reading Files....")

for (dirpath, _, _) in os.walk(path):
files = os.listdir(dirpath)
for file in files:
_, file = os.path.split(file)
file_name, extension = os.path.splitext(file)

if extension not in [".mp4", ".mkv", ".srt", ".avi", ".wmv"]:
continue

unwanted_stuff = [
".1080p",
".720p",
"HDTV",
"x264",
"AAC",
"E-Subs",
"ESubs",
"WEBRip",
"WEB",
"BluRay",
"Bluray",
]
for stuff in unwanted_stuff:
file_name = file_name.replace(stuff, "")
file_name = file_name.replace(".", " ")

season, episode = get_season_episode(file_name)
if not (season and episode):
click.secho(f'No Season/Episode found in "{file_name}"', fg="red")
continue

file_name = sanitize_name(file_name)
series = main_imdb(file_name)
if not series:
click.secho(f'Couldnt find imdb series for "{file_name}"', fg="yellow")
continue

file_name = find_most_apt(file_name, series)
file_name = removeIllegal(file_name).strip()
Final = f"SE{season}EP{episode} - {file_name}{extension}"

path_output = os.path.join(file_name, f"Season {season}") # type: ignore

subprocess.check_call(f'mkdir -p "{path_output}"', cwd=path, shell=True)

try:
if click.confirm(f'Rename "{file}" to "{Final}"?', default=True):
# cross device mv
subprocess.check_call(
f'mv "{file}" "{os.path.join(path_output, Final)}"',
cwd=path,
shell=True,
)
except FileExistsError:
print(f"Error - File Already Exist: {Final}")

click.echo("All Files Processed...")
for file in sorted(os.listdir(path)):
_, file = os.path.split(file)
file_name, extension = os.path.splitext(file)

if extension not in [".mp4", ".mkv", ".srt", ".avi", ".wmv"]:
continue

unwanted_stuff = [
".1080p",
".720p",
"HDTV",
"x264",
"AAC",
"E-Subs",
"ESubs",
"WEBRip",
"WEB",
"BluRay",
"Bluray",
]
for stuff in unwanted_stuff:
file_name = file_name.replace(stuff, "")
file_name = file_name.replace(".", " ")

season, episode = get_season_episode(file_name)
if not (season and episode):
click.secho(f'No Season/Episode found in "{file_name}"', fg="red")
continue

file_name = sanitize_name(file_name)
series = get_imdb_title(ctx.obj["imdb_client"], file_name, season, episode)
if not series:
click.secho(f'Couldnt find imdb series for "{file_name}"', fg="yellow")
continue

file_name = find_most_apt(file_name, series)
file_name = removeIllegal(file_name).strip()
Final = f"SE{season}EP{episode} - {file_name}{extension}"

path_output = os.path.join(file_name, f"Season {season}") # type: ignore

subprocess.check_call(f'mkdir -p "{path_output}"', cwd=path, shell=True)

try:
if force or click.confirm(f'Rename "{file}" to "{Final}"?', default=True):
# cross device mv
subprocess.check_call(
f'mv "{file}" "{os.path.join(path_output, Final)}"',
cwd=path,
shell=True,
)
except FileExistsError:
print(f"Error - File Already Exist: {Final}")

click.echo("All Files Processed...")