Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 79c3cb83c7 | |||
| cb9fa61bc5 | |||
| 9a1e438615 | |||
| 787cb10e21 | |||
| ad208f3403 | |||
| b60316750a | |||
| 013a6b298e | |||
| f1dce2417f | |||
| 9947c205c7 | |||
| 8510169495 | |||
| c88e673759 | |||
| f4efc17e2a | |||
| 03b2e4a0ee | |||
| 77fd1be257 | |||
| 64dc76327e | |||
| 3f4aed3978 |
@@ -6,11 +6,11 @@ on:
|
||||
image_tag:
|
||||
description: '2. Tag für das Docker-Image (außer latest) (z.B. v1.0.0)'
|
||||
required: true
|
||||
default: '0.6.0'
|
||||
default: '0.7.3'
|
||||
|
||||
env:
|
||||
image_name: mysteryhelfer
|
||||
registry: gitea.tebarius.duckdns.org
|
||||
registry_gitea: gitea.tebarius.duckdns.org
|
||||
user: tebarius
|
||||
|
||||
jobs:
|
||||
@@ -26,9 +26,15 @@ jobs:
|
||||
- name: Login to Gitea
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{ env.registry }}
|
||||
registry: ${{ env.registry_gitea }}
|
||||
username: ${{ env.user }}
|
||||
password: ${{ secrets.DOCKER_PULL_TOKEN }}
|
||||
password: ${{ secrets.IMAGE_REGISTRY_TOKEN_GITEA }}
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ env.user }}
|
||||
password: ${{ secrets.DOCKER_HUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
run: |
|
||||
@@ -39,6 +45,8 @@ jobs:
|
||||
docker buildx build \
|
||||
--file ./Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--tag ${{ env.registry }}/${{ env.user }}/${{ env.image_name }}:latest \
|
||||
--tag ${{ env.registry }}/${{ env.user }}/${{ env.image_name }}:${{ github.event.inputs.image_tag }} \
|
||||
--tag ${{ env.registry_gitea }}/${{ env.user }}/${{ env.image_name }}:latest \
|
||||
--tag ${{ env.registry_gitea }}/${{ env.user }}/${{ env.image_name }}:${{ github.event.inputs.image_tag }} \
|
||||
--tag ${{ env.user }}/${{ env.image_name }}:latest \
|
||||
--tag ${{ env.user }}/${{ env.image_name }}:${{ github.event.inputs.image_tag }} \
|
||||
--push ./
|
||||
|
||||
28
.gitea/workflows/trivy_image_scan.yml
Normal file
28
.gitea/workflows/trivy_image_scan.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
name: release-tag
|
||||
|
||||
on:
|
||||
workflow_dispatch: # Manuelles Auslösen des Workflows
|
||||
inputs:
|
||||
image_tag:
|
||||
description: 'Tag für das zu scannende Docker-Image z.B. latest'
|
||||
required: true
|
||||
default: 'latest'
|
||||
|
||||
env:
|
||||
image_name: mysteryhelfer
|
||||
registry_gitea: gitea.tebarius.duckdns.org
|
||||
user: tebarius
|
||||
|
||||
jobs:
|
||||
trivy_image_scan:
|
||||
runs-on: ubuntu-latest
|
||||
container: aquasec/trivy:latest
|
||||
steps:
|
||||
- name: Scan image with trivy
|
||||
run: |
|
||||
trivy image \
|
||||
--exit-code 1 \
|
||||
--scanners vuln,misconfig,secret \
|
||||
--severity MEDIUM,HIGH,CRITICAL \
|
||||
--ignore-unfixed \
|
||||
${{ env.registry_gitea }}/${{ env.user }}/${{ env.image_name }}:${{ github.event.inputs.image_tag }}
|
||||
22
Dockerfile
22
Dockerfile
@@ -5,20 +5,30 @@ LABEL description="tebarius Mysteryhelfer web"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y curl \
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends curl \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY ./app /app
|
||||
|
||||
COPY ./patch-streamlit/* /usr/local/lib/python3.13/site-packages/streamlit/static/
|
||||
RUN python -m pip install --upgrade pip \
|
||||
&& pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
|
||||
# ein bisschen Patchen um auch beim Bookmarken oder Versenden der Webadresse per Messenger den richtigen Titel und das
|
||||
# richtige Favicon zu verwenden/sehen
|
||||
COPY ./app/images/favicon.ico /usr/local/lib/python3.13/site-packages/streamlit/static/favicon.ico
|
||||
RUN sed -i -e 's|favicon\.png|favicon.ico|' \
|
||||
-e 's|<title>.*</title>|<title>tebarius Mysteryhelfer (web)</title>|' \
|
||||
/usr/local/lib/python3.13/site-packages/streamlit/static/index.html \
|
||||
&& useradd -m -u 1000 myst \
|
||||
&& chown -R myst:myst /app
|
||||
USER myst
|
||||
|
||||
EXPOSE 8501
|
||||
|
||||
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
|
||||
|
||||
ENTRYPOINT ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
|
||||
ENTRYPOINT ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
|
||||
|
||||
@@ -4,7 +4,7 @@ import streamlit as st
|
||||
import base64
|
||||
import tools
|
||||
import matplotlib.pyplot as plt
|
||||
from helper import show_map_folium
|
||||
import helper
|
||||
|
||||
standard_output = ('#### Um den HILFE-Text zu einzelnen Funktionen aufzurufen bitte die Funktion mit leerem'
|
||||
' Eingabefeld aufrufen.')
|
||||
@@ -224,6 +224,7 @@ if 'input_text' not in st.session_state:
|
||||
st.session_state.input_text = ""
|
||||
if 'output_text' not in st.session_state:
|
||||
st.session_state.output_text = standard_output
|
||||
st.session_state.output_text += helper.generate_special_files()
|
||||
if 'map_data' not in st.session_state:
|
||||
st.session_state.map_data = None
|
||||
if 'graph_data' not in st.session_state:
|
||||
@@ -361,7 +362,7 @@ st.markdown(st.session_state.output_text)
|
||||
# Karte anzeigen, falls aktiviert
|
||||
if st.session_state.map_data is not None:
|
||||
st.subheader("Kartenansicht")
|
||||
show_map_folium(st.session_state.map_data)
|
||||
helper.show_map_folium(st.session_state.map_data)
|
||||
|
||||
|
||||
if st.session_state.graph_data is not None:
|
||||
|
||||
@@ -5,6 +5,7 @@ from re import match # für unkennify
|
||||
import streamlit as st
|
||||
from streamlit_folium import st_folium
|
||||
import folium
|
||||
import os
|
||||
|
||||
|
||||
# ***recursive quersummenfunktion***
|
||||
@@ -175,6 +176,20 @@ def unkennify(text):
|
||||
decoded = decoded + text[i:]
|
||||
return decoded
|
||||
|
||||
def generate_special_files():
|
||||
out="\n\n\n"
|
||||
if os.path.exists("./data/morse-de.dic"):
|
||||
pass
|
||||
else:
|
||||
remorse_generate_morsede()
|
||||
out+=":blue[deutsches Re-Morse-Wörterbuch wurde generiert] \n"
|
||||
if os.path.exists("./data/t9-de.dic"):
|
||||
pass
|
||||
else:
|
||||
t9_generate_t9de()
|
||||
out+=":blue[deutsches T9-Wörterbuch wurde generiert] \n"
|
||||
return out
|
||||
|
||||
def remorse_generate_morsede():
|
||||
alphabet = {'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.',
|
||||
'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.',
|
||||
@@ -225,62 +240,6 @@ def t9_generate_t9de():
|
||||
file.close()
|
||||
ofile.close()
|
||||
|
||||
def remorse_germandic(eingabetext):
|
||||
alphabet = {'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.',
|
||||
'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.',
|
||||
'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-',
|
||||
'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '1': '.----',
|
||||
'2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...',
|
||||
'8': '---..', '9': '----.', '0': '-----', 'Ñ': '--.--', 'É': '..-..', 'È': '.-..-',
|
||||
'À': '.--.-', 'Ü': '..--', 'Ö': '---.', 'Ä': '.-.-', '_': '..--.-', '@': '.--.-.',
|
||||
'?': '..--..', '=': '-...-', ';': '-.-.-.', ':': '---...', '/': '-..-.',
|
||||
'.': '.-.-.-', '-': '-....-', ',': '--..--', '+': '.-.-.', ')': '-.--.-',
|
||||
'(': '-.--.', "'": '.----.', 'SS': '...--..'}
|
||||
ualphabet = {v: k for k, v in alphabet.items()}
|
||||
ualphabet["...--.."] = "ß"
|
||||
eingabetext = eingabetext.rstrip()
|
||||
wbfile = open("./data/german.dic", "r", encoding="iso-8859-15")
|
||||
ausgabetext = ":blue[der eingegebene Morsecode kann für folgendes stehen:] \n"
|
||||
if eingabetext in ualphabet:
|
||||
ausgabetext += ualphabet[eingabetext] + " \n"
|
||||
for zeile in wbfile:
|
||||
zeile = zeile.strip(" \t\n\r")
|
||||
mzeile = ""
|
||||
try:
|
||||
for char in zeile:
|
||||
mzeile += alphabet[char.upper()]
|
||||
except KeyError:
|
||||
continue
|
||||
if eingabetext == mzeile:
|
||||
ausgabetext += zeile + " \n"
|
||||
wbfile.close()
|
||||
return ausgabetext
|
||||
|
||||
def t9_germandic(eingabetext):
|
||||
alphabet = {'A': '2', 'B': '2', 'C': '2', 'D': '3', 'E': '3', 'F': '3', 'G': '4',
|
||||
'H': '4', 'I': '4', 'J': '5', 'K': '5', 'L': '5', 'M': '6', 'N': '6',
|
||||
'O': '6', 'P': '7', 'Q': '7', 'R': '7', 'S': '7', 'T': '8', 'U': '8',
|
||||
'V': '8', 'W': '9', 'X': '9', 'Y': '9', 'Z': '9', '1': '1', '2': '2',
|
||||
'3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9',
|
||||
'0': '0', 'Ñ': '6', 'É': '3', 'È': '3', 'À': '2', 'Ü': '8', 'Ö': '6',
|
||||
'Ä': '2', '@': '1', '?': '1', '=': '0', ':': '1', '/': '1', '.': '1',
|
||||
'-': '1', ',': '1', '+': '0', ')': '1', '(': '1', 'SS': '7'}
|
||||
eingabetext = eingabetext.rstrip()
|
||||
wbfile = open("./data/german.dic", "r", encoding="iso-8859-15")
|
||||
ausgabetext = ":blue[der eingegebene T9-Code kann für folgendes stehen:] \n"
|
||||
for zeile in wbfile:
|
||||
zeile = zeile.strip(" \t\n\r")
|
||||
mzeile = ""
|
||||
try:
|
||||
for char in zeile:
|
||||
mzeile += alphabet[char.upper()]
|
||||
except KeyError:
|
||||
continue
|
||||
if eingabetext == mzeile:
|
||||
ausgabetext += zeile + " \n"
|
||||
wbfile.close()
|
||||
return ausgabetext
|
||||
|
||||
def rail_encrypt(plain_text: str, rails: int):
|
||||
arr = [["" for _ in range(len(plain_text))] for _ in range(rails)]
|
||||
r = 0
|
||||
|
||||
@@ -299,13 +299,9 @@ wortsuche_en = ("### Wortsuche mit Wörterbuch EN\n"
|
||||
remorse_de = ("### RE-Morse DE\n"
|
||||
"Es gibt ja so Leute, die finden es lustig einen Morsecode so aufzuschreiben, daß zwar Wort für Wort "
|
||||
"getrennt wird, aber ansonsten einfach mal die Leerzeichen weggelassen werden. Bei genau solchen "
|
||||
"fiesen Gemeinheiten hilft diese Funktion. Diese Funktion benutzt die deutsche Wörterbuchdatei vom "
|
||||
"Project https://sourceforge.net/projects/germandict \n"
|
||||
"Da eine Abfrage relativ lange dauert gibt es die Möglichkeit ein ca. 100 MB großes remorse-de.dic "
|
||||
"generieren zu lassen, welches ab der nächsten Abfrage dann genutzt wird und wodurch dann nur noch "
|
||||
"ca. 20% der Zeit pro Abfrage benötigt wird. Um die Erstellung zu starten muß das Wort GENERATE "
|
||||
"(Großschreibung beachten!) ins Eingabefeld eingetragen werden und der Funktionsknopf betätigt "
|
||||
"werden.")
|
||||
"fiesen Gemeinheiten hilft diese Funktion. Für diese Funktion wurde basierend auf der deutschen "
|
||||
"Wörterbuchdatei vom Project https://sourceforge.net/projects/germandict eine "
|
||||
"spezielle Wörterbuchdatei generiert, um eine beschleunigte Abfrage zu ermöglichen.")
|
||||
|
||||
remorse_en = ("### RE-Morse EN\n"
|
||||
"Es gibt ja so Leute, die finden es lustig einen Morsecode so aufzuschreiben, daß zwar Wort für Wort "
|
||||
@@ -320,11 +316,9 @@ t9_de = ("### T9-DE\n"
|
||||
"enthaltenen Wörter die zu der eingegebenen T9-kodierten Ziffernfolge passen und gibt "
|
||||
"diese aus. \n"
|
||||
"Bsp. 56673462836 liefert das Wort Koordinaten \n"
|
||||
"Da eine Abfrage relativ lange dauert gibt es die Möglichkeit ein spezielles t9-Wörterbuch "
|
||||
"generieren zu lassen, welches ab der nächsten Abfrage dann genutzt wird und wodurch dann nur noch ca. "
|
||||
"15% der Zeit pro Abfrage benötigt wird. Um die Erstellung des t9-de.dic zu starten muß das Wort "
|
||||
"GENERATE (Großschreibung beachten!) ins Eingabefeld eingetragen werden und der Funktionsknopf "
|
||||
"betätigt werden.")
|
||||
"Für diese Funktion wurde basierend auf der deutschen Wörterbuchdatei vom Project "
|
||||
"https://sourceforge.net/projects/germandict eine spezielle Wörterbuchdatei generiert, um eine beschleunigte "
|
||||
"Abfrage zu ermöglichen.")
|
||||
|
||||
t9_en = ("### T9-EN\n"
|
||||
"Mit Hilfe der englischen Wörterliste en_US-large.txt vom Project "
|
||||
|
||||
96
app/tools.py
96
app/tools.py
@@ -172,11 +172,14 @@ def zeichenanzahl(eingabetext):
|
||||
else:
|
||||
anzahl[b] = 1
|
||||
s = []
|
||||
zeichensumme = 0
|
||||
for key in anzahl:
|
||||
s.append(key)
|
||||
zeichensumme += anzahl[key]
|
||||
s.sort()
|
||||
ausgabetext += f"Es wurden __:orange[{len(anzahl)}]__ unterschiedliche Zeichen gefunden. \n"
|
||||
ausgabetext += "| :blue[Zeichen] | :blue[Anzahl] |\n|----|----|\n"
|
||||
ausgabetext += (f"Es wurden __:orange[{len(anzahl)}]__ unterschiedliche Zeichen in insgesamt "
|
||||
f"__:orange[{zeichensumme}]__ Zeichen gefunden. \n"
|
||||
f"| :blue[Zeichen] | :blue[Anzahl] |\n|----|----|\n")
|
||||
for i in s:
|
||||
if ord(i) == 9:
|
||||
ausgabetext += f"|TAB|{anzahl[i]}|\n"
|
||||
@@ -1461,34 +1464,19 @@ def remorse_de(eingabetext):
|
||||
if eingabetext == "":
|
||||
return hilfetexte.remorse_de
|
||||
else:
|
||||
try:
|
||||
wbfile = open("./data/morse-de.dic", "r",
|
||||
encoding="iso-8859-15") # german.dic von https://sourceforge.net/projects/germandict/
|
||||
except FileNotFoundError:
|
||||
try:
|
||||
testfile = open("./data/german.dic", "r")
|
||||
testfile.close()
|
||||
if eingabetext == "GENERATE":
|
||||
helper.remorse_generate_morsede()
|
||||
return (":green[Remorse-Wörterbuch wurde erzeugt und wird ab dem nächsten Aufruf der Funktion "
|
||||
"benutzt.]")
|
||||
else:
|
||||
ausgabetext = (":green[Da das Remorse-Wörterbuch noch nicht generiert wurde, wurde das normale "
|
||||
"Wörterbuch für die Suche benutzt, das dauert zwar ca. 5x so lange, aber geht "
|
||||
"auch. \n"
|
||||
"Um das Remorse-Wörterbuch zu erzeugen bitte das Wort:] :orange[GENERATE] "
|
||||
":green[ins Eingabefeld eingeben und die Funktion starten.] \n \n")
|
||||
return ausgabetext + helper.remorse_germandic(eingabetext)
|
||||
except FileNotFoundError:
|
||||
return ":red[Leider konnte die Wörterbuchdatei nicht geladen werden.]"
|
||||
wbfile = open("./data/morse-de.dic", "r", encoding="iso-8859-15")
|
||||
ausgabetext = ":blue[der eingegebene Morsecode kann für folgendes stehen:] \n"
|
||||
count = 0
|
||||
for zeile in wbfile:
|
||||
zeile = zeile.strip(" \t\n\r")
|
||||
mline = zeile.split(",")
|
||||
if eingabetext == mline[0]:
|
||||
ausgabetext += mline[1] + " \n"
|
||||
count += 1
|
||||
wbfile.close()
|
||||
if count == 0:
|
||||
return ":red[leider nichts gefunden :disappointed:]"
|
||||
else:
|
||||
ausgabetext = ":blue[der eingegebene Morsecode kann für folgendes stehen:] \n"
|
||||
for zeile in wbfile:
|
||||
zeile = zeile.strip(" \t\n\r")
|
||||
mline = zeile.split(",")
|
||||
if eingabetext == mline[0]:
|
||||
ausgabetext += mline[1] + " \n"
|
||||
wbfile.close()
|
||||
return ausgabetext
|
||||
|
||||
def remorse_en(eingabetext):
|
||||
@@ -1516,6 +1504,7 @@ def remorse_en(eingabetext):
|
||||
ausgabetext = ":blue[der eingegebene Morsecode kann für folgendes stehen:] \n"
|
||||
if eingabetext in ualphabet:
|
||||
ausgabetext += ualphabet[eingabetext] + " \n"
|
||||
count = 0
|
||||
for zeile in wbfile:
|
||||
zeile = zeile.strip(" \t\n\r")
|
||||
mzeile = ""
|
||||
@@ -1526,39 +1515,31 @@ def remorse_en(eingabetext):
|
||||
continue
|
||||
if eingabetext == mzeile:
|
||||
ausgabetext += zeile + " \n"
|
||||
count += 1
|
||||
wbfile.close()
|
||||
return ausgabetext
|
||||
if count == 0:
|
||||
return ":red[leider nichts gefunden :disappointed:]"
|
||||
else:
|
||||
return ausgabetext
|
||||
|
||||
def t9_de(eingabetext):
|
||||
eingabetext = eingabetext.rstrip()
|
||||
if eingabetext == "":
|
||||
return hilfetexte.t9_de
|
||||
else:
|
||||
try:
|
||||
wbfile = open("./data/t9-de.dic", "r", encoding="iso-8859-15")
|
||||
except FileNotFoundError:
|
||||
try:
|
||||
testfile = open("./data/german.dic", "r")
|
||||
testfile.close()
|
||||
if eingabetext == "GENERATE":
|
||||
helper.t9_generate_t9de()
|
||||
return ":green[t9-Wörterbuch wurde erzeugt und wird ab dem nächsten Aufruf der Funktion benutzt.]"
|
||||
else:
|
||||
ausgabetext = (":green[Da das T9-Wörterbuch nicht vorhanden ist, wurde das normale Wörterbuch für "
|
||||
"die Suche benutzt. Das dauert zwar ca. 7x so lange, aber geht auch. \n"
|
||||
"Um das spezielle T9-Wörterbuch zu erzeugen bitte das Wort:] :orange[GENERATE] "
|
||||
":green[ins Eingabefeld eingeben und die Funktion starten.] \n \n")
|
||||
return ausgabetext + helper.t9_germandic(eingabetext)
|
||||
except FileNotFoundError:
|
||||
return ":red[Leider konnte die Wörterbuchdatei nicht geladen werden.]"
|
||||
wbfile = open("./data/t9-de.dic", "r", encoding="iso-8859-15")
|
||||
ausgabetext = ":blue[der eingegebene T9-Code kann für folgendes stehen:] \n"
|
||||
count = 0
|
||||
for zeile in wbfile:
|
||||
zeile = zeile.strip(" \t\n\r")
|
||||
mline = zeile.split(",")
|
||||
if eingabetext == mline[0]:
|
||||
ausgabetext += mline[1] + " \n"
|
||||
count += 1
|
||||
wbfile.close()
|
||||
if count == 0:
|
||||
return ":red[leider nichts gefunden :disappointed:]"
|
||||
else:
|
||||
ausgabetext = ":blue[der eingegebene T9-Code kann für folgendes stehen:] \n"
|
||||
for zeile in wbfile:
|
||||
zeile = zeile.strip(" \t\n\r")
|
||||
mline = zeile.split(",")
|
||||
if eingabetext == mline[0]:
|
||||
ausgabetext += mline[1] + " \n"
|
||||
wbfile.close()
|
||||
return ausgabetext
|
||||
|
||||
def t9_en(eingabetext):
|
||||
@@ -1580,6 +1561,7 @@ def t9_en(eingabetext):
|
||||
return ":red[Leider konnte die Wörterbuchdatei nicht geladen werden.]"
|
||||
else:
|
||||
ausgabetext = ":blue[der eingegebene T9-Code kann für folgendes stehen:] \n"
|
||||
count = 0
|
||||
for zeile in wbfile:
|
||||
zeile = zeile.strip(" \t\n\r")
|
||||
mzeile = ""
|
||||
@@ -1590,8 +1572,12 @@ def t9_en(eingabetext):
|
||||
continue
|
||||
if eingabetext == mzeile:
|
||||
ausgabetext += zeile + " \n"
|
||||
count += 1
|
||||
wbfile.close()
|
||||
return ausgabetext
|
||||
if count == 0:
|
||||
return ":red[leider nichts gefunden :disappointed:]"
|
||||
else:
|
||||
return ausgabetext
|
||||
|
||||
def vigenere(eingabetext, pw):
|
||||
bw = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'H': 8, 'I': 9, 'J': 10, 'K': 11, 'L': 12, 'M': 13,
|
||||
|
||||
84
examples.py
84
examples.py
@@ -1,84 +0,0 @@
|
||||
# Copyright (c) 2025 Martin Kayser (tebarius)
|
||||
# Licensed under the MIT License. See LICENSE file in the project root.
|
||||
# start with: streamlit run examples.py
|
||||
import streamlit as st
|
||||
|
||||
|
||||
st.write("# Hello World !")
|
||||
|
||||
|
||||
import pandas as pd
|
||||
df = pd.DataFrame({
|
||||
'first column': [1, 2, 3, 4],
|
||||
'second column': [10, 20, 30, 40]
|
||||
})
|
||||
df
|
||||
|
||||
|
||||
st.table(df)
|
||||
|
||||
|
||||
import pandas as pd
|
||||
st.map(pd.DataFrame({'lat':[52.3642], 'lon':[13.0906]}), zoom=17, size=5)
|
||||
|
||||
|
||||
import streamlit as st
|
||||
x = st.slider('x', 32, 233) # 👈 this is a widget
|
||||
st.write(x, 'squared is', x * x)
|
||||
|
||||
|
||||
st.text_input("Your name", key="name")
|
||||
# You can access the value at any point with:
|
||||
st.session_state.name
|
||||
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
if st.checkbox('Show dataframe'):
|
||||
chart_data = pd.DataFrame(
|
||||
np.random.randn(20, 3),
|
||||
columns=['a', 'b', 'c'])
|
||||
chart_data
|
||||
|
||||
|
||||
import pandas as pd
|
||||
df = pd.DataFrame({
|
||||
'first column': [1, 2, 3, 4],
|
||||
'second column': [10, 20, 30, 40]
|
||||
})
|
||||
option = st.selectbox(
|
||||
'Which number do you like best?',
|
||||
df['first column'])
|
||||
'You selected: ', option
|
||||
|
||||
|
||||
add_selectbox = st.sidebar.selectbox(
|
||||
'How would you like to be contacted?',
|
||||
('Email', 'Home phone', 'Mobile phone')
|
||||
)
|
||||
# Add a slider to the sidebar:
|
||||
add_slider = st.sidebar.slider(
|
||||
'Select a range of values',
|
||||
0.0, 100.0, (25.0, 75.0)
|
||||
)
|
||||
|
||||
add_selectbox
|
||||
add_slider
|
||||
|
||||
|
||||
left_column, right_column = st.columns(2)
|
||||
# You can use a column just like st.sidebar:
|
||||
left_column.button('Press me!')
|
||||
# Or even better, call Streamlit functions inside a "with" block:
|
||||
with right_column:
|
||||
chosen = st.radio(
|
||||
'Sorting hat',
|
||||
("Gryffindor", "Ravenclaw", "Hufflepuff", "Slytherin"))
|
||||
st.write(f"You are in {chosen} house!")
|
||||
|
||||
|
||||
st.progress(80)
|
||||
|
||||
st.text_area("Your text", key="te")
|
||||
st.session_state.te
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 159 KiB |
@@ -1,47 +0,0 @@
|
||||
<!--
|
||||
Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||
/>
|
||||
<link rel="shortcut icon" href="./favicon.ico" />
|
||||
<link
|
||||
rel="preload"
|
||||
href="./static/media/SourceSansVF-Upright.ttf.BsWL4Kly.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin
|
||||
/>
|
||||
|
||||
<title>tebarius Mysteryhelfer (web)</title>
|
||||
|
||||
<!-- initialize window.prerenderReady to false and then set to true in React app when app is ready for indexing -->
|
||||
<script>
|
||||
window.prerenderReady = false
|
||||
</script>
|
||||
<script type="module" crossorigin src="./static/js/index.BTGIlECR.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./static/css/index.CJVRHjQZ.css">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
28
readme.md
28
readme.md
@@ -7,22 +7,34 @@ Für die Umsetzung kommt das Python-Framework [Streamlit](https://streamlit.io/)
|
||||
Der einfachst Weg, um die App lokal laufen zu lassen, ist mit Docker, wobei ich hier mal 3 Möglichkeiten aufzeigen (_das vorgebaute Image ist als Multi-Arch-Image für linux/amd64,linux/arm64 gebaut und sollte somit z.B. auch auf Mac's und neueren Raspberry's mit 64 bit Betriebssystem laufen_):
|
||||
1. mit vorgebautem Image:
|
||||
- `docker run --rm -d -p 8501:8501 gitea.tebarius.duckdns.org/tebarius/mysteryhelfer`
|
||||
|
||||
- alternativ (via Docker Hub): `docker run --rm -d -p 8501:8501 tebarius/mysteryhelfer`
|
||||
2. mit vorgebautem Image und "docker compose"
|
||||
- docker-compose.yml erstellen mit folgendem Inhalt:
|
||||
```
|
||||
services:
|
||||
mysteryhelfer-web:
|
||||
image: gitea.tebarius.duckdns.org/tebarius/mysteryhelfer
|
||||
ports:
|
||||
- "8501:8501"
|
||||
restart: unless-stopped
|
||||
image: gitea.tebarius.duckdns.org/tebarius/mysteryhelfer
|
||||
ports:
|
||||
- "8501:8501"
|
||||
restart: unless-stopped
|
||||
```
|
||||
- `docker compose up`
|
||||
alternativ (via Docker Hub):
|
||||
```
|
||||
services:
|
||||
mysteryhelfer-web:
|
||||
image: tebarius/mysteryhelfer
|
||||
ports:
|
||||
- "8501:8501"
|
||||
restart: unless-stopped
|
||||
```
|
||||
- `docker compose up -d`
|
||||
|
||||
3. mit selbst gebautem Image aus dem Quellcode
|
||||
- `git clone https://gitea.tebarius.duckdns.org/tebarius/Mysteryhelfer-web.git`
|
||||
- `cd Mysteryhelfer-web`
|
||||
- `docker compose up`
|
||||
- `docker compose up -d`
|
||||
|
||||
bei allen 3 Varianten ist die App anschließend im Browser unter http://127.0.0.1:8501/ aufrufbar
|
||||
bei allen 3 Varianten ist die App anschließend im Browser unter http://127.0.0.1:8501/ aufrufbar
|
||||
|
||||
__HINWEIS: Beim ersten Aufruf der Adresse werden Special-Wörterbücher für RE-Morse und T9 generiert,
|
||||
was ca. 15-30s in Anspruch nimmt und dadurch das Laden der Seite einmalig verzögert.__
|
||||
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
Reference in New Issue
Block a user