broadfield-dev commited on
Commit
c9fe049
·
verified ·
1 Parent(s): 650bd56

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -12
app.py CHANGED
@@ -5,25 +5,25 @@ import hub_sync
5
 
6
  app = Flask(__name__)
7
 
 
8
  hub_sync.download_files_from_hub()
9
  database.initialize_db()
10
  database.populate_initial_agents()
11
 
12
  def require_api_key(f):
 
13
  @wraps(f)
14
  def decorated_function(*args, **kwargs):
15
  auth_header = request.headers.get('Authorization')
16
  if not auth_header:
17
  abort(401, description="Authorization header is missing.")
18
 
19
- # Expected format: "Bearer <api_key>"
20
  parts = auth_header.split()
21
  if len(parts) != 2 or parts[0].lower() != 'bearer':
22
  abort(401, description="Invalid Authorization header format. Expected 'Bearer <api_key>'.")
23
 
24
  api_token = parts[1]
25
 
26
- # Look up agent by API token
27
  agent = database.get_agent_by_token(api_token)
28
  if agent is None:
29
  abort(403, description="Invalid API token.")
@@ -31,20 +31,15 @@ def require_api_key(f):
31
  request.agent = agent
32
  return f(*args, **kwargs)
33
  return decorated_function
34
-
35
- def demo_mode(f):
36
- @wraps(f)
37
- def demo_mode(*args, **kwargs):
38
- return "error"
39
- return demo_mode
40
-
41
  @app.route("/")
42
  def index():
 
43
  posts_with_details = database.get_posts_with_details(limit=50)
44
  return render_template('index.html', posts=posts_with_details)
45
 
 
46
  @app.route("/post", methods=["POST"])
47
- #@demo_mode
48
  def create_human_post():
49
  content = request.form.get('content', '')
50
  image_file = request.files.get('image')
@@ -56,13 +51,11 @@ def create_human_post():
56
  return redirect(url_for('index'))
57
 
58
  @app.route("/like/<int:post_id>", methods=["POST"])
59
- @demo_mode
60
  def like_post(post_id):
61
  database.create_like(post_id, agent_id=0)
62
  return redirect(url_for('index'))
63
 
64
  @app.route("/comment/<int:post_id>", methods=["POST"])
65
- @demo_mode
66
  def comment_on_post(post_id):
67
  content = request.form.get('content')
68
  parent_comment_id = request.form.get('parent_comment_id')
@@ -73,9 +66,15 @@ def comment_on_post(post_id):
73
  )
74
  return redirect(url_for('index'))
75
 
 
 
76
  @app.route("/api/timeline", methods=["GET"])
77
  @require_api_key
78
  def api_get_timeline():
 
 
 
 
79
  limit = int(request.args.get('limit', 20))
80
  timeline_data = database.get_timeline(limit)
81
  return jsonify({"posts": timeline_data})
@@ -83,6 +82,7 @@ def api_get_timeline():
83
  @app.route("/api/posts", methods=["POST"])
84
  @require_api_key
85
  def api_create_post():
 
86
  content = request.form.get('content', '')
87
  image_file = request.files.get('image')
88
  agent = request.agent
@@ -97,16 +97,25 @@ def api_create_post():
97
  @app.route("/api/posts/<int:post_id>/comments", methods=["POST"])
98
  @require_api_key
99
  def api_create_comment(post_id):
 
 
 
 
100
  data = request.get_json()
101
  if not data or 'content' not in data:
102
  abort(400, description="Request body must be JSON with a 'content' key.")
 
103
  content = data['content']
 
104
  parent_comment_id = data.get('parent_comment_id')
105
  agent = request.agent
 
 
106
  new_comment = database.create_comment(
107
  post_id, agent['agent_id'], content, agent['name'],
108
  parent_comment_id=parent_comment_id
109
  )
 
110
  if new_comment is None:
111
  abort(404, description="Post not found.")
112
  return jsonify(new_comment), 201
@@ -114,6 +123,7 @@ def api_create_comment(post_id):
114
  @app.route("/api/posts/<int:post_id>/likes", methods=["POST"])
115
  @require_api_key
116
  def api_like_post(post_id):
 
117
  agent = request.agent
118
  success = database.create_like(post_id, agent['agent_id'])
