easyrip 4.3.0__py3-none-any.whl → 4.3.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.
easyrip/__main__.py CHANGED
@@ -6,7 +6,7 @@ import Crypto
6
6
  import fontTools
7
7
  import prompt_toolkit
8
8
  from prompt_toolkit import ANSI, prompt
9
- from prompt_toolkit.completion import PathCompleter, merge_completers
9
+ from prompt_toolkit.completion import merge_completers
10
10
  from prompt_toolkit.history import InMemoryHistory
11
11
  from prompt_toolkit.key_binding import KeyBindings, KeyPressEvent
12
12
  from prompt_toolkit.keys import Keys
@@ -21,7 +21,7 @@ from .easyrip_command import (
21
21
  )
22
22
  from .easyrip_config.config import Config_key, config
23
23
  from .easyrip_main import Ripper, get_input_prompt, init, log, run_command
24
- from .easyrip_prompt import ConfigFileHistory, easyrip_prompt
24
+ from .easyrip_prompt import ConfigFileHistory, SmartPathCompleter, easyrip_prompt
25
25
  from .global_val import C_D, C_Z
26
26
 
27
27
 
@@ -48,7 +48,7 @@ def run() -> NoReturn:
48
48
  def _(event: KeyPressEvent) -> None:
49
49
  event.app.current_buffer.insert_text(C_D)
50
50
 
51
- path_completer = PathCompleter()
51
+ path_completer = SmartPathCompleter()
52
52
 
53
53
  def _ctv_to_nc(ctvs: Iterable[Cmd_type_val]) -> CmdCompleter:
54
54
  return CmdCompleter(
@@ -105,6 +105,7 @@ def run() -> NoReturn:
105
105
  if config.get_user_profile(Config_key.prompt_history_save_file)
106
106
  else InMemoryHistory()
107
107
  )
108
+
108
109
  while True:
109
110
  try:
110
111
  command = prompt(
@@ -25,10 +25,24 @@ from .easyrip_config.config_key import Config_key
25
25
  @dataclass(slots=True, init=False, eq=False)
26
26
  class Cmd_type_val:
27
27
  names: tuple[str, ...]
28
- param: str
28
+ _param: str
29
29
  _description: str
30
30
  childs: tuple["Cmd_type_val", ...]
31
31
 
32
+ @property
33
+ def param(self) -> str:
34
+ try:
35
+ from .easyrip_mlang import gettext
36
+
37
+ return gettext(self._param, is_format=False)
38
+
39
+ except ImportError: # 启动时,原字符串导入翻译文件
40
+ return self._param
41
+
42
+ @param.setter
43
+ def param(self, val: str) -> None:
44
+ self._param = val
45
+
32
46
  @property
33
47
  def description(self) -> str:
34
48
  try:
@@ -688,10 +702,14 @@ def get_help_doc() -> str:
688
702
 
689
703
  type nested_dict = dict[str, "nested_dict | Completer"]
690
704
  META_DICT_OPT_TYPE = {
691
- name: opt.value.param for opt in Opt_type for name in opt.value.names
705
+ name: lambda opt=opt: opt.value.param
706
+ for opt in Opt_type
707
+ for name in opt.value.names
692
708
  }
693
709
  META_DICT_CMD_TYPE = {
694
- name: opt.value.param for opt in Cmd_type for name in opt.value.names
710
+ name: lambda opt=opt: opt.value.param
711
+ for opt in Cmd_type
712
+ for name in opt.value.names
695
713
  }
696
714
 
697
715
 
@@ -710,6 +728,7 @@ class CmdCompleter(NestedCompleter):
710
728
  ) -> Iterable[Completion]:
711
729
  # Split document.
712
730
  text = document.text_before_cursor.lstrip()
731
+ words = text.split(" ")
713
732
  stripped_len = len(document.text_before_cursor) - len(text)
714
733
 
715
734
  # If there is a space, check for the first term, and use a
@@ -730,12 +749,30 @@ class CmdCompleter(NestedCompleter):
730
749
 
731
750
  yield from completer.get_completions(new_document, complete_event)
732
751
 
