Skip to content

Latest commit

 

History

31 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CP437 Telnet Client

A Python telnet client that properly handles CP437 (Code Page 437) graphical characters, including low ASCII symbols that are typically lost in standard UTF-8 telnet connections.

Features

  • ✅ Full CP437 graphical character support (including low ASCII 0x01-0x1F and 0x7F)
  • ✅ Proper Unicode mapping for all 256 CP437 characters
  • ✅ Complete ANSI/VT100 escape sequence support
  • ✅ Async/await based for non-blocking I/O
  • ✅ Built on telnetlib3 for robust telnet protocol handling
  • ✅ Bidirectional encoding/decoding
  • ✅ Interactive terminal shell
  • Compliant with historical ANSI rendering standards (16colo.rs guidelines)
  • ✅ Customizable key mappings (ANSI, SyncTerm)
  • ✅ Session logging support
  • ✅ Macro support with configurable delays

Supported Characters

The client maps all CP437 special characters to Unicode equivalents:

  • Smileys: ☺ ☻
  • Symbols: ♥ ♦ ♣ ♠ • ◘ ○ ♂ ♀ ♪ ► ◄ ↕ ‼ ¶ § ▬ ↨
  • Arrows: ↑ ↓ → ← ↔
  • Shapes: ▲ ▼ ⌠ ⌡ ⌂
  • And more: Full 256-character CP437 palette

Requirements

  • Python 3.8+
  • telnetlib3 >= 1.0.4

Installation

From source

# Clone the repository
git clone https://github.com/yourusername/cp437-telnet.git
cd cp437-telnet

# Install dependencies
pip install -r requirements.txt

# Install the package
pip install -e .

Via pip (when published)

pip install cp437-telnet

Usage

Command Line

# Connect to a telnet host with default port 23
python3 fucktel.py hostname

# Connect to a custom port
python3 fucktel.py hostname 6666

# With session logging
python3 fucktel.py hostname 23 --log session.log

# With SyncTerm key mappings (default)
python3 fucktel.py hostname 23 --syncterm

# With ANSI key mappings
python3 fucktel.py hostname 23 --ansi

# With macro support (Ctrl+G sends commands, use hjkl for arrows)
python3 fucktel.py hostname 23 --bell "vjkl"

# Custom terminal dimensions
python3 fucktel.py hostname 23 --cols 120 --rows 40

# Or use the installed command
fucktel hostname
fucktel hostname 6666

Example

# Connect to a BBS or retro telnet server
python3 cp437_telnet.py bbs.example.com 23

# Type commands as normal, graphical characters will display correctly
# Type 'exit' to disconnect

Programmatic Usage

import asyncio
from cp437_telnet import decode_cp437_graphical, encode_to_cp437

# Decode CP437 bytes to Unicode
cp437_data = bytes([0x01, 0x02, 0x03])  # ☺☻♥
unicode_text = decode_cp437_graphical(cp437_data)
print(unicode_text)  # Output: ☺☻♥

# Encode Unicode text to CP437 bytes
unicode_text = "Hello ☺"
cp437_bytes = encode_to_cp437(unicode_text)
print(cp437_bytes)  # Output: b'Hello \x01'

Development

Setup Development Environment

# Clone the repository
git clone https://github.com/yourusername/cp437-telnet.git
cd cp437-telnet

# Create virtual environment
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Install in development mode
pip install -e .

Running Tests

# Run all tests
python3 -m pytest tests/ -v

# Or use unittest
python3 -m unittest discover -s tests -p "test_*.py" -v

# Run specific test file
python3 -m unittest tests.test_cp437 -v

# With coverage
pip install coverage
coverage run -m unittest discover -s tests -p "test_*.py"
coverage report -m
coverage html  # generates htmlcov/index.html

Code Quality

# Format code
pip install black
black cp437_telnet.py tests/

# Lint
pip install flake8
flake8 cp437_telnet.py tests/

# Type checking
pip install mypy
mypy cp437_telnet.py

# All checks
black --check cp437_telnet.py tests/ && flake8 cp437_telnet.py tests/ && mypy cp437_telnet.py

ANSI Rendering Compliance

This client fully complies with proper ANSI rendering standards as outlined in the 16colo.rs guide on ANSI rendering. Key compliance points:

✅ What We Handle Correctly

  • CP437 Codepage: Full support for IBM PC Code Page 437 (standard for classic BBS ANSI art)
  • Binary 8-bit Clean: Uses force_binary=True to preserve CP437 bytes without telnet protocol interference
  • ANSI Escape Sequences: Complete support for:
    • CSI sequences (colors, cursor movement, screen operations)
    • OSC sequences (operating system commands)
    • Character set selection (line drawing modes)
    • Cursor save/restore
    • Relative and absolute positioning
    • Screen clearing and line operations
  • Sequence Buffering: Properly handles incomplete ANSI sequences split across TCP packets
  • Robustness: Auto-fixes common server bugs (e.g., clear without home cursor)

