subextract 0.2.0__tar.gz → 0.3.0__tar.gz
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.
- subextract-0.3.0/PKG-INFO +18 -0
- subextract-0.3.0/pyproject.toml +106 -0
- subextract-0.3.0/pyproject.toml.orig +97 -0
- {subextract-0.2.0 → subextract-0.3.0}/subextract/cli.py +11 -12
- subextract-0.3.0/subextract/language.py +27 -0
- subextract-0.2.0/PKG-INFO +0 -14
- subextract-0.2.0/pyproject.toml +0 -20
- subextract-0.2.0/setup.py +0 -34
- subextract-0.2.0/subextract/language.py +0 -16
- {subextract-0.2.0 → subextract-0.3.0}/subextract/__init__.py +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: subextract
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: CLI for easy extraction of subtitles from mkv files
|
|
5
|
+
Keywords: subtitle,cli,media,mkv
|
|
6
|
+
Author: disrupted
|
|
7
|
+
Author-email: disrupted <hi@salomonpopp.me>
|
|
8
|
+
License-Expression: GPL-3.0-only
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Typing :: Typed
|
|
13
|
+
Requires-Dist: langcodes>=3.5.1
|
|
14
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
15
|
+
Requires-Python: >=3.15
|
|
16
|
+
Project-URL: Homepage, https://github.com/disrupted/subextract
|
|
17
|
+
Project-URL: Repository, https://github.com/disrupted/subextract
|
|
18
|
+
Project-URL: Issues, https://github.com/disrupted/subextract/issues
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "subextract"
|
|
3
|
+
version = "0.3.0"
|
|
4
|
+
description = "CLI for easy extraction of subtitles from mkv files"
|
|
5
|
+
license = "GPL-3.0-only"
|
|
6
|
+
requires-python = ">=3.15"
|
|
7
|
+
keywords = [
|
|
8
|
+
"subtitle",
|
|
9
|
+
"cli",
|
|
10
|
+
"media",
|
|
11
|
+
"mkv",
|
|
12
|
+
]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Typing :: Typed",
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"langcodes>=3.5.1",
|
|
21
|
+
"pyyaml>=6.0.3",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[[project.authors]]
|
|
25
|
+
name = "disrupted"
|
|
26
|
+
email = "hi@salomonpopp.me"
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://github.com/disrupted/subextract"
|
|
30
|
+
Repository = "https://github.com/disrupted/subextract"
|
|
31
|
+
Issues = "https://github.com/disrupted/subextract/issues"
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
subextract = "subextract.cli:main"
|
|
35
|
+
|
|
36
|
+
[dependency-groups]
|
|
37
|
+
dev = [
|
|
38
|
+
"pytest>=9.2.0",
|
|
39
|
+
"ruff>=0.17.4",
|
|
40
|
+
"ty>=0.0.101",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["uv_build>=0.13.7,<0.14"]
|
|
45
|
+
build-backend = "uv_build"
|
|
46
|
+
|
|
47
|
+
[tool.ty.src]
|
|
48
|
+
include = [
|
|
49
|
+
"subextract",
|
|
50
|
+
"tests",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[tool.ty.environment]
|
|
54
|
+
python-version = "3.15"
|
|
55
|
+
|
|
56
|
+
[tool.ruff]
|
|
57
|
+
output-format = "grouped"
|
|
58
|
+
show-fixes = true
|
|
59
|
+
target-version = "py315"
|
|
60
|
+
|
|
61
|
+
[tool.ruff.lint]
|
|
62
|
+
select = [
|
|
63
|
+
"F",
|
|
64
|
+
"E",
|
|
65
|
+
"W",
|
|
66
|
+
"C90",
|
|
67
|
+
"I",
|
|
68
|
+
"UP",
|
|
69
|
+
"B",
|
|
70
|
+
"RUF",
|
|
71
|
+
"YTT",
|
|
72
|
+
"BLE",
|
|
73
|
+
"C4",
|
|
74
|
+
"T10",
|
|
75
|
+
"EM",
|
|
76
|
+
"ISC",
|
|
77
|
+
"ICN",
|
|
78
|
+
"INP",
|
|
79
|
+
"PIE",
|
|
80
|
+
"RSE",
|
|
81
|
+
"RET",
|
|
82
|
+
"SLOT",
|
|
83
|
+
"SIM",
|
|
84
|
+
"PTH",
|
|
85
|
+
"PGH",
|
|
86
|
+
"PL",
|
|
87
|
+
"TRY",
|
|
88
|
+
]
|
|
89
|
+
ignore = [
|
|
90
|
+
"E501",
|
|
91
|
+
"ISC001",
|
|
92
|
+
"PLR09",
|
|
93
|
+
"PLR2004",
|
|
94
|
+
"TRY003",
|
|
95
|
+
"RET504",
|
|
96
|
+
"RET505",
|
|
97
|
+
"RUF001",
|
|
98
|
+
"PLW2901",
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
[tool.uv]
|
|
102
|
+
package = true
|
|
103
|
+
trusted-publishing = "always"
|
|
104
|
+
|
|
105
|
+
[tool.uv.build-backend]
|
|
106
|
+
module-root = ""
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "subextract"
|
|
3
|
+
version = "0.3.0"
|
|
4
|
+
description = "CLI for easy extraction of subtitles from mkv files"
|
|
5
|
+
license = "GPL-3.0-only"
|
|
6
|
+
requires-python = ">=3.15"
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "disrupted", email = "hi@salomonpopp.me" },
|
|
9
|
+
]
|
|
10
|
+
keywords = ["subtitle", "cli", "media", "mkv"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Programming Language :: Python :: 3",
|
|
13
|
+
"Operating System :: OS Independent",
|
|
14
|
+
"Environment :: Console",
|
|
15
|
+
"Typing :: Typed",
|
|
16
|
+
]
|
|
17
|
+
dependencies = [
|
|
18
|
+
"langcodes>=3.5.1",
|
|
19
|
+
"pyyaml>=6.0.3",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://github.com/disrupted/subextract"
|
|
24
|
+
Repository = "https://github.com/disrupted/subextract"
|
|
25
|
+
Issues = "https://github.com/disrupted/subextract/issues"
|
|
26
|
+
|
|
27
|
+
[project.scripts]
|
|
28
|
+
subextract = "subextract.cli:main"
|
|
29
|
+
|
|
30
|
+
[dependency-groups]
|
|
31
|
+
dev = [
|
|
32
|
+
"pytest>=9.2.0",
|
|
33
|
+
"ruff>=0.17.4",
|
|
34
|
+
"ty>=0.0.101",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[build-system]
|
|
38
|
+
requires = ["uv_build>=0.13.7,<0.14"]
|
|
39
|
+
build-backend = "uv_build"
|
|
40
|
+
|
|
41
|
+
[tool.uv.build-backend]
|
|
42
|
+
module-root = ""
|
|
43
|
+
|
|
44
|
+
[tool.ty]
|
|
45
|
+
src = { include = ["subextract", "tests"] }
|
|
46
|
+
|
|
47
|
+
[tool.ty.environment]
|
|
48
|
+
python-version = "3.15"
|
|
49
|
+
|
|
50
|
+
[tool.ruff]
|
|
51
|
+
output-format = "grouped"
|
|
52
|
+
show-fixes = true
|
|
53
|
+
target-version = "py315"
|
|
54
|
+
|
|
55
|
+
[tool.ruff.lint]
|
|
56
|
+
select = [
|
|
57
|
+
"F",
|
|
58
|
+
"E",
|
|
59
|
+
"W",
|
|
60
|
+
"C90",
|
|
61
|
+
"I",
|
|
62
|
+
"UP",
|
|
63
|
+
"B",
|
|
64
|
+
"RUF",
|
|
65
|
+
"YTT",
|
|
66
|
+
"BLE",
|
|
67
|
+
"C4",
|
|
68
|
+
"T10",
|
|
69
|
+
"EM",
|
|
70
|
+
"ISC",
|
|
71
|
+
"ICN",
|
|
72
|
+
"INP",
|
|
73
|
+
"PIE",
|
|
74
|
+
"RSE",
|
|
75
|
+
"RET",
|
|
76
|
+
"SLOT",
|
|
77
|
+
"SIM",
|
|
78
|
+
"PTH",
|
|
79
|
+
"PGH",
|
|
80
|
+
"PL",
|
|
81
|
+
"TRY",
|
|
82
|
+
]
|
|
83
|
+
ignore = [
|
|
84
|
+
"E501",
|
|
85
|
+
"ISC001",
|
|
86
|
+
"PLR09",
|
|
87
|
+
"PLR2004",
|
|
88
|
+
"TRY003",
|
|
89
|
+
"RET504",
|
|
90
|
+
"RET505",
|
|
91
|
+
"RUF001",
|
|
92
|
+
"PLW2901",
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
[tool.uv]
|
|
96
|
+
package = true
|
|
97
|
+
trusted-publishing = "always"
|
|
@@ -9,7 +9,7 @@ from pathlib import Path
|
|
|
9
9
|
import yaml
|
|
10
10
|
|
|
11
11
|
from . import __version__
|
|
12
|
-
from .language import Language
|
|
12
|
+
from .language import DEFAULT_LANGUAGE, Language
|
|
13
13
|
|
|
14
14
|
parser = argparse.ArgumentParser(description="Extract subtitles from MKV files")
|
|
15
15
|
parser.add_argument(
|
|
@@ -34,9 +34,9 @@ parser.add_argument(
|
|
|
34
34
|
)
|
|
35
35
|
parser.add_argument(
|
|
36
36
|
"--lang",
|
|
37
|
-
type=Language,
|
|
38
37
|
help="Language to extract (default: en)",
|
|
39
|
-
|
|
38
|
+
type=Language.from_str,
|
|
39
|
+
default=DEFAULT_LANGUAGE,
|
|
40
40
|
)
|
|
41
41
|
parser.add_argument(
|
|
42
42
|
"--sdh",
|
|
@@ -50,7 +50,7 @@ parser.add_argument(
|
|
|
50
50
|
"file",
|
|
51
51
|
nargs="+",
|
|
52
52
|
metavar="FILE",
|
|
53
|
-
type=
|
|
53
|
+
type=Path,
|
|
54
54
|
help="the .mkv video file",
|
|
55
55
|
)
|
|
56
56
|
|
|
@@ -62,13 +62,13 @@ def mkvextract(track_id: int, path: Path, out_filename: str):
|
|
|
62
62
|
"tracks",
|
|
63
63
|
f"{track_id}:{path.with_name(out_filename)}",
|
|
64
64
|
]
|
|
65
|
-
proc = subprocess.run(mkvextract_args)
|
|
65
|
+
proc = subprocess.run(mkvextract_args, check=True)
|
|
66
66
|
return proc
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
def identify(path: Path) -> dict:
|
|
70
70
|
mkvmerge_args = ["mkvmerge", "-F", "json", "-i", path]
|
|
71
|
-
proc = subprocess.run(mkvmerge_args, stdout=subprocess.PIPE)
|
|
71
|
+
proc = subprocess.run(mkvmerge_args, stdout=subprocess.PIPE, check=True)
|
|
72
72
|
return json.loads(proc.stdout)
|
|
73
73
|
|
|
74
74
|
|
|
@@ -87,7 +87,7 @@ def is_sdh(track: dict, sdh: bool) -> bool:
|
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
def get_out_name(path: Path, track: dict) -> str:
|
|
90
|
-
lang = Language(track["properties"]["language"]).alpha1
|
|
90
|
+
lang = Language.from_str(track["properties"]["language"]).alpha1
|
|
91
91
|
return f"{path.stem}.{lang}.srt"
|
|
92
92
|
|
|
93
93
|
|
|
@@ -100,7 +100,7 @@ def extract(path: Path, track: dict):
|
|
|
100
100
|
|
|
101
101
|
def main():
|
|
102
102
|
args = parser.parse_args()
|
|
103
|
-
if args.id and (args.lang or args.sdh):
|
|
103
|
+
if args.id and (args.lang != DEFAULT_LANGUAGE or args.sdh):
|
|
104
104
|
parser.error("--id and --lang|--sdh are mutually exclusive")
|
|
105
105
|
|
|
106
106
|
logging.basicConfig(
|
|
@@ -108,9 +108,8 @@ def main():
|
|
|
108
108
|
format="%(levelname)s | %(message)s",
|
|
109
109
|
)
|
|
110
110
|
|
|
111
|
-
for
|
|
112
|
-
path
|
|
113
|
-
if path.suffix not in ".mkv":
|
|
111
|
+
for path in args.file:
|
|
112
|
+
if path.suffix != ".mkv":
|
|
114
113
|
logging.error(f"wrong file extension {path.suffix}")
|
|
115
114
|
sys.exit(1)
|
|
116
115
|
|
|
@@ -120,7 +119,7 @@ def main():
|
|
|
120
119
|
try:
|
|
121
120
|
tracks = [data["tracks"][args.id]]
|
|
122
121
|
except IndexError:
|
|
123
|
-
logging.
|
|
122
|
+
logging.exception(f"subtitle with id {args.id} doesn't exist")
|
|
124
123
|
sys.exit(1)
|
|
125
124
|
else:
|
|
126
125
|
tracks = [
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
import langcodes
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass(frozen=True)
|
|
9
|
+
class Language:
|
|
10
|
+
_lang: langcodes.Language
|
|
11
|
+
|
|
12
|
+
@staticmethod
|
|
13
|
+
def from_str(lang: str) -> Language:
|
|
14
|
+
return Language(langcodes.Language.get(lang))
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def alpha1(self):
|
|
18
|
+
"""en"""
|
|
19
|
+
return self._lang.to_tag()
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def alpha2(self):
|
|
23
|
+
"""eng"""
|
|
24
|
+
return self._lang.to_alpha3(variant="B")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
DEFAULT_LANGUAGE = Language.from_str(langcodes.DEFAULT_LANGUAGE)
|
subextract-0.2.0/PKG-INFO
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: subextract
|
|
3
|
-
Version: 0.2.0
|
|
4
|
-
Summary: CLI for easy extraction of subtitles from mkv files
|
|
5
|
-
License: GPL-3.0
|
|
6
|
-
Author: disrupted
|
|
7
|
-
Author-email: hi@salomonpopp.me
|
|
8
|
-
Requires-Python: >=3.9,<4.0
|
|
9
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
-
Requires-Dist: PyYAML (>=6.0,<7.0)
|
|
14
|
-
Requires-Dist: langcodes (>=3.3.0,<4.0.0)
|
subextract-0.2.0/pyproject.toml
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
[tool.poetry]
|
|
2
|
-
name = "subextract"
|
|
3
|
-
version = "0.2.0"
|
|
4
|
-
description = "CLI for easy extraction of subtitles from mkv files"
|
|
5
|
-
authors = ["disrupted <hi@salomonpopp.me>"]
|
|
6
|
-
license = "GPL-3.0"
|
|
7
|
-
|
|
8
|
-
[tool.poetry.scripts]
|
|
9
|
-
subextract = 'subextract.cli:main'
|
|
10
|
-
|
|
11
|
-
[tool.poetry.dependencies]
|
|
12
|
-
python = "^3.9"
|
|
13
|
-
PyYAML = "^6.0"
|
|
14
|
-
langcodes = "^3.3.0"
|
|
15
|
-
|
|
16
|
-
[tool.poetry.dev-dependencies]
|
|
17
|
-
|
|
18
|
-
[build-system]
|
|
19
|
-
requires = ["poetry-core>=1.0.0"]
|
|
20
|
-
build-backend = "poetry.core.masonry.api"
|
subextract-0.2.0/setup.py
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
from setuptools import setup
|
|
3
|
-
|
|
4
|
-
packages = \
|
|
5
|
-
['subextract']
|
|
6
|
-
|
|
7
|
-
package_data = \
|
|
8
|
-
{'': ['*']}
|
|
9
|
-
|
|
10
|
-
install_requires = \
|
|
11
|
-
['PyYAML>=6.0,<7.0', 'langcodes>=3.3.0,<4.0.0']
|
|
12
|
-
|
|
13
|
-
entry_points = \
|
|
14
|
-
{'console_scripts': ['subextract = subextract.cli:main']}
|
|
15
|
-
|
|
16
|
-
setup_kwargs = {
|
|
17
|
-
'name': 'subextract',
|
|
18
|
-
'version': '0.2.0',
|
|
19
|
-
'description': 'CLI for easy extraction of subtitles from mkv files',
|
|
20
|
-
'long_description': None,
|
|
21
|
-
'author': 'disrupted',
|
|
22
|
-
'author_email': 'hi@salomonpopp.me',
|
|
23
|
-
'maintainer': None,
|
|
24
|
-
'maintainer_email': None,
|
|
25
|
-
'url': None,
|
|
26
|
-
'packages': packages,
|
|
27
|
-
'package_data': package_data,
|
|
28
|
-
'install_requires': install_requires,
|
|
29
|
-
'entry_points': entry_points,
|
|
30
|
-
'python_requires': '>=3.9,<4.0',
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
setup(**setup_kwargs)
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import langcodes
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class Language:
|
|
5
|
-
def __init__(self, lang: str):
|
|
6
|
-
self._lang = langcodes.Language.get(lang)
|
|
7
|
-
|
|
8
|
-
@property
|
|
9
|
-
def alpha1(self):
|
|
10
|
-
"""en"""
|
|
11
|
-
return self._lang.to_tag()
|
|
12
|
-
|
|
13
|
-
@property
|
|
14
|
-
def alpha2(self):
|
|
15
|
-
"""eng"""
|
|
16
|
-
return self._lang.to_alpha3(variant="B")
|
|
File without changes
|