752
+ elif words and (_cmd := Cmd_type.from_str(words[-1])) is not None:
753
+ yield from (
754
+ Completion(
755
+ text=words[-1],
756
+ start_position=-len(words[-1]),
757
+ display_meta=META_DICT_CMD_TYPE.get(words[-1], ""),
758
+ ),
759
+ Completion(
760
+ text="",
761
+ display="✔",
762
+ display_meta=(
763
+ f"{_desc_list[0]}..."
764
+ if len(_desc_list := _cmd.value.description.split("\n")) > 1
765
+ else _desc_list[0]
766
+ ),
767
+ ),
768
+ )
769
+
733
770
  # No space in the input: behave exactly like `WordCompleter`.
734
771
  else:
735
772
  # custom
736
773
  completer = FuzzyWordCompleter(
737
774
  tuple(self.options),
738
- meta_dict=META_DICT_CMD_TYPE,
775
+ meta_dict=META_DICT_CMD_TYPE, # pyright: ignore[reportArgumentType]
739
776
  WORD=True,
740
777
  )
741
778
  yield from completer.get_completions(document, complete_event)
@@ -750,7 +787,7 @@ class OptCompleter(Completer):
750
787
  ) -> Iterable[Completion]:
751
788
  text = document.text_before_cursor.lstrip()
752
789
 
753
- words = text.split()
790
+ words = text.split(" ")
754
791
 
755
792
  if len(words) >= 1 and not text.startswith("-"):
756
793
  return
@@ -774,7 +811,17 @@ class OptCompleter(Completer):
774
811
  start_position=-len(words[-1]),
775
812
  display_meta=META_DICT_OPT_TYPE.get(words[-1], ""),
776
813
  ),
777
- Completion(text="", display="✔"),
814
+ Completion(
815
+ text="",
816
+ display="✔",
817
+ display_meta=(
818
+ ""
819
+ if (_opt := Opt_type.from_str(text)) is None
820
+ else f"{_desc_list[0]}..."
821
+ if len(_desc_list := _opt.value.description.split("\n")) > 1
822
+ else _desc_list[0]
823
+ ),
824
+ ),
778
825
  )
779
826
 
780
827
  elif isinstance(opt_tree_pos_list[-1], Completer):
easyrip/easyrip_main.py CHANGED
@@ -10,7 +10,7 @@ import sys
10
10
  import threading
11
11
  import tkinter as tk
12
12
  import tomllib
13
- from collections.abc import Callable
13
+ from collections.abc import Callable, Iterable
14
14
  from concurrent.futures import ThreadPoolExecutor
15
15
  from datetime import datetime
16
16
  from multiprocessing import shared_memory
