217 lines
7.6 KiB
Python
217 lines
7.6 KiB
Python
|
|
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
|
|
## import all config variables
|
|
from config import *
|
|
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 errorpage("All fields need to be filled and don't play with their names!")
|
|
|
|
try:
|
|
postdict["size"]=postdict["size"]*int(request.form['size_multiplier'])
|
|
except Exception as e:
|
|
return errorpage("All fields need to be filled and don't play with their names!")
|
|
postdict["owner"]=userdata[0]
|
|
res,archid=db.add_archive(postdict)
|
|
if res:
|
|
return make_response(redirect(f"/view/{str(archid)}"))
|
|
else:
|
|
return errorpage(archid), 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=RAR_COOKIE_LIFETIME # lifetime of the sesskey in seconds
|
|
sesskey=str(uuid())
|
|
db.set_sesskey(sesskey,userid,lifetime)
|
|
resp=setcookie("session",sesskey,lifetime)
|
|
return resp
|
|
else:
|
|
return errorpage("You've entered the wrong password. This incident will be reported.")
|
|
# GET: Login form
|
|
else:
|
|
return render_template("login.html", title="Login")
|
|
|
|
@app.route('/view/<int:archid>')
|
|
def viewpage(archid:int):
|
|
logged_in,userdata=get_login_info(request.cookies.get('session'))
|
|
archive,category,labels=db.get_archive_info(archid)
|
|
return render_template("view.html", title="View Archive",userdata=userdata,login=logged_in,archive=archive,category=category,labels=labels)
|
|
|
|
@app.route('/delete/<int:archid>', methods=["GET","POST"])
|
|
def deletepage(archid:int):
|
|
logged_in,userdata=get_login_info(request.cookies.get('session'))
|
|
archive,category,labels=db.get_archive_info(archid)
|
|
if not logged_in or userdata[0] != archive[8]:
|
|
return make_response(redirect(f"/view/{archid}"))
|
|
if request.method == 'POST':
|
|
if not request.form['archname'] == archive[1]:
|
|
return errorpage("The name input doesn't match!")
|
|
db.delete_archive(archid)
|
|
return make_response(redirect('/'))
|
|
# GET: return normal deletion page
|
|
return render_template("delete.html", title="Delete Archive",userdata=userdata,login=logged_in,archive=archive)
|
|
|
|
@app.route('/labels/<int:archid>', methods=["GET","POST"])
|
|
def labeleditpage(archid:int):
|
|
logged_in,userdata=get_login_info(request.cookies.get('session'))
|
|
archive,category,labels=db.get_archive_info(archid)
|
|
label_dict=db.get_label_labeltypes(category[3])
|
|
if not logged_in or userdata[0] != archive[8]:
|
|
return make_response(redirect(f"/view/{archid}"))
|
|
|
|
# POST: parse everything and update labels
|
|
if request.method == 'POST':
|
|
on_labels=[]
|
|
print(request.form)
|
|
for i in request.form:
|
|
on_labels.append(i)
|
|
res, data=db.update_labels(archid, on_labels)
|
|
if not res:
|
|
return errorpage(data)
|
|
return make_response(redirect(f"/view/{archid}"))
|
|
|
|
# GET: return normal labels page
|
|
labels_name_list=[]
|
|
for i in labels:
|
|
labels_name_list.append(i[0])
|
|
return render_template("labels.html", title="Edit Labels",userdata=userdata,login=logged_in,archive=archive,res_labels=label_dict,labels_names=labels_name_list)
|
|
|
|
@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
|
|
|
|
def errorpage(message):
|
|
return "<h2>ERROR: " + message + "</h2>Go back and try again"
|
|
|
|
## 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_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() |