From e6b69eb7b438fc6c7955d5ba2159b6091e9188cd Mon Sep 17 00:00:00 2001 From: marcel Date: Tue, 7 Nov 2023 12:58:40 +0100 Subject: [PATCH] Added label search and pages --- README.md | 2 ++ flask/app.py | 25 +++++++++++----- flask/func.py | 37 +++++++++++++++-------- flask/static/home.css | 40 +++++++++++++++++++++++++ flask/templates/home.html | 3 +- flask/templates/search.html | 60 ++++++++++++++++++++++++++----------- flask/templates/view.html | 2 +- 7 files changed, 130 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index b700c55..08d12a6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # RAR-Index It's some project for my school which is supposed to index _rar_-archives and make them searchable over a very ugly web frontend. +**!!Works only on python 3.10 and newer!!** + ## Features - Add and delete archives - edit their labels (as their owner) diff --git a/flask/app.py b/flask/app.py index 763326f..d732e77 100644 --- a/flask/app.py +++ b/flask/app.py @@ -36,7 +36,7 @@ def convsize(s:int): def homepage(): # try to get userdata, else logout state logged_in,userdata=get_login_info(request.cookies.get('session-id')) - archives=db.get_n_archives() + archives,count=db.get_n_archives() return render_template("home.html", title="Homepage",userdata=userdata,login=logged_in,archives=archives) @app.route('/user') @@ -195,7 +195,8 @@ def labeleditpage(archid:int): return render_template("labels.html", title="Edit Labels",userdata=userdata,login=logged_in,archive=archive,res_labels=label_dict,labels_names=labels_name_list) @app.route('/search') -def searchpage(): +@app.route('/search/') +def searchpage(page:int=1): # try to get userdata, else logout state logged_in,userdata=get_login_info(request.cookies.get('session-id')) @@ -205,8 +206,12 @@ def searchpage(): except Exception as e: sorttype="time" try: - category=request.args['category'] - label_dict=db.get_label_labeltypes(int(category)) + category=int(request.args['category']) + catparentid=db.get_category_info(category)[2] + if catparentid: + label_dict=db.get_label_labeltypes(catparentid) + else: + label_dict=db.get_label_labeltypes(category) except Exception as e: category=0 label_dict={} @@ -215,7 +220,7 @@ def searchpage(): except Exception as e: keywords=[] try: - count=request.args['count'] + count=int(request.args['count']) except Exception as e: count=20 labels=[] @@ -228,11 +233,16 @@ def searchpage(): continue except Exception as e: labels=[] - archives=db.get_n_archives(sorttype,category,keywords,count,labels) + archives,total_count=db.get_n_archives(sorttype,category,keywords,count,labels,page) + # if the requested page is larger than the maximum, return page 1 + if page*count > total_count and (page-1)*count >= total_count: + page=1 + archives,total_count=db.get_n_archives(sorttype,category,keywords,count,labels,page) + htmlcatlist=get_category_selection() - return render_template("search.html", title="Advanced Search",categories=htmlcatlist,userdata=userdata,login=logged_in,archives=archives,res_labels=label_dict,labels=labels) + return render_template("search.html", title="Advanced Search",page=page,count=count,total_count=total_count,categories=htmlcatlist,userdata=userdata,login=logged_in,archives=archives,res_labels=label_dict,labels=labels) ########## FUNCTIONS @@ -254,6 +264,7 @@ def get_login_info(sesskey:str): userdata=() return logged_in,userdata +## returns a cookie and redirects to the homepage def setcookie(name:str,value:str,lifetime:int=10000): resp = make_response(redirect('/')) resp.set_cookie(name, value, max_age=lifetime) diff --git a/flask/func.py b/flask/func.py index 0d36892..ef0ae06 100644 --- a/flask/func.py +++ b/flask/func.py @@ -183,6 +183,12 @@ class db: def get_categories(self): self.cur.execute("SELECT * FROM Cats;") return self.cur.fetchall() + + ## Gets and returns all info about one (1) category + ## OUTPUT: tup=(ID:int,CATEGORY:str,PARENT:int,DESCRIPTION:str) + def get_category_info(self, catid:int): + self.cur.execute(f"SELECT * FROM Cats WHERE ID={catid}") + return self.cur.fetchone() ## get all labeltypes and their respective labels based on a category parent ## OUTPUT: res_dict:dict={…,LabType.NAME:[…,(ID:int,NAME:str),…],…} @@ -245,24 +251,24 @@ class db: return True, "" ## Returns n archives, sorted by a column - ## 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!!!!! + ## OUTPUT: archives:array=[…,(ID:int,NAME:str,SIZE:str,IMPORTED[UNIX]:int),…], total_count:int + def get_n_archives(self, sorttype:str="time",category:int=0, keywords:list=[], count:int=20, labels:list=None, page:int=1): # TODO: CLEANN!!!!! match sorttype: case "size": - sorttype="SIZE DESC" + sorttype="Archs.SIZE DESC" case "time": - sorttype="IMPORTED DESC" + sorttype="Archs.IMPORTED DESC" case "za": - sorttype="NAME DESC" + sorttype="Archs.NAME DESC" case _: - sorttype="NAME ASC" + sorttype="Archs.NAME ASC" # create SQL query for keywords keyword_string="" for w in keywords: - keyword_string+=f"AND NAME LIKE '%{w}%' " + keyword_string+=f"AND Archs.NAME LIKE '%{w}%' " if len(keywords) == 1: - keyword_string+=f"OR HASH = '{keywords[0]}' " + keyword_string+=f"OR Archs.HASH = '{keywords[0]}' " # get all children of category (if exist) and put into query string categories=self.get_categories() @@ -272,13 +278,20 @@ class db: catlist.append(str(i[0])) categories="(" + ",".join(catlist) + ")" - self.cur.execute(f"""SELECT Archs.ID,Archs.NAME,Archs.SIZE,Archs.IMPORTED FROM Archs - {"WHERE 1=1" if category==0 else "WHERE CATEGORY IN " + categories} + # select all archives by keywords, categories and labels + self.cur.execute(f"""SELECT DISTINCT Archs.ID,Archs.NAME,Archs.SIZE,Archs.IMPORTED FROM Archs + JOIN ArchLab ON Archs.ID=ArchLab.ArchID + {"WHERE 1=1" if category==0 else "WHERE Archs.CATEGORY IN " + categories} + {f"AND ArchLab.LabID IN ({','.join(labels)})" if labels else ""} {keyword_string} - ORDER BY {sorttype} LIMIT {count if count else 20}""") + GROUP BY Archs.ID + {f"HAVING COUNT(Archs.ID)={len(labels)}" if labels else ""} + ORDER BY {sorttype}""") archives=self.cur.fetchall() + res_archives=archives[page*count-count:page*count] # get archives for the selected page + total_count=len(archives) - return archives + return res_archives, total_count if __name__ == "__main__": #startup() diff --git a/flask/static/home.css b/flask/static/home.css index c678dfe..69f1991 100644 --- a/flask/static/home.css +++ b/flask/static/home.css @@ -31,4 +31,44 @@ a.grid-item { div.clickable:hover { background: lightgrey; +} + +div.pageselect { + display: grid; + grid-template-columns: 1fr max-content 1fr; + margin: 1em auto; +} + +div.align-right { + display: inline-flex; + justify-content: end; +} + +div.align-left { + display: inline-flex; + justify-content: left; +} + +div.pageitem { + display: inline-block; + font-weight: 700; + text-align: center; + height: 2em; + width: 1.5em; +} + + +.pagebutton { + background: lightgrey; + font-weight: 600; + justify-self: auto; + border: none; + margin: 0 0.2em; + height: 2em; + width: 1.5em; +} + +input.pagebutton:hover { + background: grey; + border: none; } \ No newline at end of file diff --git a/flask/templates/home.html b/flask/templates/home.html index 3f4aae3..7f67a48 100644 --- a/flask/templates/home.html +++ b/flask/templates/home.html @@ -6,6 +6,7 @@ {% block content %} {% if archives|length > 0 %} +

