mkv-episode-matcher 0.1.0__py3-none-any.whl → 0.1.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/__init__.py +1 -0
- mkv_episode_matcher/__main__.py +5 -3
- mkv_episode_matcher/config.py +4 -1
- mkv_episode_matcher/episode_matcher.py +10 -8
- mkv_episode_matcher/mkv_to_srt.py +9 -8
- mkv_episode_matcher/tmdb_client.py +5 -3
- mkv_episode_matcher/utils.py +8 -6
- {mkv_episode_matcher-0.1.0.dist-info → mkv_episode_matcher-0.1.1.dist-info}/METADATA +24 -14
- mkv_episode_matcher-0.1.1.dist-info/RECORD +13 -0
- {mkv_episode_matcher-0.1.0.dist-info → mkv_episode_matcher-0.1.1.dist-info}/WHEEL +0 -1
- mkv_episode_matcher-0.1.1.dist-info/entry_points.txt +2 -0
- mkv_episode_matcher-0.1.0.dist-info/RECORD +0 -12
mkv_episode_matcher/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "0.1.1"
|
mkv_episode_matcher/__main__.py
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# __main__.py
|
|
2
2
|
import argparse
|
|
3
3
|
import os
|
|
4
|
+
|
|
4
5
|
from loguru import logger
|
|
5
|
-
from .config import set_config, get_config
|
|
6
6
|
|
|
7
|
+
from .config import get_config, set_config
|
|
8
|
+
|
|
9
|
+
# Log the start of the application
|
|
10
|
+
logger.info("Starting the application")
|
|
7
11
|
|
|
8
12
|
# Check if logs directory exists, if not create it
|
|
9
13
|
if not os.path.exists('./logs'):
|
|
@@ -49,8 +53,6 @@ def main():
|
|
|
49
53
|
The function logs its progress to two separate log files: one for standard output and one for errors.
|
|
50
54
|
"""
|
|
51
55
|
|
|
52
|
-
# Log the start of the application
|
|
53
|
-
logger.info("Starting the application")
|
|
54
56
|
|
|
55
57
|
# Parse command-line arguments
|
|
56
58
|
parser = argparse.ArgumentParser(description="Process shows with TMDb API")
|
mkv_episode_matcher/config.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# config.py
|
|
2
|
-
import os
|
|
3
2
|
import configparser
|
|
4
3
|
import multiprocessing
|
|
4
|
+
import os
|
|
5
|
+
|
|
5
6
|
from loguru import logger
|
|
6
7
|
|
|
7
8
|
MAX_THREADS = 4
|
|
@@ -13,6 +14,8 @@ def get_total_threads():
|
|
|
13
14
|
|
|
14
15
|
total_threads = get_total_threads()
|
|
15
16
|
|
|
17
|
+
if total_threads < MAX_THREADS:
|
|
18
|
+
MAX_THREADS = total_threads
|
|
16
19
|
logger.info(f"Total available threads: {total_threads} -> Setting max to {MAX_THREADS}")
|
|
17
20
|
|
|
18
21
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# episode_matcher.py
|
|
2
2
|
import os
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
from mkv_episode_matcher.utils import get_subtitles, cleanup_ocr_files,check_filename
|
|
3
|
+
import re
|
|
4
|
+
|
|
6
5
|
from loguru import logger
|
|
7
|
-
|
|
6
|
+
|
|
7
|
+
from mkv_episode_matcher.__main__ import CACHE_DIR, CONFIG_FILE
|
|
8
|
+
from mkv_episode_matcher.config import get_config
|
|
8
9
|
from mkv_episode_matcher.mkv_to_srt import convert_mkv_to_srt
|
|
9
|
-
import
|
|
10
|
+
from mkv_episode_matcher.tmdb_client import fetch_show_id
|
|
11
|
+
from mkv_episode_matcher.utils import check_filename, cleanup_ocr_files, get_subtitles
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
# hash_data = {}
|
|
@@ -98,7 +100,7 @@ def extract_srt_text(filepath):
|
|
|
98
100
|
Each inner list contains the lines of text for that block.
|
|
99
101
|
"""
|
|
100
102
|
# extract the text from the file
|
|
101
|
-
with open(filepath
|
|
103
|
+
with open(filepath) as f:
|
|
102
104
|
filepath = f.read()
|
|
103
105
|
text_lines = [
|
|
104
106
|
filepath.split("\n\n")[i].split("\n")[2:]
|
|
@@ -172,7 +174,7 @@ def process_reference_srt_files(series_name):
|
|
|
172
174
|
for filename in filenames:
|
|
173
175
|
if filename.lower().endswith(".srt"):
|
|
174
176
|
srt_file = os.path.join(dirpath, filename)
|
|
175
|
-
|
|
177
|
+
logger.info(f"Processing {srt_file}")
|
|
176
178
|
srt_text = extract_srt_text(srt_file)
|
|
177
179
|
season, episode = extract_season_episode(filename)
|
|
178
180
|
mkv_filename = f"{series_name} - S{season:02}E{episode:02}.mkv"
|
|
@@ -195,7 +197,7 @@ def process_srt_files(show_dir):
|
|
|
195
197
|
for filename in filenames:
|
|
196
198
|
if filename.lower().endswith(".srt"):
|
|
197
199
|
srt_file = os.path.join(dirpath, filename)
|
|
198
|
-
|
|
200
|
+
logger.info(f"Processing {srt_file}")
|
|
199
201
|
srt_text = extract_srt_text(srt_file)
|
|
200
202
|
srt_files[srt_file] = srt_text
|
|
201
203
|
return srt_files
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import subprocess
|
|
3
|
-
|
|
4
3
|
import sys
|
|
5
4
|
|
|
6
5
|
# Get the absolute path of the parent directory of the current script.
|
|
@@ -12,16 +11,18 @@ sys.path.append(parent_dir)
|
|
|
12
11
|
sys.path.append(os.path.join(parent_dir, "libraries"))
|
|
13
12
|
# Add the 'libraries' directory to the Python path.
|
|
14
13
|
sys.path.append(os.path.join(parent_dir, "..", "libraries", "pgs2srt"))
|
|
15
|
-
import pytesseract
|
|
16
14
|
import re
|
|
17
|
-
from PIL import Image, ImageOps
|
|
18
|
-
from mkv_episode_matcher.__main__ import CONFIG_FILE
|
|
19
|
-
from mkv_episode_matcher.config import get_config
|
|
20
|
-
from datetime import datetime, timedelta
|
|
21
15
|
from concurrent.futures import ThreadPoolExecutor
|
|
22
|
-
from
|
|
16
|
+
from datetime import datetime, timedelta
|
|
17
|
+
|
|
18
|
+
import pytesseract
|
|
23
19
|
from imagemaker import make_image
|
|
24
20
|
from loguru import logger
|
|
21
|
+
from pgsreader import PGSReader
|
|
22
|
+
from PIL import Image, ImageOps
|
|
23
|
+
|
|
24
|
+
from mkv_episode_matcher.__main__ import CONFIG_FILE
|
|
25
|
+
from mkv_episode_matcher.config import get_config
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
def convert_mkv_to_sup(mkv_file, output_dir):
|
|
@@ -80,7 +81,7 @@ def perform_ocr(sup_file_path):
|
|
|
80
81
|
si = 0
|
|
81
82
|
|
|
82
83
|
tesseract_lang = "eng"
|
|
83
|
-
tesseract_config = "-c tessedit_char_blacklist=[] --psm 6 --oem {}"
|
|
84
|
+
tesseract_config = f"-c tessedit_char_blacklist=[] --psm 6 --oem {1}"
|
|
84
85
|
|
|
85
86
|
config = get_config(CONFIG_FILE)
|
|
86
87
|
tesseract_path = config.get("tesseract_path")
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# tmdb_client.py
|
|
2
|
+
import time
|
|
3
|
+
from threading import Lock
|
|
4
|
+
|
|
2
5
|
import requests
|
|
3
6
|
from loguru import logger
|
|
4
|
-
|
|
7
|
+
|
|
5
8
|
from mkv_episode_matcher.__main__ import CONFIG_FILE
|
|
6
|
-
from
|
|
7
|
-
import time
|
|
9
|
+
from mkv_episode_matcher.config import get_config
|
|
8
10
|
|
|
9
11
|
BASE_IMAGE_URL = "https://image.tmdb.org/t/p/original"
|
|
10
12
|
|
mkv_episode_matcher/utils.py
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# utils.py
|
|
2
2
|
import os
|
|
3
|
+
import re
|
|
4
|
+
import shutil
|
|
3
5
|
from typing import Set
|
|
6
|
+
|
|
7
|
+
import requests
|
|
4
8
|
from loguru import logger
|
|
5
|
-
import
|
|
6
|
-
|
|
9
|
+
from opensubtitlescom import OpenSubtitles
|
|
10
|
+
|
|
11
|
+
from mkv_episode_matcher.__main__ import CACHE_DIR, CONFIG_FILE
|
|
7
12
|
from mkv_episode_matcher.config import get_config
|
|
8
13
|
from mkv_episode_matcher.tmdb_client import fetch_season_details
|
|
9
|
-
import requests
|
|
10
|
-
from opensubtitlescom import OpenSubtitles
|
|
11
|
-
import shutil
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
def check_filename(filename, series_title, season_number, episode_number):
|
|
@@ -199,7 +201,7 @@ def get_subtitles(show_id, seasons: Set[int]):
|
|
|
199
201
|
else:
|
|
200
202
|
continue
|
|
201
203
|
else:
|
|
202
|
-
|
|
204
|
+
logger.info(
|
|
203
205
|
f"Subtitle already exists for {series_name} - S{season:02d}E{episode:02d}"
|
|
204
206
|
)
|
|
205
207
|
continue
|
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: mkv-episode-matcher
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.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
|
+
Project-URL: Documentation, https://github.com/Jsakkos/mkv-episode-matcher#readme
|
|
6
|
+
Project-URL: Issues, https://github.com/Jsakkos/mkv-episode-matcher/issues
|
|
7
|
+
Project-URL: Source, https://github.com/Jsakkos/mkv-episode-matcher
|
|
8
|
+
Author-email: Jsakkos <jonathansakkos@protonmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Programming Language :: Python
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
18
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Requires-Dist: configparser
|
|
21
|
+
Requires-Dist: loguru
|
|
22
|
+
Requires-Dist: opensubtitlescom
|
|
23
|
+
Requires-Dist: pillow
|
|
24
|
+
Requires-Dist: pytesseract
|
|
25
|
+
Requires-Dist: requests
|
|
26
|
+
Requires-Dist: tmdb-client
|
|
6
27
|
Description-Content-Type: text/markdown
|
|
7
28
|
|
|
8
29
|
# MKV Episode Matcher
|
|
@@ -32,19 +53,8 @@ python __main__.py --api-key `your-api-key` --show-dir /path/to/show
|
|
|
32
53
|
|
|
33
54
|
## How it works
|
|
34
55
|
|
|
35
|
-
MKV Episode Matcher
|
|
56
|
+
MKV Episode Matcher extracts the subtitle text from each MKV file, then crossreferences the text against .srt subtitle files that are either user-provided or downloaded from Opensubtitles.com
|
|
36
57
|
|
|
37
|
-
## Caveats (WIP)
|
|
38
|
-
|
|
39
|
-
Currently, MKV Episode Matcher is slow (several minutes per episode), CPU intensive, and error-prone.
|
|
40
|
-
|
|
41
|
-
# Known issues
|
|
42
|
-
|
|
43
|
-
When reading BluRay files, the following warning pops up in the terminal:
|
|
44
|
-
```
|
|
45
|
-
Could not find codec parameters for stream 3 (Subtitle: hdmv_pgs_subtitle (pgssub)): unspecified size
|
|
46
|
-
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
|
|
47
|
-
```
|
|
48
58
|
|
|
49
59
|
# Contributing
|
|
50
60
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
mkv_episode_matcher/.gitattributes,sha256=Gh2-F2vCM7SZ01pX23UT8pQcmauXWfF3gwyRSb6ZAFs,66
|
|
2
|
+
mkv_episode_matcher/__init__.py,sha256=LM2LaE6ld1IdTocZPzvWFmhHRfeoMYFg3PuXn0cJvmU,19
|
|
3
|
+
mkv_episode_matcher/__main__.py,sha256=UW2-p_vhGCSlimKdVlpf-5mRR5_VIbIuZXB_Q9RXNGA,6672
|
|
4
|
+
mkv_episode_matcher/config.py,sha256=zDDKBcsDt5fME9BRqiTi7yWKeast1pZh36BNYMvIBYM,2419
|
|
5
|
+
mkv_episode_matcher/episode_matcher.py,sha256=UBT53tiC0xryl9k9XXoRUY1-08u5DH-NcwnmD-MSWG8,8914
|
|
6
|
+
mkv_episode_matcher/mkv_to_srt.py,sha256=6boR-jJ5fOCLZxHapTSFj7b01daQZNMWI_jBD__pQZE,6462
|
|
7
|
+
mkv_episode_matcher/requirements.txt,sha256=0JLuUm69lLp8anUgtW48CuULZ_lSwd-1XL3eoShVWjI,93
|
|
8
|
+
mkv_episode_matcher/tmdb_client.py,sha256=LbMCgjmp7sCbrQo_CDlpcnryKPz5S7inE24YY9Pyjk4,4172
|
|
9
|
+
mkv_episode_matcher/utils.py,sha256=UMygaE4ZUvV9BRyXxmgfd1g06-0pk1eGlM56NzfgjYM,9305
|
|
10
|
+
mkv_episode_matcher-0.1.1.dist-info/METADATA,sha256=kvxVKoydueoVzbMRg3cv6wWgM8tCa0pnWwTMyvq6GFg,4351
|
|
11
|
+
mkv_episode_matcher-0.1.1.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
|
|
12
|
+
mkv_episode_matcher-0.1.1.dist-info/entry_points.txt,sha256=IglJ43SuCZq2eQ3shMFILCkmQASJHnDCI3ogohW2Hn4,64
|
|
13
|
+
mkv_episode_matcher-0.1.1.dist-info/RECORD,,
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
mkv_episode_matcher/.gitattributes,sha256=Gh2-F2vCM7SZ01pX23UT8pQcmauXWfF3gwyRSb6ZAFs,66
|
|
2
|
-
mkv_episode_matcher/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
mkv_episode_matcher/__main__.py,sha256=kCsrekSaNOkrfaY8Lm-VzVzALsxcmuaEWeeyCE5deEQ,6678
|
|
4
|
-
mkv_episode_matcher/config.py,sha256=2Ui0f9LUc0r6pmdRUmcopdykotHoFxjqJavLKLOzy5w,2354
|
|
5
|
-
mkv_episode_matcher/episode_matcher.py,sha256=IAUDOHyMzmoqBDilA5GIXiQdomfEWR7mn4xXU5XtvsM,8904
|
|
6
|
-
mkv_episode_matcher/mkv_to_srt.py,sha256=BSDgNCgrkpr451X-P0A3-Q4bENfItv2A43yp5dtB430,6468
|
|
7
|
-
mkv_episode_matcher/requirements.txt,sha256=0JLuUm69lLp8anUgtW48CuULZ_lSwd-1XL3eoShVWjI,93
|
|
8
|
-
mkv_episode_matcher/tmdb_client.py,sha256=3sWC0tHvsW2XAYA4ndXh3PjUFCobQRpXzykNP-Z4rAA,4170
|
|
9
|
-
mkv_episode_matcher/utils.py,sha256=ZkqGV3ZNPwpTvN1dHNZb-iLwJnk4ldk6w-Znh3TPH70,9297
|
|
10
|
-
mkv_episode_matcher-0.1.0.dist-info/METADATA,sha256=Z6_kFPF6S49njL8CzfhrvxMuuXH9qNueD3FyZrTHx5c,3759
|
|
11
|
-
mkv_episode_matcher-0.1.0.dist-info/WHEEL,sha256=cDcbFFSNXOE-241I5PFuLkIYfR_FM7WTlPEi33njInY,105
|
|
12
|
-
mkv_episode_matcher-0.1.0.dist-info/RECORD,,
|