cache image not being used fixed
This commit is contained in:
@@ -83,7 +83,6 @@ python app.py
|
|||||||
- Better admin registration(?)
|
- Better admin registration(?)
|
||||||
- Cache user edited pictures
|
- Cache user edited pictures
|
||||||
- clear edited fields after scanning of new product
|
- clear edited fields after scanning of new product
|
||||||
- FIX cached images of not saved items dont get displayed
|
|
||||||
|
|
||||||
## 🥼 Food Datasets
|
## 🥼 Food Datasets
|
||||||
- https://www.ifpsglobal.com/plu-codes-search
|
- https://www.ifpsglobal.com/plu-codes-search
|
||||||
|
|||||||
33
app.py
33
app.py
@@ -62,10 +62,16 @@ def download_image(url, barcode):
|
|||||||
return url
|
return url
|
||||||
|
|
||||||
def fetch_from_openfoodfacts(barcode):
|
def fetch_from_openfoodfacts(barcode):
|
||||||
|
# Check if we already have a cached image even if API fails
|
||||||
|
local_filename = f"{barcode}.jpg"
|
||||||
|
local_path = os.path.join(CACHE_DIR, local_filename)
|
||||||
|
cached_url = f"/static/cache/{local_filename}" if os.path.exists(local_path) else None
|
||||||
|
|
||||||
url = f"https://world.openfoodfacts.org/api/v2/product/{barcode}.json"
|
url = f"https://world.openfoodfacts.org/api/v2/product/{barcode}.json"
|
||||||
try:
|
try:
|
||||||
headers = {'User-Agent': 'SekiPOS/1.0'}
|
headers = {'User-Agent': 'SekiPOS/1.0'}
|
||||||
resp = requests.get(url, headers=headers, timeout=5).json()
|
resp = requests.get(url, headers=headers, timeout=5).json()
|
||||||
|
|
||||||
if resp.get('status') == 1:
|
if resp.get('status') == 1:
|
||||||
p = resp.get('product', {})
|
p = resp.get('product', {})
|
||||||
name = p.get('product_name_es') or p.get('product_name') or p.get('brands', 'Unknown')
|
name = p.get('product_name_es') or p.get('product_name') or p.get('brands', 'Unknown')
|
||||||
@@ -73,7 +79,14 @@ def fetch_from_openfoodfacts(barcode):
|
|||||||
img_url = imgs.get('es') or imgs.get('en') or p.get('image_url', '')
|
img_url = imgs.get('es') or imgs.get('en') or p.get('image_url', '')
|
||||||
local_img = download_image(img_url, barcode)
|
local_img = download_image(img_url, barcode)
|
||||||
return {"name": name, "image": local_img}
|
return {"name": name, "image": local_img}
|
||||||
except: pass
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"API Error: {e}")
|
||||||
|
|
||||||
|
# If API fails but we have a cache, return the cache with a generic name
|
||||||
|
if cached_url:
|
||||||
|
return {"name": "Producto Cacheado", "image": cached_url}
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# --- ROUTES ---
|
# --- ROUTES ---
|
||||||
@@ -137,13 +150,19 @@ def scan():
|
|||||||
if p:
|
if p:
|
||||||
socketio.emit('new_scan', {"barcode": p[0], "name": p[1], "price": int(p[2]), "image": p[3]})
|
socketio.emit('new_scan', {"barcode": p[0], "name": p[1], "price": int(p[2]), "image": p[3]})
|
||||||
return jsonify({"status": "ok"})
|
return jsonify({"status": "ok"})
|
||||||
|
|
||||||
|
# Not in DB, try external API or Local Cache
|
||||||
|
ext = fetch_from_openfoodfacts(barcode)
|
||||||
|
if ext:
|
||||||
|
socketio.emit('scan_error', {
|
||||||
|
"barcode": barcode,
|
||||||
|
"name": ext['name'],
|
||||||
|
"image": ext['image']
|
||||||
|
})
|
||||||
else:
|
else:
|
||||||
ext = fetch_from_openfoodfacts(barcode)
|
socketio.emit('scan_error', {"barcode": barcode})
|
||||||
if ext:
|
|
||||||
socketio.emit('scan_error', {"barcode": barcode, "name": ext['name'], "image": ext['image']})
|
return jsonify({"status": "not_found"}), 404
|
||||||
else:
|
|
||||||
socketio.emit('scan_error', {"barcode": barcode})
|
|
||||||
return jsonify({"status": "not_found"}), 404
|
|
||||||
|
|
||||||
@app.route('/static/cache/<path:filename>')
|
@app.route('/static/cache/<path:filename>')
|
||||||
def serve_cache(filename):
|
def serve_cache(filename):
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
<div class="header-bar">
|
<div class="header-bar">
|
||||||
<h2 style="margin:0;">SekiPOS v1.2</h2>
|
<h2 style="margin:0;">SekiPOS v1.2</h2>
|
||||||
<div style="display: flex; align-items: center; gap: 15px;">
|
<div style="display: flex; align-items: center; gap: 15px;">
|
||||||
<button onclick="toggleTheme()" class="theme-toggle-btn" id="theme-text" style="margin: 0;">Modo Oscuro</button>
|
<button onclick="toggleTheme()" class="theme-toggle-btn" id="theme-text" style="margin: 0;">Modo
|
||||||
|
Oscuro</button>
|
||||||
<span style="color: var(--border);">|</span>
|
<span style="color: var(--border);">|</span>
|
||||||
<span>Usuario: <b>{{ user.username }}</b></span>
|
<span>Usuario: <b>{{ user.username }}</b></span>
|
||||||
<span style="color: var(--border);">|</span>
|
<span style="color: var(--border);">|</span>
|
||||||
@@ -26,8 +27,10 @@
|
|||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div id="new-product-prompt">
|
<div id="new-product-prompt">
|
||||||
<span style="flex-grow: 1;">¡Nuevo! Barcode <b><span id="new-barcode-display"></span></b>. ¿Deseas agregarlo?</span>
|
<span style="flex-grow: 1;">¡Nuevo! Barcode <b><span id="new-barcode-display"></span></b>. ¿Deseas
|
||||||
<button onclick="dismissPrompt()" style="background:rgba(0,0,0,0.2); color:white; margin-left: 15px;">Omitir</button>
|
agregarlo?</span>
|
||||||
|
<button onclick="dismissPrompt()"
|
||||||
|
style="background:rgba(0,0,0,0.2); color:white; margin-left: 15px;">Omitir</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card" id="scan-display">
|
<div class="card" id="scan-display">
|
||||||
@@ -71,9 +74,11 @@
|
|||||||
<td>{{ p[1] }}</td>
|
<td>{{ p[1] }}</td>
|
||||||
<td class="price-cell" data-value="{{ p[2] }}"></td>
|
<td class="price-cell" data-value="{{ p[2] }}"></td>
|
||||||
<td style="white-space: nowrap;">
|
<td style="white-space: nowrap;">
|
||||||
<button class="btn-edit" onclick="editProduct('{{ p[0] }}', '{{ p[1] }}', '{{ p[2] }}', '{{ p[3] }}')">Editar</button>
|
<button class="btn-edit"
|
||||||
|
onclick="editProduct('{{ p[0] }}', '{{ p[1] }}', '{{ p[2] }}', '{{ p[3] }}')">Editar</button>
|
||||||
<form action="/delete/{{ p[0] }}" method="POST" style="display:inline;">
|
<form action="/delete/{{ p[0] }}" method="POST" style="display:inline;">
|
||||||
<button type="submit" class="btn-del" onclick="return confirm('¿Eliminar producto?')">Borrar</button>
|
<button type="submit" class="btn-del"
|
||||||
|
onclick="return confirm('¿Eliminar producto?')">Borrar</button>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -131,6 +136,14 @@
|
|||||||
const prompt = document.getElementById('new-product-prompt');
|
const prompt = document.getElementById('new-product-prompt');
|
||||||
document.getElementById('new-barcode-display').innerText = data.barcode;
|
document.getElementById('new-barcode-display').innerText = data.barcode;
|
||||||
prompt.style.display = 'flex';
|
prompt.style.display = 'flex';
|
||||||
|
|
||||||
|
// FIX: Update the main display card even if it's not in the DB yet
|
||||||
|
document.getElementById('display-name').innerText = data.name || "Producto Nuevo";
|
||||||
|
document.getElementById('display-price').innerText = clpFormatter.format(0);
|
||||||
|
document.getElementById('display-barcode').innerText = data.barcode;
|
||||||
|
document.getElementById('display-img').src = data.image || './static/placeholder.png';
|
||||||
|
|
||||||
|
// Fill the form
|
||||||
document.getElementById('form-barcode').value = data.barcode;
|
document.getElementById('form-barcode').value = data.barcode;
|
||||||
document.getElementById('form-name').value = data.name || '';
|
document.getElementById('form-name').value = data.name || '';
|
||||||
document.getElementById('form-image').value = data.image || '';
|
document.getElementById('form-image').value = data.image || '';
|
||||||
|
|||||||
Reference in New Issue
Block a user