stikkapp / app.py
vagrillo's picture
Update app.py
7e839e7 verified
from flask import Flask, request, jsonify, send_from_directory, render_template_string
import uuid
import os
import base64
from datetime import datetime
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
# Servizio file uploadati
@app.route('/uploads/<filename>')
def serve_uploaded_file(filename):
try:
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
except FileNotFoundError:
return "File not found", 404
@app.route('/')
def home():
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<title>StikkApp</title>
<style>
.option { padding: 15px; margin: 10px; background: #4285f4;
color: white; text-align: center; border-radius: 5px; }
#camera-container { display: none; position: relative; max-width: 100%; }
#camera-preview { width: 100%; transform: scaleX(-1); }
#capture-btn { position: absolute; bottom: 20px; left: 50%;
transform: translateX(-50%); background: red;
width: 60px; height: 60px; border-radius: 50%; }
#file-input { display: none; }
</style>
</head>
<body>
<h1>Scegli origine immagine</h1>
<div class="option" onclick="startCamera()">Fotocamera</div>
<div class="option" onclick="document.getElementById('file-input').click()">Galleria</div>
<div class="option" onclick="pasteFromClipboard()">Clipboard</div>
<div id="camera-container">
<video id="camera-preview" autoplay playsinline></video>
<button id="capture-btn" onclick="capturePhoto()"></button>
</div>
<input type="file" id="file-input" accept="image/*">
<script>
// Gestione fotocamera
let cameraStream;
async function startCamera() {
try {
cameraStream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: 'environment' }
});
document.getElementById('camera-container').style.display = 'block';
document.getElementById('camera-preview').srcObject = cameraStream;
} catch (err) {
alert("Errore fotocamera: " + err.message);
}
}
function capturePhoto() {
const video = document.getElementById('camera-preview');
const canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
const ctx = canvas.getContext('2d');
// Corregge l'orientamento per fotocamera posteriore
ctx.translate(canvas.width, 0);
ctx.scale(-1, 1);
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
// Converti in JPG di qualità
canvas.toBlob(blob => {
const reader = new FileReader();
reader.onload = () => sendImage(reader.result);
reader.readAsDataURL(blob);
}, 'image/jpeg', 0.85);
}
// Gestione galleria
document.getElementById('file-input').addEventListener('change', function(e) {
if (e.target.files[0]) {
const reader = new FileReader();
reader.onload = (event) => sendImage(event.target.result);
reader.readAsDataURL(e.target.files[0]);
}
});
// Gestione clipboard
async function pasteFromClipboard() {
try {
const items = await navigator.clipboard.read();
for (const item of items) {
for (const type of item.types) {
if (type.startsWith('image/')) {
const blob = await item.getType(type);
const reader = new FileReader();
reader.onload = (event) => sendImage(event.target.result);
reader.readAsDataURL(blob);
return;
}
}
}
alert("Nessuna immagine trovata");
} catch (err) {
alert("Errore clipboard: " + err.message);
}
}
// Invio immagine al server
function sendImage(dataUrl) {
fetch('/upload', {
method: 'POST',
body: JSON.stringify({ image: dataUrl }),
headers: { 'Content-Type': 'application/json' }
})
.then(response => {
if (!response.ok) throw new Error('Upload failed');
return response.json();
})
.then(data => {
window.location.href = `/preview?img=${encodeURIComponent(data.image_url)}&t=${Date.now()}`;
})
.catch(error => {
console.error('Upload error:', error);
alert('Errore durante l\'upload');
});
}
</script>
</body>
</html>
''')
@app.route('/upload', methods=['POST'])
def upload_image():
try:
# Estrai i dati base64 dall'URL (rimuovi il prefisso)
image_data = request.json['image'].split(',')[1]
binary_data = base64.b64decode(image_data)
# Genera nome file univoco
unique_id = uuid.uuid4().hex
filename = f"{unique_id}.jpg"
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
# Salva il file
with open(filepath, 'wb') as f:
f.write(binary_data)
return jsonify({
'image_url': f'/uploads/{filename}',
'unique_id': unique_id
})
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/preview')
def preview():
img_url = request.args.get('img', '')
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<title>Anteprima</title>
<style>
img { max-width: 100%; height: auto; }
button { padding: 10px 20px; margin: 10px; font-size: 16px; }
</style>
</head>
<body>
<img src="{{ img_url }}" id="preview-img">
<div>
<button onclick="analyze()">Analizza</button>
<button onclick="window.location.href='/'">Annulla</button>
</div>
<script>
function analyze() {
const img = document.getElementById('preview-img');
const timestamp = new Date().getTime();
window.location.href = `/analyze?img=${encodeURIComponent("{{ img_url }}")}&t=${timestamp}`;
}
</script>
</body>
</html>
''', img_url=img_url)
@app.route('/analyze')
def analyze():
img_url = request.args.get('img', '')
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<title>Analisi</title>
<style>
#container { position: relative; }
#target-img { max-width: 100%; }
#selection-box {
position: absolute;
border: 2px solid red;
display: none;
pointer-events: none;
}
</style>
</head>
<body>
<div id="container">
<img src="{{ img_url }}" id="target-img">
<div id="selection-box"></div>
</div>
<script>
const img = document.getElementById('target-img');
const box = document.getElementById('selection-box');
img.addEventListener('click', (e) => {
const rect = img.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// Mostra il quadrato di selezione
box.style.left = `${x - 25}px`;
box.style.top = `${y - 25}px`;
box.style.width = '50px';
box.style.height = '50px';
box.style.display = 'block';
// Invia le coordinate al server
fetch('/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
img_url: "{{ img_url }}",
x: x,
y: y
})
}).then(response => response.json())
.then(data => {
// Gestisci la risposta qui
console.log(data);
});
});
</script>
</body>
</html>
''', img_url=img_url)
@app.route('/search', methods=['POST'])
def search():
data = request.json
# Qui implementa la logica di ricerca
return jsonify({
'result': 'success',
'data': data
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=True)