mirror of
https://github.com/morpheus65535/bazarr.git
synced 2025-04-24 22:57:13 -04:00
Update ffsubsync and srt module
* Update ffsubsync to 0.4.11 * Update srt to 3.4.1
This commit is contained in:
parent
8e91beed83
commit
4a0932b5d3
368 changed files with 134230 additions and 2096 deletions
173
libs/rich/control.py
Normal file
173
libs/rich/control.py
Normal file
|
@ -0,0 +1,173 @@
|
|||
from typing import Callable, Dict, Iterable, List, TYPE_CHECKING, Union
|
||||
|
||||
from .segment import ControlCode, ControlType, Segment
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .console import Console, ConsoleOptions, RenderResult
|
||||
|
||||
STRIP_CONTROL_CODES = [
|
||||
8, # Backspace
|
||||
11, # Vertical tab
|
||||
12, # Form feed
|
||||
13, # Carriage return
|
||||
]
|
||||
_CONTROL_TRANSLATE = {_codepoint: None for _codepoint in STRIP_CONTROL_CODES}
|
||||
|
||||
|
||||
CONTROL_CODES_FORMAT: Dict[int, Callable] = {
|
||||
ControlType.BELL: lambda: "\x07",
|
||||
ControlType.CARRIAGE_RETURN: lambda: "\r",
|
||||
ControlType.HOME: lambda: "\x1b[H",
|
||||
ControlType.CLEAR: lambda: "\x1b[2J",
|
||||
ControlType.ENABLE_ALT_SCREEN: lambda: "\x1b[?1049h",
|
||||
ControlType.DISABLE_ALT_SCREEN: lambda: "\x1b[?1049l",
|
||||
ControlType.SHOW_CURSOR: lambda: "\x1b[?25h",
|
||||
ControlType.HIDE_CURSOR: lambda: "\x1b[?25l",
|
||||
ControlType.CURSOR_UP: lambda param: f"\x1b[{param}A",
|
||||
ControlType.CURSOR_DOWN: lambda param: f"\x1b[{param}B",
|
||||
ControlType.CURSOR_FORWARD: lambda param: f"\x1b[{param}C",
|
||||
ControlType.CURSOR_BACKWARD: lambda param: f"\x1b[{param}D",
|
||||
ControlType.CURSOR_MOVE_TO_ROW: lambda param: f"\x1b[{param+1}G",
|
||||
ControlType.ERASE_IN_LINE: lambda param: f"\x1b[{param}K",
|
||||
ControlType.CURSOR_MOVE_TO: lambda x, y: f"\x1b[{y+1};{x+1}H",
|
||||
}
|
||||
|
||||
|
||||
class Control:
|
||||
"""A renderable that inserts a control code (non printable but may move cursor).
|
||||
|
||||
Args:
|
||||
*codes (str): Positional arguments are either a :class:`~rich.segment.ControlType` enum or a
|
||||
tuple of ControlType and an integer parameter
|
||||
"""
|
||||
|
||||
__slots__ = ["segment"]
|
||||
|
||||
def __init__(self, *codes: Union[ControlType, ControlCode]) -> None:
|
||||
control_codes: List[ControlCode] = [
|
||||
(code,) if isinstance(code, ControlType) else code for code in codes
|
||||
]
|
||||
_format_map = CONTROL_CODES_FORMAT
|
||||
rendered_codes = "".join(
|
||||
_format_map[code](*parameters) for code, *parameters in control_codes
|
||||
)
|
||||
self.segment = Segment(rendered_codes, None, control_codes)
|
||||
|
||||
@classmethod
|
||||
def bell(cls) -> "Control":
|
||||
"""Ring the 'bell'."""
|
||||
return cls(ControlType.BELL)
|
||||
|
||||
@classmethod
|
||||
def home(cls) -> "Control":
|
||||
"""Move cursor to 'home' position."""
|
||||
return cls(ControlType.HOME)
|
||||
|
||||
@classmethod
|
||||
def move(cls, x: int = 0, y: int = 0) -> "Control":
|
||||
"""Move cursor relative to current position.
|
||||
|
||||
Args:
|
||||
x (int): X offset.
|
||||
y (int): Y offset.
|
||||
|
||||
Returns:
|
||||
~Control: Control object.
|
||||
|
||||
"""
|
||||
|
||||
def get_codes() -> Iterable[ControlCode]:
|
||||
control = ControlType
|
||||
if x:
|
||||
yield (
|
||||
control.CURSOR_FORWARD if x > 0 else control.CURSOR_BACKWARD,
|
||||
abs(x),
|
||||
)
|
||||
if y:
|
||||
yield (
|
||||
control.CURSOR_DOWN if y > 0 else control.CURSOR_UP,
|
||||
abs(y),
|
||||
)
|
||||
|
||||
control = cls(*get_codes())
|
||||
return control
|
||||
|
||||
@classmethod
|
||||
def move_to_row(cls, x: int, y: int = 0) -> "Control":
|
||||
"""Move to the given row, optionally add offset to column.
|
||||
|
||||
Returns:
|
||||
x (int): absolute x (column)
|
||||
y (int): optional y offset (row)
|
||||
|
||||
Returns:
|
||||
~Control: Control object.
|
||||
"""
|
||||
|
||||
return (
|
||||
cls(
|
||||
(ControlType.CURSOR_MOVE_TO_ROW, x + 1),
|
||||
(
|
||||
ControlType.CURSOR_DOWN if y > 0 else ControlType.CURSOR_UP,
|
||||
abs(y),
|
||||
),
|
||||
)
|
||||
if y
|
||||
else cls((ControlType.CURSOR_MOVE_TO_ROW, x))
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def move_to(cls, x: int, y: int) -> "Control":
|
||||
"""Move cursor to absolute position.
|
||||
|
||||
Args:
|
||||
x (int): x offset (column)
|
||||
y (int): y offset (row)
|
||||
|
||||
Returns:
|
||||
~Control: Control object.
|
||||
"""
|
||||
return cls((ControlType.CURSOR_MOVE_TO, x, y))
|
||||
|
||||
@classmethod
|
||||
def clear(cls) -> "Control":
|
||||
"""Clear the screen."""
|
||||
return cls(ControlType.CLEAR)
|
||||
|
||||
@classmethod
|
||||
def show_cursor(cls, show: bool) -> "Control":
|
||||
"""Show or hide the cursor."""
|
||||
return cls(ControlType.SHOW_CURSOR if show else ControlType.HIDE_CURSOR)
|
||||
|
||||
@classmethod
|
||||
def alt_screen(cls, enable: bool) -> "Control":
|
||||
"""Enable or disable alt screen."""
|
||||
if enable:
|
||||
return cls(ControlType.ENABLE_ALT_SCREEN, ControlType.HOME)
|
||||
else:
|
||||
return cls(ControlType.DISABLE_ALT_SCREEN)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.segment.text
|
||||
|
||||
def __rich_console__(
|
||||
self, console: "Console", options: "ConsoleOptions"
|
||||
) -> "RenderResult":
|
||||
if self.segment.text:
|
||||
yield self.segment
|
||||
|
||||
|
||||
def strip_control_codes(text: str, _translate_table=_CONTROL_TRANSLATE) -> str:
|
||||
"""Remove control codes from text.
|
||||
|
||||
Args:
|
||||
text (str): A string possibly contain control codes.
|
||||
|
||||
Returns:
|
||||
str: String with control codes removed.
|
||||
"""
|
||||
return text.translate(_translate_table)
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
print(strip_control_codes("hello\rWorld"))
|
Loading…
Add table
Add a link
Reference in a new issue