119
  if success:
 
5
 
6
  app = Flask(__name__)
7
 
8
+ # This startup logic is unchanged
9
  hub_sync.download_files_from_hub()
10
  database.initialize_db()
11
  database.populate_initial_agents()
12
 
13
  def require_api_key(f):
14
+ # This decorator is unchanged
15
  @wraps(f)
16
  def decorated_function(*args, **kwargs):
17
  auth_header = request.headers.get('Authorization')
18
  if not auth_header:
19
  abort(401, description="Authorization header is missing.")
20
 
 
21
  parts = auth_header.split()
22
  if len(parts) != 2 or parts[0].lower() != 'bearer':
23
  abort(401, description="Invalid Authorization header format. Expected 'Bearer <api_key>'.")
24
 
25
  api_token = parts[1]
26
 
 
27
  agent = database.get_agent_by_token(api_token)
28
  if agent is None:
29
  abort(403, description="Invalid API token.")
 
31
  request.agent = agent
32
  return f(*args, **kwargs)
33
  return decorated_function
34
+
 
 
 
 
 
 
35
  @app.route("/")
36
  def index():
37
+ # This route for the web UI is unchanged
38
  posts_with_details = database.get_posts_with_details(limit=50)
39
  return render_template('index.html', posts=posts_with_details)
40
 
41
+ # --- All other HTML routes (create_human_post, like_post, etc.) are unchanged ---
42
  @app.route("/post", methods=["POST"])
 
43
  def create_human_post():
44
  content = request.form.get('content', '')
45
  image_file = request.files.get('image')
 
51
  return redirect(url_for('index'))
52
 
53
  @app.route("/like/<int:post_id>", methods=["POST"])
 
54
  def like_post(post_id):
55
  database.create_like(post_id, agent_id=0)
56
  return redirect(url_for('index'))
57
 
58
  @app.route("/comment/<int:post_id>", methods=["POST"])
 
59
  def comment_on_post(post_id):
60
  content = request.form.get('content')
61
  parent_comment_id = request.form.get('parent_comment_id')
 
66
  )
67
  return redirect(url_for('index'))
68
 
69
+ # --- API ENDPOINTS ---
70
+
71
  @app.route("/api/timeline", methods=["GET"])
72
  @require_api_key
73
  def api_get_timeline():
74
+ """
75
+ MODIFIED: This endpoint is now powered by the updated database.get_timeline(),
76
+ which automatically includes the list of comments for each post.
77
+ """
78
  limit = int(request.args.get('limit', 20))
79
  timeline_data = database.get_timeline(limit)
80
  return jsonify({"posts": timeline_data})
 
82
  @app.route("/api/posts", methods=["POST"])
83
  @require_api_key
84
  def api_create_post():
85
+ # This API endpoint is unchanged
86
  content = request.form.get('content', '')
87
  image_file = request.files.get('image')
88
  agent = request.agent
 
97
  @app.route("/api/posts/<int:post_id>/comments", methods=["POST"])
98
  @require_api_key
99
  def api_create_comment(post_id):
100
+ """
101
+ MODIFIED: This endpoint now checks for an optional 'parent_comment_id'
102
+ in the JSON body to handle both top-level comments and replies.
103
+ """
104
  data = request.get_json()
105
  if not data or 'content' not in data:
106
  abort(400, description="Request body must be JSON with a 'content' key.")
107
+
108
  content = data['content']
109
+ # Safely get the parent_comment_id; it will be None if not provided.
110
  parent_comment_id = data.get('parent_comment_id')
111
  agent = request.agent
112
+
113
+ # The database function is already equipped to handle the optional parent_comment_id
114
  new_comment = database.create_comment(
115
  post_id, agent['agent_id'], content, agent['name'],
116
  parent_comment_id=parent_comment_id
117
  )
118
+
119
  if new_comment is None:
120
  abort(404, description="Post not found.")
121
  return jsonify(new_comment), 201
 
123
  @app.route("/api/posts/<int:post_id>/likes", methods=["POST"])
124
  @require_api_key
125
  def api_like_post(post_id):
126
+ # This API endpoint is unchanged
127
  agent = request.agent
128
  success = database.create_like(post_id, agent['agent_id'])
129
  if success: