easyrip 4.11.3__tar.gz → 4.13.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.
- {easyrip-4.11.3 → easyrip-4.13.0}/PKG-INFO +1 -1
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/__init__.py +1 -10
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/__main__.py +3 -1
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_command.py +29 -11
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_main.py +84 -37
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_mlang/__init__.py +2 -11
- easyrip-4.13.0/easyrip/easyrip_mlang/global_lang_val.py +160 -0
- easyrip-4.13.0/easyrip/easyrip_mlang/lang_en.py +5 -0
- easyrip-4.11.3/easyrip/easyrip_mlang/global_lang_val.py → easyrip-4.13.0/easyrip/easyrip_mlang/lang_tag_val.py +1 -154
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_mlang/lang_zh_Hans_CN.py +17 -15
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_mlang/translator.py +24 -29
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/global_val.py +1 -1
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/ripper/param.py +57 -17
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/ripper/ripper.py +284 -208
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/ripper/sub_and_font/ass.py +160 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/ripper/sub_and_font/subset.py +1 -1
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip.egg-info/PKG-INFO +1 -1
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip.egg-info/SOURCES.txt +1 -0
- easyrip-4.11.3/easyrip/easyrip_mlang/lang_en.py +0 -5
- {easyrip-4.11.3 → easyrip-4.13.0}/LICENSE +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/README.md +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_config/config.py +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_config/config_key.py +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_log.py +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_prompt.py +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_web/__init__.py +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_web/http_server.py +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/easyrip_web/third_party_api.py +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/ripper/media_info.py +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/ripper/sub_and_font/__init__.py +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/ripper/sub_and_font/font.py +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip/utils.py +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip.egg-info/dependency_links.txt +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip.egg-info/entry_points.txt +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip.egg-info/requires.txt +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/easyrip.egg-info/top_level.txt +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/pyproject.toml +0 -0
- {easyrip-4.11.3 → easyrip-4.13.0}/setup.cfg +0 -0
|
@@ -7,13 +7,7 @@ from .easyrip_main import (
|
|
|
7
7
|
init,
|
|
8
8
|
run_command,
|
|
9
9
|
)
|
|
10
|
-
from .easyrip_mlang import
|
|
11
|
-
Global_lang_val,
|
|
12
|
-
Lang_tag,
|
|
13
|
-
Lang_tag_language,
|
|
14
|
-
Lang_tag_region,
|
|
15
|
-
Lang_tag_script,
|
|
16
|
-
)
|
|
10
|
+
from .easyrip_mlang import Global_lang_val, Lang_tag
|
|
17
11
|
from .ripper.media_info import Media_info
|
|
18
12
|
from .ripper.ripper import Ripper
|
|
19
13
|
from .ripper.sub_and_font import Ass, Font, load_fonts
|
|
@@ -23,9 +17,6 @@ __all__ = [
|
|
|
23
17
|
"Font",
|
|
24
18
|
"Global_lang_val",
|
|
25
19
|
"Lang_tag",
|
|
26
|
-
"Lang_tag_language",
|
|
27
|
-
"Lang_tag_region",
|
|
28
|
-
"Lang_tag_script",
|
|
29
20
|
"Media_info",
|
|
30
21
|
"Ripper",
|
|
31
22
|
"check_env",
|
|
@@ -74,6 +74,7 @@ def run() -> NoReturn:
|
|
|
74
74
|
in {
|
|
75
75
|
*Cmd_type.cd.value.names,
|
|
76
76
|
*Cmd_type.mediainfo.value.names,
|
|
77
|
+
*Cmd_type.assinfo.value.names,
|
|
77
78
|
*Cmd_type.fontinfo.value.names,
|
|
78
79
|
}
|
|
79
80
|
else ()
|
|
@@ -98,6 +99,7 @@ def run() -> NoReturn:
|
|
|
98
99
|
*Opt_type._i.value.names,
|
|
99
100
|
*Opt_type._o_dir.value.names,
|
|
100
101
|
*Opt_type._o.value.names,
|
|
102
|
+
*Opt_type._pipe.value.names,
|
|
101
103
|
*Opt_type._sub.value.names,
|
|
102
104
|
*Opt_type._only_mux_sub_path.value.names,
|
|
103
105
|
*Opt_type._soft_sub.value.names,
|
|
@@ -141,7 +143,7 @@ def run() -> NoReturn:
|
|
|
141
143
|
|
|
142
144
|
try:
|
|
143
145
|
if not run_command(command):
|
|
144
|
-
log.warning("
|
|
146
|
+
log.warning("Command run terminated")
|
|
145
147
|
except KeyboardInterrupt:
|
|
146
148
|
log.warning("Manually stop run command")
|
|
147
149
|
|
|
@@ -18,7 +18,7 @@ from prompt_toolkit.document import Document
|
|
|
18
18
|
|
|
19
19
|
from . import global_val
|
|
20
20
|
from .easyrip_config.config_key import Config_key
|
|
21
|
-
from .ripper.param import
|
|
21
|
+
from .ripper.param import Audio_codec, Muxer, Preset_name
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
@final
|
|
@@ -268,7 +268,6 @@ class Cmd_type(enum.Enum):
|
|
|
268
268
|
"Translate subtitle files\n"
|
|
269
269
|
"e.g. 'translate zh-Hans zh-Hant' will translate all '*.zh-Hans.ass' files into zh-Hant"
|
|
270
270
|
),
|
|
271
|
-
childs=(Cmd_type_val(("-overwrite",)),),
|
|
272
271
|
)
|
|
273
272
|
mediainfo = Cmd_type_val(
|
|
274
273
|
("mediainfo",),
|
|
@@ -279,6 +278,15 @@ class Cmd_type(enum.Enum):
|
|
|
279
278
|
Cmd_type_val(("cfd",)),
|
|
280
279
|
),
|
|
281
280
|
)
|
|
281
|
+
assinfo = Cmd_type_val(
|
|
282
|
+
("assinfo",),
|
|
283
|
+
param="<<path> | 'fd' | 'cfd'> [-use-libass-spec <0|1>] [-show-chars-len <0|1>]",
|
|
284
|
+
description="Get the ass info by the Ass class",
|
|
285
|
+
childs=(
|
|
286
|
+
Cmd_type_val(("fd",)),
|
|
287
|
+
Cmd_type_val(("cfd",)),
|
|
288
|
+
),
|
|
289
|
+
)
|
|
282
290
|
fontinfo = Cmd_type_val(
|
|
283
291
|
("fontinfo",),
|
|
284
292
|
param="<<path> | 'fd' | 'cfd'>",
|
|
@@ -353,7 +361,8 @@ class Opt_type(enum.Enum):
|
|
|
353
361
|
param="<string>",
|
|
354
362
|
description=(
|
|
355
363
|
"Setting preset\n"
|
|
356
|
-
"
|
|
364
|
+
"\n" # .
|
|
365
|
+
"Preset name:\n"
|
|
357
366
|
f"{Preset_name.to_help_string(' ')}"
|
|
358
367
|
),
|
|
359
368
|
childs=(Cmd_type_val(tuple(Preset_name._value2member_map_)),),
|
|
@@ -442,7 +451,7 @@ class Opt_type(enum.Enum):
|
|
|
442
451
|
'e.g. "11\\{22}33" ->\n'
|
|
443
452
|
' "11\\33" (VSFilter)\n'
|
|
444
453
|
' "11{22}33" (libass)\n'
|
|
445
|
-
"Default:
|
|
454
|
+
"Default: 1"
|
|
446
455
|
),
|
|
447
456
|
childs=(Cmd_type_val(("0", "1")),),
|
|
448
457
|
)
|
|
@@ -486,7 +495,8 @@ class Opt_type(enum.Enum):
|
|
|
486
495
|
param="<string>",
|
|
487
496
|
description=(
|
|
488
497
|
"Setting audio encoder\n"
|
|
489
|
-
"
|
|
498
|
+
"\n" # .
|
|
499
|
+
"Audio encoder:\n"
|
|
490
500
|
f"{Audio_codec.to_help_string(' ')}"
|
|
491
501
|
),
|
|
492
502
|
childs=(Cmd_type_val(tuple(Audio_codec._value2member_map_)),),
|
|
@@ -501,11 +511,11 @@ class Opt_type(enum.Enum):
|
|
|
501
511
|
param="<string>",
|
|
502
512
|
description=(
|
|
503
513
|
"Setting muxer\n"
|
|
504
|
-
"
|
|
514
|
+
"\n" # .
|
|
505
515
|
"Muxer:\n"
|
|
506
|
-
"
|
|
507
|
-
" mkv\n"
|
|
516
|
+
f"{Audio_codec.to_help_string(' ')}"
|
|
508
517
|
),
|
|
518
|
+
childs=(Cmd_type_val(tuple(Muxer._value2member_map_)),),
|
|
509
519
|
)
|
|
510
520
|
_r = _fps = Cmd_type_val(
|
|
511
521
|
("-r", "-fps"),
|
|
@@ -789,8 +799,10 @@ class OptCompleter(Completer):
|
|
|
789
799
|
_preset_name = None
|
|
790
800
|
if _preset in Preset_name._member_map_:
|
|
791
801
|
_preset_name = Preset_name[_preset]
|
|
792
|
-
if _preset_name is not None
|
|
793
|
-
add_set: set[str] = {
|
|
802
|
+
if _preset_name is not None:
|
|
803
|
+
add_set: set[str] = {
|
|
804
|
+
f"-{n}" for n in _preset_name.get_param_name_set(set())
|
|
805
|
+
}
|
|
794
806
|
add_comp_words |= add_set
|
|
795
807
|
add_comp_meta_dict |= dict.fromkeys(add_set, f"{_preset} param")
|
|
796
808
|
|
|
@@ -859,7 +871,13 @@ class OptCompleter(Completer):
|
|
|
859
871
|
|
|
860
872
|
yield from merge_completers(
|
|
861
873
|
(
|
|
862
|
-
|
|
874
|
+
merge_completers(
|
|
875
|
+
(
|
|
876
|
+
_nested_dict_to_nc(new_nd),
|
|
877
|
+
FuzzyCompleter(_nested_dict_to_nc(new_nd), WORD=True),
|
|
878
|
+
),
|
|
879
|
+
deduplicate=True,
|
|
880
|
+
),
|
|
863
881
|
FuzzyCompleter(
|
|
864
882
|
WordCompleter(
|
|
865
883
|
words=tuple(opt_tree_pos_list[-1]),
|
|
@@ -30,16 +30,14 @@ from .easyrip_log import log
|
|
|
30
30
|
from .easyrip_mlang import (
|
|
31
31
|
Global_lang_val,
|
|
32
32
|
Lang_tag,
|
|
33
|
-
Lang_tag_language,
|
|
34
33
|
get_system_language,
|
|
35
34
|
gettext,
|
|
36
35
|
translate_subtitles,
|
|
37
36
|
)
|
|
38
37
|
from .easyrip_prompt import easyrip_prompt
|
|
39
38
|
from .ripper.media_info import Media_info
|
|
40
|
-
from .ripper.param import DEFAULT_PRESET_PARAMS, PRESET_OPT_NAME
|
|
41
39
|
from .ripper.ripper import Ripper
|
|
42
|
-
from .ripper.sub_and_font import load_fonts
|
|
40
|
+
from .ripper.sub_and_font import Ass, load_fonts
|
|
43
41
|
from .utils import change_title, check_ver, read_text
|
|
44
42
|
|
|
45
43
|
__all__ = ["init", "run_command"]
|
|
@@ -307,6 +305,10 @@ def run_ripper_list(
|
|
|
307
305
|
except Exception as e:
|
|
308
306
|
log.error(e, deep=True)
|
|
309
307
|
log.warning("Stop run Ripper")
|
|
308
|
+
except KeyboardInterrupt:
|
|
309
|
+
log.warning("Manually stop run and clear Ripper list")
|
|
310
|
+
Ripper.ripper_list.clear()
|
|
311
|
+
raise
|
|
310
312
|
|
|
311
313
|
with ThreadPoolExecutor() as executor:
|
|
312
314
|
for ripper in Ripper.ripper_list:
|
|
@@ -324,6 +326,10 @@ def run_ripper_list(
|
|
|
324
326
|
except Exception as e:
|
|
325
327
|
log.error(e, deep=True)
|
|
326
328
|
log.warning("Stop run Ripper")
|
|
329
|
+
except KeyboardInterrupt:
|
|
330
|
+
log.warning("Manually stop run and clear Ripper list")
|
|
331
|
+
Ripper.ripper_list.clear()
|
|
332
|
+
raise
|
|
327
333
|
sleep(0.5)
|
|
328
334
|
|
|
329
335
|
if log.warning_num > warning_num:
|
|
@@ -419,40 +425,41 @@ def run_command(command: Iterable[str] | str) -> bool:
|
|
|
419
425
|
log.send(_want_doc_cmd_type.value.to_doc(), is_format=False)
|
|
420
426
|
elif cmd_list[2] in Ripper.Preset_name._value2member_map_:
|
|
421
427
|
_preset = Ripper.Preset_name(cmd_list[2])
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
):
|
|
426
|
-
if _preset in PRESET_OPT_NAME:
|
|
427
|
-
log.send(
|
|
428
|
-
"Params that can be directly used:\n{}",
|
|
429
|
-
textwrap.indent(
|
|
430
|
-
"\n".join(
|
|
431
|
-
f"-{n}"
|
|
432
|
-
for n in PRESET_OPT_NAME[_preset]
|
|
433
|
-
),
|
|
434
|
-
prefix=" ",
|
|
435
|
-
),
|
|
436
|
-
)
|
|
437
|
-
if _preset in DEFAULT_PRESET_PARAMS:
|
|
438
|
-
_default_params = DEFAULT_PRESET_PARAMS[_preset]
|
|
439
|
-
max_name_len = (
|
|
440
|
-
max(len(str(n)) for n in _default_params) + 1
|
|
441
|
-
)
|
|
442
|
-
log.send(
|
|
443
|
-
"Default val:\n{}",
|
|
444
|
-
textwrap.indent(
|
|
445
|
-
"\n".join(
|
|
446
|
-
f"{f'-{n}':>{max_name_len}} {v}"
|
|
447
|
-
for n, v in _default_params.items()
|
|
448
|
-
),
|
|
449
|
-
prefix=" ",
|
|
450
|
-
),
|
|
451
|
-
)
|
|
452
|
-
else:
|
|
428
|
+
_param_default_dict = _preset.get_param_default_dict()
|
|
429
|
+
_param_name_set = _preset.get_param_name_set()
|
|
430
|
+
if not any((_param_default_dict, _param_name_set)):
|
|
453
431
|
log.send(
|
|
454
432
|
"The preset '{}' has no separate help", cmd_list[2]
|
|
455
433
|
)
|
|
434
|
+
if _param_name_set:
|
|
435
|
+
log.send(
|
|
436
|
+
"Params that can be directly used:\n{}",
|
|
437
|
+
textwrap.indent(
|
|
438
|
+
"\n".join(f"-{n}" for n in _param_name_set),
|
|
439
|
+
prefix=" ",
|
|
440
|
+
),
|
|
441
|
+
)
|
|
442
|
+
if _param_default_dict:
|
|
443
|
+
max_name_len = (
|
|
444
|
+
max(len(str(n)) for n in _param_default_dict) + 1
|
|
445
|
+
)
|
|
446
|
+
log.send(
|
|
447
|
+
"Default val:\n{}",
|
|
448
|
+
textwrap.indent(
|
|
449
|
+
"\n".join(
|
|
450
|
+
f"{f'-{n}':>{max_name_len}} {v}"
|
|
451
|
+
for n, v in _param_default_dict.items()
|
|
452
|
+
),
|
|
453
|
+
prefix=" ",
|
|
454
|
+
),
|
|
455
|
+
)
|
|
456
|
+
log.send(
|
|
457
|
+
" FFmpeg format:\n {}",
|
|
458
|
+
":".join(
|
|
459
|
+
f"{n}={v}"
|
|
460
|
+
for n, v in _param_default_dict.items()
|
|
461
|
+
),
|
|
462
|
+
)
|
|
456
463
|
else:
|
|
457
464
|
log.error("'{}' is not a member of preset", cmd_list[2])
|
|
458
465
|
|
|
@@ -495,8 +502,8 @@ def run_command(command: Iterable[str] | str) -> bool:
|
|
|
495
502
|
case Cmd_type.exit:
|
|
496
503
|
sys.exit(0)
|
|
497
504
|
|
|
498
|
-
case Cmd_type.cd | Cmd_type.mediainfo | Cmd_type.fontinfo:
|
|
499
|
-
_path_tuple:
|
|
505
|
+
case Cmd_type.cd | Cmd_type.mediainfo | Cmd_type.assinfo | Cmd_type.fontinfo:
|
|
506
|
+
_path_tuple: Iterable[str] | None = None
|
|
500
507
|
|
|
501
508
|
match cmd_list[1]:
|
|
502
509
|
case "fd" | "cfd" as fd_param:
|
|
@@ -528,6 +535,46 @@ def run_command(command: Iterable[str] | str) -> bool:
|
|
|
528
535
|
case Cmd_type.mediainfo:
|
|
529
536
|
for _path in _path_tuple:
|
|
530
537
|
log.send(f"{_path}: {Media_info.from_path(_path)}")
|
|
538
|
+
case Cmd_type.assinfo:
|
|
539
|
+
USE_LIBASS_SPEC_OPT_NAME = "-use-libass-spec"
|
|
540
|
+
use_libass_spec: bool = True
|
|
541
|
+
SHOW_CHARS_LEN_OPT_NAME = "-show-chars-len"
|
|
542
|
+
show_chars_len: bool = False
|
|
543
|
+
is_use_opt: bool = False
|
|
544
|
+
for i, s in tuple(enumerate(cmd_list))[2:]:
|
|
545
|
+
if s == USE_LIBASS_SPEC_OPT_NAME:
|
|
546
|
+
use_libass_spec = cmd_list[i + 1] != "0"
|
|
547
|
+
is_use_opt = True
|
|
548
|
+
if s == SHOW_CHARS_LEN_OPT_NAME:
|
|
549
|
+
show_chars_len = cmd_list[i + 1] != "0"
|
|
550
|
+
is_use_opt = True
|
|
551
|
+
if is_use_opt:
|
|
552
|
+
_path_tuple = cmd_list[1:2]
|
|
553
|
+
log.send(
|
|
554
|
+
" ".join(
|
|
555
|
+
(
|
|
556
|
+
f"{USE_LIBASS_SPEC_OPT_NAME} {1 if use_libass_spec else 0}",
|
|
557
|
+
f"{SHOW_CHARS_LEN_OPT_NAME} {1 if show_chars_len else 0}",
|
|
558
|
+
)
|
|
559
|
+
)
|
|
560
|
+
)
|
|
561
|
+
for _path in _path_tuple:
|
|
562
|
+
try:
|
|
563
|
+
ass = Ass(_path)
|
|
564
|
+
except Exception as e:
|
|
565
|
+
log.error(e)
|
|
566
|
+
return False
|
|
567
|
+
|
|
568
|
+
log.send(_path)
|
|
569
|
+
for font_sign, ss in ass.get_font_info(
|
|
570
|
+
use_libass_spec=use_libass_spec,
|
|
571
|
+
).items():
|
|
572
|
+
show_chars_len_log_str = ""
|
|
573
|
+
if show_chars_len:
|
|
574
|
+
show_chars_len_log_str = f": {len(ss)}"
|
|
575
|
+
log.send(
|
|
576
|
+
f" ( {font_sign[0]} / {font_sign[1].name} ){show_chars_len_log_str}"
|
|
577
|
+
)
|
|
531
578
|
case Cmd_type.fontinfo:
|
|
532
579
|
for _font in itertools.chain.from_iterable(
|
|
533
580
|
load_fonts(_path) for _path in _path_tuple
|
|
@@ -1156,7 +1203,7 @@ def init(is_first_run: bool = False) -> None:
|
|
|
1156
1203
|
|
|
1157
1204
|
if (
|
|
1158
1205
|
lang_tag := Lang_tag.from_str(file.stem[5:])
|
|
1159
|
-
).language is not
|
|
1206
|
+
).language is not Lang_tag.Language.Unknown:
|
|
1160
1207
|
easyrip_mlang.all_supported_lang_map[lang_tag] = lang_map
|
|
1161
1208
|
|
|
1162
1209
|
log.debug("Loading \"{}\" as '{}' language successfully", file, lang_tag)
|
|
@@ -1,22 +1,13 @@
|
|
|
1
1
|
import locale
|
|
2
2
|
|
|
3
3
|
from . import lang_en, lang_zh_Hans_CN
|
|
4
|
-
from .global_lang_val import
|
|
5
|
-
|
|
6
|
-
Lang_tag,
|
|
7
|
-
Lang_tag_language,
|
|
8
|
-
Lang_tag_region,
|
|
9
|
-
Lang_tag_script,
|
|
10
|
-
Lang_tag_val,
|
|
11
|
-
)
|
|
4
|
+
from .global_lang_val import Global_lang_val, Lang_tag
|
|
5
|
+
from .lang_tag_val import Lang_tag_val
|
|
12
6
|
from .translator import translate_subtitles
|
|
13
7
|
|
|
14
8
|
__all__ = [
|
|
15
9
|
"Global_lang_val",
|
|
16
10
|
"Lang_tag",
|
|
17
|
-
"Lang_tag_language",
|
|
18
|
-
"Lang_tag_region",
|
|
19
|
-
"Lang_tag_script",
|
|
20
11
|
"Lang_tag_val",
|
|
21
12
|
"Mlang_exception",
|
|
22
13
|
"get_system_language",
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
from collections.abc import Iterable
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Self, final
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@final
|
|
8
|
+
@dataclass(slots=True, kw_only=True)
|
|
9
|
+
class Lang_tag:
|
|
10
|
+
from .lang_tag_val import Lang_tag_language as Language
|
|
11
|
+
from .lang_tag_val import Lang_tag_region as Region
|
|
12
|
+
from .lang_tag_val import Lang_tag_script as Script
|
|
13
|
+
|
|
14
|
+
language: Language = Language.Unknown
|
|
15
|
+
script: Script = Script.Unknown
|
|
16
|
+
region: Region = Region.Unknown
|
|
17
|
+
|
|
18
|
+
class Match_priority(enum.Enum):
|
|
19
|
+
script = enum.auto()
|
|
20
|
+
region = enum.auto()
|
|
21
|
+
|
|
22
|
+
def match(
|
|
23
|
+
self,
|
|
24
|
+
target_tags: Iterable[Self],
|
|
25
|
+
*,
|
|
26
|
+
is_incomplete_match: bool = True,
|
|
27
|
+
priority: Match_priority = Match_priority.script,
|
|
28
|
+
is_allow_mismatch_language: bool = False,
|
|
29
|
+
) -> Self | None:
|
|
30
|
+
"""启用不完整匹配时,找到最匹配的第一项"""
|
|
31
|
+
target_tags_tuple = tuple(target_tags)
|
|
32
|
+
del target_tags
|
|
33
|
+
|
|
34
|
+
matching_tags_tuple = tuple(
|
|
35
|
+
tag for tag in target_tags_tuple if tag.language is self.language
|
|
36
|
+
)
|
|
37
|
+
if not matching_tags_tuple:
|
|
38
|
+
if is_allow_mismatch_language:
|
|
39
|
+
matching_tags_tuple = target_tags_tuple
|
|
40
|
+
else:
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
if self in matching_tags_tuple:
|
|
44
|
+
return self
|
|
45
|
+
if not is_incomplete_match:
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
same_region_tuple = tuple(
|
|
49
|
+
tag for tag in matching_tags_tuple if tag.region is self.region
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
same_script_tuple = tuple(
|
|
53
|
+
tag for tag in matching_tags_tuple if tag.script is self.script
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
if priority_same_tuple := (
|
|
57
|
+
same_script_tuple + same_region_tuple
|
|
58
|
+
if priority is self.__class__.Match_priority.script
|
|
59
|
+
else same_region_tuple + same_script_tuple
|
|
60
|
+
):
|
|
61
|
+
return priority_same_tuple[0]
|
|
62
|
+
|
|
63
|
+
return matching_tags_tuple[0]
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def from_str(
|
|
67
|
+
cls,
|
|
68
|
+
str_tag: str,
|
|
69
|
+
) -> Self:
|
|
70
|
+
"""
|
|
71
|
+
输入语言标签字符串,输出标签对象
|
|
72
|
+
|
|
73
|
+
e.g. zh-Hans-CN -> Self(Language.zh, Script.Hans, Region.CN)
|
|
74
|
+
"""
|
|
75
|
+
from ..easyrip_mlang import gettext
|
|
76
|
+
|
|
77
|
+
str_tag_list = str_tag.split("-")
|
|
78
|
+
|
|
79
|
+
language: Lang_tag.Language = cls.Language.from_name(str_tag_list[0])
|
|
80
|
+
script: Lang_tag.Script = cls.Script.Unknown
|
|
81
|
+
region: Lang_tag.Region = cls.Region.Unknown
|
|
82
|
+
|
|
83
|
+
for i, s in enumerate(str_tag_list[1:]):
|
|
84
|
+
if s in cls.Script._member_map_:
|
|
85
|
+
if i != 0:
|
|
86
|
+
raise ValueError(
|
|
87
|
+
gettext("The input language tag string format is illegal")
|
|
88
|
+
)
|
|
89
|
+
script = cls.Script[s]
|
|
90
|
+
elif s in cls.Region._member_map_:
|
|
91
|
+
region = cls.Region[s]
|
|
92
|
+
|
|
93
|
+
return cls(
|
|
94
|
+
language=language,
|
|
95
|
+
script=script,
|
|
96
|
+
region=region,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def __str__(self) -> str:
|
|
100
|
+
"""返回语言标签字符串"""
|
|
101
|
+
if self.language == self.__class__.Language.Unknown:
|
|
102
|
+
raise Exception("The Language is Unknown")
|
|
103
|
+
|
|
104
|
+
res_str: str = self.language.name
|
|
105
|
+
if self.script != self.__class__.Script.Unknown:
|
|
106
|
+
res_str += f"-{self.script.name}"
|
|
107
|
+
if self.region != self.__class__.Region.Unknown:
|
|
108
|
+
res_str += f"-{self.region.name}"
|
|
109
|
+
|
|
110
|
+
return res_str
|
|
111
|
+
|
|
112
|
+
def __hash__(self) -> int:
|
|
113
|
+
return hash((self.language, self.script, self.region))
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class Global_lang_val:
|
|
117
|
+
gettext_target_lang: Lang_tag = Lang_tag()
|
|
118
|
+
|
|
119
|
+
@staticmethod
|
|
120
|
+
def language_tag_to_local_str(language_tag: str) -> str:
|
|
121
|
+
from ..easyrip_mlang import gettext
|
|
122
|
+
|
|
123
|
+
tag_list = language_tag.split("-")
|
|
124
|
+
tag_list_len = len(tag_list)
|
|
125
|
+
|
|
126
|
+
if tag_list_len == 0:
|
|
127
|
+
raise Exception(gettext("The input language tag string format is illegal"))
|
|
128
|
+
|
|
129
|
+
res_str_list: list[str] = [
|
|
130
|
+
_local_name
|
|
131
|
+
if (_org_name := tag_list[0]) in Lang_tag.Language._member_map_
|
|
132
|
+
and (_local_name := Lang_tag.Language[_org_name].value.local_name)
|
|
133
|
+
else _org_name
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
if tag_list_len >= 2:
|
|
137
|
+
_org_name = tag_list[1]
|
|
138
|
+
|
|
139
|
+
if _org_name in Lang_tag.Script.__members__:
|
|
140
|
+
_local_name = Lang_tag.Script[_org_name].value.local_name
|
|
141
|
+
elif _org_name in Lang_tag.Region._member_map_:
|
|
142
|
+
_local_name = Lang_tag.Region[_org_name].value.local_name
|
|
143
|
+
else:
|
|
144
|
+
_local_name = _org_name
|
|
145
|
+
|
|
146
|
+
res_str_list.append(_local_name)
|
|
147
|
+
|
|
148
|
+
if tag_list_len >= 3:
|
|
149
|
+
_org_name = tag_list[2]
|
|
150
|
+
|
|
151
|
+
if _org_name in Lang_tag.Region._member_map_:
|
|
152
|
+
_local_name = Lang_tag.Region[_org_name].value.local_name
|
|
153
|
+
else:
|
|
154
|
+
_local_name = _org_name
|
|
155
|
+
|
|
156
|
+
res_str_list.append(_local_name)
|
|
157
|
+
|
|
158
|
+
return (" - " if any(" " in s for s in res_str_list) else "-").join(
|
|
159
|
+
res_str_list
|
|
160
|
+
)
|