Many fixes and improvements

Fixes: #20,#22,#23,#24,#25,#26,#27,#28,#29,#30,#31,#32,#33,#34,#35,#36,#37,#38,#39,#40,#41,#42,#43,#46,#48
This commit is contained in:
Michael Rodin 2023-11-02 15:20:03 +01:00
parent d263701297
commit 78ed396c36
2 changed files with 98 additions and 94 deletions

View file

@ -13,12 +13,16 @@ db.startup()
app = Flask(__name__) app = Flask(__name__)
########## CUSTOM FILTERS ########## CUSTOM FILTERS
## converts a unix timestamp to a human-readable format
## OUTPUT: str="2023-11-02 12:33"
@app.template_filter('ctime') @app.template_filter('ctime')
def timectime(s): def timectime(s:int):
return datetime.utcfromtimestamp(s).strftime('%Y-%m-%d %H:%M') return datetime.utcfromtimestamp(s).strftime('%Y-%m-%d %H:%M')
## converts a bytes to a human readable scale
## OUTPUT: str="XXX.XXYB"
@app.template_filter('spacer') @app.template_filter('spacer')
def convsize(s): def convsize(s:int):
sizes=("B","KB","MB","GB","TB") sizes=("B","KB","MB","GB","TB")
n=0 n=0
while s >= 1000: while s >= 1000:
@ -31,19 +35,21 @@ 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
logged_in,userdata=get_login_info(request.cookies.get('session')) logged_in,userdata=get_login_info(request.cookies.get('session-id'))
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:page_userid>', methods=['GET','POST']) @app.route('/user/<int:page_userid>', methods=['GET','POST'])
def userpage(page_userid:int=0): def userpage(page_userid:int=0):
logged_in,userdata=get_login_info(request.cookies.get('session')) logged_in,userdata=get_login_info(request.cookies.get('session-id'))
if not logged_in: if not logged_in:
return make_response(redirect('/')) return make_response(redirect('/'))
if page_userid == 0: if page_userid == 0:
return make_response(redirect(f"/user/{userdata[0]}")) return make_response(redirect(f"/user/{userdata[0]}"))
page_userdata=db.get_user_info(page_userid) res,page_userdata=db.get_user_info(page_userid)
if not res:
return errorpage(page_userdata) # page_userdata is error
# POST: Update display name or password # POST: Update display name or password
if request.method == 'POST': if request.method == 'POST':
@ -66,11 +72,13 @@ def userpage(page_userid:int=0):
return make_response(redirect('/')) return make_response(redirect('/'))
# GET: return normal info page # GET: return normal info page
return render_template("user.html", title="User Details",userdata=page_userdata,login_userid=userdata[0],userid=page_userid) return render_template("user.html", title="User Details",login=logged_in,userdata=page_userdata,login_userid=userdata[0],userid=page_userid)
@app.route('/user/<uname>') @app.route('/user/<uname>')
def user_redirect(uname:str): def user_redirect(uname:str):
userdata=db.get_user_info_from_uname(uname) res,userdata=db.get_user_info(uname)
if not res:
return errorpage(userdata) # userdata is error
if not userdata: if not userdata:
return make_response(redirect(f"/user")) return make_response(redirect(f"/user"))
return make_response(redirect(f"/user/{userdata[0]}")) return make_response(redirect(f"/user/{userdata[0]}"))
@ -78,23 +86,21 @@ def user_redirect(uname:str):
@app.route('/add', methods=['GET','POST']) @app.route('/add', methods=['GET','POST'])
def addpage(): def addpage():
# try to get userdata, else yeet to the homepage # try to get userdata, else yeet to the homepage
logged_in,userdata=get_login_info(request.cookies.get('session')) logged_in,userdata=get_login_info(request.cookies.get('session-id'))
if not logged_in: if not logged_in:
return make_response(redirect('/')) return make_response(redirect('/'))
# POST: check and add archive, show confirmation/error message at the end # POST: check and add archive, show confirmation/error message at the end
if request.method == 'POST': if request.method == 'POST':
postdict={} postdict={}
# get and save all inputs, error if one doesn't exist or is wrong type # 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)]: for i,itype in [("name",str),("hash",str),("category",int),("size",float),("size_multiplier",int)]:
try: try:
postdict[i]=itype(request.form[i]) postdict[i]=itype(request.form[i])
if i == "size_multiplier":
postdict["size"]+=i
except Exception as e: except Exception as e:
return errorpage("All fields need to be filled and don't play with their names!") 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] postdict["owner"]=userdata[0]
res,archid=db.add_archive(postdict) res,archid=db.add_archive(postdict)
if res: if res:
@ -111,16 +117,16 @@ def loginpage():
# POST: Process login request # POST: Process login request
if request.method == 'POST': if request.method == 'POST':
username=request.form['username'] username=request.form['username']
password=sha256(request.form['password'].encode()).hexdigest() login_passhash=sha256(request.form['password'].encode()).hexdigest()
code,userid,passhash=db.get_passhash(username) res,userid,db_passhash=db.get_passhash(username)
if code != 200: if not res:
return passhash return errorpage(userid)# userid is the error
# if passwords match, create session and return cookie # if passwords match, create session and return cookie
if password.upper() == passhash.upper(): if login_passhash.upper() == db_passhash.upper():
lifetime=RAR_COOKIE_LIFETIME # lifetime of the sesskey in seconds lifetime=RAR_COOKIE_LIFETIME # lifetime of the sesskey in seconds
sesskey=str(uuid()) sesskey=str(uuid())
db.set_sesskey(sesskey,userid,lifetime) db.set_sesskey(sesskey,userid,lifetime)
resp=setcookie("session",sesskey,lifetime) resp=setcookie("session-id",sesskey,lifetime)
return resp return resp
else: else:
return errorpage("You've entered the wrong password. This incident will be reported.") return errorpage("You've entered the wrong password. This incident will be reported.")
@ -130,7 +136,7 @@ def loginpage():
@app.route('/logout') @app.route('/logout')
def logout(): def logout():
sesskey=request.cookies.get('session') sesskey=request.cookies.get('session-id')
logged_in,userdata=get_login_info(sesskey) logged_in,userdata=get_login_info(sesskey)
if not logged_in: if not logged_in:
return make_response(redirect('/login')) return make_response(redirect('/login'))
@ -139,16 +145,21 @@ def logout():
@app.route('/view/<int:archid>') @app.route('/view/<int:archid>')
def viewpage(archid:int): def viewpage(archid:int):
logged_in,userdata=get_login_info(request.cookies.get('session')) logged_in,userdata=get_login_info(request.cookies.get('session-id'))
archive,category,labels=db.get_archive_info(archid) res,archive,category,labels=db.get_archive_info(archid)
if not res:
return errorpage(archive) # archive is error
return render_template("view.html", title="View Archive",userdata=userdata,login=logged_in,archive=archive,category=category,labels=labels) 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"]) @app.route('/delete/<int:archid>', methods=["GET","POST"])
def deletepage(archid:int): def deletepage(archid:int):
logged_in,userdata=get_login_info(request.cookies.get('session')) logged_in,userdata=get_login_info(request.cookies.get('session-id'))
archive,category,labels=db.get_archive_info(archid) res,archive,category,labels=db.get_archive_info(archid)
if not res:
return errorpage(archive) # archive is error
if not logged_in or userdata[0] != archive[8]: if not logged_in or userdata[0] != archive[8]:
return make_response(redirect(f"/view/{archid}")) return make_response(redirect(f"/view/{archid}"))
# POST: check if input is correct and delete relevant data
if request.method == 'POST': if request.method == 'POST':
if not request.form['archname'] == archive[1]: if not request.form['archname'] == archive[1]:
return errorpage("The name input doesn't match!") return errorpage("The name input doesn't match!")
@ -159,8 +170,10 @@ def deletepage(archid:int):
@app.route('/labels/<int:archid>', methods=["GET","POST"]) @app.route('/labels/<int:archid>', methods=["GET","POST"])
def labeleditpage(archid:int): def labeleditpage(archid:int):
logged_in,userdata=get_login_info(request.cookies.get('session')) logged_in,userdata=get_login_info(request.cookies.get('session-id'))
archive,category,labels=db.get_archive_info(archid) res,archive,category,labels=db.get_archive_info(archid)
if not res:
return errorpage(archive) # archive is error
label_dict=db.get_label_labeltypes(category[3]) label_dict=db.get_label_labeltypes(category[3])
if not logged_in or userdata[0] != archive[8]: if not logged_in or userdata[0] != archive[8]:
return make_response(redirect(f"/view/{archid}")) return make_response(redirect(f"/view/{archid}"))
@ -168,7 +181,6 @@ def labeleditpage(archid:int):
# POST: parse everything and update labels # POST: parse everything and update labels
if request.method == 'POST': if request.method == 'POST':
on_labels=[] on_labels=[]
print(request.form)
for i in request.form: for i in request.form:
on_labels.append(i) on_labels.append(i)
res, data=db.update_labels(archid, on_labels) res, data=db.update_labels(archid, on_labels)
@ -185,7 +197,7 @@ def labeleditpage(archid:int):
@app.route('/search') @app.route('/search')
def searchpage(): def searchpage():
# try to get userdata, else logout state # try to get userdata, else logout state
logged_in,userdata=get_login_info(request.cookies.get('session')) logged_in,userdata=get_login_info(request.cookies.get('session-id'))
# try to set all required variables, else defaults # try to set all required variables, else defaults
try: try:
@ -199,8 +211,7 @@ def searchpage():
category=0 category=0
label_dict={} label_dict={}
try: try:
keywords=request.args['q'] keywords="".join(request.args['q']).split(" ")
keywords="".join(keywords).split(" ")
except Exception as e: except Exception as e:
keywords=[] keywords=[]
try: try:
@ -226,7 +237,7 @@ def searchpage():
########## FUNCTIONS ########## FUNCTIONS
def errorpage(message): def errorpage(message):
return "<h2>ERROR: " + str(message) + "</h2>Go back and try again" return "<h2>ERROR: " + str(message) + "</h2>Go back and try again", 400
## 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:tuple ## OUTPUT: (if sesskey valid) logged_in:bool=True, userdata:tuple
@ -236,7 +247,9 @@ def get_login_info(sesskey:str):
return False,() 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) res,userdata=db.get_user_info(userid)
if not res:
return errorpage(userdata) # userdata is error
else: else:
userdata=() userdata=()
return logged_in,userdata return logged_in,userdata
@ -256,11 +269,11 @@ def get_category_selection(include_parents:bool=True):
if not cat[2]: if not cat[2]:
if include_parents: if include_parents:
htmlcatlist.append((cat[0],cat[1])) htmlcatlist.append((cat[0],cat[1]))
parent=cat[1] parentname=cat[1]
parentid=cat[0] parentid=cat[0]
for i in catlist: for i in catlist:
if i[2] == parentid: if i[2] == parentid:
htmlcatlist.append((i[0],f"{parent}/{i[1]}")) htmlcatlist.append((i[0],f"{parentname}/{i[1]}"))
return htmlcatlist return htmlcatlist
## API CALLS (NO THANKS) ## API CALLS (NO THANKS)

