Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions docs/api/color_filter.rst

This file was deleted.

35 changes: 19 additions & 16 deletions docs/history.rst
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
History
=======
3.0.3 (unreleased)
* new: :func:`~telnetlib3.accessories.make_logger` accepts a ``filemode``
parameter (``"a"`` append or ``"w"`` overwrite) so callers can control
whether log files are truncated on each run. The default remains
``"a"`` (append), matching historical behaviour.
* new: ``--logfile-mode {append,rewrite}`` CLI flag controls whether the
log file is appended to (default) or overwritten on each connection.
* new: ``--typescript-mode {append,rewrite}`` CLI flag controls whether the
typescript file is appended to (default) or overwritten on each connection.
* bugfix: kludge mode not detected when server negotiates WILL ECHO + DO SGA
(requesting client WILL SGA) instead of WILL ECHO + WILL SGA.
:attr:`~telnetlib3.stream_writer.TelnetWriter.mode` and
``_server_will_sga()`` now check SGA in either direction
(``remote_option`` or ``local_option``), so clients correctly switch from
line mode to character-at-a-time mode with these servers.
4.0.0
* removed: ``telnetlib3.color_filter``. ``ColorFilter``, ``ColorConfig``, ``PALETTES``,
``PetsciiColorFilter``, and ``AtasciiControlFilter`` have all been moved to the downstream
`Telix <https://github.com/jquast/Telix>`_ project, recommended for connecting to legacy `BBSs
<https://bbs.modem.xyz/>`_ systems requiring color correction.

``telnetlib3-client`` CLI args ``--colormatch``, ``--color-brightness``, ``--color-contrast``,
``--background-color``, ``--ice-colors`` removed.

3.0.3
* bugfix: server and client now correctly complete LINEMODE negotiation when prompted to.
* new: ``--logfile-mode {append,rewrite}`` and ``--typescript-mode`` CLI flags
and :func:`~telnetlib3.accessories.make_logger` ``filemode`` argument control whether the log
file is appended to (default) or overwritten on each connection.
* new: :class:`~telnetlib3.client_shell.LinemodeBuffer` used by ``telnetlib3-client``, a
client-side line buffer for LINEMODE EDIT mode with local erase-char, erase-line, erase-word
editing, forwardmask flushing, and TRAPSIG IAC command generation. The default 'telsh' server
was also updated to support linemode.

3.0.2
* bugfix: :meth:`~telnetlib3.stream_writer.TelnetWriter.request_charset` raised :exc:`TypeError`,
Expand Down Expand Up @@ -130,7 +133,7 @@ History
art) as surrogates instead of replacing them with U+FFFD.

2.4.0
* new: :mod:`telnetlib3.color_filter` module — translates 16-color ANSI SGR
* new: ``telnetlib3.color_filter`` module — translates 16-color ANSI SGR
codes to 24-bit RGB from hardware palettes (EGA, CGA, VGA, xterm).
Enabled by default. New client CLI options: ``--colormatch``,
``--color-brightness``, ``--color-contrast``, ``--background-color``,
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "telnetlib3"
version = "3.0.2" # Keep in sync with telnetlib3/accessories.py::get_version !
version = "4.0.0" # Keep in sync with telnetlib3/accessories.py::get_version !
description = " Python Telnet server and client CLI and Protocol library"
readme = "README.rst"
license = "ISC"
Expand Down
1 change: 0 additions & 1 deletion telnetlib3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from . import stream_reader
from . import client_base
from . import client_shell
from . import color_filter
from . import client
from . import telopt
from . import mud
Expand Down
1 change: 0 additions & 1 deletion telnetlib3/_session_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def __init__(self) -> None:
self.raw_mode: Optional[bool] = None
self.ascii_eol: bool = False
self.input_filter: Optional[Any] = None
self.color_filter: Optional[Any] = None
self.autoreply_engine: Optional[Any] = None
self.autoreply_wait_fn: Optional[Callable[..., Awaitable[None]]] = None
self.typescript_file: Optional[IO[str]] = None
Expand Down
2 changes: 1 addition & 1 deletion telnetlib3/accessories.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

def get_version() -> str:
"""Return the current version of telnetlib3."""
return "3.0.2" # keep in sync with pyproject.toml !
return "4.0.0" # keep in sync with pyproject.toml !


def encoding_from_lang(lang: str) -> Optional[str]:
Expand Down
106 changes: 0 additions & 106 deletions telnetlib3/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,56 +685,7 @@ def _patched_connection_made(transport: asyncio.BaseTransport) -> None:

client_factory: Optional[Callable[..., client_base.BaseClient]] = _client_factory

