From a395a5b930fe79e0e078c99ddc7208074c34f18b Mon Sep 17 00:00:00 2001 From: MarekWo Date: Sun, 21 Dec 2025 13:30:19 +0100 Subject: [PATCH] Phase 0: Environment setup - Docker infrastructure and project scaffolding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created complete project structure for mc-webui MVP: - Docker configuration (Dockerfile, docker-compose.yml) - Environment configuration (.env.example) - Python dependencies (requirements.txt) - Project documentation (README.md) - Git ignore rules (.gitignore) - Directory structure for app, routes, templates, static files Ready for Phase 1: Backend implementation ๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .env.example | 39 +++++++ .gitignore | 79 +++++++++++++ README.md | 234 ++++++++++++++++++++++++++++++++++++++ docker/Dockerfile | 35 ++++++ docker/docker-compose.yml | 32 ++++++ requirements.txt | 14 +++ 6 files changed, 433 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 README.md create mode 100644 docker/Dockerfile create mode 100644 docker/docker-compose.yml create mode 100644 requirements.txt diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..720b7e5 --- /dev/null +++ b/.env.example @@ -0,0 +1,39 @@ +# mc-webui Environment Configuration +# Copy this file to .env and adjust values for your setup + +# ============================================ +# MeshCore Device Configuration +# ============================================ + +# Serial port path (use /dev/serial/by-id for stable device names) +# Find your device: ls -l /dev/serial/by-id/ +MC_SERIAL_PORT=/dev/serial/by-id/usb-Espressif_Systems_heltec_wifi_lora_32_v4__16_MB_FLASH__2_MB_PSRAM__90706984A000-if00 + +# Your MeshCore device name (used for .msgs file) +MC_DEVICE_NAME=MarWoj + +# MeshCore configuration directory (where .msgs file is stored) +MC_CONFIG_DIR=/root/.config/meshcore + +# ============================================ +# Application Settings +# ============================================ + +# Auto-refresh interval in seconds +MC_REFRESH_INTERVAL=60 + +# Hours of inactivity before contacts can be cleaned up +MC_INACTIVE_HOURS=48 + +# ============================================ +# Flask Server Configuration +# ============================================ + +# Listen on all interfaces (0.0.0.0) or specific IP +FLASK_HOST=0.0.0.0 + +# Port to expose the web interface +FLASK_PORT=5000 + +# Debug mode (true/false) - use false in production +FLASK_DEBUG=false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..05bcfed --- /dev/null +++ b/.gitignore @@ -0,0 +1,79 @@ +# mc-webui .gitignore + +# ============================================ +# Environment and Configuration +# ============================================ +.env +*.env +!.env.example + +# ============================================ +# Python +# ============================================ +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# ============================================ +# Virtual Environment +# ============================================ +venv/ +ENV/ +env/ +.venv + +# ============================================ +# IDE and Editors +# ============================================ +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store + +# ============================================ +# Testing and Coverage +# ============================================ +.pytest_cache/ +.coverage +htmlcov/ +*.cover +.hypothesis/ + +# ============================================ +# Docker +# ============================================ +docker-compose.override.yml + +# ============================================ +# Logs and Databases +# ============================================ +*.log +*.sql +*.sqlite +*.db + +# ============================================ +# OS +# ============================================ +Thumbs.db +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..ca29554 --- /dev/null +++ b/README.md @@ -0,0 +1,234 @@ +# mc-webui + +A lightweight web interface for meshcore-cli, providing browser-based access to MeshCore mesh network. + +## Overview + +**mc-webui** is a Flask-based web application that wraps `meshcore-cli`, eliminating the need for SSH/terminal access when using MeshCore chat on a Heltec V4 device connected to a Debian VM. + +### Key Features (MVP) + +- ๐Ÿ“ฑ **View messages** - Display chat history from Public channel with auto-refresh +- โœ‰๏ธ **Send messages** - Publish to Public channel +- ๐Ÿ’ฌ **Reply to users** - Quick reply with `@[UserName]` format +- ๐Ÿงน **Clean contacts** - Remove inactive contacts with configurable threshold + +## Tech Stack + +- **Backend:** Python 3.11+, Flask +- **Frontend:** HTML5, Bootstrap 5, vanilla JavaScript +- **Deployment:** Docker / Docker Compose +- **Communication:** subprocess calls to `meshcli` +- **Data source:** `~/.config/meshcore/.msgs` (JSON Lines) + +## Quick Start + +### Prerequisites + +- Docker and Docker Compose installed +- Heltec V4 device connected via USB +- meshcore-cli configured on host system + +### Installation + +1. **Clone the repository** + ```bash + git clone + cd mc-webui + ``` + +2. **Configure environment** + ```bash + cp .env.example .env + # Edit .env with your settings + nano .env + ``` + +3. **Find your serial device** + ```bash + ls -l /dev/serial/by-id/ + ``` + Update `MC_SERIAL_PORT` in `.env` with your device path. + +4. **Build and run** + ```bash + cd docker + docker-compose up -d + ``` + +5. **Access the web interface** + Open your browser and navigate to: + ``` + http://localhost:5000 + ``` + Or from another device on your network: + ``` + http://:5000 + ``` + +## Configuration + +All configuration is done via environment variables in the `.env` file: + +| Variable | Description | Default | +|----------|-------------|---------| +| `MC_SERIAL_PORT` | Path to serial device | `/dev/ttyUSB0` | +| `MC_DEVICE_NAME` | Device name (for .msgs file) | `MeshCore` | +| `MC_CONFIG_DIR` | meshcore configuration directory | `/root/.config/meshcore` | +| `MC_REFRESH_INTERVAL` | Auto-refresh interval (seconds) | `60` | +| `MC_INACTIVE_HOURS` | Inactivity threshold for cleanup | `48` | +| `FLASK_HOST` | Listen address | `0.0.0.0` | +| `FLASK_PORT` | Application port | `5000` | +| `FLASK_DEBUG` | Debug mode | `false` | + +See [.env.example](.env.example) for a complete example. + +## Project Structure + +``` +mc-webui/ +โ”œโ”€โ”€ docker/ +โ”‚ โ”œโ”€โ”€ Dockerfile # Docker image definition +โ”‚ โ””โ”€โ”€ docker-compose.yml # Docker Compose configuration +โ”œโ”€โ”€ app/ +โ”‚ โ”œโ”€โ”€ __init__.py +โ”‚ โ”œโ”€โ”€ main.py # Flask entry point +โ”‚ โ”œโ”€โ”€ config.py # Configuration from env vars +โ”‚ โ”œโ”€โ”€ meshcore/ +โ”‚ โ”‚ โ”œโ”€โ”€ __init__.py +โ”‚ โ”‚ โ”œโ”€โ”€ cli.py # meshcli wrapper (subprocess) +โ”‚ โ”‚ โ””โ”€โ”€ parser.py # .msgs file parser +โ”‚ โ”œโ”€โ”€ routes/ +โ”‚ โ”‚ โ”œโ”€โ”€ __init__.py +โ”‚ โ”‚ โ”œโ”€โ”€ api.py # REST API endpoints +โ”‚ โ”‚ โ””โ”€โ”€ views.py # HTML views +โ”‚ โ”œโ”€โ”€ static/ +โ”‚ โ”‚ โ”œโ”€โ”€ css/ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ style.css # Custom styles +โ”‚ โ”‚ โ””โ”€โ”€ js/ +โ”‚ โ”‚ โ””โ”€โ”€ app.js # Frontend logic +โ”‚ โ””โ”€โ”€ templates/ +โ”‚ โ”œโ”€โ”€ base.html # Base template +โ”‚ โ”œโ”€โ”€ index.html # Main chat view +โ”‚ โ””โ”€โ”€ components/ # Reusable components +โ”œโ”€โ”€ requirements.txt # Python dependencies +โ”œโ”€โ”€ .env.example # Example environment config +โ”œโ”€โ”€ .gitignore +โ”œโ”€โ”€ README.md # This file +โ””โ”€โ”€ PRD.md # Product Requirements Document +``` + +## Development Status + +๐Ÿšง **Current Phase: 0 - Environment Setup** โœ… + +### Roadmap + +- [x] Phase 0: Environment Setup +- [ ] Phase 1: Backend Basics +- [ ] Phase 2: Frontend Chat View +- [ ] Phase 3: Message Sending +- [ ] Phase 4: Auto-refresh +- [ ] Phase 5: Contact Management +- [ ] Phase 6: Polish & Documentation + +See [PRD.md](PRD.md) for detailed requirements and implementation plan. + +## Usage + +### Viewing Messages + +The main page displays chat history from the Public channel (channel 0). Messages auto-refresh every 60 seconds by default. + +### Sending Messages + +1. Type your message in the text field at the bottom +2. Press Enter or click "Send" +3. Your message will be published to the Public channel + +### Replying to Users + +Click the reply button on any message to insert `@[UserName]` into the text field, then type your reply. + +### Managing Contacts + +Access the settings panel to clean up inactive contacts: +1. Click the settings icon +2. Adjust the inactivity threshold (default: 48 hours) +3. Click "Clean Inactive Contacts" +4. Confirm the action + +## Docker Commands + +```bash +# Start the application +cd docker +docker-compose up -d + +# View logs +docker-compose logs -f + +# Stop the application +docker-compose down + +# Rebuild after code changes +docker-compose up -d --build + +# Check container status +docker-compose ps +``` + +## Troubleshooting + +### Device not found +```bash +# Check if device is connected +ls -l /dev/serial/by-id/ + +# Verify device permissions +sudo chmod 666 /dev/serial/by-id/usb-Espressif* +``` + +### Container won't start +```bash +# Check logs +docker-compose logs mc-webui + +# Verify .env file exists +ls -la ../.env + +# Check if port 5000 is available +sudo netstat -tulpn | grep 5000 +``` + +### Messages not updating +- Ensure meshcore-cli is properly configured +- Check that `.msgs` file exists in `MC_CONFIG_DIR` +- Verify serial device is accessible from container + +## Security Notes + +โš ๏ธ **Important**: This application is designed for **trusted local networks only** and has **no authentication**. Do not expose it to the internet without implementing proper security measures. + +## Contributing + +This is an open-source project. Contributions are welcome! + +- All code, comments, and documentation must be in English +- Follow the existing code style +- Test your changes with real hardware if possible + +## License + +[License TBD] + +## References + +- [MeshCore Documentation](https://meshcore.org) +- [meshcore-cli GitHub](https://github.com/meshcore/meshcore-cli) +- [Product Requirements Document](PRD.md) + +--- + +**Target Deployment:** Debian VM @ 192.168.131.80 +**Hardware:** Heltec WiFi LoRa 32 V4 diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..e8d4e61 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,35 @@ +# mc-webui Dockerfile +# Python 3.11+ with Flask and meshcore-cli + +FROM python:3.11-slim + +# Set working directory +WORKDIR /app + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + gcc \ + && rm -rf /var/lib/apt/lists/* + +# Copy requirements first for better layer caching +COPY requirements.txt . + +# Install Python dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# Install meshcore-cli +RUN pip install --no-cache-dir meshcore-cli + +# Copy application code +COPY app/ ./app/ + +# Expose Flask port +EXPOSE 5000 + +# Environment variables (can be overridden by docker-compose) +ENV FLASK_HOST=0.0.0.0 +ENV FLASK_PORT=5000 +ENV FLASK_DEBUG=false + +# Run the application +CMD ["python", "-m", "app.main"] diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..4fe0540 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,32 @@ +version: '3.8' + +services: + mc-webui: + build: + context: .. + dockerfile: docker/Dockerfile + container_name: mc-webui + restart: unless-stopped + ports: + - "${FLASK_PORT:-5000}:5000" + devices: + - "${MC_SERIAL_PORT}:${MC_SERIAL_PORT}" + volumes: + - "${MC_CONFIG_DIR}:/root/.config/meshcore:rw" + environment: + - MC_SERIAL_PORT=${MC_SERIAL_PORT} + - MC_DEVICE_NAME=${MC_DEVICE_NAME} + - MC_CONFIG_DIR=/root/.config/meshcore + - MC_REFRESH_INTERVAL=${MC_REFRESH_INTERVAL:-60} + - MC_INACTIVE_HOURS=${MC_INACTIVE_HOURS:-48} + - FLASK_HOST=${FLASK_HOST:-0.0.0.0} + - FLASK_PORT=${FLASK_PORT:-5000} + - FLASK_DEBUG=${FLASK_DEBUG:-false} + env_file: + - ../.env + healthcheck: + test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:5000/api/status')"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..97f9ae5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,14 @@ +# mc-webui Python Dependencies + +# Web Framework +Flask==3.0.0 +Werkzeug==3.0.1 + +# WSGI Server for production +gunicorn==21.2.0 + +# Configuration +python-dotenv==1.0.0 + +# Additional utilities (if needed later) +# requests==2.31.0 # For future API integrations