fixed project and dockerrized everything
This commit is contained in:
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"[python]": {
|
||||
"editor.defaultFormatter": "ms-python.black-formatter"
|
||||
"editor.defaultFormatter": "ms-python.autopep8"
|
||||
},
|
||||
"python.formatting.provider": "none"
|
||||
}
|
||||
17
DOCKERFILE
17
DOCKERFILE
@@ -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
10
Dockerfile
Executable 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
9
docker-compose.yml
Normal 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.
@@ -1,10 +1,13 @@
|
||||
import pdfplumber
|
||||
import re
|
||||
"""Function to extract text from pdf and convert it to anki anntation"""
|
||||
|
||||
import re
|
||||
import codecs
|
||||
import pdfplumber
|
||||
|
||||
|
||||
|
||||
def convert(file_path=False):
|
||||
"""Opens pdf and converts it into text"""
|
||||
if not file_path:
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog
|
||||
@@ -21,23 +24,9 @@ def convert(file_path=False):
|
||||
with pdfplumber.open(file_path) as pdf:
|
||||
for page in pdf.pages:
|
||||
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)
|
||||
no_trail = re.sub("\ +\\n", "\n", text) # cleared trailing spaces
|
||||
no_wrong_nl = re.sub(
|
||||
"\\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()
|
||||
new_str = convert_text(no_trail)
|
||||
conv_string.append(new_str)
|
||||
|
||||
conv_string = "#################### neue Seite ####################\n".join(
|
||||
@@ -50,27 +39,28 @@ def convert(file_path=False):
|
||||
text_file.close()
|
||||
|
||||
print(f"Alles fertig, die Datei befindet sich unter {file_path}")
|
||||
if not __name__ == "__main__":
|
||||
if __name__ != "__main__":
|
||||
return conv_string
|
||||
|
||||
|
||||
def convert_text(text):
|
||||
"""Seraches for ':' and converts into anki annotation"""
|
||||
text = str(text)
|
||||
if "\r\n" in text:
|
||||
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
|
||||
|
||||
test = 1
|
||||
changed_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:
|
||||
test += 1
|
||||
changed_lines.append(line)
|
||||
new_str = "\n".join(changed_lines).strip()
|
||||
if not __name__ == "__main__":
|
||||
if __name__ != "__main__":
|
||||
return new_str
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
from flask import Flask, render_template, request, redirect, url_for, make_response
|
||||
from os import makedirs, path
|
||||
"""Main App Module"""
|
||||
|
||||
from os import makedirs, path, environ
|
||||
|
||||
from flask import Flask, render_template, request
|
||||
import functions
|
||||
|
||||
app = Flask(__name__)
|
||||
@@ -7,11 +10,13 @@ app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
"""Renders Index Page"""
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
@app.route("/upload", methods=["POST"])
|
||||
def upload_file():
|
||||
"""Handles Upload -> Files will be extracted and converted, text just converted"""
|
||||
uploaded_file = request.files["file"]
|
||||
text = request.form["text"]
|
||||
makedirs("uploads", exist_ok=True)
|
||||
@@ -20,6 +25,7 @@ def upload_file():
|
||||
filepath = path.join("uploads", uploaded_file.filename)
|
||||
uploaded_file.save(filepath)
|
||||
response_text = functions.convert(filepath)
|
||||
text = response_text
|
||||
# response = make_response(response_text, 200)
|
||||
# response.mimetype = "text/plain"
|
||||
else:
|
||||
@@ -27,10 +33,11 @@ def upload_file():
|
||||
# response = make_response(response_text, 200)
|
||||
# response.mimetype = "text/plain"
|
||||
# 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__":
|
||||
app.jinja_env.auto_reload = True
|
||||
app.config["TEMPLATES_AUTO_RELOAD"] = True
|
||||
app.run(host="0.0.0.0", port=8000)
|
||||
# app.jinja_env.auto_reload = True
|
||||
# app.config["TEMPLATES_AUTO_RELOAD"] = True
|
||||
port = int(environ.get('PORT', 5000))
|
||||
app.run(debug=True, host='0.0.0.0', port=port)
|
||||
112
src/static/style.css
Executable file
112
src/static/style.css
Executable 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%;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Upload Text</title>
|
||||
<title>Anki Converter</title>
|
||||
<link rel="stylesheet" href='/static/style.css' />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div id="left">
|
||||
<h1>File Upload Example</h1>
|
||||
<h1>Upload File/Enter Text</h1>
|
||||
<form action="/upload" method="post" enctype="multipart/form-data">
|
||||
<label class="custom-file-upload">
|
||||
<input id="myfile" type="file" name="file" accept=".pdf"/>
|
||||
@@ -15,14 +15,14 @@
|
||||
</label>
|
||||
<button type="submit">Upload</button>
|
||||
<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>
|
||||
</div>
|
||||
{% if text %}
|
||||
{% if resp_text %}
|
||||
<div id="right">
|
||||
<h1>Converted Text</h1>
|
||||
<button id="copy-btn">Copy Text</button>
|
||||
<pre id="myInput">{{ text }}
|
||||
<pre id="myInput">{{ resp_text }}
|
||||
</pre>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -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.
Binary file not shown.
@@ -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
|
||||
_________ _________
|
||||
Binary file not shown.
@@ -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}}
|
||||
Reference in New Issue
Block a user