rairo commited on
Commit
58b94ca
·
verified ·
1 Parent(s): 357f4ce

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +103 -3
main.py CHANGED
@@ -57,9 +57,6 @@ except Exception as e:
57
  print(f"Error initializing Firebase: {e}")
58
 
59
 
60
-
61
-
62
-
63
  bucket = storage.bucket()
64
 
65
 
@@ -233,6 +230,49 @@ def upload_log():
233
  logging.error(f"❌ ERROR: Failed to upload log file: {e}")
234
  return None
235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
  # -----------------------
238
  # Content
@@ -1368,7 +1408,67 @@ def admin_list_stories():
1368
  except Exception as e:
1369
  return jsonify({'error': str(e)}), 500
1370
 
 
 
 
 
 
 
 
 
 
 
1371
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1372
  # ---------- Admin Endpoint to Directly Update Credits ----------
1373
  @app.route('/api/admin/users/<string:uid>/credits', methods=['PUT'])
1374
  def admin_update_credits(uid):
 
57
  print(f"Error initializing Firebase: {e}")
58
 
59
 
 
 
 
60
  bucket = storage.bucket()
61
 
62
 
 
230
  logging.error(f"❌ ERROR: Failed to upload log file: {e}")
231
  return None
232
 
233
+ @app.route('/api/feedback', methods=['POST'])
234
+ def submit_feedback():
235
+ """
236
+ Allows a user to submit feedback, bug reports, or feature requests.
237
+ """
238
+ try:
239
+ # --- Authentication ---
240
+ auth_header = request.headers.get('Authorization', '')
241
+ if not auth_header.startswith('Bearer '):
242
+ return jsonify({'error': 'Missing or invalid token'}), 401
243
+ token = auth_header.split(' ')[1]
244
+ uid = verify_token(token)
245
+ if not uid:
246
+ return jsonify({'error': 'Invalid or expired token'}), 401
247
+
248
+ # --- Parse Feedback Data ---
249
+ data = request.get_json()
250
+ feedback_type = data.get('type', 'general') # e.g. "bug", "feature_request", "general"
251
+ message = data.get('message')
252
+ if not message:
253
+ return jsonify({'error': 'message is required'}), 400
254
+
255
+ # Optionally, store some user info like email or name
256
+ user_data = db.reference(f'users/{uid}').get() or {}
257
+ user_email = user_data.get('email', 'unknown')
258
+
259
+ # Create a new feedback entry in "feedback" node
260
+ feedback_id = str(uuid.uuid4())
261
+ feedback_ref = db.reference(f'feedback/{feedback_id}')
262
+ feedback_record = {
263
+ "user_id": uid,
264
+ "user_email": user_email,
265
+ "type": feedback_type,
266
+ "message": message,
267
+ "created_at": datetime.utcnow().isoformat(),
268
+ "status": "open" # admin can mark "resolved" or "in progress"
269
+ }
270
+ feedback_ref.set(feedback_record)
271
+
272
+ return jsonify({"success": True, "feedback_id": feedback_id}), 201
273
+
274
+ except Exception as e:
275
+ return jsonify({'error': str(e)}), 500
276
 
277
  # -----------------------
278
  # Content
 
1408
  except Exception as e:
1409
  return jsonify({'error': str(e)}), 500
1410
 
1411
+ @app.route('/api/admin/notifications', methods=['POST'])
1412
+ def send_notifications():
1413
+ """
1414
+ Admin sends notifications to one, multiple, or all users.
1415
+ """
1416
+ try:
1417
+ # 1) Verify admin
1418
+ admin_uid = verify_admin(request.headers.get('Authorization', ''))
1419
+ if not admin_uid:
1420
+ return jsonify({'error': 'Unauthorized: Admin access required'}), 401
1421
 
1422
+ # 2) Parse request data
1423
+ data = request.get_json()
1424
+ message = data.get('message')
1425
+ if not message:
1426
+ return jsonify({'error': 'message is required'}), 400
1427
+
1428
+ # 'recipients' can be a single user_id, a list of user_ids, or "all"
1429
+ recipients = data.get('recipients', "all")
1430
+
1431
+ # 3) If recipients == "all", get all user IDs
1432
+ all_users_ref = db.reference('users')
1433
+ all_users_data = all_users_ref.get() or {}
1434
+
1435
+ user_ids_to_notify = []
1436
+
1437
+ if recipients == "all":
1438
+ user_ids_to_notify = list(all_users_data.keys())
1439
+ elif isinstance(recipients, list):
1440
+ # Filter out invalid user IDs
1441
+ user_ids_to_notify = [uid for uid in recipients if uid in all_users_data]
1442
+ elif isinstance(recipients, str):
1443
+ # Could be a single user_id if not "all"
1444
+ if recipients in all_users_data:
1445
+ user_ids_to_notify = [recipients]
1446
+ else:
1447
+ return jsonify({'error': 'Invalid single user_id'}), 400
1448
+ else:
1449
+ return jsonify({'error': 'recipients must be "all", a user_id, or a list of user_ids'}), 400
1450
+
1451
+ # 4) Create a "notifications" node for each user
1452
+ # E.g., notifications/{user_id}/{notification_id}
1453
+ now_str = datetime.utcnow().isoformat()
1454
+ for user_id in user_ids_to_notify:
1455
+ notif_id = str(uuid.uuid4())
1456
+ notif_ref = db.reference(f'notifications/{user_id}/{notif_id}')
1457
+ notif_data = {
1458
+ "from_admin": admin_uid,
1459
+ "message": message,
1460
+ "created_at": now_str,
1461
+ "read": False
1462
+ }
1463
+ notif_ref.set(notif_data)
1464
+
1465
+ return jsonify({
1466
+ 'success': True,
1467
+ 'message': f"Notification sent to {len(user_ids_to_notify)} user(s)."
1468
+ }), 200
1469
+
1470
+ except Exception as e:
1471
+ return jsonify({'error': str(e)}), 500
1472
  # ---------- Admin Endpoint to Directly Update Credits ----------
1473
  @app.route('/api/admin/users/<string:uid>/credits', methods=['PUT'])
1474
  def admin_update_credits(uid):