easyrip 4.13.1__py3-none-any.whl → 4.13.3__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.
easyrip/__main__.py CHANGED
@@ -17,6 +17,8 @@ from .easyrip_command import (
17
17
  Cmd_type,
18
18
  Cmd_type_val,
19
19
  CmdCompleter,
20
+ FuzzyCompleter,
21
+ NestedCompleter,
20
22
  Opt_type,
21
23
  OptCompleter,
22
24
  nested_dict,
@@ -128,6 +130,14 @@ def run() -> NoReturn:
128
130
  (
129
131
  _ctv_to_nc(cmd_ctv_tuple),
130
132
  OptCompleter(opt_tree=_ctv_to_nd(ct.value for ct in Opt_type)),
133
+ FuzzyCompleter(
134
+ NestedCompleter(
135
+ {
136
+ k: NestedCompleter({v: None})
137
+ for k, v in easyrip_prompt.get_custom_prompt().items()
138
+ }
139
+ ),
140
+ ),
131
141
  )
132
142
  ),
133
143
  history=prompt_history,
@@ -254,11 +254,18 @@ class Cmd_type(enum.Enum):
254
254
  "history\n" # .
255
255
  " Show prompt history\n"
256
256
  "clear | clean\n"
257
- " Delete history file"
257
+ " Delete history file\n"
258
+ "add <name:string> <cmd:string>\n"
259
+ " Add a custom prompt\n"
260
+ " e.g. prompt add myprompt echo my prompt\n"
261
+ "del <name:string>\n"
262
+ " Delete a custom prompt"
258
263
  ),
259
264
  childs=(
260
265
  Cmd_type_val(("history",)),
261
266
  Cmd_type_val(("clear", "clean")),
267
+ Cmd_type_val(("add",)),
268
+ Cmd_type_val(("del",)),
262
269
  ),
263
270
  )
264
271
  translate = Cmd_type_val(
easyrip/easyrip_main.py CHANGED
@@ -775,8 +775,27 @@ def run_command(command: Iterable[str] | str) -> bool:
775
775
  ) as f:
776
776
  for line in f.read().splitlines():
777
777
  log.send(line, is_format=False)
778
+
778
779
  case "clear" | "clean":
779
- easyrip_prompt.clear()
780
+ easyrip_prompt.clear_history()
781
+
782
+ case "add":
783
+ _name = cmd_list[2]
784
+ _cmd = (
785
+ command.split(maxsplit=3)[-1]
786
+ if isinstance(command, str)
787
+ else " ".join(cmd_list[3:])
788
+ )
789
+ if " " in _name:
790
+ log.error("The name must not contain spaces")
791
+ return False
792
+ log.info("Add custom prompt {!r} = {!r}", _name, _cmd)
793
+ return easyrip_prompt.add_custom_prompt(_name, _cmd)
794
+
795
+ case "del":
796
+ _name = cmd_list[2]
797
+ log.info("Del custom prompt {!r}", _name)
798
+ return easyrip_prompt.del_custom_prompt(_name)
780
799
 
781
800
  case Cmd_type.translate:
782
801
  if not (_infix := cmd_list[1]):
easyrip/easyrip_prompt.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import re
3
+ import tomllib
3
4
  from collections.abc import Iterable
4
5
 
5
6
  from prompt_toolkit.completion import CompleteEvent, Completer, Completion
@@ -8,15 +9,73 @@ from prompt_toolkit.formatted_text import StyleAndTextTuples
8
9
  from prompt_toolkit.history import FileHistory
9
10
 
10
11
  from .global_val import C_Z, get_CONFIG_DIR
12
+ from .utils import type_match
11
13
 
12
14
 
13
15
  class easyrip_prompt:
14
16
  PROMPT_HISTORY_FILE = get_CONFIG_DIR() / "prompt_history.txt"
17
+ PROMPT_CUSTOM_FILE = get_CONFIG_DIR() / "prompt_custom.toml"
18
+
19
+ __prompt_custom_data: dict[str, str] | None = None
15
20
 
16
21
  @classmethod
17
- def clear(cls) -> None:
22
+ def clear_history(cls) -> None:
18
23
  cls.PROMPT_HISTORY_FILE.unlink(True)
19
24
 
