diff --git a/flask/app.py b/flask/app.py index b6401aa..7a1610d 100644 --- a/flask/app.py +++ b/flask/app.py @@ -14,6 +14,7 @@ app = Flask(__name__) @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") @@ -26,25 +27,30 @@ def convsize(s): ## WEB FRONTEND @app.route('/') def homepage(): - # try to get sesskey, else logout state + # try to get userdata, else logout state + print(request.base_url) try: - # 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 + logged_in,userdata=get_login_info(request.cookies.get('session')) except Exception as e: - logged_in=False - userdata=() + 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() return render_template("home.html", title="Homepage",userdata=userdata,login=logged_in,archives=archives) @app.route('/user') -@app.route('/user/') +@app.route('/user/') def userpage(userid:int=0): - if userid==0: + if userid == 0: return make_response(redirect('/')) @app.route('/login', methods=["GET","POST"]) @@ -64,18 +70,72 @@ def loginpage(): resp=setcookie("session",sesskey,lifetime) return resp else: - return "

You've entered the wrong password. This incident will be reported.


Go back and try again.
" + password.upper() + "
" + passhash.upper() # TODO: DELETE + return "

You've entered the wrong password. This incident will be reported.


Go back and try again." # GET: Login form else: return render_template("login.html", title="Login") +@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,() + + # 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) + + 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]}")) + + 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) +def get_login_info(sesskey:str): + 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 -## API CALLS +## API CALLS (NO THANKS) # main driver function if __name__ == '__main__': diff --git a/flask/func.py b/flask/func.py index 55e4a8c..649e198 100644 --- a/flask/func.py +++ b/flask/func.py @@ -96,7 +96,6 @@ class db: ## Gets and returns all user info about one (1) user ## OUTPUT: tuple=(ID:int,UNAME:str,DNAME:str,CREATED:int,STATE:text,PASSHASH:text) def get_user_info(self, userid:int): - print("USERID:::::::::::" + userid) self.cur.execute(f"SELECT * FROM Users WHERE ID='{userid}'") return self.cur.fetchone() @@ -104,7 +103,6 @@ class db: ## 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): - #global cur self.cur.execute(f"""SELECT Archs.NAME,Archs.HASH,Archs.IMPORTED,Cats.CATEGORY,Cats.DESCRIPTION,Users.UNAME,Users.DNAME FROM Archs JOIN Cats ON Cats.ID=Archs.CATEGORY JOIN Users ON Users.ID=Archs.OWNER @@ -119,16 +117,45 @@ class db: labels=self.cur.fetchall() return archive, labels + ## Returns all categories. + ## OUTPUT: array=[…,(ID:int,CATEGORY:str,PARENT:int,DESCRIPTION:str),…] + def get_all_categories(self): + self.cur.execute("SELECT * FROM Cats;") + return self.cur.fetchall() + ## Returns n archives, sorted by (imported )time or size ## OUTPUT: archives:array=[…,(ID:int,NAME:str,SIZE:str,IMPORTED[UNIX]:int),…] - def get_n_archives(self, sorttype:str="time",category:int=0, count:int=20): - global cur + def get_n_archives(self, sorttype:str="time",category:int=0, keywords:list=[], count:int=20): match sorttype: case "size": - sorttype="SIZE" + sorttype="SIZE DESC" + case "time": + sorttype="IMPORTED DESC" + case "za": + sorttype="NAME DESC" case _: - sorttype="IMPORTED" - self.cur.execute(f"""SELECT ID,NAME,SIZE,IMPORTED FROM Archs{"" if category==0 else " WHERE CATEGORY=" + category} ORDER BY {sorttype} DESC LIMIT {count};""") + sorttype="NAME ASC" + + # create SQL query for keywords + keyword_string="" + for w in keywords: + keyword_string+=f"AND NAME LIKE '%{w}%' " + if len(keywords) == 1: + for w in keywords: + keyword_string+=f"OR HASH = '{w}' " + + # Get all children of category (if exist) and put into query string + categories=self.get_all_categories() + catlist=[category] + for i in categories: + if i[2] == int(category): + catlist.append(str(i[0])) + category="(" + ",".join(catlist) + ")" + + self.cur.execute(f"""SELECT ID,NAME,SIZE,IMPORTED FROM Archs + {"WHERE 1=1" if category==0 else " WHERE CATEGORY IN " + category} + {keyword_string} + ORDER BY {sorttype} LIMIT {count};""") archives=self.cur.fetchall() return archives diff --git a/flask/static/base.css b/flask/static/base.css index 30291ea..0fd47dd 100644 --- a/flask/static/base.css +++ b/flask/static/base.css @@ -26,6 +26,7 @@ header > div#container { height: 2em; margin: auto 0.1em; border: none; + border-radius: 0.1em; background: linear-gradient(135deg, white, yellow); } diff --git a/flask/static/home.css b/flask/static/home.css index dc61c44..c678dfe 100644 --- a/flask/static/home.css +++ b/flask/static/home.css @@ -1,8 +1,24 @@ div.grid-container { display: grid; - grid-template-columns: auto auto auto; + grid-template-columns: auto max-content max-content; } div.grid-item { + padding: 0.2em; + border: 2px black solid; +} + +div.grid-header:first-child { + border-radius: 0.5em 0 0 0; +} + +div.grid-header:nth-child(3) { + border-radius: 0 0.5em 0 0; +} + +div.grid-header { + text-align: center; + background: lightyellow; + padding: 0.4em; border: 2px black solid; } diff --git a/flask/static/search.css b/flask/static/search.css new file mode 100644 index 0000000..e69de29 diff --git a/flask/templates/base.html b/flask/templates/base.html index 9afe676..d60ed25 100644 --- a/flask/templates/base.html +++ b/flask/templates/base.html @@ -12,7 +12,12 @@
{{title}}
-
+ + {% if login %} + + {% endif %} + +
diff --git a/flask/templates/home.html b/flask/templates/home.html index c59f1fb..3f4aae3 100644 --- a/flask/templates/home.html +++ b/flask/templates/home.html @@ -7,13 +7,16 @@ {% block content %} {% if archives|length > 0 %}
-{% for arch in archives %} -
{{arch[1]}}
-

{{arch[2]|spacer}}

-

{{arch[3]|ctime}}

+
ARCHIVE
+
SIZE
+
IMPORTED
+ {% for arch in archives %} +
{{arch[1]}}
+

{{arch[2]|spacer}}

+

{{arch[3]|ctime}}

-{% endfor %} -
+ {% endfor %} +
{% else %}

No matching archives

{% endif %} diff --git a/flask/templates/search.html b/flask/templates/search.html new file mode 100644 index 0000000..347a1cd --- /dev/null +++ b/flask/templates/search.html @@ -0,0 +1,50 @@ +{% extends "base.html" %} + +{% block meta %} + + +{% endblock %} + +{% block content %} +
+
+ Sort by: + +
+
+ Category: + +
+ {% if request.args.get('q') %} + + {% else %} + + {% endif %} + +
+
+{% if archives|length > 0 %} +
+
ARCHIVE
+
SIZE
+
IMPORTED
+ {% for arch in archives %} +
{{arch[1]}}
+

{{arch[2]|spacer}}

+

{{arch[3]|ctime}}

+ + {% endfor %} +
+{% else %} +

No matching archives

+{% endif %} +{% endblock %} \ No newline at end of file