Implement a number of small fixes
This commit is contained in:
@@ -1,18 +1,15 @@
|
|||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from urllib import request as urlrequest
|
|
||||||
from urllib.error import URLError, HTTPError
|
from urllib.error import URLError, HTTPError
|
||||||
import requests
|
|
||||||
|
|
||||||
from flask import Flask, render_template, jsonify, request
|
import requests
|
||||||
from flask.cli import load_dotenv
|
from flask import Flask, render_template, jsonify, request, Blueprint
|
||||||
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1)
|
||||||
app.config["MAX_CONTENT_LENGTH"] = 16 * 1024
|
app.config["MAX_CONTENT_LENGTH"] = 16 * 1024
|
||||||
|
|
||||||
load_dotenv()
|
|
||||||
DISCORD_WEBHOOK_URL = os.getenv("DISCORD_WEBHOOK_URL")
|
DISCORD_WEBHOOK_URL = os.getenv("DISCORD_WEBHOOK_URL")
|
||||||
|
|
||||||
COOLDOWN_SECONDS = 60 * 60
|
COOLDOWN_SECONDS = 60 * 60
|
||||||
@@ -30,6 +27,8 @@ PROHIBITED_WORDS = {
|
|||||||
'git', 'shag', 'minge', 'nonce', 'plonker', 'pillock'
|
'git', 'shag', 'minge', 'nonce', 'plonker', 'pillock'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
api = Blueprint("api", __name__, url_prefix="/api")
|
||||||
|
|
||||||
|
|
||||||
def _get_client_ip() -> str:
|
def _get_client_ip() -> str:
|
||||||
xff = request.headers.get("X-Forwarded-For", "").split(",")[0].strip()
|
xff = request.headers.get("X-Forwarded-For", "").split(",")[0].strip()
|
||||||
@@ -47,17 +46,19 @@ def _post_to_discord(payload: dict) -> None:
|
|||||||
url = DISCORD_WEBHOOK_URL.strip()
|
url = DISCORD_WEBHOOK_URL.strip()
|
||||||
if "?" not in url:
|
if "?" not in url:
|
||||||
url += "?wait=true"
|
url += "?wait=true"
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"User-Agent": "TRLStatsFeedback/1.0 (contact: fretux@fretux.ch)",
|
"User-Agent": "TRLStatsFeedback/1.0 (contact: fretux@fretux.ch)",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Accept": "application/json",
|
"Accept": "application/json",
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = requests.post(url, json=payload, headers=headers, timeout=10)
|
resp = requests.post(url, json=payload, headers=headers, timeout=10)
|
||||||
if resp.status_code not in (200, 204):
|
if resp.status_code not in (200, 204):
|
||||||
raise RuntimeError(f"Discord returned {resp.status_code}: {resp.text[:500]}")
|
raise RuntimeError(f"Discord returned {resp.status_code}: {resp.text[:500]}")
|
||||||
|
|
||||||
|
|
||||||
@app.post("/api/feedback")
|
@api.post("/feedback")
|
||||||
def api_feedback():
|
def api_feedback():
|
||||||
ip = _get_client_ip()
|
ip = _get_client_ip()
|
||||||
now = time.time()
|
now = time.time()
|
||||||
@@ -76,7 +77,6 @@ def api_feedback():
|
|||||||
rating = data.get("rating")
|
rating = data.get("rating")
|
||||||
comment = (data.get("comment") or "").strip()
|
comment = (data.get("comment") or "").strip()
|
||||||
|
|
||||||
# Normalize and validate
|
|
||||||
if len(name) > 32:
|
if len(name) > 32:
|
||||||
name = name[:32]
|
name = name[:32]
|
||||||
|
|
||||||
@@ -97,10 +97,7 @@ def api_feedback():
|
|||||||
content = f"**Rating:** {rating_int}\n**Comment:**\n{comment}"
|
content = f"**Rating:** {rating_int}\n**Comment:**\n{comment}"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_post_to_discord({
|
_post_to_discord({"username": name, "content": content})
|
||||||
"username": name,
|
|
||||||
"content": content
|
|
||||||
})
|
|
||||||
except (HTTPError, URLError, RuntimeError) as e:
|
except (HTTPError, URLError, RuntimeError) as e:
|
||||||
return jsonify({"ok": False, "error": f"Failed to forward feedback: {str(e)}"}), 502
|
return jsonify({"ok": False, "error": f"Failed to forward feedback: {str(e)}"}), 502
|
||||||
|
|
||||||
@@ -108,24 +105,27 @@ def api_feedback():
|
|||||||
return jsonify({"ok": True}), 200
|
return jsonify({"ok": True}), 200
|
||||||
|
|
||||||
|
|
||||||
@app.route('/')
|
app.register_blueprint(api)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
return render_template('index.html')
|
return render_template("index.html")
|
||||||
|
|
||||||
|
|
||||||
@app.route('/calculator')
|
@app.route("/calculator")
|
||||||
def calculator():
|
def calculator():
|
||||||
return render_template('calculator.html')
|
return render_template("calculator.html")
|
||||||
|
|
||||||
|
|
||||||
@app.route('/about_us')
|
@app.route("/about_us")
|
||||||
def about_us():
|
def about_us():
|
||||||
return render_template('about_us.html')
|
return render_template("about_us.html")
|
||||||
|
|
||||||
|
|
||||||
@app.route('/suggestion')
|
@app.route("/suggestion")
|
||||||
def suggestion():
|
def suggestion():
|
||||||
return render_template('suggestion.html')
|
return render_template("suggestion.html")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
Binary file not shown.
+1
-1
@@ -27,7 +27,7 @@ input[type="text"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-image: url("/static/img/trlbg1.jpg");
|
background-image: url("/trlstats/static/img/trlbg1.jpg");
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ async function sendMessage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch("/api/feedback", {
|
const res = await fetch("/trlstats/api/feedback", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {"Content-Type": "application/json"},
|
headers: {"Content-Type": "application/json"},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<div class="nav-menu" id="nav-menu">
|
<div class="nav-menu" id="nav-menu">
|
||||||
<a href="{{ url_for('calculator') }}">DPS/DPM CALCULATOR</a>
|
<a href="{{ url_for('calculator') }}">DPS/DPM CALCULATOR</a>
|
||||||
<a href="{{ url_for('about_us') }}">ABOUT US</a>
|
<a href="{{ url_for('index') }}">GUN STATS</a>
|
||||||
<a href="{{ url_for('suggestion') }}">SUGGESTIONS & FEEDBACK</a>
|
<a href="{{ url_for('suggestion') }}">SUGGESTIONS & FEEDBACK</a>
|
||||||
<a href="https://www.roblox.com/games/5766084948/SCP-The-Red-Lake-EVENT">PLAY THE RED LAKE</a>
|
<a href="https://www.roblox.com/games/5766084948/SCP-The-Red-Lake-EVENT">PLAY THE RED LAKE</a>
|
||||||
<a href="https://discord.gg/2jDevH8aTd">OUR DISCORD</a>
|
<a href="https://discord.gg/2jDevH8aTd">OUR DISCORD</a>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="icon" type="image/x-icon" href="/static/img/TRL_Logo_Custom.jpg">
|
<link rel="icon" type="image/x-icon" href="/trlstats/static/img/TRL_Logo_Custom.jpg">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||||
<title>Suggestion</title>
|
<title>Suggestion</title>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
Reference in New Issue
Block a user