diff --git a/ER-rar-index.graphml b/ER-rar-index.graphml
index 6ed562a..5d25a36 100644
--- a/ER-rar-index.graphml
+++ b/ER-rar-index.graphml
@@ -36,10 +36,12 @@
-
-
-
-
+
+
+
+
+
+
@@ -135,7 +137,6 @@
IDLABEL
- CATEGORYTYPE
@@ -165,7 +166,7 @@
-
+ ArchLab
@@ -253,7 +254,7 @@
8
-
+
@@ -281,53 +282,105 @@
+
+
+
+
+
+
+
+ 9
+
+
+
+
+
+
+
+ CatLabType
+
+
+ ID
+ CATID
+ LABID
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ArchLab
+
+
+ ID
+ ARCHID
+ LABID
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
-
+
-
+
-
+
diff --git a/flask/app.py b/flask/app.py
index 7a1610d..806876c 100644
--- a/flask/app.py
+++ b/flask/app.py
@@ -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/')
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 "
ERROR: All fields need to be filled and don't play with their names!
Go back and try again."
+
+ try:
+ postdict["size"]=postdict["size"]*int(request.form['size_multiplier'])
+ except Exception as e:
+ return "
ERROR: All fields need to be filled and don't play with their names!
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"
ERROR: {archid}
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
diff --git a/flask/func.py b/flask/func.py
index 649e198..b3c6d6b 100644
--- a/flask/func.py
+++ b/flask/func.py
@@ -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()
diff --git a/flask/static/add.css b/flask/static/add.css
new file mode 100644
index 0000000..4982aec
--- /dev/null
+++ b/flask/static/add.css
@@ -0,0 +1,4 @@
+div.grid-container {
+ display: grid;
+ grid-template-columns: max-content max-content;
+}
\ No newline at end of file
diff --git a/flask/static/base.css b/flask/static/base.css
index 0fd47dd..d759416 100644
--- a/flask/static/base.css
+++ b/flask/static/base.css
@@ -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;
diff --git a/flask/templates/add.html b/flask/templates/add.html
new file mode 100644
index 0000000..c560712
--- /dev/null
+++ b/flask/templates/add.html
@@ -0,0 +1,34 @@
+{% extends "base.html" %}
+
+{% block meta %}
+
+{% endblock %}
+
+{% block content %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/flask/templates/base.html b/flask/templates/base.html
index d60ed25..55e2ece 100644
--- a/flask/templates/base.html
+++ b/flask/templates/base.html
@@ -10,6 +10,7 @@
+ {{title}}