25
+ @classmethod
26
+ def get_custom_prompt(cls) -> dict[str, str]:
27
+ if cls.__prompt_custom_data is not None:
28
+ return cls.__prompt_custom_data
29
+
30
+ cls.PROMPT_CUSTOM_FILE.touch()
31
+ with cls.PROMPT_CUSTOM_FILE.open("rb") as f:
32
+ data = tomllib.load(f)
33
+ assert type_match(data, dict[str, str])
34
+ cls.__prompt_custom_data = data
35
+ return data
36
+
37
+ @classmethod
38
+ def update_custom_prompt(cls, data: dict[str, str]) -> bool:
39
+ cls.PROMPT_CUSTOM_FILE.touch()
40
+ with cls.PROMPT_CUSTOM_FILE.open("wt", encoding="utf-8", newline="\n") as f:
41
+ f.writelines(f"{k!r} = {v!r}\n" for k, v in data.items())
42
+ cls.__prompt_custom_data = None
43
+ return True
44
+
45
+ @classmethod
46
+ def add_custom_prompt(cls, name: str, cmd: str) -> bool:
47
+ data: dict[str, str] = cls.get_custom_prompt()
48
+ assert type_match(data, dict[str, str])
49
+
50
+ if name in data:
51
+ from .easyrip_log import log
52
+
53
+ log.error("The name {!r} is already in custom prompt", name)
54
+ return False
55
+
56
+ data[name] = cmd
57
+
58
+ cls.update_custom_prompt(data)
59
+
60
+ return True
61
+
62
+ @classmethod
63
+ def del_custom_prompt(cls, name: str) -> bool:
64
+ data: dict[str, str] = cls.get_custom_prompt()
65
+
66
+ pop_res: bool
67
+ if name in data:
68
+ data.pop(name)
69
+ pop_res = True
70
+ cls.update_custom_prompt(data)
71
+ else:
72
+ from .easyrip_log import log
73
+
74
+ log.warning("The name {!r} not in custom prompt", name)
75
+ pop_res = False
76
+
77
+ return pop_res
78
+
20
79
 
21
80
  class ConfigFileHistory(FileHistory):
22
81
  def store_string(self, string: str) -> None:
easyrip/global_val.py CHANGED
@@ -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.13.1"
7
+ PROJECT_VERSION = "4.13.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"
easyrip/ripper/ripper.py CHANGED
@@ -474,17 +474,21 @@ class Ripper:
474
474
  f"-map 0:{_audio_info.index} -c:a {_encoder} {ffparams_out} "
475
475
  f'"{_new_output_str}.wav" '
476
476
  )
477
- _flac_encode_str_list = [
478
- (
479
- f"flac -j 32 -8 -e -p -l {'19' if _audio_info.sample_rate > 48000 else '12'} "
480
- f'-o "{_new_output_str}.flac" "{_new_output_str}.wav"'
481
- ),
482
- f'{cmd_head_del} "{_new_output_str}.wav"',
483
- ]
477
+ _flac_encode_str_list.extend(
478
+ [
479
+ (
480
+ f"flac -j 32 -8 -e -p -l {'19' if _audio_info.sample_rate > 48000 else '12'} "
481
+ f'-o "{_new_output_str}.flac" "{_new_output_str}.wav"'
482
+ ),
483
+ f'{cmd_head_del} "{_new_output_str}.wav"',
484
+ ]
485
+ )
484
486
 
485
487
  _mux_flac_input_list.append(f'"{_new_output_str}.flac"')
486
488
 
487
- _del_flac_str_list = [f'{cmd_head_del} "{_new_output_str}.flac" ']
489
+ _del_flac_str_list.append(
490
+ f'{cmd_head_del} "{_new_output_str}.flac" '
491
+ )
488
492
 
489
493
  match len(_mux_flac_input_list):
490
494
  case 0:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easyrip
3
- Version: 4.13.1
3
+ Version: 4.13.3
4
4
  Author: op200
5
5
  License-Expression: AGPL-3.0-or-later
6
6
  Project-URL: Homepage, https://github.com/op200/EasyRip
@@ -1,10 +1,10 @@
1
1
  easyrip/__init__.py,sha256=DULQoFEAEHYk7dS8Zxky56so7qDPqHm7jUc_Zop1eXw,616
2
- easyrip/__main__.py,sha256=wvMAp5i5-Pjv5dkEtPyoTs12QFq48B4u8lujYkcpy9I,5065
3
- easyrip/easyrip_command.py,sha256=AifME_dEPHzUAGJVFqwdIDE6RItOk2TO8QsKYV1kLYQ,29920
2
+ easyrip/__main__.py,sha256=QkzhmJPZUf79J-9ugJbks46fyYNG6dPn1K29nzfFVvU,5474
3
+ easyrip/easyrip_command.py,sha256=g6gOJUrtQrSH2Hh6np2JgDqnWKVIWcV8SpMlkxApNgw,30210
4
4
  easyrip/easyrip_log.py,sha256=R-dM3CWUBFITtG7GSD1zy4X4MhZqxkoiBPjlIpI76cY,15573
