diff --git a/alerts.py b/alerts.py index 66dad05..818b7d3 100644 --- a/alerts.py +++ b/alerts.py @@ -262,6 +262,12 @@ def startTGBot(mainThread: bool = False): print( "Telegram bot token or name not set. Notifications via Telegram will not work.") return + + # Check if DEV=true + if os.getenv('DEV', 'false').lower() == 'true': + print("Development mode is enabled. Skipping Telegram bot start.") + return + if TG_bot_running: print("Telegram bot is already running.") diff --git a/server.py b/server.py index 355789d..da574ae 100644 --- a/server.py +++ b/server.py @@ -135,6 +135,89 @@ def logout(): return response +@app.route("/bulk_upload", methods=["POST"]) +def bulk_upload_notifications(): + """ + Bulk upload notifications from a CSV file. + """ + token = request.cookies.get("token") + if not token: + return redirect(f"https://login.hns.au/auth?return={request.host_url}login") + + user_data = requests.get(f"https://login.hns.au/auth/user?token={token}") + if user_data.status_code != 200: + return redirect(f"https://login.hns.au/auth?return={request.host_url}login") + user_data = user_data.json() + + username = user_data.get("username", None) + if not username: + return jsonify({"error": "Invalid user data"}), 400 + + # Check if the request contains a file + if 'file' not in request.files: + return jsonify({"error": "No file part in the request"}), 400 + + file = request.files['file'] + if file.filename == '': + return jsonify({"error": "No selected file"}), 400 + + # Read the CSV file + try: + content = file.read().decode('utf-8') + lines = content.splitlines() + for line in lines: + parts = line.split(',') + if len(parts) < 3: + continue # Skip invalid lines + + domain = parts[0].strip() + blocks = parts[1].strip() + notification_type = parts[2].strip().lower() # Normalize to lowercase + + # Find the notification type + notificationType = None + for notification in NOTIFICATION_TYPES: + if notification['type'] == notification_type: + notificationType = notification + break + else: + return jsonify({"error": f"Invalid notification type: {notification_type}"}), 400 + continue # Skip invalid notification types + + + # Create the notification data + notification_data = { + 'domain': domain, + 'blocks': blocks, + 'type': notification_type, + 'user_name': username, + 'id': os.urandom(16).hex() # Generate a random ID for the notification + } + + arg = 3 + # Add additional fields based on the notification type + for field in notificationType['fields']: + if field['name'] not in notification_data and field.get('required', False): + # Try to read the field from the line + if len(parts) > arg: + field_value = parts[arg].strip() + if field_value: + notification_data[field['name']] = field_value + else: + return jsonify({"error": f"Missing required field: {field['name']}"}), 400 + else: + # Auto fill default values for username + if field['type'] == 'username': + notification_data[field['name']] = username + else: + return jsonify({"error": f"Missing required field: {field['name']}"}), 400 + print(notification_data) + domains.add_notification(domain, notification_data) + + return redirect(f"{request.host_url}account") + except Exception as e: + return jsonify({"error": f"Failed to process file: {str(e)}"}), 500 + @app.route("/notification/", methods=["POST"]) def addNotification(notificationtype: str): """ @@ -252,7 +335,6 @@ def catch_all(path: str): return render_template("404.html"), 404 - # endregion # region API routes diff --git a/templates/account.html b/templates/account.html index 2e41555..657ad18 100644 --- a/templates/account.html +++ b/templates/account.html @@ -126,6 +126,28 @@ {% endfor %} + +
+

Bulk Upload Domains

+

Upload a CSV file with your Handshake domains to set up multiple alerts at once.

+
+
+
+ + + Upload a CSV file with one domain per line. +
+
+ +
+
+
+

Format: Each line should contain a domain name, followed by the type of notification (e.g., "exampledomain, email") & notification parameters

+

Example: exampledomain, email

+

Supported types: email, discord, slack, webhook

+

Download example CSV: Download Example CSV

+
+
diff --git a/templates/assets/css/account.css b/templates/assets/css/account.css index 623613b..9c7143c 100644 --- a/templates/assets/css/account.css +++ b/templates/assets/css/account.css @@ -29,6 +29,8 @@ .alerts-section, .add-alerts-section { margin-bottom: 60px; + max-width: 1000px; + margin: 16px auto; } .alerts-section h2, .add-alerts-section h2 { diff --git a/templates/assets/csv/example.csv b/templates/assets/csv/example.csv new file mode 100644 index 0000000..15d2e2f --- /dev/null +++ b/templates/assets/csv/example.csv @@ -0,0 +1,3 @@ +woodburn,1008,email,example@woodburn.au +woodburn1,1008,discord_webhook,https://discord.com/api/webhooks/123456789012345678/abcdefghijklmnopqrstuvwxyz +woodburn2,1008,telegram \ No newline at end of file