Spaces:
Sleeping
Sleeping
# app.py (With JSON Download Feature) | |
from flask import Flask, render_template, request, redirect, url_for, session, flash, abort, Response | |
from datetime import datetime | |
import copy | |
import json # Import the json library | |
# --- App Configuration --- | |
app = Flask(__name__) | |
app.config['SECRET_KEY'] = 'a-key-for-json-download-demo' | |
# --- In-Memory Data Store --- | |
chirps_data = {} | |
chirp_id_counter = 0 | |
# --- Helper Function to Build the Comment Tree --- | |
def get_chirp_tree(): | |
nodes = copy.deepcopy(chirps_data) | |
for chirp_id in nodes: | |
nodes[chirp_id]['children'] = [] | |
nested_chirps = [] | |
for chirp_id, chirp in nodes.items(): | |
if chirp['parent_id'] is not None: | |
parent = nodes.get(chirp['parent_id']) | |
if parent: | |
parent['children'].append(chirp) | |
else: | |
nested_chirps.append(chirp) | |
for chirp_id in nodes: | |
nodes[chirp_id]['children'].sort(key=lambda x: x['timestamp']) | |
nested_chirps.sort(key=lambda x: x['timestamp'], reverse=True) | |
return nested_chirps | |
# --- Routes --- | |
def index(): | |
if 'username' not in session: | |
return redirect(url_for('join')) | |
if request.method == 'POST': | |
global chirp_id_counter | |
content = request.form.get('content') | |
if content: | |
chirp_id_counter += 1 | |
new_chirp = { | |
'id': chirp_id_counter, 'parent_id': None, 'username': session['username'], | |
'content': content, 'timestamp': datetime.utcnow() | |
} | |
chirps_data[new_chirp['id']] = new_chirp | |
flash('Your new chirp has been posted!', 'success') | |
return redirect(url_for('index')) | |
top_level_posts = get_chirp_tree() | |
return render_template('index.html', posts=top_level_posts) | |
def view_chirp(chirp_id): | |
if 'username' not in session: | |
return redirect(url_for('join')) | |
all_chirps_tree = get_chirp_tree() | |
def find_chirp_in_tree(chirp_id, chirps): | |
for chirp in chirps: | |
if chirp['id'] == chirp_id: return chirp | |
found = find_chirp_in_tree(chirp_id, chirp.get('children', [])) | |
if found: return found | |
return None | |
main_chirp = find_chirp_in_tree(chirp_id, all_chirps_tree) | |
if not main_chirp: | |
abort(404) | |
return render_template('view_chirp.html', main_chirp=main_chirp) | |
def reply(parent_id): | |
if 'username' not in session: | |
return redirect(url_for('join')) | |
global chirp_id_counter | |
content = request.form.get('content') | |
if parent_id not in chirps_data: | |
flash('Cannot reply to a non-existent chirp.', 'danger') | |
return redirect(url_for('index')) | |
if content: | |
chirp_id_counter += 1 | |
new_comment = { | |
'id': chirp_id_counter, 'parent_id': parent_id, 'username': session['username'], | |
'content': content, 'timestamp': datetime.utcnow() | |
} | |
chirps_data[new_comment['id']] = new_comment | |
flash('Your reply was posted!', 'success') | |
else: | |
flash('Reply cannot be empty.', 'danger') | |
return redirect(url_for('view_chirp', chirp_id=parent_id)) | |
# --- NEW DOWNLOAD ROUTE --- | |
def download_data(): | |
"""Filters user's chirps and provides them as a JSON file download.""" | |
if 'username' not in session: | |
flash("You must be logged in to download your data.", "danger") | |
return redirect(url_for('join')) | |
current_username = session['username'] | |
# Filter the chirps_data dictionary to get only the user's posts and comments | |
user_chirps = [ | |
chirp for chirp in chirps_data.values() | |
if chirp['username'] == current_username | |
] | |
# Sort the user's data by time for consistency | |
user_chirps.sort(key=lambda x: x['timestamp']) | |
# Prepare the JSON data. `indent=2` makes it human-readable. | |
# `default=str` is crucial to handle datetime objects, which are not JSON serializable by default. | |
json_data = json.dumps(user_chirps, indent=2, default=str) | |
# Create a dynamic filename | |
filename = f"chirp_data_{current_username}.json" | |
# Create a Flask Response object | |
return Response( | |
json_data, | |
mimetype="application/json", | |
headers={"Content-Disposition": f"attachment;filename={filename}"} | |
) | |
# --- Standard User Routes --- | |
def join(): | |
if 'username' in session: | |
return redirect(url_for('index')) | |
if request.method == 'POST': | |
username = request.form.get('username') | |
if username: | |
session['username'] = username | |
flash(f'Welcome, {username}!', 'success') | |
return redirect(url_for('index')) | |
else: | |
flash('Please enter a name to join.', 'danger') | |
return render_template('join.html') | |
def logout(): | |
session.pop('username', None) | |
flash('You have been logged out.', 'success') | |
return redirect(url_for('join')) | |
if __name__ == '__main__': | |
app.run(debug=True,host="0.0.0.0",port=7860) |