Initial commit
This commit is contained in:
commit
ae59e020d8
3 changed files with 139 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
__pycache__/
|
||||
secret.py
|
||||
blocked.json
|
81
main.py
Normal file
81
main.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
import json
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import flask
|
||||
import requests
|
||||
|
||||
from secret import token
|
||||
|
||||
REVERSE_PROXY = False # if True: uses X-Real-IP header instead of remote addr
|
||||
BASE_DIR = Path(__file__).parent
|
||||
TIMEOUT = 15 * 60
|
||||
CONTENT_WARNING = "test post ignore" # "Post from a random person - trinkey is not responsible for the content!!"
|
||||
POST_URL = "https://is.trinkey.com/api/iceshrimp/notes"
|
||||
RUN_CONF = {
|
||||
"debug": True,
|
||||
"host": "127.0.0.1",
|
||||
"port": "8000"
|
||||
}
|
||||
|
||||
app = flask.Flask(__file__)
|
||||
|
||||
data: dict[str, int] = {}
|
||||
|
||||
try:
|
||||
data = json.load(open(BASE_DIR / "blocked.json", "r"))
|
||||
except FileNotFoundError:
|
||||
...
|
||||
except json.JSONDecodeError:
|
||||
...
|
||||
|
||||
def save():
|
||||
with open(BASE_DIR / "blocked.json", "w") as f:
|
||||
json.dump(data, f)
|
||||
|
||||
def get_ip() -> str:
|
||||
return (flask.request.headers.get("X-Real-IP") if REVERSE_PROXY else flask.request.remote_addr) or "0.0.0.0"
|
||||
|
||||
app.route("/about/")(lambda: open(BASE_DIR / "public/about.html", "rb").read())
|
||||
|
||||
@app.route("/", methods=["POST", "GET"])
|
||||
def index() -> bytes:
|
||||
ip = get_ip()
|
||||
cant_post = ip in data and data[ip] > time.time()
|
||||
message = ""
|
||||
|
||||
if flask.request.method == "POST":
|
||||
if not cant_post:
|
||||
content = (flask.request.form.get("text") or "").strip()
|
||||
|
||||
if content:
|
||||
resp = requests.post(POST_URL, json={
|
||||
"text": content,
|
||||
"cw": CONTENT_WARNING,
|
||||
"replyId": None,
|
||||
"renoteId": None,
|
||||
"mediaIds": None,
|
||||
"visibility": "home",
|
||||
"idempotencyKey": None
|
||||
}, headers={
|
||||
"Authorization": f"Bearer {token}"
|
||||
})
|
||||
|
||||
if resp.status_code == 200:
|
||||
data[ip] = int(time.time() + TIMEOUT)
|
||||
save()
|
||||
message = "Success!"
|
||||
else:
|
||||
message = f"Got non-200 status code ({resp})"
|
||||
else:
|
||||
message = "Enter some text!"
|
||||
else:
|
||||
message = "You can't post yet!"
|
||||
|
||||
return open(BASE_DIR / "public/index.html", "rb").read() \
|
||||
.replace(b"{{ IP }}", str.encode(ip)) \
|
||||
.replace(b"{{ EXPIRE }}", str.encode(str(data[ip] if cant_post else 0))) \
|
||||
.replace(b"{{ ERROR }}", str.encode(message))
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(**RUN_CONF)
|
55
public/index.html
Normal file
55
public/index.html
Normal file
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>EveryoneBot</title>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta name="pronouns" content="she/her">
|
||||
<meta property="og:type" content="website">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="author" content="EveryoneBot">
|
||||
<meta name="description" content="The fedi bot anyone can post to">
|
||||
<meta property="og:title" content="EveryoneBot">
|
||||
<meta property="og:description" content="The fedi bot anyone can post to">
|
||||
<meta name="twitter:title" content="EveryoneBot">
|
||||
<meta name="twitter:description" content="The fedi bot anyone can post to">
|
||||
|
||||
<style>
|
||||
body { font-family: sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>EveryoneBot</h1>
|
||||
<h3>The fedi bot anyone can post to</h3>
|
||||
<a href="https://git.trinkey.com/trinkey/everyonebot" target="_blank">Source Code</a> - Fedi: <b>@everyonebot@is.trinkey.com</b>
|
||||
<p>{{ ERROR }}</p>
|
||||
<hr>
|
||||
<p>Enter your post below. Anyone can post anything, once every 15 minutes per IP address.</p>
|
||||
<form method="POST" action="/">
|
||||
<div><textarea name="text" id="text" required placeholder="a stupid fedi post"></textarea></div>
|
||||
<div><input type="submit" value="Post!"></div>
|
||||
</form>
|
||||
<small>Moderation enforced at trinkey's discretion. This service can go down temporarily or permanently at any time. All posts are viewable by anyone and cannot be deleted.</small>
|
||||
<p>You can post <span id="until-post">in <i>Please enable JavaScript for this to work!</i></span></p>
|
||||
<p><details>
|
||||
<summary>Your IP address:</summary> {{ IP }}
|
||||
</details></p>
|
||||
|
||||
<script>
|
||||
let expire = +"{{ EXPIRE }}" * 1000;
|
||||
|
||||
function updateTimestamp() {
|
||||
let remaining = Math.floor((expire - Date.now()) / 1000);
|
||||
|
||||
document.getElementById("until-post").innerHTML = remaining <= 0 ? "<b>now!</b>" : (remaining < 60 ? `in <b>${remaining}s</b>` : `in <b>${Math.floor(remaining / 60)}m${remaining % 60}s</b>`);
|
||||
}
|
||||
|
||||
updateTimestamp();
|
||||
|
||||
setInterval(updateTimestamp, 500);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue