rar-index-py/flask/app.py

166 lines
5.6 KiB
Python
Raw Normal View History

from flask import Flask,redirect,url_for,request,render_template,make_response
from datetime import datetime
from hashlib import sha256
from uuid import uuid4 as uuid
## Import db class from func.py and initialise it
from func import db
db=db()
db.startup()
app = Flask(__name__)
## CUSTOM FILTERS
@app.template_filter('ctime')
def timectime(s):
return datetime.utcfromtimestamp(s).strftime('%Y-%m-%d %H:%M')
@app.template_filter('spacer')
def convsize(s):
sizes=("B","KB","MB","GB","TB")
n=0
while s >= 1000:
n+=1
s=s/1000
return str("%.2f" % s)+sizes[n]
## WEB FRONTEND
@app.route('/')
def homepage():
# try to get userdata, else logout state
logged_in,userdata=get_login_info(request.cookies.get('session'))
archives=db.get_n_archives()
return render_template("home.html", title="Homepage",userdata=userdata,login=logged_in,archives=archives)
@app.route('/user')
@app.route('/user/<int:userid>')
def userpage(userid:int=0):
logged_in,userdata=get_login_info(request.cookies.get('session'))
if not logged_in:
return make_response(redirect('/'))
@app.route('/add', methods=['GET','POST'])
def addpage():
# try to get userdata, else yeet to the homepage
logged_in,userdata=get_login_info(request.cookies.get('session'))
if not logged_in:
return make_response(redirect('/'))
# POST: check and add archive, show confirmation/error message at the end
if request.method == 'POST':
postdict={}
# get and save all inputs, error if one doesn't exist or is wrong type
for i,itype in [("name",str),("hash",str),("category",int),("size",float)]:
try:
postdict[i]=itype(request.form[i])
except Exception as e:
return "<h2>ERROR: All fields need to be filled and don't play with their names!</h2> Go back and try again."
try:
postdict["size"]=postdict["size"]*int(request.form['size_multiplier'])
except Exception as e:
return "<h2>ERROR: All fields need to be filled and don't play with their names!</h2> Go back and try again."
postdict["owner"]=userdata[0]
res,archid=db.add_archive(postdict)
if res:
return make_response(redirect(f"/view/{str(archid)}"))
else:
return f"<h2>ERROR: {archid}</h2> Go back and try again.", 400
# GET: return normal page
htmlcatlist=get_category_selection(False)
return render_template("add.html", title="Add Archive",categories=htmlcatlist)
@app.route('/login', methods=["GET","POST"])
def loginpage():
# POST: Process login request
if request.method == 'POST':
username=request.form['username']
password=sha256(request.form['password'].encode()).hexdigest()
code,userid,passhash=db.get_passhash(username)
if code != 200:
return passhash
# if passwords match, create session and return cookie
if password.upper() == passhash.upper():
lifetime=3000000 # lifetime of the sesskey in seconds
sesskey=str(uuid())
db.set_sesskey(sesskey,userid,lifetime)
resp=setcookie("session",sesskey,lifetime)
return resp
else:
return "<h2>You've entered the wrong password. This incident will be reported.</h2><br> Go back and try again."
# GET: Login form
else:
return render_template("login.html", title="Login")
@app.route('/search')
def searchpage():
# try to get userdata, else logout state
logged_in,userdata=get_login_info(request.cookies.get('session'))
# try to set all required variables, else defaults
try:
sorttype=request.args['sort']
except Exception as e:
sorttype="time"
try:
category=request.args['category']
except Exception as e:
category=0
try:
keywords=request.args['q']
keywords="".join(keywords).split(" ")
except Exception as e:
keywords=[]
try:
count=request.args['count']
except Exception as e:
count=20
archives=db.get_n_archives(sorttype,category,keywords,count)
htmlcatlist=get_category_selection()
return render_template("search.html", title="Advanced Search",categories=htmlcatlist,userdata=userdata,login=logged_in,archives=archives)
## FUNCTIONS
## Checks if given sesskey is valid and returns user data
## OUTPUT: (if sesskey valid) logged_in:bool=True, userdata:tuple
## (if sesskey invalid) logged_in:bool=False, userdata:tuple=()
def get_login_info(sesskey:str):
if not sesskey:
return False,()
logged_in,userid=db.check_sesskey(sesskey)
if logged_in:
userdata=db.get_user_info(userid)
else:
userdata=()
return logged_in,userdata
def setcookie(name:str,value:str,lifetime:int=10000):
resp = make_response(redirect('/'))
resp.set_cookie(name, value, max_age=lifetime)
return resp
## Gets all categories and returns them (with or without parents)
## OUTPUT: […,(ID:int,NAME:str),…]
def get_category_selection(include_parents:bool=True):
catlist=db.get_all_categories()
htmlcatlist=[]
# parse all categories and sort them into list
for cat in catlist:
if not cat[2]:
if include_parents:
htmlcatlist.append((cat[0],cat[1]))
parent=cat[1]
parentid=cat[0]
for i in catlist:
if i[2] == parentid:
htmlcatlist.append((i[0],f"{parent}/{i[1]}"))
return htmlcatlist
## API CALLS (NO THANKS)
# main driver function
if __name__ == '__main__':
# run app if executed directly
app.run()