Daily Dashboard
A terminal-based dashboard (TUI) built with Python's Textual framework. Displays news feeds from RSS/JSON sources, weather information, saved links, and performs network scanning using scapy's ARP-based discovery.
Features
- News Feeds: RSS and JSON feed support with tabbed interface
- Weather: Current conditions and 5-day forecast via Open-Meteo API
- Links: Organized bookmarks by category
- Network Scanner: ARP-based device discovery on your local network
- MAC vendor identification (40,000+ vendors)
- mDNS hostname discovery (macOS)
- Known hosts tracking (alerts for new devices)
- Configurable scan timeouts
- Keyboard Navigation: Vim-style bindings (j/k) and standard arrows
- Auto-refresh: Configurable automatic data refresh
- Caching: Smart caching to reduce API calls
- Settings UI: In-app configuration (press
s)
Installation
From PyPI (Recommended)
pip install daily-dashboard
From Homebrew
brew tap grego360/tap
brew install daily-dashboard
From Source
git clone https://github.com/grego360/daily-dashboard.git
cd daily-dashboard
pip install -e .
Quick Start
-
Create a configuration file
# Copy the example configuration curl -o config.json https://raw.githubusercontent.com/grego360/daily-dashboard/main/config.example.json
-
Edit the configuration to add your feeds, location, and network targets
-
Run the dashboard
# With network scanning (requires sudo) sudo daily-dashboard # Without network scanning daily-dashboard
Configuration
Create a config.json file in your working directory:
{
"feeds": [
{
"name": "Hacker News",
"url": "https://hnrss.org/frontpage",
"type": "rss",
"enabled": true
}
],
"links": [
{
"name": "Development",
"links": [
{
"name": "GitHub",
"url": "https://github.com",
"description": "Code hosting"
}
]
}
],
"network": {
"scanner": "scapy",
"targets": [
{
"name": "Home Network",
"range": "192.168.1.0/24",
"expected_hosts": []
}
],
"scan_interval_minutes": 15,
"dns_timeout_seconds": 1.0,
"arp_timeout_seconds": 3.0
},
"weather": {
"enabled": true,
"location_name": "London",
"latitude": 51.5074,
"longitude": -0.1278
},
"settings": {
"user_name": "Your Name",
"refresh_interval_minutes": 15,
"cache_ttl_minutes": 5,
"log_level": "INFO"
}
}
See config.example.json for a complete example.
Privacy Note
The following files contain personal data and are excluded from git:
| File | Contains |
|---|---|
config.json |
Your name, location, network ranges |
known_hosts.json |
Discovered network devices (MAC addresses) |
.cache/ |
Cached API responses |
When sharing your setup, use config.example.json as a template.
Usage
# Run with default config (config.json in current directory)
daily-dashboard
# Run with sudo for network scanning
sudo daily-dashboard
# Run with custom config file
daily-dashboard --config /path/to/config.json
# Run with verbose logging
daily-dashboard -v
# Show version
daily-dashboard --version
Running as a Module
python -m dashboard
Keyboard Shortcuts
Global
| Key | Action |
|---|---|
Tab / 1-5 |
Switch feed tabs |
j / k or Up / Down |
Navigate lists |
Enter |
Open selected item in browser |
r |
Refresh all data |
s |
Open settings |
n |
Quick network scan |
w |
Quick weather search |
? |
Show help |
q |
Quit |
Escape |
Close dialogs |
Context-Specific
| Key | Context | Action |
|---|---|---|
a |
News panel | Add new feed |
a |
Links panel | Add new link |
c |
Network panel | Copy IP address |
m |
Network panel | Copy MAC address |
o |
Network panel | Open IP in browser |
Project Structure
daily-dashboard/
├── dashboard/
│ ├── __main__.py # CLI entry point
│ ├── app.py # Main Textual application
│ ├── components/ # UI widgets
│ │ ├── news_panel.py # News feeds display
│ │ ├── network_panel.py # Network scan results
│ │ ├── weather_panel.py # Weather display
│ │ ├── links_panel.py # Bookmarks panel
│ │ └── status_bar.py # Bottom status bar
│ ├── models/ # Pydantic data models
│ │ ├── config.py # Configuration schema
│ │ ├── news_item.py # News item model
│ │ ├── scan_result.py # Network scan results
│ │ └── weather.py # Weather data model
│ └── services/ # Business logic
│ ├── feed_parser.py # RSS/JSON feed parsing
│ ├── weather_service.py # Open-Meteo API client
│ ├── network_scanner.py # ARP-based scanning (scapy)
│ ├── known_hosts.py # Device history persistence
│ └── cache.py # Response caching
├── tests/ # Test suite
├── .github/ # CI/CD workflows
├── config.example.json # Example configuration
├── pyproject.toml # Project metadata
├── CONTRIBUTING.md # Development guidelines
├── CHANGELOG.md # Version history
└── README.md
Troubleshooting
Network scanning not working
- Ensure you're running with
sudo - On Linux, you can grant capabilities to avoid running as root:
sudo setcap cap_net_raw,cap_net_admin=eip $(which python)
Feed not loading
- Check the URL is accessible
- RSS feeds should return valid XML
- JSON feeds need a
json_pathconfigured to extract items
Weather not showing
- Verify latitude/longitude are correct
- Use the
wkey to search for a location by name
Development
See CONTRIBUTING.md for development setup and guidelines.
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run linter
ruff check .
# Run type checker
mypy dashboard
License
MIT License - see LICENSE for details.
Author
Costel Grigoras (@grego360)
Acknowledgments
- Textual - TUI framework
- Open-Meteo - Free weather API
- Scapy - Network packet manipulation
- mac-vendor-lookup - MAC address vendor database
Metadata
Release files for daily-dashboard 0.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| daily_dashboard-0.1.6.tar.gz | 44.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| daily_dashboard-0.1.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 96.9 kB
Release files / daily_dashboard-0.1.6.tar.gz
| Download URL | daily_dashboard-0.1.6.tar.gz |
|---|---|
| Size | 44.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d7d2ee29b854428e06145ffdf6ed0b77b9d96310e704fca5b350aaf2f54a9c01
|
|
BLAKE2b-256 checksum How to use checksums |
a32e72001c2553a54836d5b985ffca4f5059fb99efb61b8f4056df10443b547d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 30, 2025.
Transparency logRelease files / daily_dashboard-0.1.6-py3-none-any.whl
| Download URL | daily_dashboard-0.1.6-py3-none-any.whl |
|---|---|
| Size | 52.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a65eb1bda4cde05072eae330926b72c94d1ab2f87b23d6b03fe403a71b31b72f
|
|
BLAKE2b-256 checksum How to use checksums |
4ff09c299f3b551149a5c1b37a1e5cd66ae47a5b573c9b870483bd8f65fbfae4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 30, 2025.
Transparency log