kinda working??? cant pass a string through curl:(

This commit is contained in:
Jack Eilles 2023-12-14 11:39:23 +00:00
parent ff9fb826e8
commit e582c74363
9 changed files with 289 additions and 0 deletions

1
.flaskenv Normal file
View file

@ -0,0 +1 @@
FLASK_APP=main.py

5
.gitignore vendored
View file

@ -6,6 +6,8 @@ __pycache__/
# C extensions
*.so
.vscode/
# Distribution / packaging
.Python
build/
@ -158,3 +160,6 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# xygt Files
data/

View file

@ -2,6 +2,11 @@
This repository hosts all of the code for the file hosting site 'xygt.cc'.
## About
xygt.cc is a simple, anonymous, temporary file-hosting service, designed with Python and Flask.
This uses MongoDB by default for the file index, user database, and the URL shortening DB, I'm **not** adding support for SQL.
## Website
You can access the site on [https://xygt.cc](https://xygt.cc).

5
app/__init__.py Normal file
View file

@ -0,0 +1,5 @@
from flask import Flask
app = Flask(__name__)
from app import routes

82
app/routes.py Normal file
View file

@ -0,0 +1,82 @@
from app import app, worker
from config import Config, Errors
from flask import render_template, request, send_file
import os
import io
import random
import magic
@app.route('/', methods=["GET", "POST"])
def index():
# Check for a GET or POST request
if request.method == "GET":
return render_template('index.html')
elif request.method == "POST":
# Before anything else, we want to take the IP if the logging is enabled
if Config.ipLogEnabled == True:
ip = request.remote_addr
else:
# If not then return a 0
ip = 0
# Init variables before they're passed
userid = request.form.get("userid") if request.form.get("userid") else None
filename = request.form.get("filename") if request.form.get("filename") else None
retention = request.form.get("retention") if request.form.get("retention") else None
id = request.form.get("filename") if Config.files.find_one({"id": filename}) is None else None
# We got a file or a url?
if 'file' in request.files:
# Grab the file and store it, this is a FileStorage object
file = request.files['file']
# Call the function to upload the file, this will return either HTTP Status codes or a 200 with a URL.
result, status = worker.uploadFile(file, ip, userid, filename, id, retention)
result = "https://xygt.cc/{}".format(result)
return result, status
elif 'url' in request.form:
result, status = worker.shortURL(url, ip, userid, id, retention)
@app.route('/<id>')
def getData(id):
# Does it exist in the files DB?
if Config.files.find_one({"id": id}) is not None:
data = Config.files.find_one({"id": id})
with open(os.path.join(Config.fileDir, id), "rb") as f:
file = f.read()
# Get MIME type from file, if fails then use magic
try:
mimetype = data["mimetype"]
except KeyError:
mimetype = magic.from_buffer(file, mime=True)
# Return the file with the correct MIME type
return send_file(io.BytesIO(file), mimetype=mimetype)
# If not then check the URL Shortening DB
elif Config.url.find_one({"id": id}) is not None:
data = Config.url.find_one({"id": id})
return redirect(data["url"])
else:
return random.choice(Errors.file404)
@app.route('/<id>/info')
def getInfo(id):
return worker.idInfo(id)
@app.route('/teapot')
def teapot():
return 'I\'m a teapot. 418.', 418

1
app/templates/index.html Normal file
View file

@ -0,0 +1 @@
Under Construction - No frontend available yet.

111
app/worker.py Normal file
View file

@ -0,0 +1,111 @@
from config import disallowedMimeTypes, Errors, Config
import secrets
import magic
import datetime
import random
import time
import os
def uploadFile(file, ip, userid, filename, id, retention):
# Is the MIME and file size good?
if file.content_type not in disallowedMimeTypes:
if file.content_length <= Config.maxFileSize:
# We're going to check whether the id variable has been filled
while True: # Loop to find an available file ID
id = randomHex() # Prevent conflicts if 2 of the same get made
if Config.files.find_one({'id': id}) is None:
filename = id
break
if userid == None:
userid = 0
elif Config.users.find_one({'userid': userid}) == None:
userid = 0
# Calculate retention before the file is written, we'll grab the filesize here as it's needed for the equation.
fileSize = round(float(file.content_length) / 1024, 2)
if retention == None:
retention = (Config.minretention+(-Config.maxretention + Config.minretention)*pow((fileSize / Config.maxFileSize -1), 3))
elif retention > (Config.minretention+(-Config.maxretention + Config.minretention)*pow((fileSize / Config.maxFileSize -1), 3)):
retention = (Config.minretention+(-Config.maxretention + Config.minretention)*pow((fileSize / Config.maxFileSize -1), 3))
if file.
# Create the file
with open(f"{os.path.abspath(Config.fileDir)}/{filename}", "wb") as f:
f.write(file.read())
date = time.mktime(datetime.datetime.now().timetuple())
# Create the dictionary that we'll insert into the db
data = {
'id': id,
'filename': filename,
'filesize': fileSize,
'retention': round(retention * 86400), # Convert to seconds
'userid': userid,
'ip': ip,
'date': date,
'expiry': date + round(retention * 86400)
}
# Add the data and verify its there.
Config.files.insert_one(data)
print(Config.files.find_one({"id": id}))
return id, 200
else:
return random.choice(Errors.fileTooLarge), 400
else:
return random.choice(Errors.fileTypeNotAllowed), 400
def shortenURL(url, ip, userid, id, retention):
# We're going to check whether the id variable has been filled
# If not then we'll generate one. (The ID variable will be the same as the filename if not rejected earlier.)
if id == None:
while True: # Loop to find an available file ID
id = randomHex() # Prevent conflicts if 2 of the same get made
if Config.files.find_one({'id': id}) is None:
filename = id
break
if userid == None:
userid = 0
elif Config.users.find_one({'userid': userid}) == None:
userid = 0
if retention == None:
retention = 14
elif retention > 365:
retention = 365
data = {
"id": id,
"url": url,
"userid": userid,
"retention": retention,
"ip": ip
}
Config.url.insert_one(data)
print(Config.url.find_one({"id": data["id"]}))
return id
def idInfo(id):
# Check files and url for the ID
if Config.files.find_one({"id": id}) is not None:
check = Config.files.find_one({"id": id}, {'_id': False}, {"ip": False})
# "ip": False removes the IP from the returned data.
# If it's not there then check url
elif Config.url.find_one({"id": id}) is not None:
check = Config.url.find_one({"id": id}, {'_id': False}, {"ip": False})
# Return the mongodb info about the file, removing IP if its present
return check
def randomHex():
hexRand = ''.join(secrets.choice('0123456789abcdef') for _ in range(6))
return hexRand

75
config.py Normal file
View file

@ -0,0 +1,75 @@
import os
from pymongo import MongoClient
class Config:
# MongoDB init stuff
client = MongoClient("mongodb://localhost:27017/")
db = client["xygt"]
files = db["file"]
url = db["url"]
users = db["users"]
# Basic configs
maxFileSize = 256
premMaxFileSize = 512
maxretention = 365
minretention = 7
fileDir = "./data"
ipLogEnabled = False
quotes = {
"Anon /g/": "Biometrics are shit, you lose a limb and you're fucked.",
"Jack": "i named it xygt because it sounds cool lmao",
"Cow": "Does this server run Gentoo? (no it doesn't)",
"uname -a": "Linux xygt 6.1.0-12-arm64 #1 SMP Debian 6.1.52-1 (2023-09-07) aarch64 GNU/Linux",
"Luna": "shit you moth",
"Maze": "Mein Gott Leute, meine Mama hat mir einfach erlaubt dass ich Cola trinken darf! Wie cool ist das bitte? Jetzt zocke ich Fortnite und trinke Cola! YIPPEE!",
}
disallowedMimeTypes = [
"application/x-dosexec",
"application/java-archive",
"application/java-vm"
]
class Errors:
file404 = [
"The file you seek does not exist...",
"Nope, can't find it.",
"AVE FOOKIN LOST IT",
"My shitty filehost can't find this, sorry lmao",
"Your file could not be found.",
"You fucked up somewhere, this link doesn't work.",
"If someone gave you this link, go shout at them, it's broken.",
"404.",
"The file isn't in our db, so it's probably expired or just never existed in the first place."
]
fileTooLarge = [
"Too big, nah.",
"File size goes over the limit, you're not uploading this"
"Your file is too large, get it under 256mb first.",
"I don't know what the hell you're trying to upload but it's over 256mb, so no.",
"Your file is over 256mb, remember, we don't store your files forever!",
"File is too big, 265mb is the limit.",
"nuh uh, too big"
]
fileTypeNotAllowed = [
"Nice try idiot. You're not uploading that onto my server.",
"No executables allowed, NO EXCEPTIONS.",
"So bud... what you trying to do there? You can't upload executables you know.",
"Nah, not getting that on here today.",
"Stop trying to upload executables, goddamnit.",
"Executables can suck my dick, you're not uploading that"
"nuh uh (executables not allowed)"
]
def file404Error():
return random.choice(self.file404.items())
def fileTooLargeError():
return random.choice(self.fileTooLarge.items())
def fileTypeNotAllowedError():
return random.choice(self.fileTypeNotAllowed.items())

4
requirements.txt Normal file
View file

@ -0,0 +1,4 @@
flask
flask-dotenv
pymongo
python-magic