Compare commits
8 Commits
acd7daf36f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 312e4e713f | |||
| 7d5d3dc0c8 | |||
| 8167a3ffff | |||
| 3e68e96c8a | |||
| 3b9b7f8789 | |||
| 62f739344c | |||
| 9b913a48bb | |||
| c1f1b48f6b |
@@ -5,35 +5,35 @@ Dieses Dokument beschreibt die Funktionsweise, das Berechtigungssystem und die Z
|
|||||||
## 1. Systemübersicht
|
## 1. Systemübersicht
|
||||||
Der Server fungiert als zentraler Datenaustauschpunkt für die Systeme Bremen und Amondis:
|
Der Server fungiert als zentraler Datenaustauschpunkt für die Systeme Bremen und Amondis:
|
||||||
1. **Bremen-Mave Import:** Empfang externer Daten über SFTP.
|
1. **Bremen-Mave Import:** Empfang externer Daten über SFTP.
|
||||||
2. **Amondis-Mave Import:** Interner und externer Datenaustausch über SMB (Samba) und SFTP Protokolle.
|
2. **Amondis-Mave Import:** Empfang externer Daten über SMB (Samba), und import nach Mave mit SFTP Protokolle.
|
||||||
|
|
||||||
## 2. Benutzer und Zugriff
|
## 2. Benutzer und Zugriff
|
||||||
┌──────────────────┬──────────────┬───────────────┬─────────────────┬─────────────────────────────┐
|
┌──────────────────┬──────────────┬───────────────┬─────────────────┬─────────────────────────────┐
|
||||||
│ Benutzer │ Prozess │ Typ │ Shell │ Aufgabe │
|
│ Benutzer │ Prozess │ Typ │ Shell │ Aufgabe │
|
||||||
├──────────────────┼──────────────┼───────────────┼─────────────────┼─────────────────────────────┤
|
├──────────────────┼──────────────┼───────────────┼─────────────────┼─────────────────────────────┤
|
||||||
│ mave-sftp │ Bremen-Mave │ Nur SFTP │ /sbin/nologin │ Import von Bremen-Daten │
|
│ mave-sftp │ Bremen-Mave │ Nur SFTP │ /sbin/nologin │ Import von Bremen-Daten │
|
||||||
│ mave-amondis │ Amondis-Mave │ SFTP & SMB │ /sbin/nologin │ Verwaltung von Amondis-Daten│
|
│ mave-amondis │ Amondis-Mave │ SFTP & SMB │ /sbin/nologin │ Import von Amondis-Daten │
|
||||||
└──────────────────┴──────────────┴───────────────┴─────────────────┴─────────────────────────────┘
|
└──────────────────┴──────────────┴───────────────┴─────────────────┴─────────────────────────────┘
|
||||||
*Hinweis: Keiner der Benutzer ist für eine interaktive SSH-Anmeldung (Terminal) berechtigt.*
|
*Hinweis: Keiner der Benutzer ist für eine interaktive SSH-Anmeldung (Terminal) berechtigt.*
|
||||||
|
|
||||||
## 3. Verzeichnisstruktur und Berechtigungen
|
## 3. Verzeichnisstruktur und Berechtigungen
|
||||||
|
|
||||||
### Bremen-Mave Import (mave-sftp)
|
### Bremen-Mave Import (mave-sftp)
|
||||||
┌────────────────────────────┬─────────────────────┬──────────────┬──────────────────────────────────┐
|
┌────────────────────────────────────────┬─────────────────────┬──────────────┬──────────────────────────────────┐
|
||||||
│ Pfad │ Besitzer │ Berechtigung │ Rolle │
|
│ Pfad │ Besitzer │ Berechtigung │ Rolle │
|
||||||
├────────────────────────────┼─────────────────────┼──────────────┼──────────────────────────────────┤
|
├────────────────────────────────────────┼─────────────────────┼──────────────┼──────────────────────────────────┤
|
||||||
│ /home/mave-sftp │ root:root │ 755 │ SFTP Chroot-Gefängnis │
|
│ /home/mave-sftp │ root:root │ 755 │ SFTP Chroot-Gefängnis │
|
||||||
│ /home/mave-sftp/feltoltes │ mave-sftp:mave-sftp │ 775 │ Beschreibbarer Ordner für Bremen │
|
│ /home/mave-sftp/Schnittstellen/Bremen │ mave-sftp:mave-sftp │ 775 │ Beschreibbarer Ordner für Bremen │
|
||||||
└────────────────────────────┴─────────────────────┴──────────────┴──────────────────────────────────┘
|
└────────────────────────────────────────┴─────────────────────┴──────────────┴──────────────────────────────────┘
|
||||||
|
|
||||||
### Amondis-Mave Import (mave-amondis)
|
### Amondis-Mave Import (mave-amondis)
|
||||||
┌───────────────────────────────────────────┬───────────────────────────┬──────────────┬─────────────────────────────┐
|
┌───────────────────────────────────────────────┬───────────────────────────┬──────────────┬─────────────────────────────┐
|
||||||
│ Pfad │ Besitzer │ Berechtigung │ Rolle │
|
│ Pfad │ Besitzer │ Berechtigung │ Rolle │
|
||||||
├───────────────────────────────────────────┼───────────────────────────┼──────────────┼─────────────────────────────┤
|
├───────────────────────────────────────────────┼───────────────────────────┼──────────────┼─────────────────────────────┤
|
||||||
│ /home/mave-amondis │ root:root │ 755 │ SFTP Home (nicht schreibbar)|
|
│ /home/mave-amondis │ root:root │ 755 │ SFTP Home (nicht schreibbar)|
|
||||||
│ /home/mave-amondis/Schnittstellen │ root:root │ 755 │ SFTP Chroot-Gefängnis │
|
│ /home/mave-amondis/Schnittstellen │ root:root │ 755 │ SFTP Chroot-Gefängnis │
|
||||||
│ /home/mave-amondis/Schnittstellen/Amondis │ mave-amondis:mave-amondis │ 775 │ Beschreibbares Verzeichnis │
|
│ /home/mave-amondis/Schnittstellen/Amondis/APO │ mave-amondis:mave-amondis │ 775 │ Beschreibbares Verzeichnis │
|
||||||
└───────────────────────────────────────────┴───────────────────────────┴──────────────┴─────────────────────────────┘
|
└───────────────────────────────────────────────┴───────────────────────────┴──────────────┴─────────────────────────────┘
|
||||||
|
|
||||||
## 4. Netzwerkzugriff
|
## 4. Netzwerkzugriff
|
||||||
|
|
||||||
@@ -42,11 +42,15 @@ Der Server fungiert als zentraler Datenaustauschpunkt für die Systeme Bremen un
|
|||||||
* **Funktionsweise:** Samba verwendet die Einstellung `force user = mave-amondis`, um Berechtigungskonflikte zu vermeiden.
|
* **Funktionsweise:** Samba verwendet die Einstellung `force user = mave-amondis`, um Berechtigungskonflikte zu vermeiden.
|
||||||
|
|
||||||
### SFTP (Secure FTP)
|
### SFTP (Secure FTP)
|
||||||
* **Bremen-Verbindung:** `sftp://mave-sftp@10.102.1.202` (sieht nach der Anmeldung den Ordner `feltoltes`).
|
* **Bremen-Verbindung:** `sftp://mave-sftp@10.102.1.202` (sieht nach der Anmeldung den Ordner `mave-amondis\Schnittstellen\Bremen`).
|
||||||
* **Amondis-Verbindung:** `sftp://mave-amondis@10.102.1.202` (sieht nach der Anmeldung den Ordner `Amondis`).
|
* **Amondis-Verbindung:** `sftp://mave-amondis@10.102.1.202` (sieht nach der Anmeldung den Ordner `Amondis\APO`).
|
||||||
|
|
||||||
## 5. Automatische Benachrichtigungen (Monitoring)
|
## 5. Automatische Benachrichtigungen (Monitoring)
|
||||||
Bei jeder erfolgreichen Anmeldung (für beide Benutzer) wird eine E-Mail-Benachrichtigung an den Administrator gesendet (`i.meszely@antares-apo.de`).
|
Bei jeder erfolgreichen Anmeldung (für beide Benutzer) wird eine E-Mail-Benachrichtigung an den Administrator gesendet (`i.meszely@antares-apo.de`).
|
||||||
|
|
||||||
|
* **Script-Speicherort:** `/usr/local/sbin/sftp-notify.sh`
|
||||||
|
* **Funktionsweise:** Das Script wird durch das PAM-System (Pluggable Authentication Modules) bei jedem `open_session`-Ereignis aufgerufen. Es unterscheidet zwischen SFTP (eingeschränkt) und interaktiven SSH-Anmeldungen anhand der Benutzer-Shell und versendet die Details (Benutzer, Remote-IP, Zeitstempel) per E-Mail.
|
||||||
|
* **Logdatei:** `/tmp/sftp-notify.log` (für das Debugging).
|
||||||
|
|
||||||
---
|
---
|
||||||
*Aktualisiert am: 24. März 2026*
|
*Aktualisiert am: 25. März 2026*
|
||||||
|
|||||||
@@ -48,5 +48,9 @@ A szerver központi adatcsere pontként funkcionál a Bremen és az Amondis rend
|
|||||||
## 5. Automatikus Értesítések (Monitoring)
|
## 5. Automatikus Értesítések (Monitoring)
|
||||||
Minden sikeres bejelentkezéskor (mindkét felhasználó esetén) e-mail értesítés érkezik az adminisztrátornak (`i.meszely@antares-apo.de`).
|
Minden sikeres bejelentkezéskor (mindkét felhasználó esetén) e-mail értesítés érkezik az adminisztrátornak (`i.meszely@antares-apo.de`).
|
||||||
|
|
||||||
|
* **Script helye:** `/usr/local/sbin/sftp-notify.sh`
|
||||||
|
* **Működés:** A scriptet a PAM (Pluggable Authentication Modules) rendszer hívja meg minden `open_session` eseménynél. A script megkülönbözteti az SFTP (korlátozott) és az interaktív SSH belépéseket a felhasználó shellje alapján, majd elküldi az adatokat (felhasználó, távoli IP, időpont) e-mailben.
|
||||||
|
* **Log fájl:** `/tmp/sftp-notify.log` (hibakereséshez).
|
||||||
|
|
||||||
---
|
---
|
||||||
*Frissítve: 2026. március 24.*
|
*Frissítve: 2026. március 24.*
|
||||||
|
|||||||
45
Dev/APS-SFTP01/sftp-notify_de.sh
Normal file
45
Dev/APS-SFTP01/sftp-notify_de.sh
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Locale-Einstellungen, damit der Mail-Befehl keine Zeichenkodierungsfehler verursacht
|
||||||
|
export LC_ALL=C.UTF-8
|
||||||
|
export LANG=C.UTF-8
|
||||||
|
|
||||||
|
# Logdatei für das Debugging (Schreibrechte setzen: chmod 666 /tmp/sftp-notify.log)
|
||||||
|
LOGFILE="/tmp/sftp-notify.log"
|
||||||
|
|
||||||
|
# Benachrichtigung nur bei erfolgreichen Anmeldungen (open_session)
|
||||||
|
if [ "$PAM_TYPE" = "open_session" ]; then
|
||||||
|
|
||||||
|
# Umgebung in Log speichern
|
||||||
|
echo "--- $(/usr/bin/date): Anmeldeversuch für $PAM_USER von $PAM_RHOST ---" >> "$LOGFILE"
|
||||||
|
|
||||||
|
# Überprüfung der Benutzer-Shell
|
||||||
|
USER_SHELL=$(/usr/bin/getent passwd "$PAM_USER" | /usr/bin/cut -d: -f7)
|
||||||
|
|
||||||
|
# Bestimmung des Typs
|
||||||
|
if [[ "$USER_SHELL" == *"/nologin" ]] || [[ "$USER_SHELL" == *"/false" ]]; then
|
||||||
|
LOGIN_TYPE="SFTP (Eingeschränkt)"
|
||||||
|
else
|
||||||
|
LOGIN_TYPE="SSH (Interaktiv)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MESSAGE="Anmeldebenachrichtigung ($PAM_SERVICE):
|
||||||
|
Typ: $LOGIN_TYPE
|
||||||
|
Benutzer: $PAM_USER
|
||||||
|
Remote-Host: $PAM_RHOST
|
||||||
|
Shell: $USER_SHELL
|
||||||
|
Zeitpunkt: $(/usr/bin/date)
|
||||||
|
Host: $(/usr/bin/hostname)"
|
||||||
|
|
||||||
|
# E-Mail-Versand (mit absolutem Pfad)
|
||||||
|
# Prüfen, ob der 'mail'-Befehl unter /usr/sbin/mail verfügbar ist!
|
||||||
|
echo "$MESSAGE" | /usr/sbin/mail -s "$LOGIN_TYPE: $PAM_USER" i.meszely@antares-apo.de >> "$LOGFILE" 2>&1
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Erfolg: E-Mail gesendet." >> "$LOGFILE"
|
||||||
|
else
|
||||||
|
echo "FEHLER: E-Mail-Versand fehlgeschlagen! (Exit code: $?)" >> "$LOGFILE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
6
Dev/n8n/docker compose refresh.md
Normal file
6
Dev/n8n/docker compose refresh.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
docker compose pull
|
||||||
|
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
docker image prune -f
|
||||||
|
|
||||||
BIN
Doc/Bilders/Development.png
Normal file
BIN
Doc/Bilders/Development.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 877 KiB |
BIN
Doc/Bilders/Infrastrukture.png
Normal file
BIN
Doc/Bilders/Infrastrukture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
BIN
Doc/Bilders/Infrastrukture2.png
Normal file
BIN
Doc/Bilders/Infrastrukture2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
BIN
Doc/Bilders/Knowledge Base.png
Normal file
BIN
Doc/Bilders/Knowledge Base.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 789 KiB |
BIN
Doc/Bilders/Scripts.png
Normal file
BIN
Doc/Bilders/Scripts.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 760 KiB |
@@ -34,6 +34,7 @@ A kedvenc programozási nyelvem a Python.
|
|||||||
Weboldalak amiket hasznälni szoktunk:
|
Weboldalak amiket hasznälni szoktunk:
|
||||||
mermaid.live
|
mermaid.live
|
||||||
|
|
||||||
Általában fedora linux alatt dolgozunk.
|
Általában szerver oldalon Fedora Linux alatt dolgozunk.
|
||||||
Második leggyakrabban használt linux az Ubuntu alapu.
|
A második leggyakrabban használt linux az Ubuntu alapú (szintén szerver).
|
||||||
Virtualizácionk Proxmox VE
|
Kliens oldalon (munkaállomás) Windows 11-et vagy macOS-t használunk.
|
||||||
|
Virtualizációnk Proxmox VE.
|
||||||
|
|||||||
92
Scripts/python/check_file_age.py
Normal file
92
Scripts/python/check_file_age.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Fájl kor ellenőrző script n8n automatizáláshoz.
|
||||||
|
Használat: python3 check_file_age.py <mappa_utvonal> <max_perc>
|
||||||
|
|
||||||
|
Kimenet: JSON formátum (n8n barát)
|
||||||
|
Exit kód: 0 (ha minden rendben), 1 (ha régi fájlt talált vagy hiba történt)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
|
def check_files(directory, max_age_minutes=40):
|
||||||
|
now = time.time()
|
||||||
|
max_age_seconds = max_age_minutes * 60
|
||||||
|
too_old_files = []
|
||||||
|
|
||||||
|
# Mappa létezésének ellenőrzése
|
||||||
|
if not os.path.exists(directory):
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"alert": True,
|
||||||
|
"message": f"A megadott könyvtár nem létezik: {directory}",
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Fájlok listázása
|
||||||
|
files_in_dir = os.listdir(directory)
|
||||||
|
|
||||||
|
for filename in files_in_dir:
|
||||||
|
filepath = os.path.join(directory, filename)
|
||||||
|
|
||||||
|
# Csak a fájlokat ellenőrizzük (mappákat nem)
|
||||||
|
if os.path.isfile(filepath):
|
||||||
|
file_age_seconds = now - os.path.getmtime(filepath)
|
||||||
|
|
||||||
|
if file_age_seconds > max_age_seconds:
|
||||||
|
age_min = round(file_age_seconds / 60, 1)
|
||||||
|
too_old_files.append({
|
||||||
|
"file": filename,
|
||||||
|
"age_minutes": age_min,
|
||||||
|
"last_modified": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getmtime(filepath)))
|
||||||
|
})
|
||||||
|
|
||||||
|
if too_old_files:
|
||||||
|
return {
|
||||||
|
"status": "alert",
|
||||||
|
"alert": True,
|
||||||
|
"message": f"Találtam {len(too_old_files)} db fájlt, ami régebbi mint {max_age_minutes} perc!",
|
||||||
|
"directory": directory,
|
||||||
|
"limit_minutes": max_age_minutes,
|
||||||
|
"files": too_old_files
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"status": "ok",
|
||||||
|
"alert": False,
|
||||||
|
"message": "Minden fájl friss.",
|
||||||
|
"directory": directory,
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"alert": True,
|
||||||
|
"message": f"Hiba történt az ellenőrzés közben: {str(e)}",
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Paraméterek átvétele a parancssorból
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print(json.dumps({"status": "error", "message": "Hiányzó paraméter! Használat: python3 check_file_age.py <mappa> <perc>"}))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
dir_to_check = sys.argv[1]
|
||||||
|
age_limit = int(sys.argv[2]) if len(sys.argv) > 2 else 40
|
||||||
|
|
||||||
|
result = check_files(dir_to_check, age_limit)
|
||||||
|
|
||||||
|
# JSON kimenet az n8n számára
|
||||||
|
print(json.dumps(result, indent=2))
|
||||||
|
|
||||||
|
# Exit code beállítása az n8n SSH Node számára
|
||||||
|
if result.get("alert"):
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
sys.exit(0)
|
||||||
92
Scripts/python/check_file_age_de.py
Normal file
92
Scripts/python/check_file_age_de.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Skript zur Überprüfung des Dateialters für n8n-Automatisierung.
|
||||||
|
Verwendung: python3 check_file_age_de.py <verzeichnispfad> <max_minuten>
|
||||||
|
|
||||||
|
Ausgabe: JSON-Format (n8n-freundlich)
|
||||||
|
Exit-Code: 0 (wenn alles ok), 1 (wenn eine alte Datei gefunden wurde oder ein Fehler auftrat)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
|
def check_files(directory, max_age_minutes=40):
|
||||||
|
now = time.time()
|
||||||
|
max_age_seconds = max_age_minutes * 60
|
||||||
|
too_old_files = []
|
||||||
|
|
||||||
|
# Überprüfung, ob das Verzeichnis existiert
|
||||||
|
if not os.path.exists(directory):
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"alert": True,
|
||||||
|
"message": f"Das angegebene Verzeichnis existiert nicht: {directory}",
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Dateien auflisten
|
||||||
|
files_in_dir = os.listdir(directory)
|
||||||
|
|
||||||
|
for filename in files_in_dir:
|
||||||
|
filepath = os.path.join(directory, filename)
|
||||||
|
|
||||||
|
# Nur Dateien prüfen (keine Verzeichnisse)
|
||||||
|
if os.path.isfile(filepath):
|
||||||
|
file_age_seconds = now - os.path.getmtime(filepath)
|
||||||
|
|
||||||
|
if file_age_seconds > max_age_seconds:
|
||||||
|
age_min = round(file_age_seconds / 60, 1)
|
||||||
|
too_old_files.append({
|
||||||
|
"file": filename,
|
||||||
|
"age_minutes": age_min,
|
||||||
|
"last_modified": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getmtime(filepath)))
|
||||||
|
})
|
||||||
|
|
||||||
|
if too_old_files:
|
||||||
|
return {
|
||||||
|
"status": "alert",
|
||||||
|
"alert": True,
|
||||||
|
"message": f"{len(too_old_files)} Datei(en) gefunden, die älter als {max_age_minutes} Minuten sind!",
|
||||||
|
"directory": directory,
|
||||||
|
"limit_minutes": max_age_minutes,
|
||||||
|
"files": too_old_files
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"status": "ok",
|
||||||
|
"alert": False,
|
||||||
|
"message": "Alle Dateien sind aktuell.",
|
||||||
|
"directory": directory,
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"alert": True,
|
||||||
|
"message": f"Fehler während der Überprüfung aufgetreten: {str(e)}",
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Parameter aus der Befehlszeile übernehmen
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print(json.dumps({"status": "error", "message": "Fehlender Parameter! Verwendung: python3 check_file_age_de.py <verzeichnis> <minuten>"}))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
dir_to_check = sys.argv[1]
|
||||||
|
age_limit = int(sys.argv[2]) if len(sys.argv) > 2 else 40
|
||||||
|
|
||||||
|
result = check_files(dir_to_check, age_limit)
|
||||||
|
|
||||||
|
# JSON-Ausgabe für n8n
|
||||||
|
print(json.dumps(result, indent=2))
|
||||||
|
|
||||||
|
# Exit-Code für den n8n SSH-Node festlegen
|
||||||
|
if result.get("alert"):
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
sys.exit(0)
|
||||||
70
Scripts/python/md_to_pdf_recursive.py
Normal file
70
Scripts/python/md_to_pdf_recursive.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
"""
|
||||||
|
Használati útmutató / Usage:
|
||||||
|
|
||||||
|
1. Telepítés / Installation:
|
||||||
|
pip install markdown-pdf
|
||||||
|
|
||||||
|
2. Futtatás / Execution:
|
||||||
|
- Aktuális könyvtár bejárása:
|
||||||
|
python Scripts/python/md_to_pdf_recursive.py
|
||||||
|
- Konkrét könyvtár megadása:
|
||||||
|
python Scripts/python/md_to_pdf_recursive.py Dev/APS-SFTP01
|
||||||
|
|
||||||
|
A script rekurzívan végigjárja a megadott könyvtárat, és minden .md fájl mellé
|
||||||
|
létrehoz egy azonos nevű .pdf fájlt. A .git, .venv és __pycache__ könyvtárakat kihagyja.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from markdown_pdf import Section, MarkdownPdf
|
||||||
|
|
||||||
|
def convert_md_to_pdf(root_dir):
|
||||||
|
"""
|
||||||
|
Rekurzívan végigjárja a megadott könyvtárat és minden .md fájlból PDF-et készít.
|
||||||
|
"""
|
||||||
|
print(f"Keresés indítása a következő könyvtárban: {root_dir}")
|
||||||
|
|
||||||
|
# Kizárandó könyvtárak (pl. git, virtuális környezet)
|
||||||
|
exclude_dirs = {'.git', '.venv', '__pycache__', 'node_modules'}
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
for root, dirs, files in os.walk(root_dir):
|
||||||
|
# Alkönyvtárak szűrése (helyben módosítva a dirs listát)
|
||||||
|
dirs[:] = [d for d in dirs if d not in exclude_dirs]
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(".md"):
|
||||||
|
md_path = os.path.join(root, file)
|
||||||
|
pdf_path = os.path.splitext(md_path)[0] + ".pdf"
|
||||||
|
|
||||||
|
print(f"Konvertálás: {md_path} -> {pdf_path}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Markdown olvasása
|
||||||
|
with open(md_path, "r", encoding="utf-8") as f:
|
||||||
|
md_content = f.read()
|
||||||
|
|
||||||
|
# PDF generálása
|
||||||
|
pdf = MarkdownPdf(toc_level=2)
|
||||||
|
pdf.add_section(Section(md_content, toc=False))
|
||||||
|
pdf.save(pdf_path)
|
||||||
|
|
||||||
|
count += 1
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Hiba a fájl feldolgozása közben ({md_path}): {e}")
|
||||||
|
|
||||||
|
print(f"\nKész! Összesen {count} fájl lett konvertálva.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Ha nincs megadva útvonal, az aktuális könyvtárat használja
|
||||||
|
target_path = sys.argv[1] if len(sys.argv) > 1 else "."
|
||||||
|
|
||||||
|
# Ellenőrizzük a függőséget
|
||||||
|
try:
|
||||||
|
import markdown_pdf
|
||||||
|
except ImportError:
|
||||||
|
print("Hiba: A 'markdown-pdf' könyvtár nincs telepítve.")
|
||||||
|
print("Telepítés: pip install markdown-pdf")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
convert_md_to_pdf(target_path)
|
||||||
Reference in New Issue
Block a user