fixed project and dockerrized everything

This commit is contained in:
2023-10-16 22:35:46 +02:00
parent 6a67dc40bf
commit 4bd4a3796e
16 changed files with 161 additions and 178 deletions

View File

@@ -1,6 +1,6 @@
{ {
"[python]": { "[python]": {
"editor.defaultFormatter": "ms-python.black-formatter" "editor.defaultFormatter": "ms-python.autopep8"
}, },
"python.formatting.provider": "none" "python.formatting.provider": "none"
} }

View File

@@ -1,17 +0,0 @@
FROM python:3.11.3-alpine
WORKDIR /code
RUN apk --update --upgrade add --no-cache gcc musl-dev jpeg-dev zlib-dev libffi-dev cairo-dev pango-dev gdk-pixbuf-dev
RUN python -m pip install --upgrade pip
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
#set Enviroment Variables used in FLASK
ENV FLASK_APP=app
ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_RUN_PORT=8080
EXPOSE 8080
CMD [ "flask", "run" ]

10
Dockerfile Executable file
View File

@@ -0,0 +1,10 @@
FROM alpine:3.18.4
RUN apk add --no-cache python3 py3-pip
COPY requirements.txt /home
RUN pip install -r /home/requirements.txt
COPY src webserver
WORKDIR /webserver
ENV FLASK_DEGUB=false
ENTRYPOINT [ "python3", "-u", "main.py" ]
EXPOSE 5000

9
docker-compose.yml Normal file
View File

@@ -0,0 +1,9 @@
version: '3.0'
services:
web:
build: .
image: anki_convert
container_name: anki_convert
restart: unless-stopped
ports:
- 8080:5000

Binary file not shown.

View File

