# Liiga 221 Teletext Terminal App
A Rust terminal application that displays Finnish Liiga hockey results in authentic YLE Teksti-TV style.
<img width="889" height="562" alt="image" src="https://github.com/user-attachments/assets/968d1926-3485-4bb9-bbd6-bbffa15c23a1" />
## Features
- **Authentic teletext interface** - YLE Teksti-TV channel 221 appearance
- **Real-time updates** - Automatic refresh (every minute for live games, hourly for completed)
- **Tournament support** - Regular season, playoffs, playout, qualifications, practice games
- **Interactive navigation** - Arrow keys for page navigation, automatic date navigation
- **Detailed game info** - Scores, goal scorers with timestamps, video links with play icons
- **Standings view** - Toggle league standings with 's' key, live mode support
- **Playoff series info** - Series scores, phase headers, and win indicators during playoffs
- **Multiple display modes** - Compact (multi-column), wide (side-by-side), standard
- **Configuration system** - Platform-specific storage, customizable settings
- **Performance optimized** - Caching, request deduplication, intelligent refresh intervals
## Requirements
- **Rust 1.89 or newer** - This project uses modern Rust features including if-let chains
- Terminal with Unicode support for best display experience
You can check your Rust version with:
```bash
rustc --version
```
If you need to update Rust, visit [rustup.rs](https://rustup.rs/) or run:
```bash
rustup update
```
## Installation
### Install from crates.io
```bash
cargo install liiga_teletext
```
You can create a symlink to the binary to make it available from anywhere:
```bash
sudo ln -s ~/.cargo/bin/liiga_teletext /usr/local/bin/221 # 221 is the channel number of YLE Teksti-TV
```
### Install from source
1. Make sure Rust and Cargo are installed on your system. If not, install them from [rustup.rs](https://rustup.rs/).
2. Clone this repository:
```bash
git clone https://github.com/nikosalonen/liiga_teletext.git
cd liiga_teletext
```
3. Build and run the application:
```bash
cargo build --release
cargo run --release
```
## Usage
### Interactive Mode (Default)
- Press `q` to quit the application
- Use left/right arrow keys to navigate between pages
- Use **Shift+Left/Right** to navigate between dates with games
- **Note**: Date navigation is limited to the current season for performance and UX reasons
- To view games from previous seasons, use the `-d` flag with a specific date
- Press `s` to toggle standings view (press again to toggle live mode, once more to return)
- Press `r` to manually refresh data
- Data refreshes automatically:
- Every minute for live games
- Every hour for non-live games
### Command Line Options
#### Display Options
- `-d, --date <DATE>` - Show games for a specific date in YYYY-MM-DD format
- `-o, --once` - Show scores once and exit immediately (useful for scripts)
- `-p, --plain` - Disable clickable video links in the output
- `-c, --compact` - Enable compact mode with space-efficient multi-column layout
- `-w, --wide` - Enable wide mode with two-column side-by-side layout (requires 128+ character wide terminal)
- `--min-refresh-interval <SECONDS>` - Set minimum refresh interval in seconds (default: auto-detect based on game count). Higher values reduce API calls but may miss updates. Use with caution.
#### Configuration
- `--config [DOMAIN]` - Update API domain in config (prompts if not provided)
- **Breaking Change**: The `-c` short flag has been removed to avoid conflict with `--compact`. Use the full `--config` flag instead.
- `--set-log-file <PATH>` - Set a persistent custom log file location
- `--clear-log-file` - Clear custom log file path and revert to default location
- `-l, --list-config` - List current configuration settings
#### Debug Options
- `--debug` - Enable debug mode (doesn't clear terminal, logs to file)
- `--log-file <PATH>` - Specify a custom log file path for this session
#### Info
- `-V, --version` - Show version information
### Display Modes
#### Compact Mode (`--compact`)
Space-efficient multi-column layout with team abbreviations. Adapts from 1-3 columns based on terminal width.
```bash
liiga_teletext --compact --once # Quick compact view
```
#### Wide Mode (`--wide`)
Side-by-side two-column layout for wide terminals (128+ characters). Shows full game details in each column.
```bash
liiga_teletext --wide --date 2025-03-21 # Wide view for specific date
```
## Player Name Disambiguation
When multiple players share the same last name on a team, the app automatically adds first initials for clarity (e.g., "Koivu M.", "Koivu S."). This works per-team, so players with the same last name on different teams remain unchanged.
## Configuration
On first run, you will be prompted to enter your API domain. This will be saved to a config file at:
- Linux: `~/.config/liiga_teletext/config.toml`
- macOS: `~/Library/Application Support/liiga_teletext/config.toml`
- Windows: `%APPDATA%\liiga_teletext\config.toml`
The configuration can be manually edited at any time by modifying this file. You can:
- Update the API domain
- Set a custom log file path
### Logging
The application includes comprehensive logging that can be configured:
- **Default location**: `~/.config/liiga_teletext/logs/liiga_teletext.log`
- **Custom location**: Can be set via `--set-log-file` or `--log-file`
- **Debug mode**: Logs are written to file instead of terminal display
- **Log rotation**: Logs are automatically rotated by date
## Tournament Support
The application intelligently handles different tournament types based on the season:
- **Regular Season** (`runkosarja`) - Main league games (September-April)
- **Playoffs** (`playoffs`) - Championship playoffs (March-June)
- **Playout** (`playout`) - Relegation playoffs (March-June)
- **Qualifications** (`qualifications`) - Qualification games (March-June)
- **Practice Games** (`valmistavat_ottelut`) - Preseason practice games (May-September)
During off-season periods, the app shows a countdown to the next regular season start.
## Performance Features
- **Smart caching** - HTTP response caching with time-based expiration
- **Request deduplication** - Prevents simultaneous identical API calls
- **Adaptive refresh** - Intelligent intervals based on game state and count
- **Connection pooling** - Efficient HTTP connection reuse
- **Async architecture** - Non-blocking operations for responsive UI
## Development
```bash
# Build and test
cargo build --all-features
cargo test --all-features
# Code quality checks
cargo fmt
cargo clippy --all-features --all-targets -- -D warnings
```
Uses Rust 2024 edition with modular architecture: CLI/main, data fetcher, teletext UI, config, and performance modules.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request. See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines including commit message format and development workflow.
**Important**: Before submitting any changes, please ensure:
- All tests pass: `cargo test --all-features`
- Code is formatted: `cargo fmt`
- No clippy warnings: `cargo clippy --all-features --all-targets -- -D warnings`
- New functionality includes appropriate tests
- Follow conventional commits for commit messages
## License
This project is licensed under the MIT License - see the LICENSE file for details.
## Acknowledgements
- [YLE Teksti-TV](https://yle.fi/aihe/tekstitv?P=221) for the design inspiration
- [NHL-235](https://github.com/Hamatti/nhl-235) by Juha-Matti Santala for pioneering the concept of bringing teletext hockey scores to the terminal. My original inspiration for this project.