more api stuff
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
.env
|
||||
MOBILE_APP_SPEC.md
|
||||
|
||||
65
app.py
65
app.py
@@ -1060,6 +1060,43 @@ def api_task_detail(user_id, task_id):
|
||||
|
||||
# --- Logbook Detail / Edit API ---
|
||||
|
||||
@app.route('/api/logbook', methods=['GET'])
|
||||
@token_required
|
||||
def api_logbook_list(user_id):
|
||||
# Fetch last 100 entries
|
||||
entries = list(db.time_entries.find({'user_id': user_id}).sort('start_time', -1).limit(100))
|
||||
|
||||
result = []
|
||||
# Cache activities to avoid N+1 queries
|
||||
activities = {a['_id']: a for a in db.activities.find({'user_id': user_id})}
|
||||
|
||||
for entry in entries:
|
||||
act = activities.get(entry.get('activity_id'))
|
||||
|
||||
# Calculate duration string
|
||||
duration_str = "Running"
|
||||
total_seconds = 0
|
||||
if entry.get('end_time') and entry.get('start_time'):
|
||||
diff = entry['end_time'] - entry['start_time']
|
||||
total_seconds = diff.total_seconds()
|
||||
hours = int(total_seconds // 3600)
|
||||
mins = int((total_seconds % 3600) // 60)
|
||||
duration_str = f"{hours:02}:{mins:02}"
|
||||
|
||||
result.append({
|
||||
'id': str(entry['_id']),
|
||||
'activity_name': act['name'] if act else 'Unknown',
|
||||
'activity_color': act.get('color', '#ccc') if act else '#ccc',
|
||||
'start_time': entry['start_time'].isoformat(),
|
||||
'end_time': entry['end_time'].isoformat() if entry.get('end_time') else None,
|
||||
'duration_str': duration_str,
|
||||
'duration_seconds': total_seconds,
|
||||
'note': entry.get('note', ''),
|
||||
'subcategory': entry.get('subcategory', '')
|
||||
})
|
||||
|
||||
return jsonify(result)
|
||||
|
||||
@app.route('/api/logbook/<entry_id>', methods=['GET', 'PUT', 'DELETE'])
|
||||
@token_required
|
||||
def api_log_entry(user_id, entry_id):
|
||||
@@ -1170,11 +1207,31 @@ def api_goals(user_id):
|
||||
})
|
||||
return jsonify({'status': 'created'})
|
||||
|
||||
@app.route('/api/goals/<goal_id>', methods=['DELETE'])
|
||||
@app.route('/api/goals/<goal_id>', methods=['PUT', 'DELETE'])
|
||||
@token_required
|
||||
def api_goal_delete(user_id, goal_id):
|
||||
db.goals.delete_one({'_id': ObjectId(goal_id), 'user_id': user_id})
|
||||
return jsonify({'status': 'deleted'})
|
||||
def api_manage_goal(user_id, goal_id):
|
||||
if request.method == 'DELETE':
|
||||
db.goals.delete_one({'_id': ObjectId(goal_id), 'user_id': user_id})
|
||||
return jsonify({'status': 'deleted'})
|
||||
|
||||
if request.method == 'PUT':
|
||||
data = request.get_json()
|
||||
update_fields = {}
|
||||
|
||||
if 'name' in data: update_fields['name'] = data['name']
|
||||
if 'target_hours' in data: update_fields['target_hours'] = float(data['target_hours'])
|
||||
if 'frequency' in data: update_fields['frequency'] = data['frequency']
|
||||
if 'activity_id' in data: update_fields['activity_id'] = ObjectId(data['activity_id'])
|
||||
if 'subcategory' in data: update_fields['subcategory'] = data['subcategory']
|
||||
|
||||
result = db.goals.update_one(
|
||||
{'_id': ObjectId(goal_id), 'user_id': user_id},
|
||||
{'$set': update_fields}
|
||||
)
|
||||
if result.matched_count == 0:
|
||||
return jsonify({'message': 'Goal not found'}), 404
|
||||
|
||||
return jsonify({'status': 'updated'})
|
||||
|
||||
debug = os.getenv('DEBUG') == 'False'
|
||||
host = os.getenv('HOST')
|
||||
|
||||
Reference in New Issue
Block a user