mkv-episode-matcher 0.8.1__py3-none-any.whl → 0.9.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mkv-episode-matcher might be problematic. Click here for more details.
- mkv_episode_matcher/__main__.py +17 -17
- mkv_episode_matcher/config.py +2 -2
- mkv_episode_matcher/episode_matcher.py +6 -7
- mkv_episode_matcher/subtitle_utils.py +3 -3
- mkv_episode_matcher/utils.py +72 -46
- {mkv_episode_matcher-0.8.1.dist-info → mkv_episode_matcher-0.9.1.dist-info}/METADATA +1 -2
- mkv_episode_matcher-0.9.1.dist-info/RECORD +14 -0
- {mkv_episode_matcher-0.8.1.dist-info → mkv_episode_matcher-0.9.1.dist-info}/WHEEL +1 -1
- mkv_episode_matcher-0.8.1.dist-info/RECORD +0 -14
- {mkv_episode_matcher-0.8.1.dist-info → mkv_episode_matcher-0.9.1.dist-info}/entry_points.txt +0 -0
- {mkv_episode_matcher-0.8.1.dist-info → mkv_episode_matcher-0.9.1.dist-info}/top_level.txt +0 -0
mkv_episode_matcher/__main__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# __main__.py (enhanced version)
|
|
2
2
|
import argparse
|
|
3
|
-
import os
|
|
4
3
|
import sys
|
|
4
|
+
from pathlib import Path
|
|
5
5
|
from typing import Optional
|
|
6
6
|
|
|
7
7
|
from loguru import logger
|
|
@@ -20,33 +20,33 @@ console = Console()
|
|
|
20
20
|
logger.info("Starting the application")
|
|
21
21
|
|
|
22
22
|
# Check if the configuration directory exists, if not create it
|
|
23
|
-
CONFIG_DIR =
|
|
24
|
-
if not
|
|
25
|
-
|
|
23
|
+
CONFIG_DIR = Path.home() / ".mkv-episode-matcher"
|
|
24
|
+
if not CONFIG_DIR.exists():
|
|
25
|
+
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
26
26
|
|
|
27
27
|
# Define the paths for the configuration file and cache directory
|
|
28
|
-
CONFIG_FILE =
|
|
29
|
-
CACHE_DIR =
|
|
28
|
+
CONFIG_FILE = CONFIG_DIR / "config.ini"
|
|
29
|
+
CACHE_DIR = CONFIG_DIR / "cache"
|
|
30
30
|
|
|
31
31
|
# Check if the cache directory exists, if not create it
|
|
32
|
-
if not
|
|
33
|
-
|
|
32
|
+
if not CACHE_DIR.exists():
|
|
33
|
+
CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
|
34
34
|
|
|
35
35
|
# Check if logs directory exists, if not create it
|
|
36
|
-
log_dir =
|
|
37
|
-
if not
|
|
38
|
-
|
|
36
|
+
log_dir = CONFIG_DIR / "logs"
|
|
37
|
+
if not log_dir.exists():
|
|
38
|
+
log_dir.mkdir(exist_ok=True)
|
|
39
39
|
logger.remove()
|
|
40
40
|
# Add a new handler for stdout logs
|
|
41
41
|
logger.add(
|
|
42
|
-
|
|
42
|
+
str(log_dir / "stdout.log"),
|
|
43
43
|
format="{time} {level} {message}",
|
|
44
44
|
level="INFO",
|
|
45
45
|
rotation="10 MB",
|
|
46
46
|
)
|
|
47
47
|
|
|
48
48
|
# Add a new handler for error logs
|
|
49
|
-
logger.add(
|
|
49
|
+
logger.add(str(log_dir / "stderr.log"), level="ERROR", rotation="10 MB")
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
def print_welcome_message():
|
|
@@ -104,7 +104,7 @@ def select_season(seasons):
|
|
|
104
104
|
"""
|
|
105
105
|
console.print("[bold cyan]Available Seasons:[/bold cyan]")
|
|
106
106
|
for i, season in enumerate(seasons, 1):
|
|
107
|
-
season_num =
|
|
107
|
+
season_num = Path(season).name.replace("Season ", "")
|
|
108
108
|
console.print(f" {i}. Season {season_num}")
|
|
109
109
|
|
|
110
110
|
console.print(f" 0. All Seasons")
|
|
@@ -119,7 +119,7 @@ def select_season(seasons):
|
|
|
119
119
|
return None
|
|
120
120
|
|
|
121
121
|
selected_season = seasons[int(choice) - 1]
|
|
122
|
-
return int(
|
|
122
|
+
return int(Path(selected_season).name.replace("Season ", ""))
|
|
123
123
|
|
|
124
124
|
|
|
125
125
|
@logger.catch
|
|
@@ -239,7 +239,7 @@ def main():
|
|
|
239
239
|
show_dir = Prompt.ask("Enter the main directory of the show")
|
|
240
240
|
|
|
241
241
|
logger.info(f"Show Directory: {show_dir}")
|
|
242
|
-
if not
|
|
242
|
+
if not Path(show_dir).exists():
|
|
243
243
|
console.print(f"[bold red]Error:[/bold red] Show directory '{show_dir}' does not exist.")
|
|
244
244
|
return
|
|
245
245
|
|
|
@@ -286,7 +286,7 @@ def main():
|
|
|
286
286
|
selected_season = select_season(seasons)
|
|
287
287
|
|
|
288
288
|
# Show what's going to happen
|
|
289
|
-
show_name =
|
|
289
|
+
show_name = Path(show_dir).name
|
|
290
290
|
season_text = f"Season {selected_season}" if selected_season else "all seasons"
|
|
291
291
|
|
|
292
292
|
console.print(
|
mkv_episode_matcher/config.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# config.py
|
|
2
2
|
import configparser
|
|
3
3
|
import multiprocessing
|
|
4
|
-
import
|
|
4
|
+
from pathlib import Path
|
|
5
5
|
|
|
6
6
|
from loguru import logger
|
|
7
7
|
|
|
@@ -73,7 +73,7 @@ def get_config(file):
|
|
|
73
73
|
"""
|
|
74
74
|
logger.info(f"Loading config from {file}")
|
|
75
75
|
config = configparser.ConfigParser()
|
|
76
|
-
if
|
|
76
|
+
if Path(file).exists():
|
|
77
77
|
config.read(file)
|
|
78
78
|
return config["Config"] if "Config" in config else None
|
|
79
79
|
return {}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# mkv_episode_matcher/episode_matcher.py
|
|
2
2
|
|
|
3
|
-
import glob
|
|
4
|
-
import os
|
|
5
3
|
import re
|
|
6
4
|
import shutil
|
|
7
5
|
from pathlib import Path
|
|
@@ -19,6 +17,7 @@ from mkv_episode_matcher.utils import (
|
|
|
19
17
|
clean_text,
|
|
20
18
|
get_subtitles,
|
|
21
19
|
get_valid_seasons,
|
|
20
|
+
normalize_path,
|
|
22
21
|
rename_episode_file,
|
|
23
22
|
)
|
|
24
23
|
|
|
@@ -39,7 +38,7 @@ def process_show(season=None, dry_run=False, get_subs=False, verbose=False, conf
|
|
|
39
38
|
"""
|
|
40
39
|
config = get_config(CONFIG_FILE)
|
|
41
40
|
show_dir = config.get("show_dir")
|
|
42
|
-
show_name = clean_text(
|
|
41
|
+
show_name = clean_text(normalize_path(show_dir).name)
|
|
43
42
|
matcher = EpisodeMatcher(CACHE_DIR, show_name, min_confidence=confidence)
|
|
44
43
|
|
|
45
44
|
# Early check for reference files
|
|
@@ -58,7 +57,7 @@ def process_show(season=None, dry_run=False, get_subs=False, verbose=False, conf
|
|
|
58
57
|
return
|
|
59
58
|
|
|
60
59
|
if season is not None:
|
|
61
|
-
season_path =
|
|
60
|
+
season_path = str(Path(show_dir) / f"Season {season}")
|
|
62
61
|
if season_path not in season_paths:
|
|
63
62
|
console.print(f"[bold red]Error:[/bold red] Season {season} has no .mkv files to process")
|
|
64
63
|
return
|
|
@@ -69,12 +68,12 @@ def process_show(season=None, dry_run=False, get_subs=False, verbose=False, conf
|
|
|
69
68
|
|
|
70
69
|
for season_path in season_paths:
|
|
71
70
|
mkv_files = [
|
|
72
|
-
f for f in
|
|
71
|
+
f for f in Path(season_path).glob("*.mkv")
|
|
73
72
|
if not check_filename(f)
|
|
74
73
|
]
|
|
75
74
|
|
|
76
75
|
if not mkv_files:
|
|
77
|
-
season_num =
|
|
76
|
+
season_num = Path(season_path).name.replace("Season ", "")
|
|
78
77
|
console.print(f"[dim]No new files to process in Season {season_num}[/dim]")
|
|
79
78
|
continue
|
|
80
79
|
|
|
@@ -104,7 +103,7 @@ def process_show(season=None, dry_run=False, get_subs=False, verbose=False, conf
|
|
|
104
103
|
task = progress.add_task(f"[cyan]Matching Season {season_num}[/cyan]", total=len(mkv_files))
|
|
105
104
|
|
|
106
105
|
for mkv_file in mkv_files:
|
|
107
|
-
file_basename =
|
|
106
|
+
file_basename = Path(mkv_file).name
|
|
108
107
|
progress.update(task, description=f"[cyan]Processing[/cyan] {file_basename}")
|
|
109
108
|
|
|
110
109
|
if verbose:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import re
|
|
2
|
+
from pathlib import Path
|
|
3
3
|
from typing import Optional
|
|
4
4
|
|
|
5
5
|
|
|
@@ -55,8 +55,8 @@ def find_existing_subtitle(
|
|
|
55
55
|
patterns = generate_subtitle_patterns(series_name, season, episode)
|
|
56
56
|
|
|
57
57
|
for pattern in patterns:
|
|
58
|
-
filepath =
|
|
59
|
-
if
|
|
58
|
+
filepath = Path(series_cache_dir) / pattern
|
|
59
|
+
if filepath.exists():
|
|
60
60
|
return filepath
|
|
61
61
|
|
|
62
62
|
return None
|
mkv_episode_matcher/utils.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# utils.py
|
|
2
|
-
import os
|
|
3
2
|
import re
|
|
4
3
|
import shutil
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
5
6
|
|
|
6
7
|
import requests
|
|
7
8
|
import torch
|
|
@@ -16,6 +17,35 @@ from mkv_episode_matcher.subtitle_utils import find_existing_subtitle, sanitize_
|
|
|
16
17
|
from mkv_episode_matcher.tmdb_client import fetch_season_details
|
|
17
18
|
|
|
18
19
|
console = Console()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def normalize_path(path_str):
|
|
23
|
+
"""
|
|
24
|
+
Normalize a path string to handle cross-platform path issues.
|
|
25
|
+
Properly handles trailing slashes and backslashes in both Windows and Unix paths.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
path_str (str): The path string to normalize
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
pathlib.Path: A normalized Path object
|
|
32
|
+
"""
|
|
33
|
+
# Convert to string if it's a Path object
|
|
34
|
+
if isinstance(path_str, Path):
|
|
35
|
+
path_str = str(path_str)
|
|
36
|
+
|
|
37
|
+
# Remove trailing slashes or backslashes
|
|
38
|
+
path_str = path_str.rstrip('/').rstrip('\\')
|
|
39
|
+
|
|
40
|
+
# Handle Windows paths on non-Windows platforms
|
|
41
|
+
if os.name != 'nt' and '\\' in path_str and ':' in path_str[:2]:
|
|
42
|
+
# This looks like a Windows path on a non-Windows system
|
|
43
|
+
# Extract the last component which should be the directory/file name
|
|
44
|
+
components = path_str.split('\\')
|
|
45
|
+
return Path(components[-1])
|
|
46
|
+
|
|
47
|
+
return Path(path_str)
|
|
48
|
+
|
|
19
49
|
def get_valid_seasons(show_dir):
|
|
20
50
|
"""
|
|
21
51
|
Get all season directories that contain MKV files.
|
|
@@ -27,26 +57,28 @@ def get_valid_seasons(show_dir):
|
|
|
27
57
|
list: List of paths to valid season directories
|
|
28
58
|
"""
|
|
29
59
|
# Get all season directories
|
|
60
|
+
show_path = normalize_path(show_dir)
|
|
30
61
|
season_paths = [
|
|
31
|
-
|
|
32
|
-
for d in
|
|
33
|
-
if
|
|
62
|
+
str(show_path / d.name)
|
|
63
|
+
for d in show_path.iterdir()
|
|
64
|
+
if d.is_dir()
|
|
34
65
|
]
|
|
35
66
|
|
|
36
67
|
# Filter seasons to only include those with .mkv files
|
|
37
68
|
valid_season_paths = []
|
|
38
69
|
for season_path in season_paths:
|
|
39
|
-
|
|
70
|
+
season_path_obj = Path(season_path)
|
|
71
|
+
mkv_files = [f for f in season_path_obj.iterdir() if f.name.endswith(".mkv")]
|
|
40
72
|
if mkv_files:
|
|
41
73
|
valid_season_paths.append(season_path)
|
|
42
74
|
|
|
43
75
|
if not valid_season_paths:
|
|
44
76
|
logger.warning(
|
|
45
|
-
f"No seasons with .mkv files found in show '{
|
|
77
|
+
f"No seasons with .mkv files found in show '{normalize_path(show_dir).name}'"
|
|
46
78
|
)
|
|
47
79
|
else:
|
|
48
80
|
logger.info(
|
|
49
|
-
f"Found {len(valid_season_paths)} seasons with .mkv files in '{
|
|
81
|
+
f"Found {len(valid_season_paths)} seasons with .mkv files in '{normalize_path(show_dir).name}'"
|
|
50
82
|
)
|
|
51
83
|
|
|
52
84
|
return valid_season_paths
|
|
@@ -57,11 +89,14 @@ def check_filename(filename):
|
|
|
57
89
|
Check if the filename is in the correct format (S01E02).
|
|
58
90
|
|
|
59
91
|
Args:
|
|
60
|
-
filename (str): The filename to check.
|
|
92
|
+
filename (str or Path): The filename to check.
|
|
61
93
|
|
|
62
94
|
Returns:
|
|
63
95
|
bool: True if the filename matches the expected pattern.
|
|
64
96
|
"""
|
|
97
|
+
# Convert Path object to string if needed
|
|
98
|
+
if isinstance(filename, Path):
|
|
99
|
+
filename = str(filename)
|
|
65
100
|
# Check if the filename matches the expected format
|
|
66
101
|
match = re.search(r".*S\d+E\d+", filename)
|
|
67
102
|
return bool(match)
|
|
@@ -79,16 +114,14 @@ def scramble_filename(original_file_path, file_number):
|
|
|
79
114
|
None
|
|
80
115
|
"""
|
|
81
116
|
logger.info(f"Scrambling {original_file_path}")
|
|
82
|
-
series_title =
|
|
83
|
-
|
|
84
|
-
)
|
|
85
|
-
original_file_name = os.path.basename(original_file_path)
|
|
86
|
-
extension = os.path.splitext(original_file_path)[-1]
|
|
117
|
+
series_title = normalize_path(original_file_path).parent.parent.name
|
|
118
|
+
original_file_name = Path(original_file_path).name
|
|
119
|
+
extension = Path(original_file_path).suffix
|
|
87
120
|
new_file_name = f"{series_title} - {file_number:03d}{extension}"
|
|
88
|
-
new_file_path =
|
|
89
|
-
if not
|
|
121
|
+
new_file_path = Path(original_file_path).parent / new_file_name
|
|
122
|
+
if not new_file_path.exists():
|
|
90
123
|
logger.info(f"Renaming {original_file_name} -> {new_file_name}")
|
|
91
|
-
|
|
124
|
+
Path(original_file_path).rename(new_file_path)
|
|
92
125
|
|
|
93
126
|
|
|
94
127
|
def rename_episode_file(original_file_path, new_filename):
|
|
@@ -96,32 +129,32 @@ def rename_episode_file(original_file_path, new_filename):
|
|
|
96
129
|
Rename an episode file with a standardized naming convention.
|
|
97
130
|
|
|
98
131
|
Args:
|
|
99
|
-
original_file_path (str): The original file path of the episode.
|
|
100
|
-
new_filename (str): The new filename including season/episode info.
|
|
132
|
+
original_file_path (str or Path): The original file path of the episode.
|
|
133
|
+
new_filename (str or Path): The new filename including season/episode info.
|
|
101
134
|
|
|
102
135
|
Returns:
|
|
103
|
-
|
|
136
|
+
Path: Path to the renamed file, or None if rename failed.
|
|
104
137
|
"""
|
|
105
|
-
original_dir =
|
|
106
|
-
new_file_path =
|
|
138
|
+
original_dir = Path(original_file_path).parent
|
|
139
|
+
new_file_path = original_dir / new_filename
|
|
107
140
|
|
|
108
141
|
# Check if new filepath already exists
|
|
109
|
-
if
|
|
142
|
+
if new_file_path.exists():
|
|
110
143
|
logger.warning(f"File already exists: {new_filename}")
|
|
111
144
|
|
|
112
145
|
# Add numeric suffix if file exists
|
|
113
|
-
base, ext =
|
|
146
|
+
base, ext = Path(new_filename).stem, Path(new_filename).suffix
|
|
114
147
|
suffix = 2
|
|
115
148
|
while True:
|
|
116
149
|
new_filename = f"{base}_{suffix}{ext}"
|
|
117
|
-
new_file_path =
|
|
118
|
-
if not
|
|
150
|
+
new_file_path = original_dir / new_filename
|
|
151
|
+
if not new_file_path.exists():
|
|
119
152
|
break
|
|
120
153
|
suffix += 1
|
|
121
154
|
|
|
122
155
|
try:
|
|
123
|
-
|
|
124
|
-
logger.info(f"Renamed {
|
|
156
|
+
Path(original_file_path).rename(new_file_path)
|
|
157
|
+
logger.info(f"Renamed {Path(original_file_path).name} -> {new_filename}")
|
|
125
158
|
return new_file_path
|
|
126
159
|
except OSError as e:
|
|
127
160
|
logger.error(f"Failed to rename file: {e}")
|
|
@@ -143,7 +176,7 @@ def get_subtitles(show_id, seasons: set[int], config=None):
|
|
|
143
176
|
if config is None:
|
|
144
177
|
config = get_config(CONFIG_FILE)
|
|
145
178
|
show_dir = config.get("show_dir")
|
|
146
|
-
series_name = sanitize_filename(
|
|
179
|
+
series_name = sanitize_filename(normalize_path(show_dir).name)
|
|
147
180
|
tmdb_api_key = config.get("tmdb_api_key")
|
|
148
181
|
open_subtitles_api_key = config.get("open_subtitles_api_key")
|
|
149
182
|
open_subtitles_user_agent = config.get("open_subtitles_user_agent")
|
|
@@ -175,7 +208,7 @@ def get_subtitles(show_id, seasons: set[int], config=None):
|
|
|
175
208
|
for episode in range(1, episodes + 1):
|
|
176
209
|
logger.info(f"Processing Season {season}, Episode {episode}...")
|
|
177
210
|
|
|
178
|
-
series_cache_dir =
|
|
211
|
+
series_cache_dir = Path(CACHE_DIR) / "data" / series_name
|
|
179
212
|
os.makedirs(series_cache_dir, exist_ok=True)
|
|
180
213
|
|
|
181
214
|
# Check for existing subtitle in any supported format
|
|
@@ -185,15 +218,12 @@ def get_subtitles(show_id, seasons: set[int], config=None):
|
|
|
185
218
|
|
|
186
219
|
if existing_subtitle:
|
|
187
220
|
logger.info(
|
|
188
|
-
f"Subtitle already exists: {
|
|
221
|
+
f"Subtitle already exists: {Path(existing_subtitle).name}"
|
|
189
222
|
)
|
|
190
223
|
continue
|
|
191
224
|
|
|
192
225
|
# Default to standard format for new downloads
|
|
193
|
-
srt_filepath =
|
|
194
|
-
series_cache_dir,
|
|
195
|
-
f"{series_name} - S{season:02d}E{episode:02d}.srt",
|
|
196
|
-
)
|
|
226
|
+
srt_filepath = str(series_cache_dir / f"{series_name} - S{season:02d}E{episode:02d}.srt")
|
|
197
227
|
|
|
198
228
|
# get the episode info from TMDB
|
|
199
229
|
url = f"https://api.themoviedb.org/3/tv/{show_id}/season/{season}/episode/{episode}?api_key={tmdb_api_key}"
|
|
@@ -241,17 +271,15 @@ def process_reference_srt_files(series_name):
|
|
|
241
271
|
dict: A dictionary containing the reference files where the keys are the MKV filenames
|
|
242
272
|
and the values are the corresponding SRT texts.
|
|
243
273
|
"""
|
|
244
|
-
import os
|
|
245
|
-
|
|
246
274
|
from mkv_episode_matcher.__main__ import CACHE_DIR
|
|
247
275
|
|
|
248
276
|
reference_files = {}
|
|
249
|
-
reference_dir =
|
|
277
|
+
reference_dir = Path(CACHE_DIR) / "data" / series_name
|
|
250
278
|
|
|
251
279
|
for dirpath, _, filenames in os.walk(reference_dir):
|
|
252
280
|
for filename in filenames:
|
|
253
281
|
if filename.lower().endswith(".srt"):
|
|
254
|
-
srt_file =
|
|
282
|
+
srt_file = Path(dirpath) / filename
|
|
255
283
|
logger.info(f"Processing {srt_file}")
|
|
256
284
|
srt_text = extract_srt_text(srt_file)
|
|
257
285
|
season, episode = extract_season_episode(filename)
|
|
@@ -333,7 +361,7 @@ def process_srt_files(show_dir):
|
|
|
333
361
|
for dirpath, _, filenames in os.walk(show_dir):
|
|
334
362
|
for filename in filenames:
|
|
335
363
|
if filename.lower().endswith(".srt"):
|
|
336
|
-
srt_file =
|
|
364
|
+
srt_file = Path(dirpath) / filename
|
|
337
365
|
logger.info(f"Processing {srt_file}")
|
|
338
366
|
srt_text = extract_srt_text(srt_file)
|
|
339
367
|
srt_files[srt_file] = srt_text
|
|
@@ -353,22 +381,20 @@ def compare_and_rename_files(srt_files, reference_files, dry_run=False):
|
|
|
353
381
|
f"Comparing {len(srt_files)} srt files with {len(reference_files)} reference files"
|
|
354
382
|
)
|
|
355
383
|
for srt_text in srt_files.keys():
|
|
356
|
-
parent_dir =
|
|
384
|
+
parent_dir = Path(srt_text).parent.parent
|
|
357
385
|
for reference in reference_files.keys():
|
|
358
386
|
_season, _episode = extract_season_episode(reference)
|
|
359
|
-
mkv_file =
|
|
360
|
-
parent_dir, os.path.basename(srt_text).replace(".srt", ".mkv")
|
|
361
|
-
)
|
|
387
|
+
mkv_file = str(parent_dir / Path(srt_text).name.replace(".srt", ".mkv"))
|
|
362
388
|
matching_lines = compare_text(
|
|
363
389
|
reference_files[reference], srt_files[srt_text]
|
|
364
390
|
)
|
|
365
391
|
if matching_lines >= int(len(reference_files[reference]) * 0.1):
|
|
366
392
|
logger.info(f"Matching lines: {matching_lines}")
|
|
367
393
|
logger.info(f"Found matching file: {mkv_file} ->{reference}")
|
|
368
|
-
new_filename =
|
|
394
|
+
new_filename = parent_dir / reference
|
|
369
395
|
if not dry_run:
|
|
370
|
-
logger.info(f"Renaming {mkv_file} to {new_filename}")
|
|
371
|
-
rename_episode_file(mkv_file,
|
|
396
|
+
logger.info(f"Renaming {mkv_file} to {str(new_filename)}")
|
|
397
|
+
rename_episode_file(mkv_file, reference)
|
|
372
398
|
|
|
373
399
|
|
|
374
400
|
def compare_text(text1, text2):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mkv-episode-matcher
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.1
|
|
4
4
|
Summary: The MKV Episode Matcher is a tool for identifying TV series episodes from MKV files and renaming the files accordingly.
|
|
5
5
|
Home-page: https://github.com/Jsakkos/mkv-episode-matcher
|
|
6
6
|
Author: Jonathan Sakkos
|
|
@@ -28,7 +28,6 @@ Requires-Dist: tmdb-client>=0.0.1
|
|
|
28
28
|
Requires-Dist: torch>=2.5.1
|
|
29
29
|
Requires-Dist: torchaudio>=2.5.1
|
|
30
30
|
Requires-Dist: torchvision>=0.20.1
|
|
31
|
-
Requires-Dist: wave>=0.0.2
|
|
32
31
|
|
|
33
32
|
# MKV Episode Matcher
|
|
34
33
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
mkv_episode_matcher/.gitattributes,sha256=Gh2-F2vCM7SZ01pX23UT8pQcmauXWfF3gwyRSb6ZAFs,66
|
|
2
|
+
mkv_episode_matcher/__init__.py,sha256=u3yZcpuK0ICeUjxYKePvW-zS61E5ss5q2AvqnSHuz9E,240
|
|
3
|
+
mkv_episode_matcher/__main__.py,sha256=tIx_lahBMvwIGC_LHYHvCP7ILNIFGyyn0Go2gyaVA-0,10006
|
|
4
|
+
mkv_episode_matcher/config.py,sha256=KuKxvKuOrmpCZ80mjykT6oZeD3uArsq6XPioMBrAxuU,2279
|
|
5
|
+
mkv_episode_matcher/episode_identification.py,sha256=xH5HIa6oC4nXhlqzdqQn1XYQFNUrnbUVlW-R9RsBHq4,16745
|
|
6
|
+
mkv_episode_matcher/episode_matcher.py,sha256=OHtBZd3HnLpANe7HgSvcAQIZjilWgKHVOqfju557NyA,6300
|
|
7
|
+
mkv_episode_matcher/subtitle_utils.py,sha256=z4eYTMAoI8BVzdCNeqHu-9mkhwG8RzxE5BbNjWUJwCg,2552
|
|
8
|
+
mkv_episode_matcher/tmdb_client.py,sha256=LbMCgjmp7sCbrQo_CDlpcnryKPz5S7inE24YY9Pyjk4,4172
|
|
9
|
+
mkv_episode_matcher/utils.py,sha256=sQ6GpP9xDJ6_BRrTSYys2xtaF-ryJpaNcXDHgLsriOg,15394
|
|
10
|
+
mkv_episode_matcher-0.9.1.dist-info/METADATA,sha256=suiKMX54KQZ__NJ-6LOpl3fklf2YVAO3EOEMCkRvxIM,5357
|
|
11
|
+
mkv_episode_matcher-0.9.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
+
mkv_episode_matcher-0.9.1.dist-info/entry_points.txt,sha256=IglJ43SuCZq2eQ3shMFILCkmQASJHnDCI3ogohW2Hn4,64
|
|
13
|
+
mkv_episode_matcher-0.9.1.dist-info/top_level.txt,sha256=XRLbd93HUaedeWLtkyTvQjFcE5QcBRYa3V-CfHrq-OI,20
|
|
14
|
+
mkv_episode_matcher-0.9.1.dist-info/RECORD,,
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
mkv_episode_matcher/.gitattributes,sha256=Gh2-F2vCM7SZ01pX23UT8pQcmauXWfF3gwyRSb6ZAFs,66
|
|
2
|
-
mkv_episode_matcher/__init__.py,sha256=u3yZcpuK0ICeUjxYKePvW-zS61E5ss5q2AvqnSHuz9E,240
|
|
3
|
-
mkv_episode_matcher/__main__.py,sha256=O3GQk5R9BFuA-QNlqfBgDSS7G_W8IGSxiV8CFUbcaLc,10059
|
|
4
|
-
mkv_episode_matcher/config.py,sha256=EcJJjkekQ7oWtarUkufCYON_QWbQvq55-zMqCTOqSa4,2265
|
|
5
|
-
mkv_episode_matcher/episode_identification.py,sha256=xH5HIa6oC4nXhlqzdqQn1XYQFNUrnbUVlW-R9RsBHq4,16745
|
|
6
|
-
mkv_episode_matcher/episode_matcher.py,sha256=SxAbnXuTJITD1o0WohE9heE3Fm9zW_w0Nq3GzqtcIpQ,6329
|
|
7
|
-
mkv_episode_matcher/subtitle_utils.py,sha256=Hz9b4CKPV07YKTY4dcN3WbvdbvH-S3J4zcb9CiyvPlE,2551
|
|
8
|
-
mkv_episode_matcher/tmdb_client.py,sha256=LbMCgjmp7sCbrQo_CDlpcnryKPz5S7inE24YY9Pyjk4,4172
|
|
9
|
-
mkv_episode_matcher/utils.py,sha256=modXMLmt2fpny8liXwqe4ylxnwwfg_98OLOacv5izps,14501
|
|
10
|
-
mkv_episode_matcher-0.8.1.dist-info/METADATA,sha256=JpSdL1OU5UwQb6aPARqV9YzQWtoEdmoJZkmw_7FcUwM,5384
|
|
11
|
-
mkv_episode_matcher-0.8.1.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
|
12
|
-
mkv_episode_matcher-0.8.1.dist-info/entry_points.txt,sha256=IglJ43SuCZq2eQ3shMFILCkmQASJHnDCI3ogohW2Hn4,64
|
|
13
|
-
mkv_episode_matcher-0.8.1.dist-info/top_level.txt,sha256=XRLbd93HUaedeWLtkyTvQjFcE5QcBRYa3V-CfHrq-OI,20
|
|
14
|
-
mkv_episode_matcher-0.8.1.dist-info/RECORD,,
|
{mkv_episode_matcher-0.8.1.dist-info → mkv_episode_matcher-0.9.1.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|