Newest archives

ARCHIVE
SIZE
@@ -18,6 +19,6 @@ {% endfor %}
{% else %} -

No matching archives

+

Add some archives first!

{% endif %} {% endblock %} \ No newline at end of file diff --git a/flask/templates/search.html b/flask/templates/search.html index 73a129c..74b6a2d 100644 --- a/flask/templates/search.html +++ b/flask/templates/search.html @@ -18,7 +18,7 @@ Category: - {% for i in categories %} @@ -26,7 +26,6 @@ Count: - {# - #} + {% if request.args.get('q') %} @@ -44,20 +42,46 @@ {% endif %} - -{% if archives|length > 0 %} -
-
ARCHIVE
-
SIZE
-
IMPORTED
- {% for arch in archives %} -
{{arch[1]}}
-

{{arch[2]|spacer}}

-

{{arch[3]|ctime}}

- {% endfor %} + {% 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 %} + {% else %} +

No matching archives

+ {% endif %} + {% if total_count > page*count %} +
+
+ {% if page-3 > 1 %} +
+ {% endif %} + {% for pagenum in range(page-3,page) %} + {% if pagenum > 0 %} + + {% endif %} + {% endfor %} +
+
{{page}}
+
+ {% for pagenum in range(page+1,page+4) %} + {% if (pagenum-1)*count < total_count %} + + {% endif %} + {% endfor %} + {% if (page+4)*count < total_count %} +
+ {% endif %} +
+
+ {% endif %} + {% endblock %} \ No newline at end of file diff --git a/flask/templates/view.html b/flask/templates/view.html index b116829..cbc090d 100644 --- a/flask/templates/view.html +++ b/flask/templates/view.html @@ -20,6 +20,6 @@ {% endfor %}
- Cover image + Cover image {% endblock %} \ No newline at end of file