671 lines
24 KiB
Python
671 lines
24 KiB
Python
#V@MAC
|
||
from __future__ import annotations
|
||
import requests
|
||
import json
|
||
from pathlib import Path
|
||
from datetime import datetime, timezone
|
||
from openai import OpenAI
|
||
import os
|
||
import sys
|
||
import random
|
||
import shutil
|
||
import logging
|
||
from logging.handlers import RotatingFileHandler
|
||
from version import VERSION
|
||
|
||
import subprocess
|
||
|
||
VERSION = "0.2.0"
|
||
|
||
APP_NAME = "Simbriefimport"
|
||
COMPANY = "HintergassenZeug"
|
||
COPYRIGHT = "© 2025 Hubobel"
|
||
|
||
VERSION_INFO_FILE = Path("version_info.txt")
|
||
VERSION_RUNTIME_FILE = Path("version_runtime.txt")
|
||
|
||
def _git_build_number() -> int:
|
||
try:
|
||
out = subprocess.check_output(
|
||
["git", "rev-list", "--count", "HEAD"],
|
||
stderr=subprocess.DEVNULL
|
||
)
|
||
return int(out.decode().strip())
|
||
except Exception:
|
||
return 0
|
||
def get_runtime_version() -> str:
|
||
p = resource_path("version_runtime.txt")
|
||
try:
|
||
return p.read_text(encoding="utf-8").strip()
|
||
except Exception:
|
||
return "0.0.0.0"
|
||
def ensure_version_info(force: bool = False) -> str:
|
||
"""
|
||
Erzeugt version_info.txt für PyInstaller und version_runtime.txt für die
|
||
Laufzeit-Ausgabe in der EXE.
|
||
Gibt die Textversion zurück, z.B. '0.1.1.59'.
|
||
"""
|
||
build = _git_build_number()
|
||
|
||
# robust: erlaubt "1.4" -> 1.4.0
|
||
parts = [int(p) for p in VERSION.split(".")]
|
||
while len(parts) < 3:
|
||
parts.append(0)
|
||
major, minor, patch = parts[:3]
|
||
|
||
filevers = f"{major},{minor},{patch},{build}"
|
||
textvers = f"{major}.{minor}.{patch}.{build}"
|
||
|
||
# Runtime-Version IMMER schreiben, damit Log und EXE konsistent sind
|
||
VERSION_RUNTIME_FILE.write_text(textvers, encoding="utf-8")
|
||
|
||
# Version-Info nur schreiben, wenn force oder Datei fehlt
|
||
if VERSION_INFO_FILE.exists() and not force:
|
||
return textvers
|
||
|
||
content = f"""VSVersionInfo(
|
||
ffi=FixedFileInfo(
|
||
filevers=({filevers}),
|
||
prodvers=({filevers}),
|
||
mask=0x3f,
|
||
flags=0x0,
|
||
OS=0x40004,
|
||
fileType=0x1,
|
||
subtype=0x0,
|
||
date=(0,0)
|
||
),
|
||
kids=[
|
||
StringFileInfo(
|
||
[
|
||
StringTable(
|
||
'040904B0',
|
||
[
|
||
StringStruct('CompanyName', '{COMPANY}'),
|
||
StringStruct('FileDescription', '{APP_NAME}'),
|
||
StringStruct('ProductName', '{APP_NAME}'),
|
||
StringStruct('InternalName', '{APP_NAME}'),
|
||
StringStruct('OriginalFilename', '{APP_NAME}.exe'),
|
||
StringStruct('FileVersion', '{textvers}'),
|
||
StringStruct('ProductVersion', '{textvers}'),
|
||
StringStruct('LegalCopyright', '{COPYRIGHT}')
|
||
]
|
||
)
|
||
]
|
||
)
|
||
]
|
||
)
|
||
"""
|
||
VERSION_INFO_FILE.write_text(content, encoding="utf-8")
|
||
return textvers
|
||
def get_build():
|
||
try:
|
||
import subprocess
|
||
return subprocess.check_output(
|
||
["git", "rev-list", "--count", "HEAD"],
|
||
stderr=subprocess.DEVNULL
|
||
).decode().strip()
|
||
except Exception:
|
||
return "0"
|
||
def setup_logging(app_dir, level=logging.INFO, console=True):
|
||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||
log_file = app_dir / "Simbriefimport.log"
|
||
|
||
logger = logging.getLogger()
|
||
logger.setLevel(level)
|
||
logger.handlers.clear()
|
||
|
||
fmt = logging.Formatter("%(asctime)s %(levelname)s %(name)s: %(message)s")
|
||
|
||
# Datei: rotierend, damit sie nicht unendlich wächst
|
||
fh = RotatingFileHandler(log_file, maxBytes=2_000_000, backupCount=5, encoding="utf-8")
|
||
fh.setFormatter(fmt)
|
||
logger.addHandler(fh)
|
||
|
||
if console:
|
||
ch = logging.StreamHandler()
|
||
ch.setFormatter(fmt)
|
||
logger.addHandler(ch)
|
||
|
||
logging.info("Logging gestartet: %s", log_file)
|
||
def conf():
|
||
appname = os.path.basename(sys.argv[0])
|
||
appname = appname.replace(".py", ".conf")
|
||
|
||
absFilePath = os.getcwd()
|
||
absFilePath = absFilePath.replace(".exe", ".conf")
|
||
print(appname)
|
||
print(absFilePath)
|
||
|
||
if os.path.isfile(absFilePath) is False:
|
||
print(appname + ' scheint es nicht zu geben.')
|
||
print('Ich lege eine neue Datei ' + appname + ' an.')
|
||
passw = {'Prompt':
|
||
{
|
||
"PurserPrompt": "",
|
||
"CptPrompt": "",
|
||
"CptName":""
|
||
|
||
},
|
||
'AI':
|
||
{
|
||
"Token": "",
|
||
"Model": ""
|
||
}
|
||
}
|
||
|
||
print(str(appname) + ' bitte entsprechend befüllen.')
|
||
with open(absFilePath, 'w') as fp:
|
||
json.dump(passw, fp, sort_keys=True, indent=4)
|
||
quit()
|
||
else:
|
||
with open(absFilePath) as file:
|
||
passw = json.load(file)
|
||
return passw
|
||
def get_app_dir():
|
||
# Fall: als .exe (z. B. mit PyInstaller gebaut)
|
||
if getattr(sys, 'frozen', False):
|
||
return Path(sys.executable).parent
|
||
# Fall: normales Python-Skript
|
||
return Path(__file__).resolve().parent
|
||
def resource_path(filename: str) -> Path:
|
||
if hasattr(sys, "_MEIPASS"):
|
||
return Path(sys._MEIPASS) / filename
|
||
return Path(__file__).resolve().parent / filename
|
||
def minuten_zu_zeit(minuten) -> str:
|
||
minuten = int(minuten)
|
||
stunden = minuten // 60 # volle Stunden
|
||
rest_min = minuten % 60 # verbleibende Minuten
|
||
return f"{stunden}:{rest_min:02d}" # zweistellige Minutenanzeige
|
||
def old_aircr_name(aircraft_icao):
|
||
with open("aircraft_full.json", "r", encoding="utf-8") as f:
|
||
aircraft_data = json.load(f)
|
||
if aircraft_icao in aircraft_data:
|
||
antwort = (aircraft_data[aircraft_icao]["name"])
|
||
else:
|
||
print("Code nicht vorhanden")
|
||
antwort = "unbekanntes Luftfahrzeug"
|
||
return (antwort)
|
||
def aircr_name(aircraft_icao: str) -> str:
|
||
json_path = resource_path("aircraft_full.json")
|
||
|
||
with json_path.open("r", encoding="utf-8") as f:
|
||
aircraft_data = json.load(f)
|
||
|
||
if aircraft_icao in aircraft_data:
|
||
return aircraft_data[aircraft_icao].get("name", "unbekanntes Luftfahrzeug")
|
||
else:
|
||
return "unbekanntes Luftfahrzeug"
|
||
def old_start_name(ori_icao):
|
||
|
||
with open("airports_full.json", "r", encoding="utf-8") as f:
|
||
ori_data = json.load(f)
|
||
if ori_icao in ori_data:
|
||
antwort = (ori_data[ori_icao]["name"])
|
||
else:
|
||
print("Code nicht vorhanden")
|
||
antwort = "unbekannter Startflughafen"
|
||
return (antwort)
|
||
def start_name(ori_icao: str) -> str:
|
||
global _airports_cache
|
||
|
||
if _airports_cache is None:
|
||
with resource_path("airports_full.json").open(encoding="utf-8") as f:
|
||
_airports_cache = json.load(f)
|
||
|
||
return _airports_cache.get(
|
||
ori_icao, {}
|
||
).get("name", "unbekannter Startflughafen")
|
||
def old_airlinename(name):
|
||
with open("airlines_full.json", "r", encoding="utf-8") as f:
|
||
airline_data = json.load(f)
|
||
if name in airline_data:
|
||
antwort = (airline_data[name]["name"])
|
||
else:
|
||
print("Code nicht vorhanden")
|
||
antwort = "unbekanntes Luftfahrzeug"
|
||
return (antwort)
|
||
def airlinename(airline_icao: str) -> str:
|
||
global _airlines_cache
|
||
|
||
if _airlines_cache is None:
|
||
with resource_path("airlines_full.json").open(encoding="utf-8") as f:
|
||
_airlines_cache = json.load(f)
|
||
|
||
return _airlines_cache.get(
|
||
airline_icao, {}
|
||
).get(
|
||
"name",
|
||
"unbekannte Fluggesellschaft"
|
||
)
|
||
def replacedynamic(message):
|
||
message = message.replace('{AIRCRAFT_NAME}', aircraft_name)
|
||
message = message.replace('{DESTINATION_NAME}', dest_name)
|
||
message = message.replace('{AIRLINE_NAME}', airline)
|
||
message = message.replace('{DESTINATION_CITY}', dest_name)
|
||
message = message.replace('{ORIGIN_CITY}', origin_name)
|
||
message = message.replace('{xml_number<general><initial_altitude>}', flightlevel)
|
||
return (message)
|
||
def unix_to_datetime(timestamp: int) -> str:
|
||
return datetime.fromtimestamp(timestamp, tz=timezone.utc).strftime("%d.%m.%Y %H:%M:%S")
|
||
def ai(prompt):
|
||
completion = client.chat.completions.create(
|
||
model="gpt-4.1-mini",
|
||
messages=[
|
||
{"role": "user", "content": prompt}
|
||
]
|
||
)
|
||
return completion
|
||
def stimmung():
|
||
tone = (passw['Prompt']['tone'])
|
||
tone = random.choice(list(tone))
|
||
|
||
#print(tone)
|
||
return tone
|
||
def WelcomePilot():
|
||
prompt_org = passw['Prompt']['CptPrompt']
|
||
info = {"Zielflughafen: " + dest.get("icao_code") + dest_name, "Reisedauer:" + block,
|
||
"Entfernung: " + distance + "nm",
|
||
#"Menge Sprit: " + fuel + "kg",
|
||
"Passagieranzahl" + pax,
|
||
"Flugzeugtyp:" + aircraft_name,
|
||
"Du freust dich auf den Flug und bedankst dich, das man sich für " + airline + " entschieden hat.",
|
||
"Dein Name:" + passw['Prompt']['CptName'],
|
||
"Startflughafen: " + origin.get("icao_code") + origin_name,
|
||
"Du bist von deiner Art her:" + Stimmung,
|
||
"Wetter am Ziel" + metar_dest,
|
||
"Verwende nie die ICAO Abkürzungen, übersetze diese.",
|
||
#"Erwähne 2 bis 3 Sehenswürdigkeiten, die auf dem Flug von Start zum Ziel überflogen werden. Die Route lautet:" + route,
|
||
"Flugnummer" + general.get("flight_number"),
|
||
"Wetter am Start" + metar_origin}
|
||
|
||
for i in info:
|
||
prompt_org = prompt_org + i
|
||
antwort_AI = ai(prompt_org)
|
||
|
||
return antwort_AI
|
||
def CruiseElapsed10Percent():
|
||
prompt_org = passw['Prompt']['Cruise10']
|
||
info = ["Zielflughafen: " + dest.get("icao_code") + dest_name, "Reisedauer:" + block,
|
||
"Menge Sprit: " + fuel + "kg",
|
||
"Reiseflughöhe: ",
|
||
"Erwähne die typische Reiseflughöhe für diesen Flug",
|
||
"Dein Name:" + passw['Prompt']['CptName'],
|
||
"Startflughafen: " + origin.get("icao_code") + origin_name,
|
||
"Du bist von deiner Art her:" + Stimmung,
|
||
"Erwähne 2 bis 3 Sehenswürdigkeiten, die auf dem Flug von Start zum Ziel überflogen werden. Die Route lautet:" + route]
|
||
for i in info:
|
||
prompt_org = prompt_org + i
|
||
antwort_AI = ai(prompt_org)
|
||
|
||
return antwort_AI
|
||
def CruiseElapsed50Percent():
|
||
prompt_org = passw['Prompt']['Cruise50']
|
||
info = {"Zielflughafen: " + dest.get("icao_code") + dest_name, "Gesamtreisedauer:" + block,
|
||
"Du bist von deiner Art her:" + Stimmung,
|
||
"Erwähne 3 bis 6 Städte, welche auf einem Linienflug von " + origin_name + "nach " + dest_name + "überflogen werden"}
|
||
for i in info:
|
||
prompt_org = prompt_org + i
|
||
antwort_AI = ai(prompt_org)
|
||
return antwort_AI
|
||
def CruiseElapsed80Percent():
|
||
prompt_org = passw['Prompt']['Cruise80']
|
||
info = {"Zielflughafen: " + dest.get("icao_code") + dest_name,
|
||
"Du bist von deiner Art her:" + Stimmung,
|
||
"informiere über die gleich stattfinden Landevorbereitungen, welche du als Pilot im Cockpit nun machen wirst."}
|
||
for i in info:
|
||
prompt_org = prompt_org + i
|
||
antwort_AI = ai(prompt_org)
|
||
|
||
return antwort_AI
|
||
def SafetyBriefing():
|
||
prompt_org = passw['Prompt']['SafetyBriefing']
|
||
info = {
|
||
"Flugzeugtyp:" + aircraft_name,
|
||
"Du freust dich auf den Flug und bedankst dich, das man sich für " + airline + " entschieden hat.",
|
||
"Dein Name:" + passw['Prompt']['PurserName'],
|
||
"Verweise auf das Sicherheitsvideo im Infotainment und auf die Hinweise der Safety Card.",
|
||
"Du bist von deiner Art her:" + str(stimmung()),
|
||
"Beschränke deine Antwort auf maximal 160 Wörter",
|
||
"Flugnummer" + general.get("flight_number"),
|
||
"Wetter am Start in "+ origin_name + metar_origin + "hier sind aber nur eventueller Niederschlag und Temperatur interessant"
|
||
}
|
||
|
||
for i in info:
|
||
prompt_org = prompt_org + i
|
||
antwort_AI = ai(prompt_org)
|
||
|
||
return antwort_AI
|
||
def METAR():
|
||
prompt_org = passw['Prompt']['PurserPrompt_METAR']
|
||
prompt2 = prompt_org + 'Die METAR lautet ' + metar_dest
|
||
antwort_AI = ai(prompt2)
|
||
return antwort_AI
|
||
def CallCabinSecureTakeoff():
|
||
prompt_org = ("Hey " + passw['Prompt']['CptName'] + "hier ist " + passw['Prompt']['PurserName'] +
|
||
" von der EEins Links. Die Kabine ist sicher und bereit für den Flug nach " + dest_name)
|
||
prompt_org = "Formuliere diesen Satz um: " + prompt_org + "Du bist dabei eher " + Stimmung
|
||
antwort_AI = ai(prompt_org)
|
||
return antwort_AI
|
||
def CallCabinSecureLanding():
|
||
prompt_org = ("Hey " + passw['Prompt']['CptName'] + "hier ist " + passw['Prompt']['PurserName'] +
|
||
" von der EEins Links. Die Kabine ist sicher und bereit für die Landung in " + dest_name)
|
||
prompt_org = "Formuliere diesen Satz um: " + prompt_org + "Du bist dabei eher " + Stimmung
|
||
antwort_AI = ai(prompt_org)
|
||
return antwort_AI
|
||
def replaceFiles():
|
||
files = []
|
||
for datei in Path(Pfad_wd).glob("*.txt"):
|
||
with open(datei, "r", encoding="utf-8") as f:
|
||
files.append(f"{datei.name}")
|
||
inhalt = f.read()
|
||
inhalt_neu = replacedynamic(inhalt)
|
||
dateineu = str(ordnerneu) + '/' + (f"{datei.name}")
|
||
with open(dateineu, 'w', encoding="utf-8") as e:
|
||
e.write(inhalt_neu)
|
||
return files
|
||
def Simbriefimport():
|
||
#USERNAME = "hubobel"
|
||
USERNAME = passw['Prompt']['Simbrief']
|
||
URL = "https://www.simbrief.com/api/xml.fetcher.php"
|
||
params = {
|
||
"username": USERNAME,
|
||
"json": 1, # JSON statt XML
|
||
}
|
||
resp = requests.get(URL, params=params, timeout=15)
|
||
resp.raise_for_status()
|
||
data = resp.json()
|
||
general = data.get("general", {})
|
||
origin = data.get("origin", {})
|
||
|
||
origin_name = start_name(origin["icao_code"])
|
||
origin_icao = origin["icao_code"]
|
||
dest = data.get("destination", {})
|
||
dest_name = start_name(dest["icao_code"])
|
||
dest_icao = dest["icao_code"]
|
||
|
||
creationdate = unix_to_datetime(int(data['params']['time_generated']))
|
||
aircraft = data.get("aircraft", {})
|
||
time = data.get("times", {})
|
||
block = minuten_zu_zeit(int(time.get("sched_block")) / 60)
|
||
start_time = unix_to_datetime(int(time.get("sched_out")))
|
||
land_time = unix_to_datetime(int(time.get("sched_in")))
|
||
aircraft_icao = aircraft["icaocode"]
|
||
aircraft_name = aircr_name((aircraft_icao))
|
||
airline = airlinename(general.get("icao_airline"))
|
||
flightnumber = general.get("flight_number")
|
||
flightlevel = data['general']['initial_altitude']
|
||
fl = 'FL' + str(int(flightlevel) // 100)
|
||
distance = data['general']['route_distance']
|
||
fuel = data['fuel']['plan_ramp']
|
||
metar_origin = data['weather']['orig_metar']
|
||
metar_dest = data['weather']['dest_metar']
|
||
pax = data['weights']['pax_count']
|
||
payload = data['weights']['payload']
|
||
tow = data['weights']['est_tow']
|
||
zfw = data['weights']['est_zfw']
|
||
airline_icao = general.get("icao_airline")
|
||
route = data['general']['route']
|
||
#print(data.keys())
|
||
#print(data['general'])
|
||
return (zfw, tow, payload, pax, metar_dest, metar_origin, fuel, distance, fl, flightlevel, flightnumber, airline,
|
||
aircraft_name, aircraft_icao, land_time, start_time, block, time, aircraft, dest_icao, dest_name, dest,
|
||
origin_icao, origin_name, origin, general, airline_icao, route, creationdate)
|
||
def txtSave(Datei, Inhalt):
|
||
voice = None
|
||
Inhalt = Inhalt.replace("„", "").replace("“", "").replace('"', "")
|
||
try:
|
||
|
||
with open(Datei, "r", encoding="utf-8") as f:
|
||
erste_zeile = f.readline().strip()
|
||
if erste_zeile.startswith("##Role:"):
|
||
voice = erste_zeile + "\n"
|
||
Inhalt = voice + Inhalt
|
||
except:
|
||
None
|
||
with open(Datei, 'w', encoding="utf-8") as e:
|
||
e.write(Inhalt)
|
||
return None
|
||
def BACKUP(Pfad):
|
||
ryr_dir = Path(Pfad)
|
||
backup_dir = ryr_dir / "BACKUP"
|
||
|
||
# Prüfen, ob BACKUP bereits existiert
|
||
if backup_dir.exists():
|
||
logging.info("BACKUP existiert bereits – keine Dateien wurden kopiert.")
|
||
#print("BACKUP existiert bereits – keine Dateien wurden kopiert.")
|
||
else:
|
||
# BACKUP anlegen
|
||
backup_dir.mkdir(parents=True)
|
||
|
||
# Alle .txt Dateien kopieren
|
||
txt_files = list(ryr_dir.glob("*.txt"))
|
||
|
||
for src in txt_files:
|
||
dst = backup_dir / src.name
|
||
shutil.copy2(src, dst)
|
||
print(f"Kopiert: {src.name}")
|
||
|
||
logging.info(
|
||
"Backup erstellt. %d Datei(en) gesichert.",
|
||
len(txt_files)
|
||
)
|
||
return None
|
||
def zufName(geschlecht):
|
||
with resource_path("namen.json").open(encoding="utf-8") as f:
|
||
data = json.load(f)
|
||
if geschlecht == "P": # Frau
|
||
return random.choice(data["Frau"])
|
||
|
||
# Default: Mann
|
||
return random.choice(data["Mann"])
|
||
def delete(pfad_ogg):
|
||
if pfad_ogg.exists():
|
||
try:
|
||
pfad_ogg.unlink()
|
||
logging.info("Datei gelöscht: %s", pfad_ogg)
|
||
except:
|
||
logging.info("Datei gerade in Benutzung: %s", pfad_ogg)
|
||
return None
|
||
|
||
host = os.getcwd()
|
||
Pfad = os.getcwd() + '/Announcements/'
|
||
_airports_cache = None
|
||
_airlines_cache = None
|
||
|
||
app_dir = get_app_dir()
|
||
setup_logging(app_dir, level=logging.INFO, console=True)
|
||
conf_file = app_dir / "Simbriefimport.conf"
|
||
|
||
if conf_file.exists():
|
||
#print("Konfigurationsdatei gefunden:", conf_file)
|
||
logging.info(
|
||
"Konfigurationsdatei gefunden: %s",
|
||
conf_file
|
||
)
|
||
with open(conf_file) as file:
|
||
passw = json.load(file)
|
||
if passw['Prompt']['CptName'] == '':
|
||
passw['Prompt']['CptName'] = zufName("C")
|
||
if passw['Prompt']['PurserName'] == '':
|
||
passw['Prompt']['PurserName'] = zufName("P")
|
||
|
||
else:
|
||
#print("Keine Konfigurationsdatei vorhanden:", conf_file)
|
||
logging.info(
|
||
"keine Konfigurationsdatei gefunden: %s",
|
||
conf_file
|
||
)
|
||
|
||
client = OpenAI(
|
||
api_key=passw['AI']['Token'])
|
||
|
||
if "--make-version" in sys.argv:
|
||
ver = ensure_version_info(force=True) # <-- MUSS True sein
|
||
print(ver)
|
||
raise SystemExit(0)
|
||
|
||
Stimmung = str(stimmung())
|
||
|
||
(zfw, tow, payload, pax, metar_dest, metar_origin, fuel, distance, fl, flightlevel, flightnumber, airline,
|
||
aircraft_name, aircraft_icao, land_time, start_time, block, time, aircraft, dest_icao, dest_name, dest, origin_icao,
|
||
origin_name, origin, general, airline_icao, route, creationdate) = Simbriefimport()
|
||
logging.info("--------------------------------------------------")
|
||
logging.info("SimbriefUsername: %s",passw['Prompt']['Simbrief'])
|
||
logging.info("Simbriefdate: %s",creationdate)
|
||
logging.info(
|
||
"Simbrief Route: %s / %s",
|
||
origin.get("icao_code"),
|
||
dest.get("icao_code")
|
||
)
|
||
logging.info("--------------------------------------------------")
|
||
logging.info("--------------------------------------------------")
|
||
logging.info("PurserName: %s",passw['Prompt']['PurserName'])
|
||
logging.info("Cpt.Name: %s",passw['Prompt']['CptName'])
|
||
logging.info("Stimmung: %s",Stimmung)
|
||
logging.info("--------------------------------------------------")
|
||
logging.info("FLUGINFORMATIONEN")
|
||
logging.info("--------------------------------------------------")
|
||
logging.info("Airline (ICAO): %s", general.get("icao_airline"))
|
||
logging.info("Airlinename: %s", airline)
|
||
logging.info("Flugnummer: %s", general.get("flight_number"))
|
||
|
||
logging.info("Abflug ICAO: %s", origin.get("icao_code"))
|
||
logging.info("Abflugort: %s", origin_name)
|
||
|
||
logging.info("Ziel ICAO: %s", dest.get("icao_code"))
|
||
logging.info("Zielort: %s", dest_name)
|
||
logging.info("Route: %s", route)
|
||
|
||
logging.info("Geplante Blockzeit: %s", block)
|
||
logging.info("Geplanter Start: %s UTC", start_time)
|
||
logging.info("Geplante Landung: %s UTC", land_time)
|
||
|
||
logging.info("Fluggerät: %s (%s)", aircraft_icao, aircraft_name)
|
||
logging.info("Cruiselevel: FL%s", fl)
|
||
logging.info("Entfernung: %s nm", distance)
|
||
|
||
logging.info("Fuel: %s kg", fuel)
|
||
logging.info("Passagiere: %s", pax)
|
||
logging.info("ZFW: %s kg", zfw)
|
||
logging.info("TOW: %s kg", tow)
|
||
|
||
logging.info(
|
||
"Wetter Abflug %s: %s",
|
||
origin.get("icao_code"),
|
||
metar_origin
|
||
)
|
||
|
||
logging.info(
|
||
"Wetter Ziel %s: %s",
|
||
dest.get("icao_code"),
|
||
metar_dest
|
||
)
|
||
|
||
logging.info("--------------------------------------------------")
|
||
|
||
Pfad_wd = Pfad + airline_icao + '/'
|
||
|
||
ordnerneu = Path(Pfad_wd + '/neu/')
|
||
logging.info(Pfad_wd)
|
||
BACKUP(Pfad_wd)
|
||
|
||
ordnerneu.mkdir(exist_ok=True)
|
||
logging.info("--------------------------------------------------")
|
||
logging.info("START .txt Erzeugung ")
|
||
logging.info("--------------------------------------------------")
|
||
debug = False
|
||
if debug == False:
|
||
metarCabin = METAR()
|
||
metar = metarCabin.choices[0].message.content
|
||
metar = "\n".join(filter(None, map(str.strip, metar.splitlines())))
|
||
logging.info("METAR erzeugt")
|
||
|
||
welcomePilot = WelcomePilot()
|
||
Inhaltwelcome = welcomePilot.choices[0].message.content
|
||
Inhaltwelcome = "\n".join(filter(None, map(str.strip, Inhaltwelcome.splitlines())))
|
||
logging.info("WelcomePilot erzeugt")
|
||
|
||
InhaltCruise10 = CruiseElapsed10Percent().choices[0].message.content
|
||
InhaltCruise10 = "\n".join(filter(None, map(str.strip, InhaltCruise10.splitlines())))
|
||
logging.info("Cruise10 erzeugt")
|
||
|
||
InhaltCruise50 = CruiseElapsed50Percent().choices[0].message.content
|
||
InhaltCruise50 = "\n".join(filter(None, map(str.strip, InhaltCruise50.splitlines())))
|
||
logging.info("Cruise50 erzeugt")
|
||
|
||
InhaltCruise80 = CruiseElapsed80Percent().choices[0].message.content
|
||
InhaltCruise80 = "\n".join(filter(None, map(str.strip, InhaltCruise80.splitlines())))
|
||
|
||
logging.info("Cruise80 erzeugt")
|
||
|
||
Safety = SafetyBriefing().choices[0].message.content
|
||
Safety = "\n".join(filter(None, map(str.strip, Safety.splitlines())))
|
||
logging.info("SafetyBriefing erzeugt")
|
||
|
||
SecureTakeoff = CallCabinSecureTakeoff().choices[0].message.content
|
||
SecureTakeoff = "\n".join(filter(None, map(str.strip, SecureTakeoff.splitlines())))
|
||
logging.info("CallCabinSecureTakeoff erzeugt")
|
||
|
||
Pfad = Pfad_wd + 'CallCabinSecureTakeoff.txt'
|
||
txtSave(Pfad, SecureTakeoff)
|
||
pfad_txt = Path(Pfad_wd) / "CallCabinSecureTakeoff.txt"
|
||
pfad_ogg = pfad_txt.with_suffix(".ogg")
|
||
delete(pfad_ogg)
|
||
|
||
SecureLanding = CallCabinSecureLanding().choices[0].message.content
|
||
SecureLanding = "\n".join(filter(None, map(str.strip, SecureLanding.splitlines())))
|
||
logging.info("CallSecureLanding erzeugt")
|
||
|
||
Pfad = Pfad_wd + 'CallCabinSecureLanding.txt'
|
||
txtSave(Pfad, SecureLanding)
|
||
pfad_txt = Path(Pfad_wd) / "CallCabinSecureLanding.txt"
|
||
pfad_ogg = pfad_txt.with_suffix(".ogg")
|
||
delete(pfad_ogg)
|
||
|
||
Pfad = Pfad_wd + 'FastenSeatbelt.txt'
|
||
txtSave(Pfad, metar)
|
||
pfad_txt = Path(Pfad_wd) / 'FastenSeatbelt.txt'
|
||
pfad_ogg = pfad_txt.with_suffix(".ogg")
|
||
delete(pfad_ogg)
|
||
|
||
Pfad = Pfad_wd + 'CruiseElapsed10Percent.txt'
|
||
txtSave(Pfad, InhaltCruise10)
|
||
pfad_txt = Path(Pfad_wd) / 'CruiseElapsed10Percent.txt'
|
||
pfad_ogg = pfad_txt.with_suffix(".ogg")
|
||
delete(pfad_ogg)
|
||
|
||
Pfad = Pfad_wd + 'CruiseElapsed50Percent.txt'
|
||
txtSave(Pfad, InhaltCruise50)
|
||
pfad_txt = Path(Pfad_wd) / 'CruiseElapsed50Percent.txt'
|
||
pfad_ogg = pfad_txt.with_suffix(".ogg")
|
||
delete(pfad_ogg)
|
||
|
||
Pfad = Pfad_wd + 'CruiseElapsed80Percent.txt'
|
||
txtSave(Pfad, InhaltCruise80)
|
||
pfad_txt = Path(Pfad_wd) / 'CruiseElapsed80Percent.txt'
|
||
pfad_ogg = pfad_txt.with_suffix(".ogg")
|
||
delete(pfad_ogg)
|
||
|
||
Pfad = Pfad_wd + 'SafetyBriefing.txt'
|
||
txtSave(Pfad, Safety)
|
||
pfad_txt = Path(Pfad_wd) / 'SafetyBriefing.txt'
|
||
pfad_ogg = pfad_txt.with_suffix(".ogg")
|
||
delete(pfad_ogg)
|
||
|
||
Pfad = Pfad_wd + 'BoardingWelcomePilot.txt'
|
||
txtSave(Pfad, Inhaltwelcome)
|
||
pfad_txt = Path(Pfad_wd) / 'BoardingWelcomePilot.txt'
|
||
pfad_ogg = pfad_txt.with_suffix(".ogg")
|
||
delete(pfad_ogg)
|
||
|
||
|
||
|
||
|
||
|
||
logging.info("--------------------------------------------------")
|
||
logging.info(" F E R T S C H ")
|
||
logging.info("--------------------------------------------------")
|
||
|
||
logging.info("Version: %s", get_runtime_version())
|
||
ver = ensure_version_info() # erzeugt version_info.txt im Dev-Workspace
|
||
logging.info("Programmversion: %s", get_runtime_version())
|