Adding archives
Added functionality to add archives.
This commit is contained in:
parent
978c634067
commit
c3bd73a068
|
@ -36,10 +36,12 @@
|
||||||
<yjs:SolidColorFill x:Key="1" color="#FFE8EEF7"/>
|
<yjs:SolidColorFill x:Key="1" color="#FFE8EEF7"/>
|
||||||
<yjs:SolidColorFill x:Key="2" color="#FFB7C9E3"/>
|
<yjs:SolidColorFill x:Key="2" color="#FFB7C9E3"/>
|
||||||
<y:FreeNodePortLocationModelParameter x:Key="3" Ratio="0.007575757575757569,0.5"/>
|
<y:FreeNodePortLocationModelParameter x:Key="3" Ratio="0.007575757575757569,0.5"/>
|
||||||
<yjs:SolidColorFill x:Key="4" color="#FF663800"/>
|
<yjs:SolidColorFill x:Key="4" color="#FFCEDED3"/>
|
||||||
<yjs:Stroke x:Key="5" fill="{y:GraphMLReference 4}"/>
|
<yjs:SolidColorFill x:Key="5" color="#FFB7E3C5"/>
|
||||||
<yjs:Arrow x:Key="6" type="TRIANGLE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 4}" cropLength="1"/>
|
<yjs:SolidColorFill x:Key="6" color="#FF663800"/>
|
||||||
<yjs:PolylineEdgeStyle x:Key="7" stroke="{y:GraphMLReference 5}" targetArrow="{y:GraphMLReference 6}"/>
|
<yjs:Stroke x:Key="7" fill="{y:GraphMLReference 6}"/>
|
||||||
|
<yjs:Arrow x:Key="8" type="TRIANGLE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 6}" cropLength="1"/>
|
||||||
|
<yjs:PolylineEdgeStyle x:Key="9" stroke="{y:GraphMLReference 7}" targetArrow="{y:GraphMLReference 8}"/>
|
||||||
</y:SharedData>
|
</y:SharedData>
|
||||||
</data>
|
</data>
|
||||||
<graph id="G" edgedefault="directed">
|
<graph id="G" edgedefault="directed">
|
||||||
|
@ -135,7 +137,6 @@
|
||||||
<x:Array Type="sys:Object">
|
<x:Array Type="sys:Object">
|
||||||
<sys:String>ID</sys:String>
|
<sys:String>ID</sys:String>
|
||||||
<sys:String>LABEL</sys:String>
|
<sys:String>LABEL</sys:String>
|
||||||
<sys:String>CATEGORY</sys:String>
|
|
||||||
<sys:String>TYPE</sys:String>
|
<sys:String>TYPE</sys:String>
|
||||||
</x:Array>
|
</x:Array>
|
||||||
</x0:EntityRelationshipModel.attributes>
|
</x0:EntityRelationshipModel.attributes>
|
||||||
|
@ -165,7 +166,7 @@
|
||||||
<y:RectD X="-27.5" Y="-250" Width="130" Height="130"/>
|
<y:RectD X="-27.5" Y="-250" Width="130" Height="130"/>
|
||||||
</data>
|
</data>
|
||||||
<data key="d7">
|
<data key="d7">
|
||||||
<x0:EntityNodeStyle fill="#FFCEDED3" insetFill="#FFB7E3C5" stroke="BLACK">
|
<x0:EntityNodeStyle fill="{y:GraphMLReference 4}" insetFill="{y:GraphMLReference 5}" stroke="BLACK">
|
||||||
<x0:EntityNodeStyle.model>
|
<x0:EntityNodeStyle.model>
|
||||||
<x0:EntityRelationshipModel>
|
<x0:EntityRelationshipModel>
|
||||||
<x0:EntityRelationshipModel.title>ArchLab</x0:EntityRelationshipModel.title>
|
<x0:EntityRelationshipModel.title>ArchLab</x0:EntityRelationshipModel.title>
|
||||||
|
@ -253,7 +254,7 @@
|
||||||
<node id="n6">
|
<node id="n6">
|
||||||
<data key="d0">8</data>
|
<data key="d0">8</data>
|
||||||
<data key="d5">
|
<data key="d5">
|
||||||
<y:RectD X="210.5" Y="-453" Width="130" Height="130"/>
|
<y:RectD X="210.5" Y="-48" Width="130" Height="130"/>
|
||||||
</data>
|
</data>
|
||||||
<data key="d7">
|
<data key="d7">
|
||||||
<x0:EntityNodeStyle fill="{y:GraphMLReference 1}" insetFill="{y:GraphMLReference 2}" stroke="BLACK">
|
<x0:EntityNodeStyle fill="{y:GraphMLReference 1}" insetFill="{y:GraphMLReference 2}" stroke="BLACK">
|
||||||
|
@ -281,53 +282,105 @@
|
||||||
<y:FreeNodePortLocationModelParameter Ratio="0.5,0.9924242424242424"/>
|
<y:FreeNodePortLocationModelParameter Ratio="0.5,0.9924242424242424"/>
|
||||||
</data>
|
</data>
|
||||||
</port>
|
</port>
|
||||||
|
<port name="p2">
|
||||||
|
<data key="d16">
|
||||||
|
<y:FreeNodePortLocationModelParameter Ratio="0.007575757575757569,0.5"/>
|
||||||
|
</data>
|
||||||
|
</port>
|
||||||
|
</node>
|
||||||
|
<node id="n7">
|
||||||
|
<data key="d0">9</data>
|
||||||
|
<data key="d5">
|
||||||
|
<y:RectD X="-27.5" Y="-48" Width="130" Height="130"/>
|
||||||
|
</data>
|
||||||
|
<data key="d7">
|
||||||
|
<x0:EntityNodeStyle fill="{y:GraphMLReference 4}" insetFill="{y:GraphMLReference 5}" stroke="BLACK">
|
||||||
|
<x0:EntityNodeStyle.model>
|
||||||
|
<x0:EntityRelationshipModel>
|
||||||
|
<x0:EntityRelationshipModel.title>CatLabType</x0:EntityRelationshipModel.title>
|
||||||
|
<x0:EntityRelationshipModel.attributes>
|
||||||
|
<x:Array Type="sys:Object">
|
||||||
|
<sys:String>ID</sys:String>
|
||||||
|
<sys:String>CATID</sys:String>
|
||||||
|
<sys:String>LABID</sys:String>
|
||||||
|
</x:Array>
|
||||||
|
</x0:EntityRelationshipModel.attributes>
|
||||||
|
</x0:EntityRelationshipModel>
|
||||||
|
</x0:EntityNodeStyle.model>
|
||||||
|
</x0:EntityNodeStyle>
|
||||||
|
</data>
|
||||||
|
<data key="d8">
|
||||||
|
<y:ViewState>
|
||||||
|
<y:FolderNodeState x:Key="c|view" Layout="-12.5,-235,130,130">
|
||||||
|
<y:FolderNodeState.Style>
|
||||||
|
<x0:EntityNodeStyle fill="{y:GraphMLReference 4}" insetFill="{y:GraphMLReference 5}" stroke="BLACK">
|
||||||
|
<x0:EntityNodeStyle.model>
|
||||||
|
<x0:EntityRelationshipModel>
|
||||||
|
<x0:EntityRelationshipModel.title>ArchLab</x0:EntityRelationshipModel.title>
|
||||||
|
<x0:EntityRelationshipModel.attributes>
|
||||||
|
<x:Array Type="sys:Object">
|
||||||
|
<sys:String>ID</sys:String>
|
||||||
|
<sys:String>ARCHID</sys:String>
|
||||||
|
<sys:String>LABID</sys:String>
|
||||||
|
</x:Array>
|
||||||
|
</x0:EntityRelationshipModel.attributes>
|
||||||
|
</x0:EntityRelationshipModel>
|
||||||
|
</x0:EntityNodeStyle.model>
|
||||||
|
</x0:EntityNodeStyle>
|
||||||
|
</y:FolderNodeState.Style>
|
||||||
|
</y:FolderNodeState>
|
||||||
|
</y:ViewState>
|
||||||
|
</data>
|
||||||
</node>
|
</node>
|
||||||
<edge id="e0" source="n0" target="n2" sourceport="p0" targetport="p0">
|
<edge id="e0" source="n0" target="n2" sourceport="p0" targetport="p0">
|
||||||
<data key="d10"><![CDATA[]]></data>
|
<data key="d10"><![CDATA[]]></data>
|
||||||
<data key="d13">
|
<data key="d13">
|
||||||
<yjs:PolylineEdgeStyle stroke="{y:GraphMLReference 5}" targetArrow="{y:GraphMLReference 6}">
|
<yjs:PolylineEdgeStyle stroke="{y:GraphMLReference 7}" targetArrow="{y:GraphMLReference 8}">
|
||||||
<yjs:PolylineEdgeStyle.sourceArrow>
|
<yjs:PolylineEdgeStyle.sourceArrow>
|
||||||
<yjs:Arrow type="TRIANGLE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 4}" cropLength="1"/>
|
<yjs:Arrow type="TRIANGLE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 6}" cropLength="1"/>
|
||||||
</yjs:PolylineEdgeStyle.sourceArrow>
|
</yjs:PolylineEdgeStyle.sourceArrow>
|
||||||
</yjs:PolylineEdgeStyle>
|
</yjs:PolylineEdgeStyle>
|
||||||
</data>
|
</data>
|
||||||
</edge>
|
</edge>
|
||||||
<edge id="e1" source="n0" target="n1" sourceport="p1" targetport="p0">
|
<edge id="e1" source="n0" target="n1" sourceport="p1" targetport="p0">
|
||||||
<data key="d13">
|
<data key="d13">
|
||||||
<y:GraphMLReference ResourceKey="7"/>
|
<y:GraphMLReference ResourceKey="9"/>
|
||||||
</data>
|
</data>
|
||||||
</edge>
|
</edge>
|
||||||
<edge id="e2" source="n0" target="n4" sourceport="p2" targetport="p0">
|
<edge id="e2" source="n0" target="n4" sourceport="p2" targetport="p0">
|
||||||
<data key="d13">
|
<data key="d13">
|
||||||
<y:GraphMLReference ResourceKey="7"/>
|
<y:GraphMLReference ResourceKey="9"/>
|
||||||
</data>
|
</data>
|
||||||
</edge>
|
</edge>
|
||||||
<edge id="e3" source="n4" target="n5" sourceport="p1" targetport="p0">
|
<edge id="e3" source="n4" target="n5" sourceport="p1" targetport="p0">
|
||||||
<data key="d13">
|
<data key="d13">
|
||||||
<yjs:PolylineEdgeStyle stroke="{y:GraphMLReference 5}">
|
<yjs:PolylineEdgeStyle stroke="{y:GraphMLReference 7}">
|
||||||
<yjs:PolylineEdgeStyle.targetArrow>
|
<yjs:PolylineEdgeStyle.targetArrow>
|
||||||
<yjs:Arrow type="NONE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 4}"/>
|
<yjs:Arrow type="NONE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 6}"/>
|
||||||
</yjs:PolylineEdgeStyle.targetArrow>
|
</yjs:PolylineEdgeStyle.targetArrow>
|
||||||
<yjs:PolylineEdgeStyle.sourceArrow>
|
<yjs:PolylineEdgeStyle.sourceArrow>
|
||||||
<yjs:Arrow type="NONE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 4}"/>
|
<yjs:Arrow type="NONE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 6}"/>
|
||||||
</yjs:PolylineEdgeStyle.sourceArrow>
|
</yjs:PolylineEdgeStyle.sourceArrow>
|
||||||
</yjs:PolylineEdgeStyle>
|
</yjs:PolylineEdgeStyle>
|
||||||
</data>
|
</data>
|
||||||
</edge>
|
</edge>
|
||||||
<edge id="e4" source="n6" target="n2" sourceport="p1" targetport="p1">
|
<edge id="e4" source="n6" target="n2" sourceport="p1" targetport="p1">
|
||||||
<data key="d13">
|
<data key="d13">
|
||||||
<yjs:PolylineEdgeStyle stroke="{y:GraphMLReference 5}">
|
<yjs:PolylineEdgeStyle stroke="{y:GraphMLReference 7}">
|
||||||
<yjs:PolylineEdgeStyle.targetArrow>
|
<yjs:PolylineEdgeStyle.targetArrow>
|
||||||
<yjs:Arrow type="NONE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 4}"/>
|
<yjs:Arrow type="NONE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 6}"/>
|
||||||
</yjs:PolylineEdgeStyle.targetArrow>
|
</yjs:PolylineEdgeStyle.targetArrow>
|
||||||
|
<yjs:PolylineEdgeStyle.sourceArrow>
|
||||||
|
<yjs:Arrow type="TRIANGLE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 6}" cropLength="1"/>
|
||||||
|
</yjs:PolylineEdgeStyle.sourceArrow>
|
||||||
</yjs:PolylineEdgeStyle>
|
</yjs:PolylineEdgeStyle>
|
||||||
</data>
|
</data>
|
||||||
</edge>
|
</edge>
|
||||||
<edge id="e5" source="n2" target="n1" sourceport="p2" targetport="p1">
|
<edge id="e5" source="n6" target="n1" sourceport="p2" targetport="p1">
|
||||||
<data key="d13">
|
<data key="d13">
|
||||||
<yjs:PolylineEdgeStyle stroke="{y:GraphMLReference 5}" targetArrow="{y:GraphMLReference 6}">
|
<yjs:PolylineEdgeStyle stroke="{y:GraphMLReference 7}" targetArrow="{y:GraphMLReference 8}">
|
||||||
<yjs:PolylineEdgeStyle.sourceArrow>
|
<yjs:PolylineEdgeStyle.sourceArrow>
|
||||||
<yjs:Arrow type="NONE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 4}"/>
|
<yjs:Arrow type="TRIANGLE" scale="0.75" stroke="#FF663800" fill="{y:GraphMLReference 6}" cropLength="1"/>
|
||||||
</yjs:PolylineEdgeStyle.sourceArrow>
|
</yjs:PolylineEdgeStyle.sourceArrow>
|
||||||
</yjs:PolylineEdgeStyle>
|
</yjs:PolylineEdgeStyle>
|
||||||
</data>
|
</data>
|
||||||
|
|
89
flask/app.py
89
flask/app.py
|
@ -19,7 +19,7 @@ def timectime(s):
|
||||||
def convsize(s):
|
def convsize(s):
|
||||||
sizes=("B","KB","MB","GB","TB")
|
sizes=("B","KB","MB","GB","TB")
|
||||||
n=0
|
n=0
|
||||||
while s > 1000:
|
while s >= 1000:
|
||||||
n+=1
|
n+=1
|
||||||
s=s/1000
|
s=s/1000
|
||||||
return str("%.2f" % s)+sizes[n]
|
return str("%.2f" % s)+sizes[n]
|
||||||
|
@ -28,31 +28,48 @@ def convsize(s):
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def homepage():
|
def homepage():
|
||||||
# try to get userdata, else logout state
|
# try to get userdata, else logout state
|
||||||
print(request.base_url)
|
|
||||||
try:
|
|
||||||
logged_in,userdata=get_login_info(request.cookies.get('session'))
|
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=()
|
|
||||||
archives=db.get_n_archives()
|
archives=db.get_n_archives()
|
||||||
return render_template("home.html", title="Homepage",userdata=userdata,login=logged_in,archives=archives)
|
return render_template("home.html", title="Homepage",userdata=userdata,login=logged_in,archives=archives)
|
||||||
|
|
||||||
@app.route('/user')
|
@app.route('/user')
|
||||||
@app.route('/user/<int:userid>')
|
@app.route('/user/<int:userid>')
|
||||||
def userpage(userid:int=0):
|
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('/'))
|
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"])
|
@app.route('/login', methods=["GET","POST"])
|
||||||
def loginpage():
|
def loginpage():
|
||||||
# POST: Process login request
|
# POST: Process login request
|
||||||
|
@ -78,10 +95,7 @@ def loginpage():
|
||||||
@app.route('/search')
|
@app.route('/search')
|
||||||
def searchpage():
|
def searchpage():
|
||||||
# try to get userdata, else logout state
|
# try to get userdata, else logout state
|
||||||
try:
|
|
||||||
logged_in,userdata=get_login_info(request.cookies.get('session'))
|
logged_in,userdata=get_login_info(request.cookies.get('session'))
|
||||||
except Exception as e:
|
|
||||||
logged_in,userdata=False,()
|
|
||||||
|
|
||||||
# try to set all required variables, else defaults
|
# try to set all required variables, else defaults
|
||||||
try:
|
try:
|
||||||
|
@ -103,26 +117,18 @@ def searchpage():
|
||||||
count=20
|
count=20
|
||||||
archives=db.get_n_archives(sorttype,category,keywords,count)
|
archives=db.get_n_archives(sorttype,category,keywords,count)
|
||||||
|
|
||||||
catlist=db.get_all_categories()
|
htmlcatlist=get_category_selection()
|
||||||
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]}"))
|
|
||||||
|
|
||||||
return render_template("search.html", title="Advanced Search",categories=htmlcatlist,userdata=userdata,login=logged_in,archives=archives)
|
return render_template("search.html", title="Advanced Search",categories=htmlcatlist,userdata=userdata,login=logged_in,archives=archives)
|
||||||
|
|
||||||
## FUNCTIONS
|
## FUNCTIONS
|
||||||
|
|
||||||
## Checks if given sesskey is valid and returns user data
|
## Checks if given sesskey is valid and returns user data
|
||||||
## OUTPUT: (if sesskey valid) logged_in:bool=True, userdata:tup
|
## OUTPUT: (if sesskey valid) logged_in:bool=True, userdata:tuple
|
||||||
## (if sesskey invalid)
|
## (if sesskey invalid) logged_in:bool=False, userdata:tuple=()
|
||||||
def get_login_info(sesskey:str):
|
def get_login_info(sesskey:str):
|
||||||
|
if not sesskey:
|
||||||
|
return False,()
|
||||||
logged_in,userid=db.check_sesskey(sesskey)
|
logged_in,userid=db.check_sesskey(sesskey)
|
||||||
if logged_in:
|
if logged_in:
|
||||||
userdata=db.get_user_info(userid)
|
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)
|
resp.set_cookie(name, value, max_age=lifetime)
|
||||||
return resp
|
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)
|
## API CALLS (NO THANKS)
|
||||||
|
|
||||||
# main driver function
|
# main driver function
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
## MAIN FUNCTIONS FILE FOR BACK-BACKEND OF FLASK
|
## MAIN FUNCTIONS FILE FOR BACK-BACKEND OF FLASK
|
||||||
import mariadb as sql
|
import mariadb as sql
|
||||||
from os import environ
|
from os import environ
|
||||||
import time
|
import time,re
|
||||||
|
|
||||||
## params populated with environment variables, defaults can be changed for a permanent solution
|
## params populated with environment variables, defaults can be changed for a permanent solution
|
||||||
conn_params={
|
conn_params={
|
||||||
|
@ -23,7 +23,7 @@ class db:
|
||||||
self.cur.execute("""CREATE TABLE IF NOT EXISTS Archs(
|
self.cur.execute("""CREATE TABLE IF NOT EXISTS Archs(
|
||||||
ID int PRIMARY KEY AUTO_INCREMENT,
|
ID int PRIMARY KEY AUTO_INCREMENT,
|
||||||
NAME text NOT NULL,
|
NAME text NOT NULL,
|
||||||
HASH text NOT NULL,
|
HASH text NOT NULL UNIQUE,
|
||||||
SIZE int NOT NULL,
|
SIZE int NOT NULL,
|
||||||
IMPORTED int,
|
IMPORTED int,
|
||||||
CATEGORY int,
|
CATEGORY int,
|
||||||
|
@ -55,10 +55,14 @@ class db:
|
||||||
ARCHID int NOT NULL,
|
ARCHID int NOT NULL,
|
||||||
LABID 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(
|
self.cur.execute("""CREATE TABLE IF NOT EXISTS Labs(
|
||||||
ID int PRIMARY KEY AUTO_INCREMENT,
|
ID int PRIMARY KEY AUTO_INCREMENT,
|
||||||
LABEL text NOT NULL,
|
LABEL text NOT NULL,
|
||||||
CATEGORY text,
|
|
||||||
TYPE int NOT NULL
|
TYPE int NOT NULL
|
||||||
);""")
|
);""")
|
||||||
self.cur.execute("""CREATE TABLE IF NOT EXISTS LabType(
|
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}'")
|
self.cur.execute(f"SELECT * FROM Users WHERE ID='{userid}'")
|
||||||
return self.cur.fetchone()
|
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
|
## 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),…]
|
## labels:array=[…,(LABEL:str,CATEGORY:str,CATDESC:str,LABTYPE:str,LABDESC:str),…]
|
||||||
def get_archive_info(self, hash: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
|
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
|
# Get all children of category (if exist) and put into query string
|
||||||
categories=self.get_all_categories()
|
categories=self.get_all_categories()
|
||||||
catlist=[category]
|
catlist=[str(category)]
|
||||||
for i in categories:
|
for i in categories:
|
||||||
if i[2] == int(category):
|
if i[2] == int(category):
|
||||||
catlist.append(str(i[0]))
|
catlist.append(str(i[0]))
|
||||||
category="(" + ",".join(catlist) + ")"
|
categories="(" + ",".join(catlist) + ")"
|
||||||
|
|
||||||
self.cur.execute(f"""SELECT ID,NAME,SIZE,IMPORTED FROM Archs
|
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}
|
{keyword_string}
|
||||||
ORDER BY {sorttype} LIMIT {count};""")
|
ORDER BY {sorttype} LIMIT {count};""")
|
||||||
archives=self.cur.fetchall()
|
archives=self.cur.fetchall()
|
||||||
|
|
4
flask/static/add.css
Normal file
4
flask/static/add.css
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
div.grid-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: max-content max-content;
|
||||||
|
}
|
|
@ -15,6 +15,16 @@ header {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header > a {
|
||||||
|
margin: auto;
|
||||||
|
height: 2em;
|
||||||
|
width: 2em;
|
||||||
|
}
|
||||||
|
a > img {
|
||||||
|
height: 2em;
|
||||||
|
width: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
header > div#container {
|
header > div#container {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
34
flask/templates/add.html
Normal file
34
flask/templates/add.html
Normal 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 %}
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
|
<a href="/"><img src="/static/favicon.ico" alt="favicon"></a>
|
||||||
<span id="title">{{title}}</span>
|
<span id="title">{{title}}</span>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<!-- BUTTONS IF USER LOGGED IN -->
|
<!-- BUTTONS IF USER LOGGED IN -->
|
||||||
|
|
Loading…
Reference in a new issue