forked from CarlosMelicandia/EchoNote
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
167 lines (140 loc) · 5.47 KB
/
app.py
File metadata and controls
167 lines (140 loc) · 5.47 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import os
from google.cloud import speech
from google.auth.exceptions import DefaultCredentialsError
from werkzeug.utils import secure_filename
from flask import Flask, render_template, request, jsonify
from database import db, create_task, get_all_tasks, update_task, delete_task
from genai_parser import TaskParser
task_parser = TaskParser()
app = Flask(__name__)
#"sqlite:///./echo_note.db"
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///echo_note.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['UPLOAD_FOLDER'] = os.path.join(os.getcwd(), 'uploads')
db.init_app(app)
# Dummy speech client class for testing
class DummySpeechClient:
"""adding so tests can import app.py without crashing"""
def recognize(self, config, audio):
# stub - tests will override this
raise NotImplementedError("This should be monkey patched in tests")
#protect app from calling dummy stub when we aren't testing
if os.getenv("FLASK_ENV") == "testing":
speech_client = DummySpeechClient()
else:
# Initializing google speech client
speech_client = speech.SpeechClient()
#verify which client
print("speech_client is", type(speech_client).__name__)
# Define nav links to be used across routes
def get_nav_links():
return [
{'href': '/', 'text': 'Home', 'endpoint': 'index'},
{'href': '/draw', 'text': 'Draw', 'endpoint': 'draw'},
{'href': '/appearance', 'text': 'Appearance', 'endpoint': 'appearance'}
]
#updated to use Task model not Note model
@app.route('/', methods=['GET'])
def index():
tasks = get_all_tasks()
return render_template('index.html', tasks=tasks, nav_links=get_nav_links())
@app.route('/draw', methods=['GET'])
def draw():
return render_template('draw.html', nav_links=get_nav_links())
# Audio upload route
@app.route('/api/upload', methods=['POST'])
def upload_audio():
f = request.files.get('audio')
if not f:
return {"error": "no file"}, 400
# sanitizing filename (used werkzeug helper)
filename = secure_filename(f.filename)
upload_folder = app.config['UPLOAD_FOLDER']
# make sure the folder exists
os.makedirs(upload_folder, exist_ok=True)
# do we want to save audio to disk? if not we dont need next two lines
save_path = os.path.join(upload_folder, filename)
f.save(save_path)
return {"filename": filename}, 200
# Audio transcribe route
@app.route('/api/transcribe', methods=['POST'])
def transcribe_audio():
try:
if 'audio' not in request.files:
return jsonify(error='no file'), 400
audio_bytes = request.files['audio'].read()
audio = speech.RecognitionAudio(content=audio_bytes)
config = speech.RecognitionConfig(
language_code="en-US",
)
resp = speech_client.recognize(config=config, audio=audio)
transcript = " ".join(r.alternatives[0].transcript for r in resp.results)
return jsonify(transcript=transcript), 200
except NotImplementedError as e:
return jsonify(error=str(e)), 501
except Exception as e:
return jsonify(error="Transcription failed"), 500
# List tasks route
@app.route('/api/tasks', methods=['GET'])
def list_tasks():
tasks = get_all_tasks()
return jsonify([{
"id": t.id,
"name": t.name,
"completed": t.completed
} for t in tasks])
# process tasks route
@app.route('/api/save_task', methods=['POST'])
def save_task():
try:
data = request.get_json()
print("Received JSON:", data)
if not data or "transcript" not in data:
print("No transcript provided")
return jsonify(error='Transcript is required'), 400
transcript = data["transcript"]
parsed_tasks = task_parser.parse_transcript(transcript)
if not isinstance(parsed_tasks, list):
return jsonify(error="Failed to parse tasks"), 500
count = 0
for task_data in parsed_tasks:
task_text = task_data.get("text")
due_date = task_data.get("due")
print(f"Trying to save task: {task_text} (Due: {due_date})")
if task_text:
create_task(task_text, due_date)
count += 1
print(f"Saved {count} tasks to database")
return jsonify(message=f'{count} tasks saved'), 200
except NotImplementedError as e:
return jsonify(error=str(e)), 501
except Exception as e:
return jsonify(error="Save task failed"), 500
@app.route('/appearance', methods=['GET'])
def appearance():
return render_template('appearance.html', nav_links=get_nav_links())
# Update task route
@app.route('/api/tasks/<int:task_id>', methods=['PUT'])
def update_task_route(task_id):
data = request.get_json()
if not data:
return jsonify(error='No data provided'), 400
name = data.get('name')
completed = data.get('completed')
updated_task = update_task(task_id, name, completed)
if updated_task:
return jsonify(message='Task updated successfully'), 200
else:
return jsonify(error='Task not found'), 404
# Delete task route
@app.route('/api/tasks/<int:task_id>', methods=['DELETE'])
def delete_task_route(task_id):
success = delete_task(task_id)
if success:
return jsonify(message='Task deleted successfully'), 200
else:
return jsonify(error='Task not found'), 404
if __name__ == '__main__':
with app.app_context():
db.create_all()#initialize the tasks database
app.run(debug=True)