rebrand: rename project from Dispensa Manager to EverShelf

- Update app name across all files (manifest, index.html, README, docs)
- Update contact email to evershelfproject@gmail.com
- Rename Docker service/container/volume to evershelf
- Rename localStorage keys: dispensa_* → evershelf_*
- Rename SQLite DB reference: dispensa.db → evershelf.db
- Update SSH remote to dadaloop82/EverShelf
- Update Apache conf file name to evershelf.conf
- Update CI workflow Docker image/container names
- Update cron job example path
- Add data/dispensa.db to .gitignore to prevent accidental commit
This commit is contained in:
dadaloop82
2026-04-13 10:09:33 +00:00
parent da962581c0
commit 20f734d54a
21 changed files with 81 additions and 81 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
# Docker runtime files
data/dispensa.db
data/evershelf.db
data/*.db-wal
data/*.db-shm
data/backups/
+1 -1
View File
@@ -1,4 +1,4 @@
# Dispensa Manager - Configuration
# EverShelf - Configuration
# Copy this file to .env and fill in your values
# cp .env.example .env
+3 -3
View File
@@ -40,14 +40,14 @@ jobs:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t dispensa-test .
run: docker build -t evershelf-test .
- name: Test container starts
run: |
docker run -d --name test-dispensa -p 8080:80 dispensa-test
docker run -d --name test-evershelf -p 8080:80 evershelf-test
sleep 5
curl -f http://localhost:8080/ || exit 1
docker stop test-dispensa
docker stop test-evershelf
validate-translations:
name: Validate Translation Files
+1
View File
@@ -2,6 +2,7 @@
.env
# Data directory (user-specific runtime data)
data/evershelf.db
data/dispensa.db
data/*.db-wal
data/*.db-shm
+1 -1
View File
@@ -1,6 +1,6 @@
# Changelog
All notable changes to Dispensa Manager will be documented in this file.
All notable changes to EverShelf will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+5 -5
View File
@@ -1,4 +1,4 @@
# Contributing to Dispensa Manager
# Contributing to EverShelf
Thank you for your interest in contributing! This guide will help you get started.
@@ -7,8 +7,8 @@ Thank you for your interest in contributing! This guide will help you get starte
1. **Fork** the repository
2. **Clone** your fork:
```bash
git clone https://github.com/YOUR_USERNAME/dispensa.git
cd dispensa
git clone https://github.com/YOUR_USERNAME/EverShelf.git
cd EverShelf
```
3. **Create a branch** from `develop`:
```bash
@@ -55,7 +55,7 @@ Translations are one of the easiest ways to contribute! Each language is a singl
```json
{
"app.title": "Dispensa Manager",
"app.title": "EverShelf",
"nav.dashboard": "Dashboard",
"nav.inventory": "Inventario",
...
@@ -110,7 +110,7 @@ node -c assets/js/app.js
python3 -c "import json; json.load(open('translations/it.json'))"
# Test Docker build
docker build -t dispensa-test .
docker build -t evershelf-test .
```
## 📝 Pull Request Process
+2 -2
View File
@@ -29,8 +29,8 @@ RUN [ ! -f /var/www/html/.env ] && cp /var/www/html/.env.example /var/www/html/.
RUN echo '<Directory /var/www/html>\n\
AllowOverride All\n\
Require all granted\n\
</Directory>' > /etc/apache2/conf-available/dispensa.conf \
&& a2enconf dispensa
</Directory>' > /etc/apache2/conf-available/evershelf.conf \
&& a2enconf evershelf
# Expose port 80
EXPOSE 80
+13 -13
View File
@@ -1,4 +1,4 @@
# 🏠 Dispensa Manager
# 🏠 EverShelf
> **Self-hosted pantry management system** — Track your food inventory, scan barcodes, get AI-powered recipe suggestions, and reduce waste.
@@ -71,8 +71,8 @@
```bash
# 1. Clone the repository
git clone https://github.com/dadaloop82/dispensa.git
cd dispensa
git clone https://github.com/dadaloop82/EverShelf.git
cd EverShelf
# 2. Create configuration file
cp .env.example .env
@@ -88,8 +88,8 @@ docker compose up -d
```bash
# 1. Clone the repository
git clone https://github.com/dadaloop82/dispensa.git
cd dispensa
git clone https://github.com/dadaloop82/EverShelf.git
cd EverShelf
# 2. Create configuration file
cp .env.example .env
@@ -127,7 +127,7 @@ TTS_ENABLED=true
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
<Directory /var/www/html/dispensa>
<Directory /var/www/html/evershelf>
AllowOverride All
Require all granted
</Directory>
@@ -142,7 +142,7 @@ The app works out of the box with Apache if placed in the web root or a subdirec
server {
listen 80;
server_name your-server.local;
root /var/www/html/dispensa;
root /var/www/html/evershelf;
index index.html;
location /api/ {
@@ -176,7 +176,7 @@ Set up a cron job for smart shopping predictions:
```bash
# Run every 5 minutes
*/5 * * * * php /path/to/dispensa/api/cron_smart_shopping.php >> /path/to/dispensa/data/cron.log 2>&1
*/5 * * * * php /path/to/evershelf/api/cron_smart_shopping.php >> /path/to/evershelf/data/cron.log 2>&1
```
### Backup (Optional)
@@ -185,7 +185,7 @@ The included `backup.sh` creates local daily backups of your database:
```bash
# Run daily at 3 AM
0 3 * * * /path/to/dispensa/backup.sh
0 3 * * * /path/to/evershelf/backup.sh
```
---
@@ -193,7 +193,7 @@ The included `backup.sh` creates local daily backups of your database:
## 🏗️ Architecture
```
dispensa/
evershelf/
├── index.html # Single-page application (SPA)
├── manifest.json # PWA manifest
├── .env.example # Configuration template
@@ -211,7 +211,7 @@ dispensa/
│ └── img/ # Static images
└── data/ # Runtime data (gitignored)
├── dispensa.db # SQLite database (auto-created)
├── evershelf.db # SQLite database (auto-created)
├── backups/ # Local DB backups
└── *.json # Token/cache files
```
@@ -255,7 +255,7 @@ dispensa/
```bash
# Run PHP's built-in server for local development
php -S localhost:8080 -t /path/to/dispensa
php -S localhost:8080 -t /path/to/evershelf
# Check PHP syntax
php -l api/index.php
@@ -315,6 +315,6 @@ This project is licensed under the **MIT License** — see the [LICENSE](LICENSE
## 👨‍💻 Author
**Stimpfl Daniel** — [dadaloop82@gmail.com](mailto:dadaloop82@gmail.com)
**Stimpfl Daniel** — [evershelfproject@gmail.com](mailto:evershelfproject@gmail.com)
- GitHub: [@dadaloop82](https://github.com/dadaloop82)
+1 -1
View File
@@ -2,7 +2,7 @@
/**
* Cron: pre-compute smart shopping list and save to cache.
* Install with: crontab -e
* *\/5 * * * * php /var/www/html/dispensa/api/cron_smart_shopping.php >> /var/www/html/dispensa/data/cron.log 2>&1
* *\/5 * * * * php /var/www/html/evershelf/api/cron_smart_shopping.php >> /var/www/html/evershelf/data/cron.log 2>&1
*/
// Only allow CLI execution — block HTTP access
+3 -3
View File
@@ -1,13 +1,13 @@
<?php
/**
* Dispensa Manager - Database initialization, schema, and migrations.
* EverShelf - Database initialization, schema, and migrations.
* Uses SQLite with WAL journal mode for concurrent read/write performance.
*
* @author Stimpfl Daniel <dadaloop82@gmail.com>
* @author Stimpfl Daniel <evershelfproject@gmail.com>
* @license MIT
*/
define('DB_PATH', __DIR__ . '/../data/dispensa.db');
define('DB_PATH', __DIR__ . '/../data/evershelf.db');
function getDB(): PDO {
$isNew = !file_exists(DB_PATH);
+2 -2
View File
@@ -1,10 +1,10 @@
<?php
/**
* Dispensa Manager - Main API Router
* EverShelf - Main API Router
* Handles all CRUD operations for products, inventory, shopping lists,
* AI-powered features (Gemini), and third-party integrations (Bring!, DupliClick).
*
* @author Stimpfl Daniel <dadaloop82@gmail.com>
* @author Stimpfl Daniel <evershelfproject@gmail.com>
* @license MIT
*/
+2 -2
View File
@@ -1,8 +1,8 @@
/**
* Dispensa Manager - UI Styles
* EverShelf - UI Styles
* Mobile-first PWA design with CSS custom properties.
*
* @author Stimpfl Daniel <dadaloop82@gmail.com>
* @author Stimpfl Daniel <evershelfproject@gmail.com>
* @license MIT
*/
+24 -25
View File
@@ -1,9 +1,9 @@
/**
* Dispensa Manager - Main Application JS
* EverShelf - Main Application JS
* Complete pantry management with barcode scanning, AI identification,
* Bring! shopping list integration, recipe generation, and TTS cooking mode.
*
* @author Stimpfl Daniel <dadaloop82@gmail.com>
* @author Stimpfl Daniel <evershelfproject@gmail.com>
* @license MIT
*/
@@ -61,7 +61,7 @@ const API_BASE = 'api/index.php';
// ===== i18n TRANSLATION SYSTEM =====
let _i18nStrings = null; // current language translations (flat)
let _i18nFallback = null; // Italian fallback (flat)
let _currentLang = localStorage.getItem('dispensa_lang') || navigator.language?.slice(0, 2) || 'it';
let _currentLang = localStorage.getItem('evershelf_lang') || navigator.language?.slice(0, 2) || 'it';
const _SUPPORTED_LANGS = { it: 'Italiano', en: 'English', de: 'Deutsch' };
if (!_SUPPORTED_LANGS[_currentLang]) _currentLang = 'it';
@@ -107,7 +107,7 @@ async function loadTranslations(lang) {
else _i18nStrings = _i18nFallback;
}
_currentLang = lang;
localStorage.setItem('dispensa_lang', lang);
localStorage.setItem('evershelf_lang', lang);
_applyI18nToLabels();
translatePage();
} catch (e) {
@@ -170,9 +170,8 @@ function _populateLanguageSelector() {
// Change language and reload the page
function changeLanguage(lang) {
if (lang === _currentLang) return;
localStorage.setItem('dispensa_lang', lang);
localStorage.setItem('evershelf_lang', lang);
location.reload();
}
const LOCATIONS = {
'dispensa': { icon: '🗄️', label: 'Dispensa' },
@@ -728,7 +727,7 @@ let _settingsDirty = false;
function getSettings() {
if (!_settingsCache) {
try {
_settingsCache = JSON.parse(localStorage.getItem('dispensa_settings') || '{}');
_settingsCache = JSON.parse(localStorage.getItem('evershelf_settings') || '{}');
} catch(e) { _settingsCache = {}; }
}
const s = _settingsCache;
@@ -746,7 +745,7 @@ function getSettings() {
function saveSettingsToStorage(settings) {
_settingsCache = settings;
localStorage.setItem('dispensa_settings', JSON.stringify(settings));
localStorage.setItem('evershelf_settings', JSON.stringify(settings));
// Persist to DB
_settingsDirty = true;
_debouncedSyncSettings();
@@ -798,7 +797,7 @@ async function syncSettingsFromDB() {
if (db[key] !== undefined) s[key] = db[key];
}
_settingsCache = s;
localStorage.setItem('dispensa_settings', JSON.stringify(s));
localStorage.setItem('evershelf_settings', JSON.stringify(s));
}
if (res.settings.review_confirmed) {
_reviewConfirmedCache = res.settings.review_confirmed;
@@ -7716,7 +7715,7 @@ async function testTTS() {
s.tts_rate = parseFloat(document.getElementById('setting-tts-rate')?.value) || 1;
s.tts_pitch = parseFloat(document.getElementById('setting-tts-pitch')?.value) || 1;
saveSettingsToStorage(s);
_speakBrowser('Test vocale Dispensa Manager. La sintesi vocale funziona correttamente.');
_speakBrowser('Test vocale EverShelf. La sintesi vocale funziona correttamente.');
if (statusEl) { statusEl.style.display = 'block'; statusEl.className = 'settings-status success'; statusEl.textContent = '✅ Riproduzione in corso — controlla l\'audio del dispositivo.'; }
return;
}
@@ -7740,7 +7739,7 @@ async function testTTS() {
}
if (statusEl) { statusEl.style.display = 'block'; statusEl.className = 'settings-status'; statusEl.textContent = '⏳ Invio in corso…'; }
try {
const req = _buildTtsRequest('Test vocale Dispensa Manager', formSettings);
const req = _buildTtsRequest('Test vocale EverShelf', formSettings);
const res = await _ttsViaProxy(req);
const data = await res.json().catch(() => ({}));
const httpCode = data.status || res.status;
@@ -8932,7 +8931,7 @@ function _getMissingSetupSteps(serverSettings) {
const srv = serverSettings || {};
// Step 0 — language: missing only if never set at all (fresh install)
if (!localStorage.getItem('dispensa_lang') && !localStorage.getItem('dispensa_setup_done')) {
if (!localStorage.getItem('evershelf_lang') && !localStorage.getItem('evershelf_setup_done')) {
missing.push(0);
}
// Step 1 — Gemini API key (check both localStorage and server .env)
@@ -9083,10 +9082,10 @@ function setupWizardNav(dir) {
// If language changed, apply it
if (realIndex === 0 && dir === 1 && _setupData.lang !== _currentLang) {
localStorage.setItem('dispensa_lang', _setupData.lang);
localStorage.setItem('dispensa_setup_step', String(_setupStep + 1));
localStorage.setItem('dispensa_setup_pending', JSON.stringify(_setupPendingSteps));
localStorage.setItem('dispensa_setup_data', JSON.stringify(_setupData));
localStorage.setItem('evershelf_lang', _setupData.lang);
localStorage.setItem('evershelf_setup_step', String(_setupStep + 1));
localStorage.setItem('evershelf_setup_pending', JSON.stringify(_setupPendingSteps));
localStorage.setItem('evershelf_setup_data', JSON.stringify(_setupData));
location.reload();
return;
}
@@ -9112,24 +9111,24 @@ async function _finishSetup() {
});
} catch(e) { /* will work locally */ }
localStorage.setItem('dispensa_setup_done', '1');
localStorage.removeItem('dispensa_setup_step');
localStorage.removeItem('dispensa_setup_data');
localStorage.setItem('evershelf_setup_done', '1');
localStorage.removeItem('evershelf_setup_step');
localStorage.removeItem('evershelf_setup_data');
document.getElementById('setup-wizard').style.display = 'none';
}
async function _initApp() {
// Check for setup wizard resume (after language change)
const resumeStep = localStorage.getItem('dispensa_setup_step');
const resumeData = localStorage.getItem('dispensa_setup_data');
const resumePending = localStorage.getItem('dispensa_setup_pending');
const resumeStep = localStorage.getItem('evershelf_setup_step');
const resumeData = localStorage.getItem('evershelf_setup_data');
const resumePending = localStorage.getItem('evershelf_setup_pending');
if (resumeStep && resumePending) {
try { Object.assign(_setupData, JSON.parse(resumeData)); } catch(e) {}
try { _setupPendingSteps = JSON.parse(resumePending); } catch(e) {}
_setupStep = parseInt(resumeStep) || 0;
localStorage.removeItem('dispensa_setup_step');
localStorage.removeItem('dispensa_setup_data');
localStorage.removeItem('dispensa_setup_pending');
localStorage.removeItem('evershelf_setup_step');
localStorage.removeItem('evershelf_setup_data');
localStorage.removeItem('evershelf_setup_pending');
document.getElementById('setup-wizard').style.display = '';
_renderSetupStep();
} else {
+5 -5
View File
@@ -1,23 +1,23 @@
#!/bin/bash
# Daily backup of Dispensa database (local only)
# Daily backup of EverShelf database (local only)
# The database is NOT pushed to remote repositories.
# Runs via cron: creates a local timestamped backup copy
#
# Example crontab entry:
# 0 3 * * * /var/www/html/dispensa/backup.sh
# 0 3 * * * /var/www/html/evershelf/backup.sh
INSTALL_DIR="$(cd "$(dirname "$0")" && pwd)"
BACKUP_DIR="${INSTALL_DIR}/data/backups"
mkdir -p "$BACKUP_DIR"
DB_FILE="${INSTALL_DIR}/data/dispensa.db"
DB_FILE="${INSTALL_DIR}/data/evershelf.db"
if [ ! -f "$DB_FILE" ]; then
exit 0
fi
DATE=$(date '+%Y-%m-%d_%H%M')
cp "$DB_FILE" "${BACKUP_DIR}/dispensa_${DATE}.db"
cp "$DB_FILE" "${BACKUP_DIR}/evershelf_${DATE}.db"
# Keep only the last 7 backups
ls -t "${BACKUP_DIR}"/dispensa_*.db 2>/dev/null | tail -n +8 | xargs -r rm --
ls -t "${BACKUP_DIR}"/evershelf_*.db 2>/dev/null | tail -n +8 | xargs -r rm --
+4 -4
View File
@@ -1,12 +1,12 @@
services:
dispensa:
evershelf:
build: .
container_name: dispensa
container_name: evershelf
ports:
- "8080:80"
volumes:
# Persist database and runtime data
- dispensa_data:/var/www/html/data
- evershelf_data:/var/www/html/data
# Mount your local .env configuration
- ./.env:/var/www/html/.env:ro
restart: unless-stopped
@@ -14,5 +14,5 @@ services:
- TZ=Europe/Rome
volumes:
dispensa_data:
evershelf_data:
driver: local
+3 -3
View File
@@ -1,8 +1,8 @@
openapi: "3.1.0"
info:
title: Dispensa Manager API
title: EverShelf API
description: |
REST API for Dispensa Manager — a self-hosted pantry management system.
REST API for EverShelf — a self-hosted pantry management system.
All endpoints use the query parameter `action` to determine the operation.
**Base URL:** `api/index.php?action={action_name}`
@@ -14,7 +14,7 @@ info:
version: "1.0.0"
contact:
name: Stimpfl Daniel
email: dadaloop82@gmail.com
email: evershelfproject@gmail.com
license:
name: MIT
url: https://opensource.org/licenses/MIT
+4 -4
View File
@@ -8,7 +8,7 @@
<meta name="theme-color" content="#2d5016">
<meta name="author" content="Stimpfl Daniel">
<meta name="description" content="Self-hosted pantry manager with barcode scanning, AI identification, and shopping list integration.">
<title>Dispensa Manager</title>
<title>EverShelf</title>
<link rel="manifest" href="manifest.json">
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🏠</text></svg>">
<link rel="stylesheet" href="assets/css/style.css?v=20260329a">
@@ -846,13 +846,13 @@
<h4>🔒 Certificato HTTPS</h4>
<p class="settings-hint">Se il browser mostra l'errore "La connessione non è privata" (ERR_CERT_AUTHORITY_INVALID), devi installare il certificato CA nel dispositivo.</p>
<div class="form-group">
<a href="ca.crt" download="Dispensa_CA.crt" class="btn btn-large btn-accent full-width" style="text-align:center;text-decoration:none;display:block">📥 Scarica Certificato CA</a>
<a href="ca.crt" download="EverShelf_CA.crt" class="btn btn-large btn-accent full-width" style="text-align:center;text-decoration:none;display:block">📥 Scarica Certificato CA</a>
</div>
<div class="settings-hint" style="margin-top:12px;line-height:1.6">
<strong>Istruzioni per Chrome (Android):</strong><br>
1. Scarica il certificato qui sopra<br>
2. Vai in <em>Impostazioni → Sicurezza e privacy → Altre impostazioni di sicurezza → Installa da archivio dispositivo</em><br>
3. Seleziona il file <em>Dispensa_CA.crt</em> scaricato<br>
3. Seleziona il file <em>EverShelf_CA.crt</em> scaricato<br>
4. Scegli "CA" e conferma<br>
5. Riavvia Chrome<br><br>
<strong>Istruzioni per Chrome (PC):</strong><br>
@@ -1109,7 +1109,7 @@
<div class="modal-overlay" id="setup-wizard" style="display:none">
<div class="modal-content setup-wizard-content" onclick="event.stopPropagation()">
<div class="setup-header">
<h2>🏠 Dispensa Manager</h2>
<h2>🏠 EverShelf</h2>
<div class="setup-progress" id="setup-progress"></div>
</div>
<div class="setup-body" id="setup-body"></div>
+3 -3
View File
@@ -1,8 +1,8 @@
{
"name": "Dispensa Manager",
"short_name": "Dispensa",
"name": "EverShelf",
"short_name": "EverShelf",
"description": "Gestione completa della dispensa di casa con scansione barcode",
"start_url": "/dispensa/",
"start_url": "/evershelf/",
"display": "standalone",
"background_color": "#f0f4e8",
"theme_color": "#2d5016",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"app": {
"name": "Dispensa Manager",
"name": "EverShelf",
"loading": "Laden..."
},
"nav": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"app": {
"name": "Dispensa Manager",
"name": "EverShelf",
"loading": "Loading..."
},
"nav": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"app": {
"name": "Dispensa Manager",
"name": "EverShelf",
"loading": "Caricamento..."
},
"nav": {