View file

@ -4,7 +4,7 @@ from os import environ
import time,re import time,re
from config import * from config import *
## params populated with environment variables, defaults can be changed for a permanent solution ## params populated with environment variables, get data from config if environment variables not set
conn_params={ conn_params={
"user" : environ.get('MARIADB_USER') if environ.get('MARIADB_USER') else MARIADB_USER, "user" : environ.get('MARIADB_USER') if environ.get('MARIADB_USER') else MARIADB_USER,
"password" : environ.get('MARIADB_PASSWORD') if environ.get('MARIADB_PASSWORD') else MARIADB_PASSWORD, "password" : environ.get('MARIADB_PASSWORD') if environ.get('MARIADB_PASSWORD') else MARIADB_PASSWORD,
@ -28,93 +28,91 @@ class db:
SIZE bigint NOT NULL, SIZE bigint NOT NULL,
IMPORTED int, IMPORTED int,
CATEGORY int, CATEGORY int,
OWNER int OWNER int);""")
);""")
self.cur.execute("""CREATE TABLE IF NOT EXISTS Users( self.cur.execute("""CREATE TABLE IF NOT EXISTS Users(
ID int PRIMARY KEY AUTO_INCREMENT, ID int PRIMARY KEY AUTO_INCREMENT,
UNAME text NOT NULL UNIQUE, UNAME text NOT NULL UNIQUE,
DNAME text NOT NULL, DNAME text NOT NULL,
CREATED int NOT NULL, CREATED int NOT NULL,
STATE text, STATE text,
PASSHASH text NOT NULL PASSHASH text NOT NULL);""")
);""")
self.cur.execute("""CREATE TABLE IF NOT EXISTS Sessions( self.cur.execute("""CREATE TABLE IF NOT EXISTS Sessions(
ID int PRIMARY KEY AUTO_INCREMENT, ID int PRIMARY KEY AUTO_INCREMENT,
SESSKEY text NOT NULL UNIQUE, SESSKEY text NOT NULL UNIQUE,
USERID int NOT NULL, USERID int NOT NULL,
CREATED int NOT NULL, CREATED int NOT NULL,
LIFE int LIFE int);""")
);""")
self.cur.execute("""CREATE TABLE IF NOT EXISTS Cats( self.cur.execute("""CREATE TABLE IF NOT EXISTS Cats(
ID int PRIMARY KEY AUTO_INCREMENT, ID int PRIMARY KEY AUTO_INCREMENT,
CATEGORY text NOT NULL, CATEGORY text NOT NULL,
PARENT int, PARENT int,
DESCRIPTION text DESCRIPTION text);""")
);""")
self.cur.execute("""CREATE TABLE IF NOT EXISTS ArchLab( self.cur.execute("""CREATE TABLE IF NOT EXISTS ArchLab(
ID int PRIMARY KEY AUTO_INCREMENT, ID int PRIMARY KEY AUTO_INCREMENT,
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( self.cur.execute("""CREATE TABLE IF NOT EXISTS CatLabType(
ID int PRIMARY KEY AUTO_INCREMENT, ID int PRIMARY KEY AUTO_INCREMENT,
CATID int NOT NULL, CATID int NOT NULL,
LABID 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,
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(
ID int PRIMARY KEY AUTO_INCREMENT, ID int PRIMARY KEY AUTO_INCREMENT,
NAME text NOT NULL, NAME text NOT NULL,
DESCRIPTION text DESCRIPTION text);""")
);""")
## Gets the passhash from a specific user ## Gets the passhash from a specific user
## OUTPUT: (If user exists) int=200, ID:int, passhash:str ## OUTPUT: (If user exists) bool=True, ID:int, passhash:str
## (If user does not exist) int=400, Exception:str ## (If user does not exist) bool=False, Exception:str
def get_passhash(self, username:str): def get_passhash(self, username:str):
self.cur.execute(f"SELECT ID,PASSHASH FROM Users WHERE UNAME='{username}'") self.cur.execute(f"SELECT ID,PASSHASH FROM Users WHERE UNAME='{username}'")
try:
resp=self.cur.fetchone() resp=self.cur.fetchone()
except Exception as e: if not resp:
return 400, e, NULL return False, "The user does not exist!", None
return 200, resp[0], resp[1] return True, resp[0], resp[1]
## Checks if sesskey exists and is not expired ## Checks if sesskey exists and is not expired
## OUTPUT: (if valiid) bool=True, USERID:str ## OUTPUT: (if valiid) bool=True, USERID:str
## (in invalid) bool=False, str="" ## (in invalid) bool=False, str=""
def check_sesskey(self, sesskey:str): def check_sesskey(self, sesskey:str):
self.cur.execute(f"SELECT SESSKEY,USERID FROM Sessions WHERE SESSKEY='{sesskey}'") self.cur.execute(f"SELECT SESSKEY,USERID,CREATED,LIFE FROM Sessions WHERE SESSKEY='{sesskey}'")
entry=self.cur.fetchone() entry=self.cur.fetchone()
if entry and sesskey in entry: if entry and sesskey in entry and time.time() < entry[2]+entry[3]:
return True, entry[1] return True, entry[1]
else: else:
return False, "" return False, "The session key is expired or does not exist!"
## Sets a session key. That's it. ## Sets a session key. That's it.
def set_sesskey(self, sesskey:str, userid:int, lifetime:int): def set_sesskey(self, sesskey:str, userid:int, lifetime:int):
self.cur.execute(f"INSERT INTO Sessions(SESSKEY,USERID,CREATED,LIFE) VALUES('{sesskey}',{userid},{time.time()},{lifetime})") self.cur.execute(f"INSERT INTO Sessions(SESSKEY,USERID,CREATED,LIFE) VALUES('{sesskey}',{userid},{time.time()},{lifetime})")
## Removes the session key from the database (doesn't delete the cookie)
def logout_user(self, sesskey:str): def logout_user(self, sesskey:str):
self.cur.execute(f"DELETE FROM Sessions WHERE SESSKEY='{sesskey}'") self.cur.execute(f"DELETE FROM Sessions WHERE SESSKEY='{sesskey}'")
## Gets and returns all user info about one (1) user ## Gets and returns all user info about one (1) user
## OUTPUT: tuple=(ID:int,UNAME:str,DNAME:str,CREATED:int,STATE:text,PASSHASH:text) ## OUTPUT: (if successful) bool=True, tuple=(ID:int,UNAME:str,DNAME:str,CREATED:int,STATE:text,PASSHASH:text)
def get_user_info(self, userid:int): ## (if unsuccessful) bool=False, error:str
self.cur.execute(f"SELECT * FROM Users WHERE ID='{userid}'") def get_user_info(self, identifier):
return self.cur.fetchone() match identifier:
case int():
query=f"ID={identifier}"
case str():
query=f"UNAME='{identifier}'"
case _:
return False, "Wrong identifier type!"
## like above, just with uname self.cur.execute(f"SELECT * FROM Users WHERE {query}")
## OUTPUT: tuple=(ID:int,UNAME:str,DNAME:str,CREATED:int,STATE:text,PASSHASH:text) return True, self.cur.fetchone()
def get_user_info_from_uname(self, uname:str):
self.cur.execute(f"SELECT * FROM Users WHERE UNAME='{uname}'")
return self.cur.fetchone()
def update_user_info(self, userid, update_type:str,value): ## updates a value of a user in the database (if allowed in the dictionary)
allowed_types={"DNAME":str,"PASSHASH":str} ## OUTPUT: (if successful) bool=True, str="Updated"
## (if unsuccessful) bool=False, str="Not allowed"
def update_user_info(self, userid:int, update_type:str,value):
allowed_types={"DNAME":str,"PASSHASH":str} # only allow to edit these columns!
if update_type.upper() not in allowed_types: if update_type.upper() not in allowed_types:
return False, "Not allowed" return False, "Not allowed"
self.cur.execute(f"""UPDATE Users SET {update_type}={value if allowed_types[update_type]==int else f"'{value}'"} WHERE ID={userid}""") self.cur.execute(f"""UPDATE Users SET {update_type}={value if allowed_types[update_type]==int else f"'{value}'"} WHERE ID={userid}""")
@ -141,13 +139,16 @@ class db:
archid=self.cur.fetchone() archid=self.cur.fetchone()
return True,archid[0] return True,archid[0]
## Deletes all relevant entries from Archs and ArchLab
def delete_archive(self, archid:int): def delete_archive(self, archid:int):
self.cur.execute(f"""DELETE FROM Archs WHERE ID={archid}""") self.cur.execute(f"""DELETE FROM Archs WHERE ID={archid}""")
self.cur.execute(f"""DELETE FROM ArchLab WHERE ARCHID={archid}""") self.cur.execute(f"""DELETE FROM ArchLab WHERE ARCHID={archid}""")
## Returns all relevant information about one (1) archive ## Returns all relevant information about one (1) archive
## OUTPUT: archive:tuple=(ID:int,NAME:str,HASH:str,SIZE:int,IMPORTED[UNIX]:int,CATEGORY.ID:int,CATEGORY,str,CATEGORY.DESCRIPTION:str,USER.ID:int,DNAME:str), ## OUTPUT: (if archive doesn't exist) bool=False, error:str
## category:tuple=(ID:int,CATEGORY:str,DESCRIPTION:str,PID:int,PCAT:str,PDESC:str) ## (if archive exists) bool=True,
## archive:tuple=(ID:int,NAME:str,HASH:str,SIZE:int,IMPORTED[UNIX]:int,CATEGORY.ID:int,CATEGORY,str,CATEGORY.DESCRIPTION:str,USER.ID:int,DNAME:str),
## category:tuple=(ID:int,CATEGORY:str,DESCRIPTION:str,PID:int,PCAT:str,PDESC:str),
## labels:list=[…,(ID:int,LABEL:str,LABTYPE:int,LABDESC:str),…] ## labels:list=[…,(ID:int,LABEL:str,LABTYPE:int,LABDESC:str),…]
def get_archive_info(self, archid:int): def get_archive_info(self, archid:int):
# get info about archive itself # get info about archive itself
@ -156,6 +157,8 @@ class db:
JOIN Users ON Users.ID=Archs.OWNER JOIN Users ON Users.ID=Archs.OWNER
WHERE Archs.ID='{archid}'""") WHERE Archs.ID='{archid}'""")
archive=self.cur.fetchone() archive=self.cur.fetchone()
if not archive:
return False, "The archive does to exist!", None, None
# get info about category and it's parent # get info about category and it's parent
self.cur.execute(f"""SELECT c.ID,c.CATEGORY,c.DESCRIPTION,p.ID AS PID,p.CATEGORY as PCAT,p.DESCRIPTION AS PDESC FROM Cats c, Cats p self.cur.execute(f"""SELECT c.ID,c.CATEGORY,c.DESCRIPTION,p.ID AS PID,p.CATEGORY as PCAT,p.DESCRIPTION AS PDESC FROM Cats c, Cats p
WHERE c.ID={archive[5]} AND c.PARENT=p.ID""") WHERE c.ID={archive[5]} AND c.PARENT=p.ID""")
@ -163,8 +166,10 @@ class db:
# get info about labels of archive # get info about labels of archive
labels=self.get_label_info(archid) labels=self.get_label_info(archid)
return archive, category, labels return True, archive, category, labels
## Gets all labels and their parents of an archive
## OUTPUT: list=[…,(ID:int,LABEL:str,LABTYPE:int,LABDESC:str),…]
def get_label_info(self, archid:int): def get_label_info(self, archid:int):
self.cur.execute(f"""SELECT Labs.ID,Labs.LABEL,LabType.ID AS LABTYPE,LabType.DESCRIPTION AS LABDESC FROM ArchLab self.cur.execute(f"""SELECT Labs.ID,Labs.LABEL,LabType.ID AS LABTYPE,LabType.DESCRIPTION AS LABDESC FROM ArchLab
JOIN Archs ON Archs.ID=ArchLab.ARCHID JOIN Archs ON Archs.ID=ArchLab.ARCHID
@ -193,11 +198,11 @@ class db:
for w,e in labtypes_list: for w,e in labtypes_list:
labtypes_ids.append(str(w)) labtypes_ids.append(str(w))
labtypes_names.append(e) labtypes_names.append(e)
ltid_string="(" + ",".join(labtypes_ids) + ")" ltids_string="(" + ",".join(labtypes_ids) + ")"
# gets all relevant labs: […,(ID:int,NAME:str,LTNAME:str),…] # gets all relevant labs: […,(ID:int,NAME:str,LTNAME:str),…]
self.cur.execute(f"""SELECT Labs.ID,Labs.LABEL,LabType.NAME AS LTNAME FROM Labs self.cur.execute(f"""SELECT Labs.ID,Labs.LABEL,LabType.NAME AS LTNAME FROM Labs
JOIN LabType ON Labs.TYPE=LabType.ID JOIN LabType ON Labs.TYPE=LabType.ID
WHERE LabType.ID IN {ltid_string} WHERE LabType.ID IN {ltids_string}
ORDER BY Labs.LABEL ASC""") ORDER BY Labs.LABEL ASC""")
labs_list=self.cur.fetchall() labs_list=self.cur.fetchall()
res_dict={} res_dict={}
@ -211,7 +216,7 @@ class db:
## get a list of enabled labels and update the DB to reflect that state ## get a list of enabled labels and update the DB to reflect that state
## OUTPUT: (if on_labels empty) bool=False, str ## OUTPUT: (if on_labels empty) bool=False, str
## (else) ## (else) bool=True, str=""
def update_labels(self, archid:int, on_labels:list): def update_labels(self, archid:int, on_labels:list):
# fail if no labels passed # fail if no labels passed
if len(on_labels) == 0: if len(on_labels) == 0:
@ -232,13 +237,14 @@ class db:
# remove all labels which are not on # remove all labels which are not on
self.cur.execute(f"""DELETE FROM ArchLab WHERE ARCHID={archid} AND LABID NOT IN ({",".join(on_labels)})""") self.cur.execute(f"""DELETE FROM ArchLab WHERE ARCHID={archid} AND LABID NOT IN ({",".join(on_labels)})""")
to_add_list=[] to_add_list=[]
# creates all entries as strings and puts them into a list
for i in to_add: for i in to_add:
to_add_list.append("(" + str(archid) + "," + str(i) + ")") to_add_list.append("(" + str(archid) + "," + str(i) + ")")
# add all new labels # add all new labels
self.cur.execute(f"""INSERT INTO ArchLab(ARCHID,LABID) VALUES{",".join(to_add_list)}""") self.cur.execute(f"""INSERT INTO ArchLab(ARCHID,LABID) VALUES{",".join(to_add_list)}""")
return True, "" return True, ""
## Returns n archives, sorted by (imported )time or size ## Returns n archives, sorted by a column
## OUTPUT: archives:array=[…,(ID:int,NAME:str,SIZE:str,IMPORTED[UNIX]:int),…] ## OUTPUT: archives:array=[…,(ID:int,NAME:str,SIZE:str,IMPORTED[UNIX]:int),…]
def get_n_archives(self, sorttype:str="time",category:int=0, keywords:list=[], count:int=20,labels:list=[]): # TODO: CLEANN!!!!! def get_n_archives(self, sorttype:str="time",category:int=0, keywords:list=[], count:int=20,labels:list=[]): # TODO: CLEANN!!!!!
match sorttype: match sorttype:
@ -271,21 +277,6 @@ class db:
{keyword_string} {keyword_string}
ORDER BY {sorttype} LIMIT {count if count else 20}""") ORDER BY {sorttype} LIMIT {count if count else 20}""")
archives=self.cur.fetchall() archives=self.cur.fetchall()
## WARNING: JANK
#positive_archives=[]
#print("LABELS:", labels)
#if len(labels) >= 1:
# for arch in archives:
# archid=arch[0]
# archive_labels=self.get_label_info(archid)
# success=True
# for label in archive_labels:
# if not label[0] in labels:
# success=False
# if success:
# positive_archives.append(arch)
# if len(positive_archives) >= count:
# break
return archives return archives