Adding archives

Added functionality to add archives.
This commit is contained in:
Michael Rodin 2023-10-19 13:25:59 +02:00
parent 978c634067
commit c3bd73a068
7 changed files with 212 additions and 61 deletions

View file

@ -19,7 +19,7 @@ def timectime(s):
def convsize(s):
sizes=("B","KB","MB","GB","TB")
n=0
while s > 1000:
while s >= 1000:
n+=1
s=s/1000
return str("%.2f" % s)+sizes[n]
@ -28,31 +28,48 @@ def convsize(s):
@app.route('/')
def homepage():
# try to get userdata, else logout state
print(request.base_url)
try:
logged_in,userdata=get_login_info(request.cookies.get('session'))
except Exception as e:
logged_in,userdata=False,()
#try: # TODO: CLEAN!
# # get sesskey and get info about user
# sesskey=request.cookies.get('session')
# res,userid=db.check_sesskey(sesskey)
# if not res:
# return 500
# userdata=db.get_user_info(userid)
# logged_in=True
#except Exception as e:
# logged_in=False
# userdata=()
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):
if userid == 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
@ -78,10 +95,7 @@ def loginpage():
@app.route('/search')
def searchpage():
# try to get userdata, else logout state
try:
logged_in,userdata=get_login_info(request.cookies.get('session'))
except Exception as e:
logged_in,userdata=False,()
logged_in,userdata=get_login_info(request.cookies.get('session'))
# try to set all required variables, else defaults
try:
@ -103,26 +117,18 @@ def searchpage():
count=20
archives=db.get_n_archives(sorttype,category,keywords,count)
catlist=db.get_all_categories()
htmlcatlist=[]
# parse all categories and sort them into select box
for cat in catlist:
if not cat[2]:
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]}"))
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:tup
## (if sesskey invalid)
## 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)
@ -135,6 +141,23 @@ def setcookie(name:str,value:str,lifetime:int=10000):
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

View file