@@ -399,19 +399,16 @@ def get_web_server_params(
399
399
  return (host or "", int(port), password)
400
400
 
401
401
 
402
- def run_command(command: list[str] | str) -> bool:
403
- if isinstance(command, list):
404
- cmd_list = command
405
-
406
- else:
407
- try:
408
- cmd_list = [
409
- cmd.strip('"').strip("'").replace("\\\\", "\\")
410
- for cmd in shlex.split(command, posix=False)
411
- ]
412
- except ValueError as e:
413
- log.error(e)
414
- return False
402
+ def run_command(command: Iterable[str] | str) -> bool:
403
+ try:
404
+ cmd_list: list[str] = (
405
+ shlex.split(command.replace("\\", "\\\\") if os.name == "nt" else command)
406
+ if isinstance(command, str)
407
+ else list(command)
408
+ )
409
+ except ValueError as e:
410
+ log.error(e)
411
+ return False
415
412
 
416
413
  if len(cmd_list) == 0:
417
414
  return True
@@ -1,4 +1,4 @@
1
- import ctypes
1
+ import locale
2
2
 
3
3
  from . import lang_en, lang_zh_Hans_CN
4
4
  from .global_lang_val import (
@@ -18,6 +18,7 @@ __all__ = [
18
18
  "Lang_tag_region",
19
19
  "Lang_tag_script",
20
20
  "Lang_tag_val",
21
+ "Mlang_exception",
21
22
  "get_system_language",
22
23
  "gettext",
23
24
  "translate_subtitles",
@@ -31,50 +32,10 @@ all_supported_lang_map: dict[Lang_tag, dict[str, str]] = {
31
32
 
32
33
 
33
34
  def get_system_language() -> Lang_tag:
34
- # 获取系统默认的 UI 语言
35
- user_default_ui_lang = ctypes.windll.kernel32.GetUserDefaultUILanguage()
36
- lang_int = user_default_ui_lang & 0xFF # 主要语言
37
- sub_lang_int = user_default_ui_lang >> 10 # 次要语言
38
-
39
- # 语言代码映射
40
- lang_map = {
41
- 0x09: Lang_tag_language.en, # 英语
42
- 0x04: Lang_tag_language.zh, # 中文
43
- 0x0C: Lang_tag_language.fr, # 法语
44
- 0x07: Lang_tag_language.de, # 德语
45
- 0x0A: Lang_tag_language.es, # 西班牙语
46
- 0x10: Lang_tag_language.it, # 意大利语
47
- 0x13: Lang_tag_language.ja, # 日语
48
- 0x14: Lang_tag_language.ko, # 韩语
49
- 0x16: Lang_tag_language.ru, # 俄语
50
- }
51
-
52
- # 次要语言代码映射
53
- sub_lang_map = {
54
- 0x01: Lang_tag_region.US, # 美国
55
- 0x02: Lang_tag_region.GB, # 英国
56
- 0x03: Lang_tag_region.AU, # 澳大利亚
57
- 0x04: Lang_tag_region.CA, # 加拿大
58
- 0x05: Lang_tag_region.NZ, # 新西兰
59
- 0x06: Lang_tag_region.IE, # 爱尔兰
60
- 0x07: Lang_tag_region.ZA, # 南非
61
- 0x08: Lang_tag_region.JM, # 牙买加
62
- 0x09: Lang_tag_region.TT, # 加勒比地区
63
- 0x0A: Lang_tag_region.BZ, # 伯利兹
64
- 0x0B: Lang_tag_region.TT, # 特立尼达和多巴哥
65
- 0x0D: Lang_tag_region.PH, # 菲律宾
66
- 0x0E: Lang_tag_region.IN, # 印度
67
- 0x0F: Lang_tag_region.MY, # 马来西亚
68
- 0x10: Lang_tag_region.SG, # 新加坡
69
- 0x11: Lang_tag_region.HK, # 香港特别行政区
70
- 0x12: Lang_tag_region.MO, # 澳门特别行政区
71
- 0x13: Lang_tag_region.TW, # 台湾地区
72
- 0x00: Lang_tag_region.CN, # 中国大陆
73
- }
74
-
75
- return Lang_tag(
76
- language=lang_map.get(lang_int, Lang_tag_language.Unknown),
77
- region=sub_lang_map.get(sub_lang_int, Lang_tag_region.Unknown),
35
+ return (
36
+ Lang_tag()
37
+ if (sys_lang := locale.getdefaultlocale()[0]) is None
38
+ else Lang_tag.from_str(sys_lang.replace("_", "-"))
78
39
  )
79
40
 
80
41
 
@@ -102,3 +63,17 @@ def gettext(
102
63
  log.debug(f"{e!r} in gettext when str.format", deep=True, is_format=False)
103
64
 
104
65
  return new_text
66
+
67
+
68
+ class Mlang_exception(Exception):
69
+ def __init__(
70
+ self,
71
+ *args: object,
72
+ **kwargs: object,
73
+ ) -> None:
74
+ msg = args[0]
75
+ if isinstance(msg, str):
76
+ new_msg: str = gettext(msg, *args[1:], is_format=True, **kwargs)
77
+ super().__init__(new_msg)
78
+ else:
79
+ super().__init__(msg, *args[1:])
@@ -313,6 +313,7 @@ LANG_MAP: dict[str, str] = {
313
313
  "'{}' successfully: {}": "'{}' 成功: {}",
314
314
  "Unsupported option: {}": "不支持的选项: {}",
315
315
  "Unsupported param: {}": "不支持的参数: {}",
316
+ "There is no audio stream in the video, so '-c:a' cannot be used": "视频中没有音频流,所以无法使用 '-c:a'",
316
317
  "Unsupported '{}' param: {}": "'{}' 不支持此参数: {}",
317
318
  "Manually force exit": "手动强制退出",
318
319
  "or run this command to update using pip: {}": "或运行以下命令以使用 pip 更新: {}",
@@ -380,4 +381,5 @@ LANG_MAP: dict[str, str] = {
380
381
  "Run {} failed": "执行 {} 失败",
381
382
  "Unknown error": "未知错误",
382
383
  "'{}' execution failed: {}": "'{}' 执行失败: {}",
384
+ "No closing quotation": "没有闭合引号",
383
385
  }
easyrip/easyrip_prompt.py CHANGED
@@ -1,3 +1,8 @@
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
1
6
  from prompt_toolkit.history import FileHistory
2
7
 
3
8
  from .global_val import C_Z, CONFIG_DIR
@@ -15,3 +20,54 @@ class ConfigFileHistory(FileHistory):
15
20
  def store_string(self, string: str) -> None:
16
21
  if not string.startswith(C_Z):
17
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
easyrip/global_val.py CHANGED
@@ -3,7 +3,7 @@ import sys
3
3
  from pathlib import Path
4
4
 
5
5
  PROJECT_NAME = "Easy Rip"
6
- PROJECT_VERSION = "4.3.0"
6
+ PROJECT_VERSION = "4.3.1"
7
7
  PROJECT_TITLE = f"{PROJECT_NAME} v{PROJECT_VERSION}"
8
8
  PROJECT_URL = "https://github.com/op200/EasyRip"
9
9
  PROJECT_RELEASE_API = "https://api.github.com/repos/op200/EasyRip/releases/latest"
@@ -4,7 +4,8 @@ import re
4
4
  from dataclasses import dataclass, field
5
5
  from pathlib import Path
6
6
 
7
- from ...easyrip_log import gettext, log
7
+ from ...easyrip_log import log
8
+ from ...easyrip_mlang import Mlang_exception
8
9
  from ...utils import read_text, uudecode_ssa, uuencode_ssa
9
10
 
10
11
 
@@ -584,18 +585,8 @@ class Unknown_data:
584
585
  )
585
586
 
586
587
 
587
- class Ass_generate_error(Exception):
588
- def __init__(
589
- self,
590
- *args: object,
591
- **kwargs: object,
592
- ) -> None:
593
- msg = args[0]
594
- if isinstance(msg, str):
595
- new_msg: str = gettext(msg, *args[1:], is_format=True, **kwargs)
596
- super().__init__(new_msg)
597
- else:
598
- super().__init__(msg, *args[1:])
588
+ class Ass_generate_error(Mlang_exception):
589
+ pass
599
590
 
600
591
 
601
592
  class Ass:
@@ -5,9 +5,14 @@ from pathlib import Path
5
5
  from typing import Self, final
6
6
 
7
7
  from ..easyrip_log import log
8
+ from ..easyrip_mlang import Mlang_exception
8
9
  from ..utils import time_str_to_sec
9
10
 
10
11
 
12
+ class Stream_error(Mlang_exception):
13
+ pass
14
+
15
+
11
16
  @final
12
17
  @dataclass(slots=True)
13
18
  class Audio_info:
easyrip/ripper/ripper.py CHANGED
@@ -16,7 +16,7 @@ from ..easyrip_log import log
16
16
  from ..easyrip_mlang import Global_lang_val, gettext, translate_subtitles
17
17
  from ..utils import get_base62_time
18
18
  from .font_subset import subset
19
- from .media_info import Media_info
19
+ from .media_info import Media_info, Stream_error
20
20
 
21
21
  FF_PROGRESS_LOG_FILE = Path("FFProgress.log")
22
22
  FF_REPORT_LOG_FILE = Path("FFReport.log")
@@ -248,6 +248,11 @@ class Ripper:
248
248
 
249
249
  # Audio
250
250
  if audio_encoder_str := self.option_map.get("c:a"):
251
+ if not self.media_info.audio_info:
252
+ raise Stream_error(
253
+ "There is no audio stream in the video, so '-c:a' cannot be used"
254
+ )
255
+
251
256
  if audio_encoder_str not in Ripper.AudioCodec._member_map_:
252
257
  raise ValueError(
253
258
  gettext("Unsupported '{}' param: {}", "-c:a", audio_encoder_str)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easyrip
3
- Version: 4.3.0
3
+ Version: 4.3.1
4
4
  Author: op200
5
5
  License-Expression: AGPL-3.0-or-later
6
6
  Project-URL: Homepage, https://github.com/op200/EasyRip
@@ -1,31 +1,31 @@
1
1
  easyrip/__init__.py,sha256=BlDIN9htmQXETt7M8pjYSOVrKevuuyfRn2ajQI4J7us,648
2
- easyrip/__main__.py,sha256=lwEV17Xi1cBWWHd7GXloKDjuWe2empflf7rMkMiLWGw,4375
3
- easyrip/easyrip_command.py,sha256=KirlybDIkz3aYPlxqT_VCPsxfdCp-pi62KJc1P6Yc6g,26960
2
+ easyrip/__main__.py,sha256=2i4xz_WNXXEiJqbs_zaVz9hvkY90dAhT_CzB38G68KA,4386
3
+ easyrip/easyrip_command.py,sha256=tPyokfHJhLXknUG3BnR03V1l_Xd_cnLWjfsIrM7_Iz4,28491
4
4
  easyrip/easyrip_log.py,sha256=0V5wBwbqWt56w_NHoLmQmkTHPnPLkYZCAbhDSYnLnDw,15611
5
- easyrip/easyrip_main.py,sha256=dEDUoBDF6flbFrgwdnR8x7yofBdprHNe8Nwkqp00J04,43497
6
- easyrip/easyrip_prompt.py,sha256=cEWI3XFooUwwQcQ_C8dVfd5bP6TlqQSwRHtkj_ezZs4,432
7
- easyrip/global_val.py,sha256=_8DiZFRvM97uzbKlD2ELPtJwV5WjRXd-sTUtJAOuL1E,773
5
+ easyrip/easyrip_main.py,sha256=pTme6KA0dJL7PWhhd9yQmUVrHwCD4iAzwEhmE8zw7c0,43459
6
+ easyrip/easyrip_prompt.py,sha256=A5S7ybeJSGFkCmwdJ9TCQ_-lde7NWgkbFytZ2KnvkWI,2145
7
+ easyrip/global_val.py,sha256=V-2k_peorGwp6YASUDGF7iQgla1KwjcK1kRPEenv7ds,773
8
8
  easyrip/utils.py,sha256=u1Qi5z0ZF31f_dQHtvsfcfeKk5PirlTeuHnlqL4mkrs,6452
9
9
  easyrip/easyrip_config/config.py,sha256=9uskiGIpYLuS-vjzNASZlhdWLWXkEVxtSjODxcZU3pc,7935
10
10
  easyrip/easyrip_config/config_key.py,sha256=wANVusz9kNqsYJUvXM7DUQn6k_G6EO2VWTHWh9dOifw,394
11
- easyrip/easyrip_mlang/__init__.py,sha256=0XYa0kcnUPH1aaRV3ceIPuYO1Oov8LBxgVjel-1slvI,3226
11
+ easyrip/easyrip_mlang/__init__.py,sha256=QHZt4BYJFkJuaPkN89pt_zkM2grifJakyRZbeyfH8f4,1893
12
12
  easyrip/easyrip_mlang/global_lang_val.py,sha256=Un20KGMVVMQbOaV_7VaHg3E1dvK2Y7kI1cPzq_sFWKY,9984
13
13
  easyrip/easyrip_mlang/lang_en.py,sha256=heUSPeVtY1Nf9eDhrjPM28N3PLsu62op3llbXAfXvAs,140
14
- easyrip/easyrip_mlang/lang_zh_Hans_CN.py,sha256=0DtvBg7khE6NbFt1carSwgMNkigQbMx2e0LsDv4wFhY,18520
14
+ easyrip/easyrip_mlang/lang_zh_Hans_CN.py,sha256=6oczt-ziN39wIk0c-9JBfV7H7Rth99m3FI0ViHgBQew,18697
15
15
  easyrip/easyrip_mlang/translator.py,sha256=Vg0S0p2rpMNAy3LHTdK7qKFdkPEXlOoCCXcaH7PyAC4,5939
16
16
  easyrip/easyrip_web/__init__.py,sha256=tMyEeaSGeEJjND7MF0MBv9aDiDgaO3MOnppwxA70U2c,177
17
17
  easyrip/easyrip_web/http_server.py,sha256=iyulCAFQrJlz86Lrr-Dm3fhOnNCf79Bp6fVHhr0ephY,8350
18
18
  easyrip/easyrip_web/third_party_api.py,sha256=umj-QsfOa0IM60Ic2pXigVfnGfAiiC95fJSXQ-WFpJA,4419
19
19
  easyrip/ripper/__init__.py,sha256=o5gj8QRvkuVc0S9jbRjVOWXpLAaQKC0-n-o6Zx9Dowo,171
20
- easyrip/ripper/media_info.py,sha256=U_XLhNrprIQXWWdxOkGqQGN5V1wla55XxYhf5z9hRI0,4986
21
- easyrip/ripper/ripper.py,sha256=XyWU2J27xxl-2xUV6u46nspDQPx_AnozP9-LZ8SJbew,61968
20
+ easyrip/ripper/media_info.py,sha256=mQq_vbQ7S9fWpb39HLkoZlAL-pqNfwxewv6X776Nf50,5078
21
+ easyrip/ripper/ripper.py,sha256=MZ0wdu4l8-qrvEjsYCOkQbIF8Yesb8vJGQxzP7wRqs0,62170
22
22
  easyrip/ripper/font_subset/__init__.py,sha256=a6UoRH1AU1l5FkFgQ-wQxOswLmovgVUUl3rLaJnN8Co,88
23
- easyrip/ripper/font_subset/ass.py,sha256=Z1TYmF32pJoXhwsjjZKgScjcsbiayXjp9tnM533ULqs,25806
23
+ easyrip/ripper/font_subset/ass.py,sha256=eGi1eIDWAV1Ti_BYIAcAMwrAlXJ5f_zGYte3nNu4PeE,25532
24
24
  easyrip/ripper/font_subset/font.py,sha256=9yhZmZc-8wvbk2NDN3B4oJMt-UVByzM_pukzMzd-du4,7114
25
25
  easyrip/ripper/font_subset/subset.py,sha256=yj5JYZg1XPO1U0zsZUHSsOX105wrmE_g-2jLpcrvqqc,17137
26
- easyrip-4.3.0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
27
- easyrip-4.3.0.dist-info/METADATA,sha256=ynq-ebYL9XrnQDIZsnE279h1RXP1ABOpZ-VgjJUFreI,3506
28
- easyrip-4.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
29
- easyrip-4.3.0.dist-info/entry_points.txt,sha256=D6GBMMTzZ-apgX76KyZ6jxMmIFqGYwU9neeLLni_qKI,49
30
- easyrip-4.3.0.dist-info/top_level.txt,sha256=kuEteBXm-Gf90jRQgH3-fTo-Z-Q6czSuUEqY158H4Ww,8
31
- easyrip-4.3.0.dist-info/RECORD,,
26
+ easyrip-4.3.1.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
27
+ easyrip-4.3.1.dist-info/METADATA,sha256=7pmdwL-dQiOlaYELaqHgOgN12U53kFQ7LQTW5mxjBhA,3506
28
+ easyrip-4.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
29
+ easyrip-4.3.1.dist-info/entry_points.txt,sha256=D6GBMMTzZ-apgX76KyZ6jxMmIFqGYwU9neeLLni_qKI,49
30
+ easyrip-4.3.1.dist-info/top_level.txt,sha256=kuEteBXm-Gf90jRQgH3-fTo-Z-Q6czSuUEqY158H4Ww,8
31
+ easyrip-4.3.1.dist-info/RECORD,,