diff --git a/README.md b/README.md deleted file mode 100644 index d2a2c9c..0000000 --- a/README.md +++ /dev/null @@ -1,562 +0,0 @@ -# ๐Ÿ  EverShelf - -> **Self-hosted pantry management system** โ€” Track your food inventory, scan barcodes, get AI-powered recipe suggestions, and reduce waste. - ---- - -
- -### ๐Ÿš€ Try the live demo โ€” no installation required! - -**[โ–ถ Open Live Demo](https://evershelfproject.dadaloop.it/demo)** - ยท  -[๐ŸŒ Project Website](https://evershelfproject.dadaloop.it/) - ยท  -[๐Ÿ“– Wiki](https://github.com/dadaloop82/EverShelf/wiki) - -*The demo runs with mock pantry data. AI features are fully enabled. All write operations are safely sandboxed.* - -
- ---- - -[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) -[![PHP](https://img.shields.io/badge/PHP-8.0+-blue.svg)](https://www.php.net/) -[![SQLite](https://img.shields.io/badge/SQLite-3-blue.svg)](https://www.sqlite.org/) -[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED.svg)](Dockerfile) -[![i18n](https://img.shields.io/badge/i18n-IT%20%7C%20EN%20%7C%20DE%20%7C%20FR%20%7C%20ES-orange.svg)](translations/) -[![Version](https://img.shields.io/badge/version-1.7.42-brightgreen.svg)](CHANGELOG.md) -[![GitHub stars](https://img.shields.io/github/stars/dadaloop82/EverShelf?style=social)](https://github.com/dadaloop82/EverShelf/stargazers) -[![Last commit](https://img.shields.io/github/last-commit/dadaloop82/EverShelf/main)](https://github.com/dadaloop82/EverShelf/commits/main) -[![Contributors](https://img.shields.io/github/contributors/dadaloop82/EverShelf)](https://github.com/dadaloop82/EverShelf/graphs/contributors) -[![GitHub Discussions](https://img.shields.io/github/discussions/dadaloop82/EverShelf)](https://github.com/dadaloop82/EverShelf/discussions) -[![CI](https://github.com/dadaloop82/EverShelf/actions/workflows/ci.yml/badge.svg)](https://github.com/dadaloop82/EverShelf/actions/workflows/ci.yml) - -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/J3J01ZNETZ) - ---- - -> **โš ๏ธ Name disambiguation:** There is an unrelated iOS app also called **EverShelf**, developed and published by [Joshumi Technologies LLC](https://evershelf.joshumi.com/) on the [Apple App Store](https://apps.apple.com/app/evershelf/id6759439940). That application is a **completely separate, independent product** with no affiliation, association, or collaboration with this open-source project. This repository has no connection to Joshumi Technologies LLC, its products, or its services. - ---- - -### ๐Ÿ†• Release 1.7.42 (2026-06-11) - -- **Stable shopping total** โ€” Each list item is priced as one typical purchase (no more inflated totals from 14-day restock quantities or โ‚ฌ/kg ร— piece count). -- **Waste reason picker** โ€” When discarding food, choose why (expired, wrong storage, bought too much, โ€ฆ); EverShelf learns and adjusts restock suggestions and storage hints. -- **Fewer SQLite lock errors** โ€” `inventory_use` and `shopping_add` retry on `SQLITE_BUSY`; smart shopping gets a longer PHP time limit on large pantries. -- **Android kiosk** โ€” Locale string escaping fix; setup wizard JSON save fix (CI build). - -See [CHANGELOG.md](CHANGELOG.md) for full details. - ---- - -## โœจ Features - -### ๐Ÿ  NEW โ€” Home Assistant Integration - -EverShelf has a **native Home Assistant integration** available on HACS. -Connect your pantry to your smart home in minutes โ€” no YAML, no manual sensor setup. - -[![Install via HACS](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=dadaloop82&repository=ha-evershelf&category=integration) -  -[![Add Integration](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=evershelf) - -**What you get:** - -| | | -|---|---| -| **16 sensors** | Expiry counts, stock levels by location (pantry / fridge / freezer), shopping list total, AI API usage, last backup timestamp, days to next expiry | -| **6 binary sensors** | Expired items, expiring items, expiring today, shopping list active, backup overdue, Bring! connected | -| **5 action buttons** | Refresh data, Refresh prices, **Suggest Recipe** (AI โ€” result as HA notification), Sync smart shopping, Clear expired rows | -| **Shopping list todo** | Bidirectional sync โ€” add, remove, check off items directly from HA | -| **Expiry calendar** | Every product's expiry date as a native HA calendar event โ€” works with the calendar card and any calendar automation | -| **Quick-add text entity** | Type a product name in HA to instantly add it to the shopping list (great for voice assistants / Assist) | -| **6 services** | `add_to_shopping`, `mark_used`, `refresh`, `suggest_recipe`, `refresh_prices`, `clear_expired` | -| **Auto-discovery** | Detected automatically via Zeroconf/mDNS when `avahi-daemon` runs on the EverShelf host | -| **5 languages** | English, Italian, German, French, Spanish | - -> **Requires a self-hosted EverShelf instance.** The integration talks directly to your server โ€” no cloud involved. -> Full documentation: [ha-evershelf on GitHub](https://github.com/dadaloop82/ha-evershelf) - ---- - -### ๐Ÿ“ฆ Inventory Management -- **Export inventory** โ€” Download the full inventory as a UTF-8 CSV (Excel-compatible) or open a print-ready page to save as PDF; export button always visible in the inventory page header -- **Barcode scanning** โ€” Scan products with your phone camera using QuaggaJS; last 20 scanned products saved as tappable chips so you can re-select them without rescanning -- **AI identification** โ€” Take a photo and let Google Gemini identify the product, with suggestions from your existing inventory; gracefully shows a friendly message when AI quota is exhausted instead of a raw API error -- **Smart locations** โ€” Track items across Pantry, Fridge, Freezer, and custom locations -- **Expiry tracking** โ€” Automatic shelf-life estimation based on product type and storage -- **Opened product tracking** โ€” Reduced shelf-life calculation when packages are opened; opened-product expiry is now also checked when building banner alerts (not just the dashboard section) -- **Vacuum-sealed support** โ€” Extended expiry dates for vacuum-sealed items; products sealed under vacuum are only flagged as expired after a configurable grace period past the printed date (`VACUUM_EXPIRY_EXTENSION_DAYS`, default 30 days, configurable in `.env`) -- **Anomaly detection** โ€” Banner alerts for suspicious quantities and consumption predictions with inline correction; dismiss button now shows the current inventory quantity so the action is unambiguous ("Quantity is correct (2 pcs)") - -### ๐Ÿค– AI-Powered (Google Gemini) -- **Expiry date reading** โ€” Photograph a label and extract the expiry date automatically -- **Product identification** โ€” Point your camera at any product for instant recognition -- **Existing product matching** โ€” AI scan shows matching products already in your pantry before suggesting new ones -- **Storage & shelf-life hint** โ€” When adding a new product, Gemini suggests the optimal storage location and shelf-life in the background; shown as an inline AI badge next to the expiry estimate -- **Recipe generation** โ€” Get personalized recipes based on what's in your pantry; streams live via Server-Sent Events so results appear as they are generated -- **Recipe stock hints** โ€” Each pantry ingredient shows how much you have and what remains after use; when the leftover would be less than 5% of the full sealed package (10% for an already-opened partial pack), the recipe automatically uses everything on hand to avoid waste -- **Smart chat assistant** โ€” Ask questions about your inventory, get cooking tips -- **Shopping suggestions with tips** โ€” AI-powered purchase recommendations, each enriched with a short practical buying/storing tip -- **Anomaly explanation** โ€” "Explain" button on anomaly banners explains in plain language why a discrepancy likely occurred and what to do -- **Model fallback** โ€” All AI endpoints try `gemini-2.5-flash` first and fall back to `gemini-2.0-flash` automatically -- **Graceful no-key state** โ€” When no Gemini key is configured, AI entry points show a friendly message; the header button is visually greyed with an amber dot - -### ๐Ÿ›’ Shopping List -- **Bring! integration** โ€” Sync with the [Bring!](https://www.getbring.com/) shopping list app -- **Generic shopping names** โ€” Products are grouped by type (e.g. "Milk", "Cold cuts", "Cooking cream") rather than brand, keeping the Bring! list clean and consolidated -- **Smart predictions** โ€” Know what you'll need before you run out -- **Auto-add on depletion** โ€” When a product reaches zero the app adds it to Bring! automatically, no confirmation needed -- **Auto-remove on scan** โ€” Products are removed from the shopping list when scanned in - **Auto-migration** โ€” Items already on the Bring! list are silently renamed to their generic name in the background (throttled, runs on list load) - - **Catalog coverage** โ€” All product types resolve to a German Bring! catalog key for icon and category display in the Bring! app - -### ๐Ÿณ Cooking Mode -- **โ™ป๏ธ Zero-waste tips** โ€” For each cooking step that generates reusable scraps (peels, cooking water, egg whites, cheese rinds, bread crusts, vegetable tops, etc.), a dismissible โ™ป๏ธ tip card appears with a practical reuse idea; tips are generated by Gemini as part of the recipe at no extra API cost; opt-in toggle in Settings (default OFF) -- **Step-by-step guidance** โ€” Follow recipes with a hands-free cooking interface -- **Text-to-Speech** โ€” Voice readout of recipe steps; supports browser Web Speech API, native Android TTS (kiosk), or a custom REST endpoint (Home Assistant, etc.); retries voice loading for up to 10 seconds with a fallback refresh button; TTS activates automatically without requiring the global TTS setting to be enabled -- **Auto-read on navigate** โ€” Each step is read aloud automatically when you tap Next or Previous; the first step is read when entering cooking mode -- **Timer voice alerts** โ€” 10-second countdown warning spoken aloud before each timer expires; expiry announced vocally when time is up -- **Recipe completion** โ€” "Bon appรฉtit!" announced via TTS when the last step is confirmed -- **Built-in timer** โ€” Automatic timer suggestions based on recipe instructions -- **Ingredient tracking** โ€” Mark ingredients as used during cooking; leftover quantities prompt a "move to another location" flow - -### ๐Ÿ“Š Dashboard -- **Waste tracking** โ€” Monitor consumed vs. wasted products over 30 days -- **Anti-waste report** โ€” Personalised waste rate vs. national average with annual kg estimate; shown above the expiring-items list -- **Expiry alerts** โ€” Visual warnings for expired and soon-to-expire items -- **Opened products panel** โ€” Tracks partially-used items; expiry is recalculated from the opening date using AI (Gemini) + per-category rule fallback; whole sealed packages always keep their original manufacturer expiry; conf items with mixed whole + fractional units are shown as two separate entries -- **Freezer shelf-life** โ€” Granular per-product estimates (USDA/EFSA): fish 120 d, poultry 270 d, whole red-meat cuts 365 d, mince 120 d, vegetables/fruit 270 d, generic 180 d; AI + cache still take priority over rules -- **Safety ratings** โ€” Smart assessment of expired product safety (by category and location); expired unsafe items shown with a red danger banner and a discard action as the primary action -- **Expired product banner** โ€” Products that have passed their effective shelf-life (including opened-product reduced expiry) appear in the top notification banner; icon, colour and title adapt to the actual safety level (โœ… green for safe, ๐Ÿ‘€ amber to check, ๐Ÿšซ red for danger); high-risk items get a prominent discard action -- **Quick recipe bar** โ€” One-tap recipe suggestion using expiring products -- **Anomaly banner** โ€” Scrollable banner with suspicious quantities and consumption prediction mismatches, with one-tap correction or inline edit -- **Expired/expiring alerts** โ€” Priority-sorted banner notifications for expired and soon-to-expire products with use, throw, edit, and dismiss actions -- **Swipe navigation** โ€” Touch swipe or tap arrows/dots to browse banner notifications -- **Quick-access buttons** โ€” Recently used and most popular products shown on the inventory page for fast access - -### ๐ŸŒ™ Appearance -- **Dark mode** โ€” Three modes: Light, Dark, and Auto (time-based: dark from 20:00 to 07:00, light otherwise); applies immediately without page reload; auto mode re-evaluates every 5 minutes, so night/day transitions happen automatically even on always-on kiosk displays; theme is applied before the first render to prevent a white flash -- **Global settings tab** โ€” A dedicated **โš™๏ธ General** tab groups all system-wide settings (language, currency, theme, screensaver, zero-waste tips, export) at the top of the Settings panel - -### ๏ฟฝ๏ธ Database Maintenance -- **Automatic cleanup** โ€” Recipes older than `RECIPE_RETENTION_DAYS` (default 7) and transactions older than `TRANSACTION_RETENTION_DAYS` (default 7) are deleted automatically on every cron cycle; SQLite `VACUUM` runs after each cleanup to keep the file compact -- **Manual cleanup** โ€” Trigger immediately via `GET /api/?action=db_cleanup` -- **Compact by default** โ€” Fresh installs stay small; large accumulated databases shrink back to a few hundred KB within one cron cycle - -### ๏ฟฝ๐Ÿ“ฑ Progressive Web App -- **Mobile-first design** โ€” Optimized for phones, works on tablets and desktop -- **Installable** โ€” Add to home screen for a native app experience -- **Multi-device** โ€” All user data (shopping tags, pinned items, location preferences, scan history) is stored server-side in SQLite and shared across every device on the same instance; no data is siloed in a single browser's localStorage -### ๐Ÿ“ถ Offline Mode -- **Automatic detection** โ€” Full-screen overlay appears immediately on network loss; shows a "Continue offline" button after 3 s, and auto-enters offline mode after 8 s -- **Local inventory cache** โ€” Inventory is synced to `localStorage` at every startup and on each successful API call; the offline view always reflects the last known state -- **Write queue** โ€” Add, use, update and delete operations performed while offline are queued locally and synced to the server automatically on reconnect (including after a page refresh) -- **Optimistic UI** โ€” Queued writes are applied immediately to the local cache so the interface stays responsive -- **Offline-computed stats** โ€” Expiring and expired items are derived client-side from the cache; dashboard stat cards show real counts instead of zeros -- **AI/network sections hidden** โ€” Anti-waste chart, nutrition analysis, recipe generator, price fetching, and Gemini chat are hidden in offline mode; the inventory, history, and manually-managed shopping list remain fully functional -- **Broken image fallback** โ€” External product images (Open Food Facts, etc.) that fail to load are replaced with a neutral grey placeholder, keeping the layout intact -- **Startup recovery** โ€” If the page is refreshed while operations are queued, they are detected and synced automatically on the next successful startup -- **Buffered error reporting** โ€” `remoteLog` and `reportError` calls made while offline are stored locally and flushed to the server (and to GitHub issues) when the connection is restored -### โš–๏ธ Smart Scale Integration (Add-on) -- **Bluetooth gateway** โ€” Connects a BLE smart scale to EverShelf via local WebSocket -- **SSE relay** โ€” Server-side relay avoids mixed-content (HTTPSโ†’WS) issues -- **Auto-discovery** โ€” Server scans LAN to find the gateway automatically -- **Auto weight reading** โ€” When adding/using a product with unit g/ml, weight fills automatically -- **10g threshold** โ€” Ignores readings that haven't changed enough between products - **Duplicate-reading prevention** โ€” Server-side 12-second dedup window rejects a second scale-triggered deduction of the same product, guarding against BLE multi-fire- **ml conversion hint** โ€” Shows "weight in grams โ†’ will be converted to ml" when product unit is ml -- **Stability + auto-confirm** โ€” 10s stable wait + 5s countdown before confirming -- **Real-time status** โ€” Scale connection indicator always visible in the header -- **Multi-protocol** โ€” Supports Bluetooth SIG Weight Scale, Body Composition, Xiaomi Mi Scale 2 and 100+ models -- **Built into kiosk (v1.6.0+)** โ€” BLE gateway runs as an integrated foreground service inside the [EverShelf Kiosk](evershelf-kiosk/) app; no separate APK needed. - -### ๐Ÿ“บ Android Kiosk Mode (Add-on) -- **Dedicated tablet app** โ€” Full-screen WebView wrapper for wall-mounted kitchen tablets -- **True kiosk lock** โ€” Screen pinning blocks home/recent buttons -- **Setup wizard** โ€” 6-step guided configuration (language, welcome, permissions, server URL, BLE scale scan, screensaver, summary) -- **Smart auto-discovery** โ€” Scans the LAN in parallel (60 threads, TCP pre-check, ports 80/443/8080/8443) with real-time UI feedback; correctly identifies the device's Wi-Fi/Ethernet subnet (VPN and cellular interfaces are filtered out) -- **Built-in BLE scale gateway** โ€” `GatewayService` foreground service; BLE scanning + WebSocket server `:8765` run directly inside the kiosk app. Select your scale in step 5 of the wizard โ€” no external app required -- **Scale auto-configuration** โ€” After selecting the BLE device, the wizard writes `scale_enabled` and `scale_gateway_url=ws://127.0.0.1:8765` to the server automatically -- **Camera & mic permissions** โ€” Full hardware access for barcode scanning and voice; grant button transforms to a green confirmation after granting -- **Native TTS bridge** โ€” Cooking mode voice readout uses the Android TextToSpeech engine directly, bypassing Web Speech API voice limitations; no offline voice packs required -- **Hard refresh** โ€” โ†ป button clears WebView cache to pick up web app updates -- **Update notifications** โ€” Checks GitHub releases every 6h, shows banner when updates available -- **SSL support** โ€” Accepts self-signed certificates -- **Android kiosk app** โ€” [`evershelf-kiosk/`](evershelf-kiosk/) โ€” downloadable APK - ---- - -## ๐Ÿš€ Quick Start - -### Prerequisites -- **Web server** with PHP 8.0+ (Apache or Nginx) -- **PHP extensions**: `pdo_sqlite`, `curl`, `mbstring`, `json` -- **HTTPS** recommended (required for camera access on mobile) - -### Installation - -#### Option A: Docker (recommended) - -```bash -# 1. Clone the repository -git clone https://github.com/dadaloop82/EverShelf.git -cd EverShelf - -# 2. Create configuration file -cp .env.example .env -nano .env - -# 3. Start with Docker Compose -docker compose up -d - -# โ†’ Open http://localhost:8080 -``` - -#### Option B: Manual - -```bash -# 1. Clone the repository -git clone https://github.com/dadaloop82/EverShelf.git -cd EverShelf - -# 2. Create configuration file -cp .env.example .env - -# 3. Set permissions -chmod 755 data/ -chmod 664 data/.gitkeep -chown -R www-data:www-data data/ - -# 4. Edit your configuration -nano .env -``` - -### Configuration (.env) - -```ini -# Required for AI features (get a key at https://aistudio.google.com/app/apikey) -GEMINI_API_KEY=your_api_key_here - -# Optional: Bring! shopping list integration -BRING_EMAIL=your_email@example.com -BRING_PASSWORD=your_password - -# Optional: Text-to-Speech for cooking mode -TTS_URL=http://your-home-assistant:8123/api/events/tts_speak -TTS_TOKEN=your_long_lived_token -TTS_ENABLED=true - -# Optional: DB retention and cleanup (applied automatically each cron cycle) -RECIPE_RETENTION_DAYS=7 # delete recipe plans older than N days -TRANSACTION_RETENTION_DAYS=90 # delete stock transactions older than N days (min 30 enforced) - -# Optional: Vacuum-sealed expiry grace period -VACUUM_EXPIRY_EXTENSION_DAYS=30 # extra days before vacuum-sealed items are flagged expired - -# Optional: Gemini cost rates (USD per million tokens, for the Info tab cost estimate) -GEMINI_COST_25F_IN=0.15 -GEMINI_COST_25F_OUT=0.60 -GEMINI_COST_20F_IN=0.10 -GEMINI_COST_20F_OUT=0.40 - -# Optional: Security โ€” protect all API endpoints -# Set a strong random string; clients send it as X-API-Token header (or ?api_token= for HA) -API_TOKEN= - -# Optional: Legacy alias for API_TOKEN (settings save only) -SETTINGS_TOKEN= - -# Optional: Demo mode โ€” block all write operations at the router level -DEMO_MODE=false - -# Optional: Logging -# LOG_LEVEL sets the minimum severity written to disk (DEBUG / INFO / WARN / ERROR) -# DEBUG also logs every SQL query executed against the database -LOG_LEVEL=INFO -LOG_ROTATE_HOURS=24 # hours before opening a new log file (default: 24) -LOG_MAX_FILES=14 # maximum number of rotated files to keep (default: 14) -``` - -### Web Server Configuration - -
-Apache (.htaccess) - -The app works out of the box with Apache if placed in the web root or a subdirectory. Make sure `mod_rewrite` is enabled and `AllowOverride All` is set. - -```apache - - AllowOverride All - Require all granted - -``` - -
- -
-Nginx - -```nginx -server { - listen 80; - server_name your-server.local; - root /var/www/html/evershelf; - index index.html; - - location /api/ { - try_files $uri $uri/ =404; - location ~ \.php$ { - fastcgi_pass unix:/run/php/php8.2-fpm.sock; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - include fastcgi_params; - } - } - - # Deny access to sensitive files - location ~ /\.env { deny all; } - location ~ /data/ { deny all; } - location ~ /backup\.sh { deny all; } -} -``` - -
- -### HTTPS Setup (Recommended) - -Camera access requires HTTPS on most mobile browsers. Options: -- **Let's Encrypt** with Certbot (for public-facing servers) -- **Self-signed certificate** (for local network only) -- **Reverse proxy** (e.g., Caddy, Traefik) with automatic TLS - -### Cron Job (Optional) - -Set up a cron job for smart shopping predictions: - -```bash -# Run every 5 minutes -*/5 * * * * php /path/to/evershelf/api/cron_smart_shopping.php >> /path/to/evershelf/data/cron.log 2>&1 -``` - -### Backup (Optional) - -The included `backup.sh` creates local daily backups of your database: - -```bash -# Run daily at 3 AM -0 3 * * * /path/to/evershelf/backup.sh -``` - -### Google Drive Backup (Optional) - -EverShelf supports automatic daily backups to Google Drive via OAuth 2.0. This works on any server, including private IP / local network setups (no public domain required). - -**Setup:** - -1. Go to [console.cloud.google.com](https://console.cloud.google.com) and select or create a project. -2. Enable the **Google Drive API** (`APIs & Services โ†’ Enable APIs โ†’ Google Drive API`). -3. Go to `APIs & Services โ†’ Credentials โ†’ Create Credentials โ†’ OAuth client ID`. -4. Application type: **Web application**. -5. Add **`http://localhost`** as an Authorized Redirect URI (this is the key โ€” it works even without a real domain). -6. Copy **Client ID** and **Client Secret** into EverShelf Settings โ†’ Backup. -7. Enter your **Google Drive Folder ID** (the last part of the folder URL). -8. Click **Authorize with Google** and sign in. -9. The browser will redirect to `http://localhost` and may show a connection error โ€” **this is expected**. Copy the full URL from the address bar (e.g. `http://localhost/?code=4%2F0A...`) and paste it into the field that appears in EverShelf, then click **Submit**. - -> **Note:** While the OAuth app is in *Testing* status in Google Cloud Console, you must add your Google account as a test user under `APIs & Services โ†’ OAuth consent screen โ†’ Test users`. - ---- - -## ๐Ÿ—๏ธ Architecture - -``` -evershelf/ -โ”œโ”€โ”€ index.html # Single-page application (SPA) -โ”œโ”€โ”€ manifest.json # PWA manifest -โ”œโ”€โ”€ .env.example # Configuration template -โ”œโ”€โ”€ backup.sh # Local database backup script -โ”œโ”€โ”€ LICENSE # MIT License -โ”‚ -โ”œโ”€โ”€ api/ -โ”‚ โ”œโ”€โ”€ index.php # Main API router (all endpoints) -โ”‚ โ”œโ”€โ”€ database.php # SQLite schema, migrations, helpers -โ”‚ โ””โ”€โ”€ cron_smart_shopping.php # Background job for predictions -โ”‚ -โ”œโ”€โ”€ assets/ -โ”‚ โ”œโ”€โ”€ css/style.css # All application styles -โ”‚ โ”œโ”€โ”€ js/app.js # All application logic -โ”‚ โ””โ”€โ”€ img/ # Static images -โ”‚ -โ””โ”€โ”€ data/ # Runtime data (gitignored) - โ”œโ”€โ”€ evershelf.db # SQLite database (auto-created) - โ”œโ”€โ”€ backups/ # Local DB backups - โ””โ”€โ”€ *.json # Token/cache files - -evershelf-scale-gateway/ # โš–๏ธ Android BLE gateway [DEPRECATED โ€” integrated into kiosk v1.6.0+] - โ”œโ”€โ”€ README.md # Deprecation notice + legacy docs - โ””โ”€โ”€ app/src/ # Kotlin Android source (WebSocket + BLE) - -evershelf-kiosk/ # ๐Ÿ“บ Android kiosk app (add-on) - โ”œโ”€โ”€ README.md # Setup & feature docs - โ””โ”€โ”€ app/src/ # Kotlin Android source (WebView wrapper) -``` - -### API Endpoints - -| Category | Action | Method | Description | -|----------|--------|--------|-------------| -| **Products** | `search_barcode` | GET | Find product by barcode | -| | `lookup_barcode` | GET | Look up barcode on Open Food Facts | -| | `product_save` | POST | Create or update a product | -| | `products_list` | GET | List all products | -| **Inventory** | `inventory_list` | GET | List inventory items | -| | `inventory_add` | POST | Add product to inventory | -| | `inventory_use` | POST | Use/consume from inventory | -| | `inventory_summary` | GET | Count by location | -| **AI** | `gemini_identify` | POST | Identify product from photo | -| | `gemini_expiry` | POST | Read expiry date from photo | -| | `gemini_chat` | POST | Chat with AI assistant | -| | `generate_recipe` | POST | Generate recipe from inventory | -| | `gemini_product_hint` | POST | Storage location + shelf-life hint | -| | `gemini_shopping_enrich` | POST | Enrich shopping suggestions with tips | -| | `gemini_anomaly_explain` | POST | Plain-language anomaly explanation | -| **Shopping** | `bring_list` | GET | Get Bring! shopping list | -| | `bring_add` | POST | Add items to Bring! | -| | `smart_shopping` | GET | Smart shopping predictions | -| **Settings** | `get_settings` | GET | Get server configuration | -| | `save_settings` | POST | Update server configuration | - ---- - -## ๐Ÿ”’ Security Notes - -- **Credentials** are stored in `.env` (server-side, never committed to Git) -- **Database** stays local โ€” never pushed to remote repositories -- **Apache/Nginx hardening** โ€” `.env`, `data/`, and `logs/` are blocked from direct HTTP access -- **API token** โ€” set `API_TOKEN` in `.env` to require `X-API-Token` on all API calls (Home Assistant: `?api_token=`) -- **API keys are never exposed to the browser** โ€” `get_settings` returns only boolean flags (`gemini_key_set`, `ha_token_set`, โ€ฆ) -- **GitHub Issues token** โ€” stored encrypted as `GH_ISSUE_TOKEN_ENC` + `GH_ISSUE_TOKEN_KEY` (see `scripts/encrypt-gh-token.php`) -- **Settings write protection** โ€” `save_settings` requires the same API token when configured; validated with `hash_equals` -- **Demo / public mode** โ€” set `DEMO_MODE=true` to block all write operations at the PHP router level before any business logic runs -- The API uses **parameterized SQL queries** (PDO prepared statements) against injection -- **Input validation** on all inventory operations (quantity bounds, location whitelist) -- Consider adding **reverse-proxy authentication** (e.g. Authelia, Nginx `auth_basic`) if the server is accessible from the internet - ---- - -## ๐Ÿ› ๏ธ Development - -```bash -# Run PHP's built-in server for local development -php -S localhost:8080 -t /path/to/evershelf - -# Check PHP syntax -php -l api/index.php -php -l api/database.php -``` - -The application uses no build tools โ€” edit files directly and refresh. - ---- - -## ๐Ÿ“‹ Roadmap - -Feature requests, bug reports and planned work are tracked in the [**EverShelf Roadmap**](https://github.com/users/dadaloop82/projects/2) GitHub Project. - ---- - -## ๐ŸŒ Translations - -The app supports multiple languages via JSON translation files in the `translations/` folder. - -| Language | Status | -|----------|--------| -| ๐Ÿ‡ฎ๐Ÿ‡น Italian (it) | โœ… Complete (base) | -| ๐Ÿ‡ฌ๐Ÿ‡ง English (en) | โœ… Complete | -| ๐Ÿ‡ฉ๐Ÿ‡ช German (de) | โœ… Complete | -| ๐Ÿ‡ซ๐Ÿ‡ท French (fr) | โœ… Complete | -| ๐Ÿ‡ช๐Ÿ‡ธ Spanish (es) | โœ… Complete | - -**Want to add your language?** See the [Translation Guide](CONTRIBUTING.md#-adding-translations) โ€” just copy `translations/it.json`, translate the values, and submit a PR! - ---- - -## ๐Ÿค Contributing - -Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines. - -1. Fork the repository -2. Create a feature branch (`git checkout -b feature/my-feature`) -3. Commit your changes (`git commit -m 'Add my feature'`) -4. Push to the branch (`git push origin feature/my-feature`) -5. Open a Pull Request - -### Easiest way to start โ€” translate EverShelf into your language - -Translations are just JSON files. No coding, no setup โ€” fork โ†’ edit โ†’ PR. - -``` -translations/ -โ”œโ”€โ”€ it.json โœ… Italian (base) -โ”œโ”€โ”€ en.json โœ… English -โ”œโ”€โ”€ de.json โœ… German -โ”œโ”€โ”€ fr.json โœ… French -โ”œโ”€โ”€ es.json โœ… Spanish -โ”œโ”€โ”€ pt.json โŒ Portuguese โ€” wanted! -โ”œโ”€โ”€ nl.json โŒ Dutch โ€” wanted! -โ””โ”€โ”€ ... โŒ Your language here! -``` - -๐Ÿ‘‰ See [issue #93](https://github.com/dadaloop82/EverShelf/issues/93) to claim a language. - -### Other ways to contribute - -| What | Skill needed | -|---|---| -| ๐Ÿ› Report a bug | None | -| ๐Ÿ“– Improve the wiki | Markdown | -| ๐ŸŒ Add a translation | JSON editing | -| ๐ŸŽจ Fix a CSS/UI issue | CSS / HTML | -| โš™๏ธ Implement a feature | PHP / JS | -| โญ Star the repo | Clicking | - -๐Ÿ‘‰ Browse [`help wanted`](https://github.com/dadaloop82/EverShelf/labels/help%20wanted) issues for good starting points. - -Read [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide (branch naming, code style, how to run locally). - ---- - -## ๐Ÿ’ฌ Community - -Join the conversation in [GitHub Discussions](https://github.com/dadaloop82/EverShelf/discussions): -- **Vote on upcoming features** โ€” tell us what to build next -- **Show your setup** โ€” share your kitchen kiosk -- **Ask questions** โ€” get help from the community - ---- - -## ๐Ÿ“„ License - -This project is licensed under the **MIT License** โ€” see the [LICENSE](LICENSE) file for details. - ---- - -## ๐Ÿ‘จโ€๐Ÿ’ป Author - -**Stimpfl Daniel** โ€” [evershelfproject@gmail.com](mailto:evershelfproject@gmail.com) - -- Website: [evershelfproject.dadaloop.it](https://evershelfproject.dadaloop.it/) -- GitHub: [@dadaloop82](https://github.com/dadaloop82) - ---- - -## ๐Ÿ“ธ Screenshots - -
- -![EverShelf demo โ€” barcode scan, inventory management and AI recipe generation](assets/img/demo.gif) - -
- -For a live walkthrough with real data and full AI enabled, visit the **[live demo](https://evershelfproject.dadaloop.it/demo)** โ€” no installation required. - -> Want to contribute additional screenshots? See [CONTRIBUTING.md](CONTRIBUTING.md) โ€” PRs welcome!