@ -1,7 +1,7 @@
## MAIN FUNCTIONS FILE FOR BACK-BACKEND OF FLASK
import mariadb as sql
from os import environ
import time
import time,re
## params populated with environment variables, defaults can be changed for a permanent solution
conn_params={
@ -23,7 +23,7 @@ class db:
self.cur.execute("""CREATE TABLE IF NOT EXISTS Archs(
ID int PRIMARY KEY AUTO_INCREMENT,
NAME text NOT NULL,
HASH text NOT NULL,
HASH text NOT NULL UNIQUE,
SIZE int NOT NULL,
IMPORTED int,
CATEGORY int,
@ -55,10 +55,14 @@ class db:
ARCHID int NOT NULL,
LABID int NOT NULL
);""")
self.cur.execute("""CREATE TABLE IF NOT EXISTS CatLabType(
ID int PRIMARY KEY AUTO_INCREMENT,
CATID int NOT NULL,
LABID int NOT NULL
);""")
self.cur.execute("""CREATE TABLE IF NOT EXISTS Labs(
ID int PRIMARY KEY AUTO_INCREMENT,
LABEL text NOT NULL,
CATEGORY text,
TYPE int NOT NULL
);""")
self.cur.execute("""CREATE TABLE IF NOT EXISTS LabType(
@ -99,8 +103,30 @@ class db:
self.cur.execute(f"SELECT * FROM Users WHERE ID='{userid}'")
return self.cur.fetchone()
## Checks information for errors and adds archive to the DB
## OUTPUT: (if successful) res:bool=True, ID:int
## (if unsuccessful) res:bool=False, str
def add_archive(self, archive:dict):
# Check everything for errors or malicious things
archive["hash"]=archive["hash"].upper()
if not re.match('[A-Z0-9]{40}', archive["hash"]):
return False, "Hash needs to be 40 characters in hexadecimal (SHA-1)."
if re.match('.*[^A-Za-z0-9\. _-].*', archive["name"]):
return False, "The name contains illegal characters. Allowed chars: '[A-Za-z0-9\. _-]'"
print(archive["name"])
curtime=time.time()
try:
self.cur.execute(f"INSERT INTO Archs(NAME,HASH,SIZE,IMPORTED,CATEGORY,OWNER) VALUES('{archive['name']}','{archive['hash']}',{archive['size']},{curtime},{archive['category']},{archive['owner']})")
except Exception as e: # hash needs to be unique
return False, e
self.cur.execute(f"SELECT ID FROM Archs WHERE HASH='{archive['hash']}'")
archid=self.cur.fetchone()
return True,archid[0]
## Returns all relevant information about one (1) archive
## OUTPUT: archive:tuple=(NAME:str,HASH:str,IMPORTED[UNIX]:int,CATEGORY,str,CATEGORY.DESCRIPTION:str,UNAME:str,DNAME:str)
## OUTPUT: archive:tuple=(NAME:str,HASH:str,IMPORTED[UNIX]:int,CATEGORY,str,CATEGORY.DESCRIPTION:str,UNAME:str,DNAME:str),
## labels:array=[…,(LABEL:str,CATEGORY:str,CATDESC:str,LABTYPE:str,LABDESC:str),…]
def get_archive_info(self, hash:str):
self.cur.execute(f"""SELECT Archs.NAME,Archs.HASH,Archs.IMPORTED,Cats.CATEGORY,Cats.DESCRIPTION,Users.UNAME,Users.DNAME FROM Archs
@ -146,14 +172,14 @@ class db:
# Get all children of category (if exist) and put into query string
categories=self.get_all_categories()
catlist=[category]
catlist=[str(category)]
for i in categories:
if i[2] == int(category):
catlist.append(str(i[0]))
category="(" + ",".join(catlist) + ")"
categories="(" + ",".join(catlist) + ")"
self.cur.execute(f"""SELECT ID,NAME,SIZE,IMPORTED FROM Archs
{"WHERE 1=1" if category==0 else " WHERE CATEGORY IN " + category}
{"WHERE 1=1" if category==0 else " WHERE CATEGORY IN " + categories}
{keyword_string}
ORDER BY {sorttype} LIMIT {count};""")
archives=self.cur.fetchall()

4
flask/static/add.css Normal file
View file

@ -0,0 +1,4 @@
div.grid-container {
display: grid;
grid-template-columns: max-content max-content;
}

View file

@ -15,6 +15,16 @@ header {
display: flex;
}
header > a {
margin: auto;
height: 2em;
width: 2em;
}
a > img {
height: 2em;
width: 2em;
}
header > div#container {
flex-grow: 1;
display: flex;

34
flask/templates/add.html Normal file
View file

@ -0,0 +1,34 @@
{% extends "base.html" %}
{% block meta %}
<link rel="stylesheet" href="/static/add.css" />
{% endblock %}
{% block content %}
<form action="/add" method="post">
<div class="grid-container">
<div><b>Name: </b></div>
<div><input type="text" name="name" placeholder="Archive Name"></div>
<div><b>Hash: </b></div>
<div><input type="text" name="hash" placeholder="Hash"></div>
<div><b>Category: </b></div>
<div>
<select name="category">
{% for i in categories %}
<option value="{{i[0]}}">{{i[1]}}</option>
{% endfor %}
</select>
</div>
<div><b>Size: </b></div>
<div>
<input type="number" name="size" step="0.01" min="0" placeholder="Size">
<select name="size_multiplier">
{% for val,size in ((1,"B"),(1000,"KB"),(1000000,"MB"),(1000000000,"GB"),(1000000000000,"TB")) %}
<option value="{{val}}">{{size}}</option>
{% endfor %}
</select>
</div>
<input type="submit" value="Add Archive">
</div>
</form>
{% endblock %}

View file

@ -10,6 +10,7 @@
<body>
<header>
<a href="/"><img src="/static/favicon.ico" alt="favicon"></a>
<span id="title">{{title}}</span>
<div id="container">
<!-- BUTTONS IF USER LOGGED IN -->