⚠️ Important Limitations (By Design)

  • Pixel Aspect Ratio: CRT hardware used 35% taller pixels than modern LCD displays
    • Pre-2000 art may appear "squashed"
    • Solution: Use terminal fonts designed for retro BBS or research artwork date
  • Character Spacing: Classic hardware had 9-pixel spacing; modern terminals use 8-pixel
    • Line-drawing characters may have gaps
    • Solution: Use fonts like "Perfect DOS VGA 437" or "Terminus"
  • Multiple Codepages: Only CP437 is fully supported (CP850, etc. not implemented)
    • Workaround: Most classic art uses CP437

📚 Documentation

See the following for detailed compliance information:

Project Structure

fucktel/
├── fucktel.py                              # Main module
├── tests/
│   ├── __init__.py
│   ├── test_cp437.py                       # CP437 encoding/decoding tests
│   └── test_ansi_extended.py               # ANSI sequence tests
├── ANSI_RENDERING_COMPLIANCE.md            # Comprehensive compliance documentation
├── ANSI_COMPLIANCE_QUICK_REFERENCE.md      # Quick reference guide
├── ANSI_ANALYSIS.md                        # Implementation analysis
├── requirements.txt                        # Python dependencies
├── setup.py                                # Package configuration
├── .gitignore                              # Git ignore rules
├── README.md                               # This file
└── LICENSE                                 # MIT License

CP437 Character Mapping

The client includes a complete mapping of all 256 CP437 characters to Unicode:

Byte Unicode Character
0x01 U+263A ☺ (Smiley Face)
0x02 U+263B ☻ (Reverse Smiley)
0x03 U+2665 ♥ (Heart)
0x04 U+2666 ♦ (Diamond)
... ... ...

See cp437_telnet.py for the complete mapping.

How It Works

  1. Connection: Establishes a binary telnet connection in 8-bit clean mode
  2. Receiving: Incoming CP437 bytes are decoded to Unicode using the CP437 character map
  3. Display: Unicode characters are printed to the terminal
  4. Input: User input is encoded back to CP437 before sending to the server
  5. Encoding: UTF-8 text is converted to CP437 with fallback to latin-1

Technical Details

  • Uses asyncio for non-blocking I/O
  • telnetlib3 handles telnet protocol negotiation
  • Binary mode (force_binary=True) ensures 8-bit clean data transfer
  • Graphical character overrides for low ASCII (0x01-0x1F, 0x7F)
  • Inverse Unicode-to-CP437 mapping for encoding

Limitations

  • Requires Unicode-capable terminal
  • Some CP437 characters may not render perfectly depending on terminal font
  • Line endings are normalized to CRLF (telnet standard)

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -am 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Testing Requirements

All contributions should:

  • Pass existing tests: python3 -m unittest discover -s tests
  • Have no lint errors: flake8 cp437_telnet.py
  • Follow code style: black cp437_telnet.py

License

This project is licensed under the MIT License - see the LICENSE file for details.

Troubleshooting

ANSI/Rendering Issues

Art looks "squashed" vertically

  • This is expected for pre-2000 artwork on modern monitors (CRT vs LCD pixel aspect)
  • Research the artwork's creation date (check SAUCE metadata)
  • Try terminal fonts with non-square pixel ratios

Line-drawing characters have gaps

  • Modern terminals use 8-pixel character width; classic hardware used 9-pixel
  • Try retro-designed terminal fonts like "Perfect DOS VGA 437"

Colors don't work

  • Set terminal to support 256 colors minimum (or 24-bit RGB preferred)
  • Some BBS systems require manual color configuration

First line of text appears at wrong position after clear

  • This is a known server bug; fucktel auto-fixes it
  • If still occurring, try a different BBS

Connection Issues

Connection refused

  • Verify the host and port are correct
  • Ensure the telnet service is running on the target
  • Check firewall rules

Characters display incorrectly

  • Verify your terminal supports Unicode (UTF-8)
  • Try a different terminal emulator
  • Ensure your terminal font includes the required Unicode characters
  • Check if BBS uses CP850 or other codepage (fucktel uses CP437)

Keys don't work

  • Try --ansi or --syncterm key mapping modes
  • Some BBS systems use different escape sequences
  • Use --bell macro feature for common navigation patterns

Encoding Errors

  • Input characters may not have a CP437 equivalent
  • The client will fall back to the closest latin-1 equivalent
  • Safe fallback to '?' for unmapped characters

Resources

Author

Your Name (@yourusername)

Support

For issues, questions, or suggestions, please open an issue on the GitHub repository.

About

No description, website, or topics provided.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages