improved visuals
This commit is contained in:
Binary file not shown.
57
app/main.py
57
app/main.py
@@ -75,27 +75,46 @@ async def get_file(file_id: str):
|
|||||||
|
|
||||||
@app.get("/search/lva")
|
@app.get("/search/lva")
|
||||||
async def search_lva(
|
async def search_lva(
|
||||||
searchterm: str, searchlim: int = 10
|
searchterm: str = "", pid: str | None = None, searchlim: int = 10
|
||||||
) -> List[Dict[str, int | str]]:
|
) -> List[Dict[str, int | str]]:
|
||||||
"""returns the LVA for a search in the database"""
|
"""returns the LVA for a search in the database"""
|
||||||
res = []
|
res = []
|
||||||
|
zw = []
|
||||||
cur = db.cursor(dictionary=True)
|
cur = db.cursor(dictionary=True)
|
||||||
if await is_LVID(searchterm):
|
if await is_LVID(searchterm):
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"SELECT lvid,lvname FROM LVAs WHERE lvid LIKE ?", (searchterm + "%",)
|
"SELECT id,lvid,lvname FROM LVAs WHERE lvid LIKE ?", (searchterm + "%",)
|
||||||
)
|
)
|
||||||
res = cur.fetchall()
|
res = cur.fetchall()
|
||||||
else:
|
else:
|
||||||
cur.execute(
|
if pid is not None:
|
||||||
"SELECT id,lvid,lvname FROM LVAs WHERE lvname LIKE ?",
|
cur.execute(
|
||||||
(searchterm + "%",),
|
"SELECT LVAs.id,LVAs.lvid,LVAs.lvname FROM LVAs LEFT JOIN LPLink ON LVAs.id=LPLink.lid WHERE lvname like ? AND pid=?",
|
||||||
)
|
(searchterm + "%", pid),
|
||||||
res = cur.fetchall()
|
)
|
||||||
cur.execute(
|
res += cur.fetchall()
|
||||||
"SELECT id,lvid,lvname FROM LVAs WHERE lvname LIKE ?",
|
cur.execute(
|
||||||
("%" + searchterm + "%",),
|
"SELECT LVAs.id,LVAs.lvid,LVAs.lvname FROM LVAs LEFT JOIN LPLink ON LVAs.id=LPLink.lid WHERE lvname like ? AND pid=?",
|
||||||
)
|
("%" + searchterm + "%", pid),
|
||||||
res = remove_duplicates(res + cur.fetchall())
|
)
|
||||||
|
res += cur.fetchall()
|
||||||
|
cur.execute(
|
||||||
|
"SELECT LVAs.id,LVAs.lvid,LVAs.lvname FROM LVAs LEFT JOIN LPLink ON LVAs.id=LPLink.lid WHERE pid=?",
|
||||||
|
(pid,),
|
||||||
|
)
|
||||||
|
zw = cur.fetchall()
|
||||||
|
if searchterm != "":
|
||||||
|
cur.execute(
|
||||||
|
"SELECT id,lvid,lvname FROM LVAs WHERE lvname LIKE ?",
|
||||||
|
(searchterm + "%",),
|
||||||
|
)
|
||||||
|
res += cur.fetchall()
|
||||||
|
cur.execute(
|
||||||
|
"SELECT id,lvid,lvname FROM LVAs WHERE lvname LIKE ?",
|
||||||
|
("%" + searchterm + "%",),
|
||||||
|
)
|
||||||
|
res += cur.fetchall()
|
||||||
|
res = remove_duplicates(res + zw)
|
||||||
if searchlim == 0:
|
if searchlim == 0:
|
||||||
return res
|
return res
|
||||||
else:
|
else:
|
||||||
@@ -188,7 +207,7 @@ async def create_upload_file(files: List[UploadFile], c2pdf: bool = True):
|
|||||||
filename = files[0].filename if files[0].filename is not None else "None"
|
filename = files[0].filename if files[0].filename is not None else "None"
|
||||||
if len(files) == 1:
|
if len(files) == 1:
|
||||||
content = await files[0].read()
|
content = await files[0].read()
|
||||||
ft = filetype.guess(content).extension
|
ft: str = guess_filetype(content, filename)
|
||||||
if c2pdf and ft != "pdf":
|
if c2pdf and ft != "pdf":
|
||||||
ret = convert_to_pdf(content)
|
ret = convert_to_pdf(content)
|
||||||
if ret is not None:
|
if ret is not None:
|
||||||
@@ -199,7 +218,7 @@ async def create_upload_file(files: List[UploadFile], c2pdf: bool = True):
|
|||||||
filecontents = []
|
filecontents = []
|
||||||
for file in files:
|
for file in files:
|
||||||
content = await file.read()
|
content = await file.read()
|
||||||
ft = filetype.guess(content).extension
|
ft = guess_filetype(content, filename)
|
||||||
if ft == "pdf":
|
if ft == "pdf":
|
||||||
filecontents.append(content)
|
filecontents.append(content)
|
||||||
continue
|
continue
|
||||||
@@ -575,6 +594,7 @@ def make_filename_unique(filename: str, idx: int | None = None) -> str:
|
|||||||
|
|
||||||
|
|
||||||
async def save_files_to_folder(files: List[UploadFile]) -> str:
|
async def save_files_to_folder(files: List[UploadFile]) -> str:
|
||||||
|
"""saves file to files in prograss folder"""
|
||||||
filename = files[0].filename if files[0].filename is not None else "None"
|
filename = files[0].filename if files[0].filename is not None else "None"
|
||||||
filename = filename.split(".")[0]
|
filename = filename.split(".")[0]
|
||||||
if filename == "":
|
if filename == "":
|
||||||
@@ -592,3 +612,12 @@ async def save_files_to_folder(files: List[UploadFile]) -> str:
|
|||||||
# reqJson = await request.form()
|
# reqJson = await request.form()
|
||||||
# print(reqJson)
|
# print(reqJson)
|
||||||
# return {"done": "ok"}
|
# return {"done": "ok"}
|
||||||
|
def guess_filetype(content: str, filename: str) -> str:
|
||||||
|
"""Guesses the filetype of a file based on first the sontent, If that fails the extension in teh filename. If no conclusion can be reached it reutrns an empty string"""
|
||||||
|
ftyp = filetype.guess(content)
|
||||||
|
if ftyp is not None:
|
||||||
|
return ftyp.extension
|
||||||
|
farr = filename.split(".")
|
||||||
|
if len(farr) > 1:
|
||||||
|
return filename.split(".")[-1]
|
||||||
|
return ""
|
||||||
|
|||||||
35
index.html
35
index.html
@@ -7,6 +7,8 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.4.456/pdf.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.4.456/pdf.min.js"></script>
|
||||||
<script src="static/app.js" defer></script>
|
<script src="static/app.js" defer></script>
|
||||||
<script src="static/autocomplete.js" defer></script>
|
<script src="static/autocomplete.js" defer></script>
|
||||||
|
<script src="static/dynhide.js" defer></script>
|
||||||
|
<script src="static/filedrop.js" defer></script>
|
||||||
<link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96" />
|
<link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon/favicon.svg" />
|
||||||
<link rel="shortcut icon" href="/favicon/favicon.ico" />
|
<link rel="shortcut icon" href="/favicon/favicon.ico" />
|
||||||
@@ -20,23 +22,29 @@
|
|||||||
<div class="left" id="controldiv">
|
<div class="left" id="controldiv">
|
||||||
<div id="fileupload">
|
<div id="fileupload">
|
||||||
<form id="uploadform" enctype="multipart/form-data">
|
<form id="uploadform" enctype="multipart/form-data">
|
||||||
<label for="filepicker">Choose a pdf file</label>
|
<div class="filetop">
|
||||||
<input type="file" name="files" id="filepicker" multiple />
|
<!-- <label for="filepicker">Choose a file</label> -->
|
||||||
<button type="submit" id="upload" method="POST">Upload</button>
|
<input type="file" name="files" id="filepicker" multiple placeholder="Drop File" />
|
||||||
|
</div>
|
||||||
|
<button type="submit" id="upload" method="POST" class="fileupload">
|
||||||
|
Upload
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="submitdiv">
|
<div id="submitdiv">
|
||||||
<form id="submitform" ,onsubmit="submitFile(event)">
|
<form id="submitform" ,onsubmit="submitFile(event)">
|
||||||
<label for="lva">Lehrveranstaltung:</label>
|
<label for="lva">Lehrveranstaltung:</label>
|
||||||
<div class="autocomplete">
|
<div class="autocomplete">
|
||||||
<input type="text" id="lva" name="lva" placeholder="Lehrveranstaltung" autocomplete="off" /><br />
|
<input type="text" id="lva" name="lva" placeholder="Lehrveranstaltung" autocomplete="off" />
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
|
<!-- <br /> -->
|
||||||
<label for="prof">Vortragende*r:</label>
|
<label for="prof">Vortragende*r:</label>
|
||||||
<div class="autocomplete">
|
<div class="autocomplete">
|
||||||
<input type="text" id="prof" name="prof" placeholder="Vortragende*r" autocomplete="off" /><br />
|
<input type="text" id="prof" name="prof" placeholder="Vortragende*r" autocomplete="off" />
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
|
<!-- <br /> -->
|
||||||
<label for="name">Name:</label>
|
<label for="name">Name:</label>
|
||||||
<input type="text" id="name" name="fname" placeholder="Prüfung" /><br />
|
<input type="text" id="name" name="fname" placeholder="Prüfung" /><br />
|
||||||
<label for="sem">Semester:</label>
|
<label for="sem">Semester:</label>
|
||||||
@@ -55,14 +63,17 @@
|
|||||||
<label for="zusammenfassungen">Zusammenfassung</label><br />
|
<label for="zusammenfassungen">Zusammenfassung</label><br />
|
||||||
<input type="radio" id="multimedia" name="stype" value="6" />
|
<input type="radio" id="multimedia" name="stype" value="6" />
|
||||||
<label for="multimedia">Multimedia</label><br />
|
<label for="multimedia">Multimedia</label><br />
|
||||||
<label for="subcat">Veranstaltung</label>
|
<br />
|
||||||
<div class="autocomplete">
|
<div id="subcatdiv">
|
||||||
<input type="text" id="subcat" name="subcat" placeholder="Klausur 1" autocomplete="off" />
|
<label for="subcat">Veranstaltung</label>
|
||||||
|
<div class="autocomplete">
|
||||||
|
<input type="text" id="subcat" name="subcat" placeholder="Klausur 1" autocomplete="off" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="datediv">
|
||||||
|
<label for="date">Datum</label>
|
||||||
|
<input type="date" id="date" name="ex_date" placeholder="Drop File" /><br />
|
||||||
</div>
|
</div>
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<label for="date">Datum</label>
|
|
||||||
<input type="date" id="date" name="ex_date" /><br />
|
|
||||||
<button type="submit" id="send">Senden</button>
|
<button type="submit" id="send">Senden</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -20,10 +20,13 @@ function autocomplete(inp, type) {
|
|||||||
val = this.value;
|
val = this.value;
|
||||||
/*close any already open lists of autocompleted values*/
|
/*close any already open lists of autocompleted values*/
|
||||||
closeAllLists();
|
closeAllLists();
|
||||||
if (!val && type === "lva") {
|
if (!val && type === "lva" && pid === null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (type === "prof" && lid !== null) {
|
if (type === "lva" && pid !== null) {
|
||||||
|
apirq =
|
||||||
|
url + type + "?searchterm=" + val + "&pid=" + pid + "&searchlim=10";
|
||||||
|
} else if (type === "prof" && lid !== null) {
|
||||||
apirq =
|
apirq =
|
||||||
url + type + "?searchterm=" + val + "&lid=" + lid + "&searchlim=10";
|
url + type + "?searchterm=" + val + "&lid=" + lid + "&searchlim=10";
|
||||||
} else if (type === "subcat" && lid !== null && pid !== null) {
|
} else if (type === "subcat" && lid !== null && pid !== null) {
|
||||||
|
|||||||
42
static/dynhide.js
Normal file
42
static/dynhide.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
var radiobuttons;
|
||||||
|
var datediv;
|
||||||
|
var subcatdiv;
|
||||||
|
var rdbarr;
|
||||||
|
var subcatcategories = [1, 2, 3];
|
||||||
|
var datecategorires = [0, 1];
|
||||||
|
function changevis() {
|
||||||
|
for (let i = 0; i < rdbarr.length; i++) {
|
||||||
|
if (rdbarr[i].checked) {
|
||||||
|
if (subcatcategories.includes(i)) {
|
||||||
|
subcatdiv.style.display = "block";
|
||||||
|
} else {
|
||||||
|
subcatdiv.style.display = "none";
|
||||||
|
}
|
||||||
|
if (datecategorires.includes(i)) {
|
||||||
|
datediv.style.display = "block";
|
||||||
|
} else {
|
||||||
|
datediv.style.display = "none";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function starthide() {
|
||||||
|
radiobuttons = document.getElementsByName("stype");
|
||||||
|
datediv = document.getElementById("datediv");
|
||||||
|
subcatdiv = document.getElementById("subcatdiv");
|
||||||
|
rdbarr = [
|
||||||
|
document.getElementById("pruefung"),
|
||||||
|
document.getElementById("klausur"),
|
||||||
|
document.getElementById("uebung"),
|
||||||
|
document.getElementById("labor"),
|
||||||
|
document.getElementById("unterlagen"),
|
||||||
|
document.getElementById("zusammenfassungen"),
|
||||||
|
document.getElementById("multimedia"),
|
||||||
|
];
|
||||||
|
changevis();
|
||||||
|
radiobuttons.forEach((rdb) => {
|
||||||
|
rdb.addEventListener("change", changevis);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.addEventListener("load", starthide);
|
||||||
10
static/filedrop.js
Normal file
10
static/filedrop.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
var fileinput;
|
||||||
|
function dropHandler(eve) {
|
||||||
|
eve.preventDefault();
|
||||||
|
fileinput.files = eve.dataTransfer.files;
|
||||||
|
}
|
||||||
|
function init() {
|
||||||
|
fileinput = document.getElementById("filepicker");
|
||||||
|
document.getElementById("filepicker").addEventListener("drop", dropHandler);
|
||||||
|
}
|
||||||
|
window.addEventListener("load", init);
|
||||||
128
static/style.css
128
static/style.css
@@ -6,7 +6,7 @@ body {
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: slategrey;
|
background-color: #2f3957;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,11 +15,11 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
width: 75vw;
|
width: 75vw;
|
||||||
float: right;
|
float: right;
|
||||||
background-color: navy;
|
/* background-color: navy; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
background-color: blueviolet;
|
/* background-color: blueviolet; */
|
||||||
height: 100%;
|
height: 100%;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
@@ -77,6 +77,16 @@ span {
|
|||||||
#submitdiv {
|
#submitdiv {
|
||||||
/*position: relative;*/
|
/*position: relative;*/
|
||||||
width: 500px;
|
width: 500px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
/* color: white; */
|
||||||
|
background-color: grey;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
/* margin: 10px; */
|
||||||
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Things I've stolen from https://www.w3schools.com/howto/howto_js_autocomplete.asp*/
|
/*Things I've stolen from https://www.w3schools.com/howto/howto_js_autocomplete.asp*/
|
||||||
@@ -84,29 +94,59 @@ span {
|
|||||||
/*the container must be positioned relative:*/
|
/*the container must be positioned relative:*/
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 300px;
|
/* width: 400px; */
|
||||||
|
width: 100%;
|
||||||
|
padding: none;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#name {
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
border: 1px solid transparent;
|
border: 1px solid #818181;
|
||||||
background-color: #f1f1f1;
|
background-color: #a1a1a1;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
font-size: 16px;
|
/* height: 50px; */
|
||||||
|
font-size: 12pt;
|
||||||
|
border-radius: 20px;
|
||||||
|
margin-top: 10px;
|
||||||
|
/* margin-bottom: 10px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="text"] {
|
input[type="text"] {
|
||||||
background-color: #f1f1f1;
|
background-color: #b1b1b1;
|
||||||
width: 100%;
|
/* width: 100%; */
|
||||||
|
width: 478px;
|
||||||
|
border-radius: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="submit"] {
|
/* input[type="text"]:focus { */
|
||||||
background-color: DodgerBlue;
|
/* border-bottom-right-radius: 0px; */
|
||||||
color: #fff;
|
/* border-bottom-left-radius: 0px; */
|
||||||
|
/* outline: none; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
div>input[type="text"]:focus {
|
||||||
|
border-bottom-right-radius: 0px;
|
||||||
|
border-bottom-left-radius: 0px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
background-color: #0872a9;
|
||||||
|
/* color: #fff; */
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autocomplete-items {
|
.autocomplete-items {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border: 1px solid #d4d4d4;
|
/* border: 1px solid #d4d4d4; */
|
||||||
|
border: 1px solid #818181;
|
||||||
|
background-color: #b1b1b1;
|
||||||
|
/* background-color: #b1b1b1; */
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
@@ -114,22 +154,78 @@ input[type="submit"] {
|
|||||||
top: 100%;
|
top: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
border-bottom-left-radius: 20px;
|
||||||
|
border-bottom-right-radius: 20px;
|
||||||
|
/* padding: 20px; */
|
||||||
|
/* padding-top: 10px; */
|
||||||
|
padding-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autocomplete-items div {
|
.autocomplete-items div {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #fff;
|
/* border-radius: 20px; */
|
||||||
|
background-color: #b1b1b1;
|
||||||
border-bottom: 1px solid #d4d4d4;
|
border-bottom: 1px solid #d4d4d4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autocomplete-items div:hover {
|
.autocomplete-items div:hover {
|
||||||
/*when hovering an item:*/
|
/*when hovering an item:*/
|
||||||
background-color: #e9e9e9;
|
background-color: #0872a9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autocomplete-active {
|
.autocomplete-active {
|
||||||
/*when navigating through the items using the arrow keys:*/
|
/*when navigating through the items using the arrow keys:*/
|
||||||
background-color: DodgerBlue !important;
|
background-color: #0872a9 !important;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* filedrop */
|
||||||
|
input[type="file"] {
|
||||||
|
/* flex: 1; */
|
||||||
|
display: flex;
|
||||||
|
background-color: #b1b1b1;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 100%;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
/* margin-bottom: auto; */
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="file"]::file-selector-button {
|
||||||
|
background-color: #d1d1d1;
|
||||||
|
border-radius: 20px;
|
||||||
|
border-color: #a1a1a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fileupload {
|
||||||
|
/* display: inline-flex; */
|
||||||
|
width: 500px;
|
||||||
|
border-radius: 20px;
|
||||||
|
background-color: #4f5977;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileupload {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: 25%;
|
||||||
|
/* align-self: right; */
|
||||||
|
/* float: right; */
|
||||||
|
}
|
||||||
|
|
||||||
|
#uploadform {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filetop {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
/* background-color: purple; */
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user