5
- easyrip/easyrip_main.py,sha256=LnMRaUC0qZm4cN5aSoUOVPZ6QvCqjRQZI9khzF5vf_s,46980
6
- easyrip/easyrip_prompt.py,sha256=3or0Vt4s6L53MCJtQmSylrTADZIIjX5gvpSb-JRe2P4,4844
7
- easyrip/global_val.py,sha256=VFXvnK5HZjFTilBbqMrB_5L-2_y-ebJ6wCJwYq_FufE,866
5
+ easyrip/easyrip_main.py,sha256=jadrI1qyjEw_x-RSx6TCxXoqwTIjQbamsen8lA71Ewc,47757
6
+ easyrip/easyrip_prompt.py,sha256=he5gBUDwoDTPyriizFnwY39SX3UHV3eX6cHrCM7OdvI,6644
7
+ easyrip/global_val.py,sha256=q5DwBxWzBDjF2w-1TYxm9YeZmz65ttkgytFuJjGuCsI,866
8
8
  easyrip/utils.py,sha256=N1rMF1MyoC-YFBgy10_u29cFoowfhR-5Viea93O7wQ4,8750
9
9
  easyrip/easyrip_config/config.py,sha256=KWXZMEYxdXYUGLQ-MR0A7nnOwR6QZdVrWBopfb2QZSA,9869
10
10
  easyrip/easyrip_config/config_key.py,sha256=_jjdKOunskUoG7UUWOz3QZK-s4LF_x6hmM9MKttyS2Q,766
@@ -19,14 +19,14 @@ easyrip/easyrip_web/http_server.py,sha256=iyulCAFQrJlz86Lrr-Dm3fhOnNCf79Bp6fVHhr
19
19
  easyrip/easyrip_web/third_party_api.py,sha256=GhP6LmR1sVMeLLbnj82r-QYjoUdSnyaU9xp0LRnRLsw,4623
20
20
  easyrip/ripper/media_info.py,sha256=mQq_vbQ7S9fWpb39HLkoZlAL-pqNfwxewv6X776Nf50,5078
21
21
  easyrip/ripper/param.py,sha256=PfJzJz9LPCB5hAM9G4GjPxdn_EZRgAz-vxYzuHGQLp8,13084
22
- easyrip/ripper/ripper.py,sha256=4u-Rx1AMD9LjAsEkwOuJTPTAKEiDz5cuAlSaF73rnV4,52630
22
+ easyrip/ripper/ripper.py,sha256=bymJVnEqQa3lTEiLJwRQpmfVctvP-2tLprCQ2XfH9Lk,52756
23
23
  easyrip/ripper/sub_and_font/__init__.py,sha256=cBT7mxL7RRFaJXFPXuZ7RT-YK6FbnanaU5v6U9BOquw,153
24
24
  easyrip/ripper/sub_and_font/ass.py,sha256=EhDkVY5JXU77euWPId7H2v85j444m8ZLm7wUid7TYd8,35307
25
25
  easyrip/ripper/sub_and_font/font.py,sha256=X2dPcPzbwQf3fv_g_mxO-zY7puVAX9Nv-9QHn88q4oA,7745
26
26
  easyrip/ripper/sub_and_font/subset.py,sha256=--rAA3VH1rm_jBOC3yMs3rOJpn3tPuvfXqkimbBtx3s,18653
27
- easyrip-4.13.1.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
28
- easyrip-4.13.1.dist-info/METADATA,sha256=4D-2WPxCi3IHV_WfPBRKBhnSreiKvD_cdQikdlOaKgs,3507
29
- easyrip-4.13.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
- easyrip-4.13.1.dist-info/entry_points.txt,sha256=D6GBMMTzZ-apgX76KyZ6jxMmIFqGYwU9neeLLni_qKI,49
31
- easyrip-4.13.1.dist-info/top_level.txt,sha256=kuEteBXm-Gf90jRQgH3-fTo-Z-Q6czSuUEqY158H4Ww,8
32
- easyrip-4.13.1.dist-info/RECORD,,
27
+ easyrip-4.13.3.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
28
+ easyrip-4.13.3.dist-info/METADATA,sha256=fgp3xx0u6tSa8VIrAxNWMUYHSjotJOsDVF6eILHJZ20,3507
29
+ easyrip-4.13.3.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
30
+ easyrip-4.13.3.dist-info/entry_points.txt,sha256=D6GBMMTzZ-apgX76KyZ6jxMmIFqGYwU9neeLLni_qKI,49
31
+ easyrip-4.13.3.dist-info/top_level.txt,sha256=kuEteBXm-Gf90jRQgH3-fTo-Z-Q6czSuUEqY158H4Ww,8
32
+ easyrip-4.13.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5