Skip to content

Commit

Permalink
Merge pull request #16 from 3h4x/improve-series-detection
Browse files Browse the repository at this point in the history
Improve series detection
  • Loading branch information
3h4x authored Jul 17, 2022
2 parents 3b51ca8 + 8747c47 commit de097b4
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 110 deletions.
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...")

0 comments on commit de097b4

Please sign in to comment.