Files
HabitTracker/app.py
2025-07-16 22:57:28 +02:00

119 lines
4.0 KiB
Python

from flask import Flask, render_template, request, jsonify
from tinydb import TinyDB, Query
from datetime import datetime, timedelta
app = Flask(__name__)
db = TinyDB('habits.json')
Habit = Query()
# Helper function to get the current date string
def get_current_date():
return datetime.now().strftime('%Y-%m-%d')
# Helper function to get a list of dates for the last 30 days
def get_last_30_days():
dates = []
for i in range(30):
date = datetime.now() - timedelta(days=i)
dates.append(date.strftime('%Y-%m-%d'))
return dates[::-1] # Reverse to have oldest first
@app.route('/')
def index():
return render_template('index.html')
@app.route('/habits', methods=['GET'])
def get_habits():
raw_habits = db.all()
formatted_habits = []
last_30_days = get_last_30_days()
for habit_doc in raw_habits:
current_habit_data = {
'id': habit_doc.doc_id,
'name': habit_doc.get('name'),
'completed_dates': habit_doc.get('completed_dates', []),
'color': habit_doc.get('color', '#4CAF50')
}
completion_history = {}
for date_str in last_30_days:
completion_history[date_str] = date_str in current_habit_data['completed_dates']
current_habit_data['completion_history'] = completion_history
formatted_habits.append(current_habit_data)
return jsonify(formatted_habits)
@app.route('/habits', methods=['POST'])
def add_habit():
data = request.json
name = data.get('name')
color = data.get('color', '#4CAF50') # Default green color
if not name:
return jsonify({'error': 'Habit name is required'}), 400
habit_id = db.insert({'name': name, 'completed_dates': [], 'color': color})
return jsonify({'id': habit_id, 'name': name, 'completed_dates': [], 'color': color}), 201
@app.route('/habits/<int:habit_id>/complete', methods=['POST'])
def complete_habit(habit_id):
date_to_complete = request.json.get('date', get_current_date())
habit = db.get(doc_id=habit_id)
if not habit:
return jsonify({'error': 'Habit not found'}), 404
if date_to_complete not in habit['completed_dates']:
habit['completed_dates'].append(date_to_complete)
db.update({'completed_dates': habit['completed_dates']}, doc_ids=[habit_id])
return jsonify({'message': f'Habit {habit_id} marked as completed for {date_to_complete}', 'completed_dates': habit['completed_dates']})
@app.route('/habits/<int:habit_id>/uncomplete', methods=['POST'])
def uncomplete_habit(habit_id):
date_to_uncomplete = request.json.get('date', get_current_date())
habit = db.get(doc_id=habit_id)
if not habit:
return jsonify({'error': 'Habit not found'}), 404
if date_to_uncomplete in habit['completed_dates']:
habit['completed_dates'].remove(date_to_uncomplete)
db.update({'completed_dates': habit['completed_dates']}, doc_ids=[habit_id])
return jsonify({'message': f'Habit {habit_id} marked as uncompleted for {date_to_uncomplete}', 'completed_dates': habit['completed_dates']})
@app.route('/habits/<int:habit_id>', methods=['PUT'])
def update_habit(habit_id):
data = request.json
name = data.get('name')
color = data.get('color')
if not name and not color:
return jsonify({'error': 'Habit name or color is required'}), 400
habit = db.get(doc_id=habit_id)
if not habit:
return jsonify({'error': 'Habit not found'}), 404
update_data = {}
if name:
update_data['name'] = name
if color:
update_data['color'] = color
db.update(update_data, doc_ids=[habit_id])
return jsonify({'message': f'Habit {habit_id} updated', **update_data})
@app.route('/habits/<int:habit_id>', methods=['DELETE'])
def delete_habit(habit_id):
habit = db.get(doc_id=habit_id)
if not habit:
return jsonify({'error': 'Habit not found'}), 404
db.remove(doc_ids=[habit_id])
return jsonify({'message': f'Habit {habit_id} deleted'})
if __name__ == '__main__':
app.run(debug=True)