-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
105 lines (86 loc) · 3.49 KB
/
app.py
File metadata and controls
105 lines (86 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import os
import json
import uuid
import serial
import time
from flask import Flask, request, jsonify
from werkzeug.utils import secure_filename
from dotenv import load_dotenv
from modules.recoommender import recommend_fashion
from modules.weather_fetcher import prepare_arduino_weather_json
# Load environment variables
load_dotenv()
# ─── Configuration ──────────────────────────────────────────────────────────
UPLOAD_FOLDER = 'uploads'
PDF_PATH = 'fashion_style_guide.pdf'
ALLOWED_EXTENSIONS = {'jpg', 'jpeg', 'png'}
BLUETOOTH_PORT = os.getenv('BLUETOOTH_PORT', 'COM6')
BLUETOOTH_BAUD = int(os.getenv('BLUETOOTH_BAUD', '9600'))
# Ensure upload directory exists
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
"""Check if the uploaded file is an allowed image type."""
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def send_via_bluetooth(payload: dict):
"""Send the JSON payload over Bluetooth serial to the Arduino."""
try:
ser = serial.Serial(BLUETOOTH_PORT, BLUETOOTH_BAUD, timeout=2)
time.sleep(2) # give Arduino time to reset and initialize
ser.write((json.dumps(payload, ensure_ascii=False) + '\n').encode('utf-8'))
ser.close()
except Exception as e:
app.logger.error(f"Bluetooth send failed: {e}")
@app.route('/upload', methods=['GET', 'POST'])
def upload_page():
if request.method == 'POST':
# 1) Save the uploaded image
file = request.files.get('image')
if not file or file.filename == '' or not allowed_file(file.filename):
return "Invalid file", 400
task_id = uuid.uuid4().hex
filename = secure_filename(file.filename)
path = os.path.join(app.config['UPLOAD_FOLDER'], f"{task_id}_{filename}")
file.save(path)
# 2) Run fashion recommendation and clean up Markdown fences
rec = recommend_fashion(path, PDF_PATH)
if isinstance(rec, str):
s = rec.strip()
if s.startswith('```'):
lines = s.splitlines()
if lines and lines[0].startswith('```'):
lines.pop(0)
if lines and lines[-1].startswith('```'):
lines.pop(-1)
s = '\n'.join(lines)
try:
rec = json.loads(s)
except json.JSONDecodeError:
rec = {'error': s}
# 3) Run weather JSON generator
w_out = prepare_arduino_weather_json()
if isinstance(w_out, str):
try:
weather = json.loads(w_out)
except json.JSONDecodeError:
weather = {}
else:
weather = w_out
# 4) Build payload: message or reason, color as top/bottom, weather with min/max temps
payload = {
'is_good': rec.get('is_good')
}
# 5) Send to Arduino via Bluetooth
send_via_bluetooth(payload)
return jsonify({'status': 'sent', 'payload': payload})
# GET: show upload form
return '''
<h2>Fashion Upload & Push to Arduino</h2>
<form method="post" enctype="multipart/form-data">
<input type="file" name="image">
<button type="submit">Upload & Send</button>
</form>
'''
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5001, debug=True)