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', []) } 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') if not name: return jsonify({'error': 'Habit name is required'}), 400 habit_id = db.insert({'name': name, 'completed_dates': []}) return jsonify({'id': habit_id, 'name': name, 'completed_dates': []}), 201 @app.route('/habits//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//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/', methods=['PUT']) def update_habit(habit_id): data = request.json name = data.get('name') if not name: return jsonify({'error': 'Habit name is required'}), 400 habit = db.get(doc_id=habit_id) if not habit: return jsonify({'error': 'Habit not found'}), 404 db.update({'name': name}, doc_ids=[habit_id]) return jsonify({'message': f'Habit {habit_id} updated', 'name': name}) @app.route('/habits/', 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)