@@ -1,10 +1,13 @@
import pdfplumber """Function to extract text from pdf and convert it to anki anntation"""
import re
import re
import codecs import codecs
import pdfplumber
def convert(file_path=False): def convert(file_path=False):
"""Opens pdf and converts it into text"""
if not file_path: if not file_path:
import tkinter as tk import tkinter as tk
from tkinter import filedialog from tkinter import filedialog
@@ -21,23 +24,9 @@ def convert(file_path=False):
with pdfplumber.open(file_path) as pdf: with pdfplumber.open(file_path) as pdf:
for page in pdf.pages: for page in pdf.pages:
crop = page.crop((60, 80, page.width, page.height)) crop = page.crop((60, 80, page.width, page.height))
# first_page = pdf.pages[0]
# first_page = first_page.crop((60, 80, first_page.width, first_page.height))
text = crop.extract_text(layout=True) text = crop.extract_text(layout=True)
no_trail = re.sub("\ +\\n", "\n", text) # cleared trailing spaces no_trail = re.sub("\ +\\n", "\n", text) # cleared trailing spaces
no_wrong_nl = re.sub( new_str = convert_text(no_trail)
"\\n\ +([A-Za-z0-9])", r" \1", no_trail
) # clear wrong newlins
lines = re.split("\n", no_wrong_nl) # split into lines
test = 1
changed_lines = []
for line in lines:
line, num = re.subn("(:)(.+)", rf"\1 {{{{c{test}::\2}}}}", line)
if num > 0:
test += 1
changed_lines.append(line)
new_str = "\n".join(changed_lines).strip()
conv_string.append(new_str) conv_string.append(new_str)
conv_string = "#################### neue Seite ####################\n".join( conv_string = "#################### neue Seite ####################\n".join(
@@ -50,27 +39,28 @@ def convert(file_path=False):
text_file.close() text_file.close()
print(f"Alles fertig, die Datei befindet sich unter {file_path}") print(f"Alles fertig, die Datei befindet sich unter {file_path}")
if not __name__ == "__main__": if __name__ != "__main__":
return conv_string return conv_string
def convert_text(text): def convert_text(text):
"""Seraches for ':' and converts into anki annotation"""
text = str(text) text = str(text)
if "\r\n" in text: if "\r\n" in text:
text = text.replace("\r\n", "\n") text = text.replace("\r\n", "\n")
no_wrong_nl = re.sub("\\n\ +([A-Za-z0-9])", r" \1", text) # clear wrong newlins no_wrong_nl = re.sub("\\n\ +([A-Za-z0-9])",r" \1", text) # clear wrong newlins
lines = re.split("\n", no_wrong_nl) # split into lines lines = re.split("\n", no_wrong_nl) # split into lines
test = 1 test = 1
changed_lines = [] changed_lines = []
for line in lines: for line in lines:
line, num = re.subn("(:)(.+)", rf"\1 {{{{c{test}::\2}}}}", line) line, num = re.subn("(:)(..+)", rf"\1 {{{{c{test}::\2}}}}", line)
if num > 0: if num > 0:
test += 1 test += 1
changed_lines.append(line) changed_lines.append(line)
new_str = "\n".join(changed_lines).strip() new_str = "\n".join(changed_lines).strip()
if not __name__ == "__main__": if __name__ != "__main__":
return new_str return new_str

View File

@@ -1,5 +1,8 @@
from flask import Flask, render_template, request, redirect, url_for, make_response """Main App Module"""
from os import makedirs, path
from os import makedirs, path, environ
from flask import Flask, render_template, request
import functions import functions
app = Flask(__name__) app = Flask(__name__)
@@ -7,11 +10,13 @@ app = Flask(__name__)
@app.route("/") @app.route("/")
def index(): def index():
"""Renders Index Page"""
return render_template("index.html") return render_template("index.html")
@app.route("/upload", methods=["POST"]) @app.route("/upload", methods=["POST"])
def upload_file(): def upload_file():
"""Handles Upload -> Files will be extracted and converted, text just converted"""
uploaded_file = request.files["file"] uploaded_file = request.files["file"]
text = request.form["text"] text = request.form["text"]
makedirs("uploads", exist_ok=True) makedirs("uploads", exist_ok=True)
@@ -20,6 +25,7 @@ def upload_file():
filepath = path.join("uploads", uploaded_file.filename) filepath = path.join("uploads", uploaded_file.filename)
uploaded_file.save(filepath) uploaded_file.save(filepath)
response_text = functions.convert(filepath) response_text = functions.convert(filepath)
text = response_text
# response = make_response(response_text, 200) # response = make_response(response_text, 200)
# response.mimetype = "text/plain" # response.mimetype = "text/plain"
else: else:
@@ -27,10 +33,11 @@ def upload_file():
# response = make_response(response_text, 200) # response = make_response(response_text, 200)
# response.mimetype = "text/plain" # response.mimetype = "text/plain"
# return response #redirect(url_for('index')) # return response #redirect(url_for('index'))
return render_template("index.html", text=response_text) return render_template("index.html", resp_text=response_text, base_text=text)
if __name__ == "__main__": if __name__ == "__main__":
app.jinja_env.auto_reload = True # app.jinja_env.auto_reload = True
app.config["TEMPLATES_AUTO_RELOAD"] = True # app.config["TEMPLATES_AUTO_RELOAD"] = True
app.run(host="0.0.0.0", port=8000) port = int(environ.get('PORT', 5000))
app.run(debug=True, host='0.0.0.0', port=port)

112
src/static/style.css Executable file
View File

@@ -0,0 +1,112 @@
:root{
--green:#4CAF50;
--primary:#3b3b3b;
}
*{
font-family: sans-serif;
font-size: 18px;
}
body{
margin: 0;
padding: 0;
color: var(--primary);
}
main{
display: grid;
width: 90vw;
margin: 5vw;
flex-wrap: wrap;
grid-template-areas: "head-input head-output"
"input output";
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
h1.input{
grid-area: head-input;
}
h1.output{
grid-area: head-output;
}
h1{
font-size: 2rem;
margin: 0;
margin-bottom: .5rem;
}
textarea{
grid-area: input;
}
pre{
grid-area: output;
}
main > div{
width: 100%;
box-sizing: border-box;
}
textarea{
width: 100%;
height: 20vh;
margin: 20px 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
input[type="file"] {
display: none;
}
.custom-file-upload, button {
background-color: white;
color: var(--primary);
border: 2px solid var(--green); /* Green */
/* background-color: lightgray; */
display: inline-block;
padding: 6px 12px;
cursor: pointer;
font-size: 1rem;
border-radius: .2rem;
transition-duration: 0.4s;
}
.custom-file-upload:hover, button:hover {
background-color: var(--green); /* Green */
color: white;
}
.custom-file-upload span, button span {
vertical-align: bottom;
}
.material-symbols-outlined {
padding-right: 0.3rem;
}
textarea, pre{
background-color: white;
color: var(--primary);
border: 2px solid var(--green); /* Green */
border-radius: .2rem;
margin: .5rem 0;
min-height: 10rem;
padding: .2rem;
}
@media (max-width: 600px) {
main{
width: 100wv;
}
main > div{
width: 100%;
}
}

View File

@@ -1,13 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Upload Text</title> <title>Anki Converter</title>
<link rel="stylesheet" href='/static/style.css' /> <link rel="stylesheet" href='/static/style.css' />
</head> </head>
<body> <body>
<main> <main>
<div id="left"> <div id="left">
<h1>File Upload Example</h1> <h1>Upload File/Enter Text</h1>
<form action="/upload" method="post" enctype="multipart/form-data"> <form action="/upload" method="post" enctype="multipart/form-data">
<label class="custom-file-upload"> <label class="custom-file-upload">
<input id="myfile" type="file" name="file" accept=".pdf"/> <input id="myfile" type="file" name="file" accept=".pdf"/>
@@ -15,14 +15,14 @@
</label> </label>
<button type="submit">Upload</button> <button type="submit">Upload</button>
<br> <br>
<textarea name="text">{% if text %}{{ text }}{% else %}Text in here{% endif %}</textarea> <textarea name="text">{% if resp_text %}{{ base_text }}{% else %}Text in here{% endif %}</textarea>
</form> </form>
</div> </div>
{% if text %} {% if resp_text %}
<div id="right"> <div id="right">
<h1>Converted Text</h1> <h1>Converted Text</h1>
<button id="copy-btn">Copy Text</button> <button id="copy-btn">Copy Text</button>
<pre id="myInput">{{ text }} <pre id="myInput">{{ resp_text }}
</pre> </pre>
</div> </div>
{% endif %} {% endif %}

View File

@@ -1,42 +0,0 @@
*{
font-family: sans-serif;
}
main{
display: flex;
width: 90vw;
height: 50vh;
margin: 0 5vw;
gap: 2rem;
}
main div{
width: 50%;
}
textarea{
width: 90%;
height: 20vh;
margin: 20px 0;
min-height: fit-content;
}
/* button{
border: 1px solid black;
padding: 5px;
border-radius: 2.5px;
} */
input[type="file"] {
display: none;
}
.custom-file-upload, button {
border: 1px solid #313131;
background-color: lightgray;
display: inline-block;
padding: 6px 12px;
cursor: pointer;
font-size: 1rem;
border-radius: .2rem;
}

Binary file not shown.

View File

@@ -1,49 +0,0 @@
Aufgabenvorschlag OOP
Namen und Seminargruppe(n) der Studierenden:
Projekttitel
Beschreibung des Programmvorschlags (inkl. Programmiersprache)
Skizzen
(als Bild einfügen und separat per E-Mail einreichen)
Mindestumfang
Mögliche Erweiterungen
__________________________ __________ __________ __________ Ort, Datum Unterschriften
_________ _________

View File

@@ -1,37 +0,0 @@
Vestibulospinale Reflexe
• Aufteilung:
◦statische Reflexe
‣ Def: {{c1:: durch bestimmte Körperhaltung ausgelöst, für Aufrechterhaltung des Gleichgewichts in Stand und Gang, Unterteilt in Steh- und Stellreflexe}}
◦statokinetische Reflexe
‣ Def: {{c2:: ausgelöst durch Bewegeung, Für Gleichgewicht beim Laufen, Springen}}
Vestibulookulärer Reflex -> siehe Hirnstammreflexe
• Def: {{c3:: Augenbewegung gegen Kopfbewegung zur Fixierung des Gegenstands bej Kopfbewegung}}
• Funktion: {{c4:: Blickstabilisierung, Fixierung Bild auf Netzhaut}}
Nystagmus:
• pathologische Arten: {{c5:: Spontannystagmus}}
◦Unterteilung
‣ Ausfallnystagmus
• Def: {{c6:: Zerstören der Vestibularbahn}}
• Richtung: {{c7:: von kranker Seite weg}}
‣ Reiznystagmus
• Def: {{c8:: Reizung des Vestibularapparats}}
• Richtung: {{c9:: zu kranker Seite hin}}
• physiologische Arten
◦vestibulärer Nystagmus
‣ rotatorischef Nystagmus
• Ursache: {{c10:: Fixierung eines Punkts bei Rotation des Probanden}}
• Richtung: {{c11:: in Rotationsrichtung}}
‣ postrotatorischer Nystagmus
• Ursache: {{c12:: Stopp einer Rotation}}
• Richtung: {{c13:: gegen Rotation}}
‣ kalorischer Nystagmus
• Auslösung: {{c14:: Spülung des Gehörgangs mit kaltem oder warmem Wasser}}
• Vorgang: {{c15:: Reizung Bogengang durch Spülung, Bewgeung Endolymphe durch Temperatur}}
• Richtung: {{c16:: Warmspülung zeigt der Nystagmus zum gespülten Ohr hin, bei Kaltspülung vom gespülten Ohr weg}}
◦optokinetischer Nystagmus = Eisenbahnnystagmus
‣ Vorgang:
• Augen fixieren Punkt, versuchen diesen so lange wie möglich im Blickfeld zu behalten -> Augenauslenkbewegung
• Rückstellbewegung falls Bulbus maximal ausgelenkt
‣ Richtung: {{c17:: gegen Bewegung der Umwelt}}