# Wrap the shell callback to inject color filter when enabled
colormatch: str = args["colormatch"]
shell_callback = args["shell"]
if colormatch.lower() != "none":
from .color_filter import (
PALETTES,
ColorConfig,
ColorFilter,
PetsciiColorFilter,
AtasciiControlFilter,
)

# Auto-select encoding-specific filters
encoding_name: str = args.get("encoding", "") or ""
is_petscii = encoding_name.lower() in ("petscii", "cbm", "commodore", "c64", "c128")
is_atascii = encoding_name.lower() in ("atascii", "atari8bit", "atari_8bit")
if colormatch == "petscii":
colormatch = "c64"
if is_petscii and colormatch != "c64":
colormatch = "c64"

if colormatch not in PALETTES:
print(
f"Unknown palette {colormatch!r}," f" available: {', '.join(sorted(PALETTES))}",
file=sys.stderr,
)
sys.exit(1)
color_config = ColorConfig(
palette_name=colormatch,
brightness=args["color_brightness"],
contrast=args["color_contrast"],
background_color=args["background_color"],
ice_colors=args["ice_colors"],
)
if is_petscii or colormatch == "c64":
color_filter_obj: object = PetsciiColorFilter(color_config)
elif is_atascii:
color_filter_obj = AtasciiControlFilter()
else:
color_filter_obj = ColorFilter(color_config)
original_shell = shell_callback

async def _color_shell(
reader: Union[TelnetReader, TelnetReaderUnicode],
writer_arg: Union[TelnetWriter, TelnetWriterUnicode],
) -> None:
writer_arg.ctx.color_filter = color_filter_obj
await original_shell(reader, writer_arg)

shell_callback = _color_shell

# Wrap shell to inject raw_mode flag and input translation for retro encodings
raw_mode_val: Optional[bool] = args.get("raw_mode", False)
Expand Down Expand Up @@ -894,44 +845,6 @@ def _get_argument_parser() -> argparse.ArgumentParser:
metavar="OPT",
help="always send DO for this option (name like GMCP or number, repeatable)",
)
parser.add_argument(
"--colormatch",
default="vga",
metavar="PALETTE",
help=(
"translate basic 16-color ANSI codes to exact 24-bit RGB values"
" from a named hardware palette, bypassing the terminal's custom"
" palette to preserve intended MUD/BBS artwork colors"
" (vga, xterm, none)"
),
)
parser.add_argument(
"--color-brightness",
default=1.0,
type=float,
metavar="FLOAT",
help="color brightness scale [0.0..1.0], where 1.0 is original",
)
parser.add_argument(
"--color-contrast",
default=1.0,
type=float,
metavar="FLOAT",
help="color contrast scale [0.0..1.0], where 1.0 is original",
)
parser.add_argument(
"--background-color",
default="#000000",
metavar="#RRGGBB",
help="forced background color as hex RGB (near-black by default)",
)
parser.add_argument(
"--ice-colors",
action=argparse.BooleanOptionalAction,
default=True,
help="treat SGR 5 (blink) as bright background (iCE colors)"
" for BBS/ANSI art (default: enabled)",
)
parser.add_argument(
"--ascii-eol",
action="store_true",
Expand Down Expand Up @@ -1013,20 +926,6 @@ def _parse_option_arg(value: str) -> bytes:
return bytes([int(value)])


def _parse_background_color(value: str) -> Tuple[int, int, int]:
"""
Parse hex color string to RGB tuple.

:param value: Color string like ``"#RRGGBB"`` or ``"RRGGBB"``.
:returns: (R, G, B) tuple with values 0-255.
:raises ValueError: When *value* is not a valid hex color.
"""
h = value.lstrip("#")
if len(h) != 6:
raise ValueError(f"invalid hex color: {value!r}")
return (int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16))


def _transform_args(args: argparse.Namespace) -> Dict[str, Any]:
# Auto-enable force_binary for any non-ASCII encoding that uses high-bit bytes.
from .encodings import FORCE_BINARY_ENCODINGS
Expand Down Expand Up @@ -1075,11 +974,6 @@ def _transform_args(args: argparse.Namespace) -> Dict[str, Any]:
"send_environ": tuple(v.strip() for v in args.send_environ.split(",") if v.strip()),
"always_will": {_parse_option_arg(v) for v in args.always_will},
"always_do": {_parse_option_arg(v) for v in args.always_do},
"colormatch": args.colormatch,
"color_brightness": args.color_brightness,
"color_contrast": args.color_contrast,
"background_color": _parse_background_color(args.background_color),
"ice_colors": args.ice_colors,
"raw_mode": raw_mode,
"ascii_eol": args.ascii_eol,
"ansi_keys": args.ansi_keys,
Expand Down
Loading
Loading