easyrip 4.11.1__tar.gz → 4.11.3__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.
- {easyrip-4.11.1 → easyrip-4.11.3}/PKG-INFO +1 -1
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_command.py +17 -10
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_mlang/translator.py +9 -9
- easyrip-4.11.3/easyrip/easyrip_prompt.py +151 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/global_val.py +1 -1
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/ripper/param.py +10 -1
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/ripper/ripper.py +41 -38
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip.egg-info/PKG-INFO +1 -1
- easyrip-4.11.1/easyrip/easyrip_prompt.py +0 -73
- {easyrip-4.11.1 → easyrip-4.11.3}/LICENSE +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/README.md +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/__init__.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/__main__.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_config/config.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_config/config_key.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_log.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_main.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_mlang/__init__.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_mlang/global_lang_val.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_mlang/lang_en.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_mlang/lang_zh_Hans_CN.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_web/__init__.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_web/http_server.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/easyrip_web/third_party_api.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/ripper/media_info.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/ripper/sub_and_font/__init__.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/ripper/sub_and_font/ass.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/ripper/sub_and_font/font.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/ripper/sub_and_font/subset.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip/utils.py +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip.egg-info/SOURCES.txt +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip.egg-info/dependency_links.txt +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip.egg-info/entry_points.txt +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip.egg-info/requires.txt +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/easyrip.egg-info/top_level.txt +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/pyproject.toml +0 -0
- {easyrip-4.11.1 → easyrip-4.11.3}/setup.cfg +0 -0
|
@@ -7,7 +7,6 @@ from typing import Final, Self, final
|
|
|
7
7
|
|
|
8
8
|
from prompt_toolkit.completion import (
|
|
9
9
|
Completer,
|
|
10
|
-
DeduplicateCompleter,
|
|
11
10
|
FuzzyCompleter,
|
|
12
11
|
FuzzyWordCompleter,
|
|
13
12
|
NestedCompleter,
|
|
@@ -595,6 +594,21 @@ class Opt_type(enum.Enum):
|
|
|
595
594
|
("-hwaccel",),
|
|
596
595
|
param="<string>",
|
|
597
596
|
description="Use FFmpeg hwaccel (See 'ffmpeg -hwaccels' for details)",
|
|
597
|
+
childs=(
|
|
598
|
+
Cmd_type_val(
|
|
599
|
+
names=(
|
|
600
|
+
"cuda",
|
|
601
|
+
"vaapi",
|
|
602
|
+
"dxva2",
|
|
603
|
+
"qsv",
|
|
604
|
+
"d3d11va",
|
|
605
|
+
"opencl",
|
|
606
|
+
"vulkan",
|
|
607
|
+
"d3d12va",
|
|
608
|
+
"amf",
|
|
609
|
+
)
|
|
610
|
+
),
|
|
611
|
+
),
|
|
598
612
|
)
|
|
599
613
|
_ss = Cmd_type_val(
|
|
600
614
|
("-ss",),
|
|
@@ -793,7 +807,7 @@ class OptCompleter(Completer):
|
|
|
793
807
|
|
|
794
808
|
if (
|
|
795
809
|
(opt_tree_pos_list[-1] is not self.opt_tree)
|
|
796
|
-
or (words[-1] in add_comp_words)
|
|
810
|
+
or (words and words[-1] in add_comp_words)
|
|
797
811
|
) and not text.endswith(" "):
|
|
798
812
|
# 不在根(上个单词没让这个单词回退到根) or 匹配额外提示
|
|
799
813
|
# 且尾部不是空格
|
|
@@ -845,14 +859,7 @@ class OptCompleter(Completer):
|
|
|
845
859
|
|
|
846
860
|
yield from merge_completers(
|
|
847
861
|
(
|
|
848
|
-
|
|
849
|
-
merge_completers(
|
|
850
|
-
(
|
|
851
|
-
_nested_dict_to_nc(new_nd),
|
|
852
|
-
FuzzyCompleter(_nested_dict_to_nc(new_nd), WORD=True),
|
|
853
|
-
)
|
|
854
|
-
)
|
|
855
|
-
),
|
|
862
|
+
_nested_dict_to_nc(new_nd),
|
|
856
863
|
FuzzyCompleter(
|
|
857
864
|
WordCompleter(
|
|
858
865
|
words=tuple(opt_tree_pos_list[-1]),
|
|
@@ -42,20 +42,20 @@ def translate_subtitles(
|
|
|
42
42
|
|
|
43
43
|
file_list: Final[list[tuple[Path, str]]] = []
|
|
44
44
|
for f in directory.iterdir():
|
|
45
|
-
if
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
if (
|
|
46
|
+
not f.is_file()
|
|
47
|
+
or f.suffix not in {".ass", ".ssa", ".srt"}
|
|
48
|
+
or (
|
|
49
|
+
file_intersection_selector is not None
|
|
50
|
+
and not all(map(f.samefile, file_intersection_selector))
|
|
51
|
+
)
|
|
48
52
|
):
|
|
49
53
|
continue
|
|
50
54
|
|
|
51
|
-
if
|
|
52
|
-
continue
|
|
53
|
-
if infix == _stems[-1]:
|
|
55
|
+
if (_stems := f.stem.split(".")) and (infix == _stems[-1]):
|
|
54
56
|
file_list.append(
|
|
55
57
|
(
|
|
56
|
-
f.with_name(
|
|
57
|
-
f"{'.'.join(f.stem.split('.')[:-1])}.{target_lang_tag}{f.suffix}"
|
|
58
|
-
),
|
|
58
|
+
f.with_name(f"{'.'.join(_stems[:-1])}.{target_lang_tag}{f.suffix}"),
|
|
59
59
|
read_text(f),
|
|
60
60
|
)
|
|
61
61
|
)
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
from collections.abc import Iterable
|
|
4
|
+
|
|
5
|
+
from prompt_toolkit.completion import CompleteEvent, Completer, Completion
|
|
6
|
+
from prompt_toolkit.document import Document
|
|
7
|
+
from prompt_toolkit.formatted_text import StyleAndTextTuples
|
|
8
|
+
from prompt_toolkit.history import FileHistory
|
|
9
|
+
|
|
10
|
+
from .global_val import C_Z, get_CONFIG_DIR
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class easyrip_prompt:
|
|
14
|
+
PROMPT_HISTORY_FILE = get_CONFIG_DIR() / "prompt_history.txt"
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def clear(cls) -> None:
|
|
18
|
+
cls.PROMPT_HISTORY_FILE.unlink(True)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ConfigFileHistory(FileHistory):
|
|
22
|
+
def store_string(self, string: str) -> None:
|
|
23
|
+
if not string.startswith(C_Z):
|
|
24
|
+
super().store_string(string)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SmartPathCompleter(Completer):
|
|
28
|
+
def __init__(self) -> None:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
def _highlight_fuzzy_match(
|
|
32
|
+
self,
|
|
33
|
+
suggestion: str,
|
|
34
|
+
user_input: str,
|
|
35
|
+
style_config: dict | None = None,
|
|
36
|
+
) -> StyleAndTextTuples:
|
|
37
|
+
"""
|
|
38
|
+
高亮显示模糊匹配结果
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
suggestion: 建议的完整字符串
|
|
42
|
+
user_input: 用户输入的匹配字符
|
|
43
|
+
style_config: 样式配置字典
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
包含样式信息的格式化文本
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
if style_config is None:
|
|
50
|
+
style_config = {
|
|
51
|
+
"match_char": "class:fuzzymatch.inside.character",
|
|
52
|
+
"match_section": "class:fuzzymatch.inside",
|
|
53
|
+
"non_match": "class:fuzzymatch.outside",
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if not user_input:
|
|
57
|
+
# 用户没有输入,返回原始字符串
|
|
58
|
+
return [(style_config["non_match"], suggestion)]
|
|
59
|
+
|
|
60
|
+
# 找到最佳匹配位置
|
|
61
|
+
result = []
|
|
62
|
+
|
|
63
|
+
# 简化的模糊匹配算法
|
|
64
|
+
pattern = ".*?".join(map(re.escape, user_input))
|
|
65
|
+
regex = re.compile(pattern, re.IGNORECASE)
|
|
66
|
+
|
|
67
|
+
match = regex.search(suggestion)
|
|
68
|
+
if not match:
|
|
69
|
+
# 没有匹配,返回原始字符串
|
|
70
|
+
return [(style_config["non_match"], suggestion)]
|
|
71
|
+
|
|
72
|
+
start, end = match.span()
|
|
73
|
+
match_text = suggestion[start:end]
|
|
74
|
+
|
|
75
|
+
# 匹配段之前的文本
|
|
76
|
+
if start > 0:
|
|
77
|
+
result.append((style_config["non_match"], suggestion[:start]))
|
|
78
|
+
|
|
79
|
+
# 匹配段内部的字符
|
|
80
|
+
input_chars = list(user_input)
|
|
81
|
+
for char in match_text:
|
|
82
|
+
if input_chars and char.lower() == input_chars[0].lower():
|
|
83
|
+
result.append((style_config["match_char"], char))
|
|
84
|
+
input_chars.pop(0)
|
|
85
|
+
else:
|
|
86
|
+
result.append((style_config["match_section"], char))
|
|
87
|
+
|
|
88
|
+
# 匹配段之后的文本
|
|
89
|
+
if end < len(suggestion):
|
|
90
|
+
result.append((style_config["non_match"], suggestion[end:]))
|
|
91
|
+
|
|
92
|
+
return result
|
|
93
|
+
|
|
94
|
+
def _fuzzy_filter_and_sort(self, filenames: list[str], match_str: str) -> list[str]:
|
|
95
|
+
"""模糊过滤和排序"""
|
|
96
|
+
if not match_str:
|
|
97
|
+
return sorted(filenames)
|
|
98
|
+
|
|
99
|
+
# 构建模糊匹配模式
|
|
100
|
+
pattern = ".*?".join(map(re.escape, match_str))
|
|
101
|
+
regex = re.compile(f"(?=({pattern}))", re.IGNORECASE)
|
|
102
|
+
|
|
103
|
+
matches = []
|
|
104
|
+
for filename in filenames:
|
|
105
|
+
regex_matches = list(regex.finditer(filename))
|
|
106
|
+
if regex_matches:
|
|
107
|
+
# 找到最佳匹配(最左、最短)
|
|
108
|
+
best = min(regex_matches, key=lambda m: (m.start(), len(m.group(1))))
|
|
109
|
+
matches.append((best.start(), len(best.group(1)), filename))
|
|
110
|
+
|
|
111
|
+
# 按匹配质量排序:先按匹配位置,再按匹配长度
|
|
112
|
+
matches.sort(key=lambda x: (x[0], x[1]))
|
|
113
|
+
return [item[2] for item in matches]
|
|
114
|
+
|
|
115
|
+
def get_completions(
|
|
116
|
+
self,
|
|
117
|
+
document: Document,
|
|
118
|
+
complete_event: CompleteEvent, # noqa: ARG002
|
|
119
|
+
) -> Iterable[Completion]:
|
|
120
|
+
text = document.text_before_cursor
|
|
121
|
+
input_path = text.strip("\"'")
|
|
122
|
+
|
|
123
|
+
try:
|
|
124
|
+
directory = os.path.dirname(input_path) or "."
|
|
125
|
+
basename = os.path.basename(input_path)
|
|
126
|
+
|
|
127
|
+
filenames: list[str] = (
|
|
128
|
+
os.listdir(directory) if os.path.isdir(directory) else []
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
for filename in self._fuzzy_filter_and_sort(filenames, basename):
|
|
132
|
+
full_name = (
|
|
133
|
+
filename if directory == "." else os.path.join(directory, filename)
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
if os.path.isdir(full_name):
|
|
137
|
+
filename += "/"
|
|
138
|
+
|
|
139
|
+
completion = full_name
|
|
140
|
+
|
|
141
|
+
if any(c in r""" !$%&()*:;<=>?[]^`{|}~""" for c in completion):
|
|
142
|
+
completion = f'"{completion}"'
|
|
143
|
+
|
|
144
|
+
yield Completion(
|
|
145
|
+
text=completion,
|
|
146
|
+
start_position=-len(text),
|
|
147
|
+
display=self._highlight_fuzzy_match(filename, basename),
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
except OSError:
|
|
151
|
+
pass
|
|
@@ -4,7 +4,7 @@ from functools import cache
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
6
|
PROJECT_NAME = "Easy Rip"
|
|
7
|
-
PROJECT_VERSION = "4.11.
|
|
7
|
+
PROJECT_VERSION = "4.11.3"
|
|
8
8
|
PROJECT_TITLE = f"{PROJECT_NAME} v{PROJECT_VERSION}"
|
|
9
9
|
PROJECT_URL = "https://github.com/op200/EasyRip"
|
|
10
10
|
PROJECT_RELEASE_API = "https://api.github.com/repos/op200/EasyRip/releases/latest"
|
|
@@ -213,6 +213,7 @@ _DEFAULT_X265_PARAMS: Final[dict[LiteralString, LiteralString]] = {
|
|
|
213
213
|
"open-gop": "1",
|
|
214
214
|
"gop-lookahead": "0",
|
|
215
215
|
"rc-lookahead": "20",
|
|
216
|
+
"lookahead-slices": "8",
|
|
216
217
|
"rect": "0",
|
|
217
218
|
"amp": "0",
|
|
218
219
|
"cbqpoffs": "0",
|
|
@@ -227,6 +228,11 @@ _DEFAULT_X265_PARAMS: Final[dict[LiteralString, LiteralString]] = {
|
|
|
227
228
|
"sao": "0",
|
|
228
229
|
"weightb": "1",
|
|
229
230
|
"info": "1",
|
|
231
|
+
# 性能
|
|
232
|
+
"lookahead-threads": "0",
|
|
233
|
+
"asm": "auto",
|
|
234
|
+
"frame-threads": "0",
|
|
235
|
+
"pools": "*",
|
|
230
236
|
}
|
|
231
237
|
|
|
232
238
|
|
|
@@ -391,6 +397,7 @@ DEFAULT_PRESET_PARAMS: Final[dict[Preset_name, dict[LiteralString, LiteralString
|
|
|
391
397
|
"subme": "5",
|
|
392
398
|
"gop-lookahead": "8",
|
|
393
399
|
"rc-lookahead": "216",
|
|
400
|
+
"lookahead-slices": "4",
|
|
394
401
|
"cbqpoffs": "-2",
|
|
395
402
|
"crqpoffs": "-2",
|
|
396
403
|
"pbratio": "1.2",
|
|
@@ -421,6 +428,7 @@ DEFAULT_PRESET_PARAMS: Final[dict[Preset_name, dict[LiteralString, LiteralString
|
|
|
421
428
|
"subme": "6",
|
|
422
429
|
"gop-lookahead": "14",
|
|
423
430
|
"rc-lookahead": "250",
|
|
431
|
+
"lookahead-slices": "2",
|
|
424
432
|
"rect": "1",
|
|
425
433
|
"min-keyint": "2",
|
|
426
434
|
"cbqpoffs": "-2",
|
|
@@ -434,7 +442,7 @@ DEFAULT_PRESET_PARAMS: Final[dict[Preset_name, dict[LiteralString, LiteralString
|
|
|
434
442
|
{
|
|
435
443
|
"crf": "17",
|
|
436
444
|
"qpmin": "3",
|
|
437
|
-
"qpmax": "
|
|
445
|
+
"qpmax": "23",
|
|
438
446
|
"psy-rd": "2.2",
|
|
439
447
|
"rd": "5",
|
|
440
448
|
"rdoq-level": "2",
|
|
@@ -456,6 +464,7 @@ DEFAULT_PRESET_PARAMS: Final[dict[Preset_name, dict[LiteralString, LiteralString
|
|
|
456
464
|
"open-gop": "1",
|
|
457
465
|
"gop-lookahead": "14",
|
|
458
466
|
"rc-lookahead": "250",
|
|
467
|
+
"lookahead-slices": "1",
|
|
459
468
|
"rect": "1",
|
|
460
469
|
"amp": "1",
|
|
461
470
|
"cbqpoffs": "-3",
|
|
@@ -802,11 +802,42 @@ class Ripper:
|
|
|
802
802
|
)
|
|
803
803
|
|
|
804
804
|
case Ripper.Preset_name.subset:
|
|
805
|
+
# 临时翻译
|
|
806
|
+
add_tr_file_list: Final[list[Path]] = []
|
|
807
|
+
if translate_sub := self.option_map.get("translate-sub"):
|
|
808
|
+
_tr = translate_sub.split(":")
|
|
809
|
+
if len(_tr) != 2:
|
|
810
|
+
log.error("{} param illegal", "-translate-sub")
|
|
811
|
+
else:
|
|
812
|
+
try:
|
|
813
|
+
_file_list = translate_subtitles(
|
|
814
|
+
Path(self.output_dir),
|
|
815
|
+
_tr[0],
|
|
816
|
+
_tr[1],
|
|
817
|
+
file_intersection_selector=self.input_path_list,
|
|
818
|
+
)
|
|
819
|
+
except Exception as e:
|
|
820
|
+
log.error(e, is_format=False)
|
|
821
|
+
else:
|
|
822
|
+
for f_and_s in _file_list:
|
|
823
|
+
if f_and_s[0].is_file():
|
|
824
|
+
log.warning(
|
|
825
|
+
'The file "{}" already exists, skip translating it',
|
|
826
|
+
f_and_s[0],
|
|
827
|
+
)
|
|
828
|
+
continue
|
|
829
|
+
|
|
830
|
+
with f_and_s[0].open(
|
|
831
|
+
"wt", encoding="utf-8-sig", newline="\n"
|
|
832
|
+
) as f:
|
|
833
|
+
f.write(f_and_s[1])
|
|
834
|
+
add_tr_file_list.append(f_and_s[0])
|
|
835
|
+
|
|
805
836
|
_output_dir = Path(self.output_dir) / basename
|
|
806
837
|
_output_dir.mkdir(parents=True, exist_ok=True)
|
|
807
838
|
|
|
808
|
-
_ass_list: list[Path] =
|
|
809
|
-
_other_sub_list: list[Path] = []
|
|
839
|
+
_ass_list: Final[list[Path]] = add_tr_file_list.copy()
|
|
840
|
+
_other_sub_list: Final[list[Path]] = []
|
|
810
841
|
|
|
811
842
|
for path in self.input_path_list:
|
|
812
843
|
if path.suffix == ".ass":
|
|
@@ -861,6 +892,13 @@ class Ripper:
|
|
|
861
892
|
for path in _other_sub_list:
|
|
862
893
|
shutil.copy2(path, _output_dir / path.name)
|
|
863
894
|
|
|
895
|
+
# 清理临时文件
|
|
896
|
+
for f in add_tr_file_list:
|
|
897
|
+
try:
|
|
898
|
+
f.unlink()
|
|
899
|
+
except Exception as e:
|
|
900
|
+
log.error(f"{e!r} {e}", deep=True, is_format=False)
|
|
901
|
+
|
|
864
902
|
if subset_res is False:
|
|
865
903
|
log.error("Run {} failed", "subset")
|
|
866
904
|
return subset_res
|
|
@@ -1085,39 +1123,9 @@ class Ripper:
|
|
|
1085
1123
|
log.warning("-soft-sub is empty")
|
|
1086
1124
|
log.info("-soft-sub list = {}", soft_sub_list)
|
|
1087
1125
|
|
|
1088
|
-
# 临时翻译
|
|
1089
|
-
add_tr_files: Final[list[Path]] = []
|
|
1090
|
-
if translate_sub := self.option_map.get("translate-sub"):
|
|
1091
|
-
_tr = translate_sub.split(":")
|
|
1092
|
-
if len(_tr) != 2:
|
|
1093
|
-
log.error("{} param illegal", "-translate-sub")
|
|
1094
|
-
else:
|
|
1095
|
-
try:
|
|
1096
|
-
_file_list = translate_subtitles(
|
|
1097
|
-
Path(self.output_dir),
|
|
1098
|
-
_tr[0],
|
|
1099
|
-
_tr[1],
|
|
1100
|
-
file_intersection_selector=soft_sub_list,
|
|
1101
|
-
)
|
|
1102
|
-
except Exception as e:
|
|
1103
|
-
log.error(e, is_format=False)
|
|
1104
|
-
else:
|
|
1105
|
-
for f_and_s in _file_list:
|
|
1106
|
-
if f_and_s[0].is_file():
|
|
1107
|
-
log.warning(
|
|
1108
|
-
'The file "{}" already exists, skip translating it',
|
|
1109
|
-
f_and_s[0],
|
|
1110
|
-
)
|
|
1111
|
-
continue
|
|
1112
|
-
with f_and_s[0].open(
|
|
1113
|
-
"wt", encoding="utf-8-sig", newline="\n"
|
|
1114
|
-
) as f:
|
|
1115
|
-
f.write(f_and_s[1])
|
|
1116
|
-
add_tr_files.append(f_and_s[0])
|
|
1117
|
-
|
|
1118
1126
|
# 子集化
|
|
1119
1127
|
if Ripper(
|
|
1120
|
-
soft_sub_list
|
|
1128
|
+
soft_sub_list,
|
|
1121
1129
|
(subset_folder.name,),
|
|
1122
1130
|
self.output_dir,
|
|
1123
1131
|
Ripper.Preset_name.subset,
|
|
@@ -1161,11 +1169,6 @@ class Ripper:
|
|
|
1161
1169
|
|
|
1162
1170
|
# 清理临时文件
|
|
1163
1171
|
shutil.rmtree(subset_folder)
|
|
1164
|
-
for f in add_tr_files:
|
|
1165
|
-
try:
|
|
1166
|
-
f.unlink()
|
|
1167
|
-
except Exception as e:
|
|
1168
|
-
log.error(f"{e!r} {e}", deep=True, is_format=False)
|
|
1169
1172
|
|
|
1170
1173
|
# 获取 ffmpeg report 中的报错
|
|
1171
1174
|
if FF_REPORT_LOG_FILE.is_file():
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from collections.abc import Iterable
|
|
3
|
-
|
|
4
|
-
from prompt_toolkit.completion import CompleteEvent, Completer, Completion
|
|
5
|
-
from prompt_toolkit.document import Document
|
|
6
|
-
from prompt_toolkit.history import FileHistory
|
|
7
|
-
|
|
8
|
-
from .global_val import C_Z, get_CONFIG_DIR
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class easyrip_prompt:
|
|
12
|
-
PROMPT_HISTORY_FILE = get_CONFIG_DIR() / "prompt_history.txt"
|
|
13
|
-
|
|
14
|
-
@classmethod
|
|
15
|
-
def clear(cls) -> None:
|
|
16
|
-
cls.PROMPT_HISTORY_FILE.unlink(True)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class ConfigFileHistory(FileHistory):
|
|
20
|
-
def store_string(self, string: str) -> None:
|
|
21
|
-
if not string.startswith(C_Z):
|
|
22
|
-
super().store_string(string)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class SmartPathCompleter(Completer):
|
|
26
|
-
def __init__(self) -> None:
|
|
27
|
-
pass
|
|
28
|
-
|
|
29
|
-
def get_completions(
|
|
30
|
-
self,
|
|
31
|
-
document: Document,
|
|
32
|
-
complete_event: CompleteEvent, # noqa: ARG002
|
|
33
|
-
) -> Iterable[Completion]:
|
|
34
|
-
text = document.text_before_cursor.strip("\"'")
|
|
35
|
-
|
|
36
|
-
try:
|
|
37
|
-
directory = (
|
|
38
|
-
os.path.dirname(os.path.join(".", text))
|
|
39
|
-
if os.path.dirname(text)
|
|
40
|
-
else "."
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
prefix = os.path.basename(text)
|
|
44
|
-
|
|
45
|
-
filenames: list[tuple[str, str]] = (
|
|
46
|
-
[
|
|
47
|
-
(directory, filename)
|
|
48
|
-
for filename in os.listdir(directory)
|
|
49
|
-
if filename.startswith(prefix)
|
|
50
|
-
]
|
|
51
|
-
if os.path.isdir(directory)
|
|
52
|
-
else []
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
for directory, filename in sorted(filenames, key=lambda k: k[1]):
|
|
56
|
-
completion = filename[len(prefix) :]
|
|
57
|
-
full_name = os.path.join(directory, filename)
|
|
58
|
-
|
|
59
|
-
if os.path.isdir(full_name):
|
|
60
|
-
filename += "/"
|
|
61
|
-
|
|
62
|
-
yield Completion(
|
|
63
|
-
text=(
|
|
64
|
-
f'{"" if any(c in text for c in "\\/") else '"'}{completion}"'
|
|
65
|
-
if any(c in r"""!$%&()*:;<=>?[]^`{|}~""" for c in completion)
|
|
66
|
-
else completion
|
|
67
|
-
),
|
|
68
|
-
start_position=0,
|
|
69
|
-
display=filename,
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
except OSError:
|
|
73
|
-
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|