From d4016ce80c92a65ab8d882d6d3ae798aaeca6a49 Mon Sep 17 00:00:00 2001 From: marcel Date: Tue, 17 Oct 2023 18:25:38 +0200 Subject: [PATCH] First functions Added first functions in backend The homepage can now show the most recent archives --- .gitignore | 4 +- Dockerfile | 13 ----- ER-rar-index.graphml | 38 ++++++++++---- flask/app.py | 26 +++++++--- flask/func.py | 106 ++++++++++++++++++++++++++++++++++++++ flask/static/home.css | 11 ++++ flask/templates/base.html | 2 + flask/templates/home.html | 17 +++++- 8 files changed, 187 insertions(+), 30 deletions(-) delete mode 100644 Dockerfile create mode 100644 flask/func.py create mode 100644 flask/static/home.css diff --git a/.gitignore b/.gitignore index b6f3a60..4cef53c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ !/flask** !/.gitignore !/README.md -!/requirements.txt \ No newline at end of file +!/requirements.txt + +**__pycache__** \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index e2c5992..0000000 --- a/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -#Download Python from DockerHub and use it -FROM python:3.11.3 - -#Set the working directory in the Docker container -WORKDIR /app - -#Copy the dependencies file to the working directory -COPY ./requirements.txt . - -#Install the dependencies -RUN pip install -r requirements.txt - -COPY ./flask/ . \ No newline at end of file diff --git a/ER-rar-index.graphml b/ER-rar-index.graphml index ba15361..52f96ae 100644 --- a/ER-rar-index.graphml +++ b/ER-rar-index.graphml @@ -49,7 +49,7 @@ 1 - + @@ -61,6 +61,7 @@ ID NAME HASH + SIZE IMPORTED CATEGORY OWNER @@ -100,9 +101,9 @@ ID - NAME + CATEGORY PARENT - DESC + DESCRIPTION @@ -114,6 +115,11 @@ + + + + + 3 @@ -128,7 +134,7 @@ ID - NAME + LABEL CATEGORY TYPE @@ -147,6 +153,11 @@ + + + + + 4 @@ -161,8 +172,8 @@ ID - ARCH - LAB + ARCHID + LABID @@ -225,7 +236,7 @@ ID SESSKEY CREATED - LIMIT + LIFE @@ -251,8 +262,8 @@ ID - NAME - DESC + TYPE + DESCRIPTION @@ -311,5 +322,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/flask/app.py b/flask/app.py index 8b89898..f18152b 100644 --- a/flask/app.py +++ b/flask/app.py @@ -1,17 +1,31 @@ -# Importing flask module in the project is mandatory -# An object of Flask class is our WSGI application. from flask import Flask,redirect,url_for,request,render_template - -# Flask constructor takes the name of -# current module (__name__) as argument. +from datetime import datetime +## Import db class from func.py and initialise it +from func import db +db=db() + app = Flask(__name__) +## CUSTOM FILTERS +@app.template_filter('ctime') +def timectime(s): + return datetime.utcfromtimestamp(s).strftime('%Y-%m-%d %H:%M') +@app.template_filter('spacer') +def timectime(s): + sizes=("B","KB","MB","GB","TB") + n=0 + while s > 1000: + n+=1 + s=s/1000 + return str("%.2f" % s)+sizes[n] + ## WEB FRONTEND @app.route('/') def homepage(): - return render_template("home.html", title="Homepage") + archives=db.get_n_archives() + return render_template("home.html", title="Homepage",archives=archives) ## API CALLS diff --git a/flask/func.py b/flask/func.py new file mode 100644 index 0000000..6b589c3 --- /dev/null +++ b/flask/func.py @@ -0,0 +1,106 @@ +## MAIN FUNCTIONS FILE FOR BACK-BACKEND OF FLASK +import mariadb as sql +from os import environ + +## params populated with environment variables, defaults can be changed for a permanent solution +conn_params={ + "user" : environ.get('MARIADB_USER') if environ.get('MARIADB_USER') else "rar_index_app", + "password" : environ.get('MARIADB_PASSWORD') if environ.get('MARIADB_PASSWORD') else "password", + "host" : environ.get('MARIADB_HOST') if environ.get('MARIADB_HOST') else "marcelsite.com", + "database" : environ.get('MARIADB_DB') if environ.get('MARIADB_DB') else "rar_index" +} + +class db: + def __init__(self): + self.conn=sql.connect(**conn_params) + self.cur=self.conn.cursor() + + ## Creates all archives, if they don't exist already + ## Called only on startup, hence the name + def startup(self): + self.cur.execute(""" + CREATE TABLE IF NOT EXISTS Archs( + ID int PRIMARY KEY AUTO_INCREMENT, + NAME text NOT NULL, + HASH text NOT NULL, + SIZE int NOT NULL, + IMPORTED int, + CATEGORY int, + OWNER int + ); + CREATE TABLE IF NOT EXISTS Users( + ID int PRIMARY KEY AUTO_INCREMENT, + UNAME text NOT NULL, + DNAME text NOT NULL, + CREATED int NOT NULL, + STATE text, + PASSHASH text NOT NULL + ); + CREATE TABLE IF NOT EXISTS Sessions( + ID int PRIMARY KEY AUTO_INCREMENT, + SESSKEY text NOT NULL, + CREATED int NOT NULL, + LIFE int + ); + CREATE TABLE IF NOT EXISTS Cats( + ID int PRIMARY KEY AUTO_INCREMENT, + CATEGORY text NOT NULL, + PARENT int, + DESCRIPTION text + ); + CREATE TABLE IF NOT EXISTS ArchLab( + ID int PRIMARY KEY AUTO_INCREMENT, + ARCHID int NOT NULL, + LABID int NOT NULL + ); + CREATE TABLE IF NOT EXISTS Labs( + ID int PRIMARY KEY AUTO_INCREMENT, + LABEL text NOT NULL, + CATEGORY text, + TYPE int NOT NULL + ); + CREATE TABLE IF NOT EXISTS LabType( + ID int PRIMARY KEY AUTO_INCREMENT, + NAME text NOT NULL, + DESCRIPTION text + ); + """) + + ## 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) + ## 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 + WHERE hash='{hash}'""") + archive=self.cur.fetchone() + self.cur.execute(f"""SELECT Labs.LABEL,Cats.CATEGORY,Cats.DESCRIPTION AS CATDESC,LabType.NAME AS LABTYPE,LabType.DESCRIPTION AS LABDESC FROM ArchLab + JOIN Archs ON Archs.ID=ArchLab.ARCHID + JOIN Labs ON Labs.ID=ArchLab.LABID + JOIN Cats ON Labs.CATEGORY=Cats.ID + JOIN LabType ON Labs.TYPE=LabType.ID + WHERE ARCHID=1;""") + labels=self.cur.fetchall() + return archive, labels + + ## Returns n archives, sorted by (imported )time or size + ## OUTPUT: archives:array=[…,(NAME:str,SIZE:str,IMPORTED[UNIX]:int),…] + def get_n_archives(self, sorttype:str="time",category:int=0, count:int=20): + global cur + match sorttype: + case "size": + sorttype="SIZE" + case _: + sorttype="IMPORTED" + self.cur.execute(f"""SELECT NAME,SIZE,IMPORTED FROM Archs{"" if category==0 else " WHERE CATEGORY=" + category} ORDER BY {sorttype} DESC LIMIT {count};""") + archives=self.cur.fetchall() + return archives + +if __name__ == "__main__": + #startup() + db=db(conn_params) + db.cur.close() + db.conn.close() + exit() \ No newline at end of file diff --git a/flask/static/home.css b/flask/static/home.css new file mode 100644 index 0000000..5ccd682 --- /dev/null +++ b/flask/static/home.css @@ -0,0 +1,11 @@ +div.grid-container { + display: grid; + grid-template-columns: auto auto auto; +} +div.grid-item { + border: 2px black solid; +} + +div.clickable:hover { + background: grey; +} \ No newline at end of file diff --git a/flask/templates/base.html b/flask/templates/base.html index d479676..a58cf17 100644 --- a/flask/templates/base.html +++ b/flask/templates/base.html @@ -2,6 +2,8 @@ + {% block meta %} + {% endblock %} RAR-Index – {{title}} diff --git a/flask/templates/home.html b/flask/templates/home.html index f683c4d..d5d0582 100644 --- a/flask/templates/home.html +++ b/flask/templates/home.html @@ -1,5 +1,20 @@ {% extends "base.html" %} +{% block meta %} + +{% endblock %} + {% block content %} -

Test

+{% if archives|length > 0 %} +
+{% for arch in archives %} +
{{arch[0]}}
+

{{arch[1]|spacer}}

+

{{arch[2]|ctime}}

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

No matching archives

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