Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d816c9d302 | ||
|
a4006721d3 | ||
|
47c1c5ceb8 | ||
|
b82d1bed1f | ||
|
69da949aa8 | ||
|
fa67553299 | ||
|
b5c9a2761f | ||
|
1748f754ca |
1
.env.dev
1
.env.dev
@ -12,3 +12,4 @@ alarminator_token=""
|
|||||||
alarminator_zvies_use_PEALGRP="False"
|
alarminator_zvies_use_PEALGRP="False"
|
||||||
printer=DEFAULT
|
printer=DEFAULT
|
||||||
print_num=0
|
print_num=0
|
||||||
|
BASIC_AUTH_PASSWORD=""
|
23
Dockerfile
23
Dockerfile
@ -13,6 +13,8 @@ ENV alarminator_zvies_use_PEALGRP="False"
|
|||||||
ENV print_num=0
|
ENV print_num=0
|
||||||
ENV printer="DEFAULT"
|
ENV printer="DEFAULT"
|
||||||
ENV REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
|
ENV REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
|
||||||
|
ENV MAPS_API_KEY=""
|
||||||
|
ENV BASIC_AUTH_PASSWORD=""
|
||||||
|
|
||||||
|
|
||||||
COPY *.deb /
|
COPY *.deb /
|
||||||
@ -44,6 +46,7 @@ RUN apt-get --yes --force-yes install ca-certificates cups cups-filters libcups
|
|||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
EXPOSE 631
|
EXPOSE 631
|
||||||
|
EXPOSE 5000
|
||||||
# Add user and disable sudo password checking
|
# Add user and disable sudo password checking
|
||||||
RUN useradd \
|
RUN useradd \
|
||||||
--groups=sudo,lp,lpadmin \
|
--groups=sudo,lp,lpadmin \
|
||||||
@ -54,11 +57,29 @@ RUN useradd \
|
|||||||
print \
|
print \
|
||||||
&& sed -i '/%sudo[[:space:]]/ s/ALL[[:space:]]*$/NOPASSWD:ALL/' /etc/sudoers
|
&& sed -i '/%sudo[[:space:]]/ s/ALL[[:space:]]*$/NOPASSWD:ALL/' /etc/sudoers
|
||||||
|
|
||||||
|
# Print PDF
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
apt-transport-https \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
--no-install-recommends \
|
||||||
|
&& curl -sSL https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \
|
||||||
|
&& echo "deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \
|
||||||
|
&& apt-get update && apt-get install -y \
|
||||||
|
google-chrome-stable \
|
||||||
|
--no-install-recommends
|
||||||
|
|
||||||
|
# It won't run from the root user.
|
||||||
|
RUN groupadd chrome && useradd -g chrome -s /bin/bash -G audio,video chrome \
|
||||||
|
&& mkdir -p /home/chrome && chown -R chrome:chrome /home/chrome
|
||||||
|
|
||||||
COPY requirements.txt ./
|
COPY requirements.txt ./
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
RUN pip install --no-cache-dir waitress
|
||||||
|
|
||||||
COPY ./app .
|
COPY ./app .
|
||||||
COPY *.crt /usr/local/share/ca-certificates/
|
COPY *.crt /usr/local/share/ca-certificates/
|
||||||
RUN update-ca-certificates
|
RUN update-ca-certificates
|
||||||
|
|
||||||
CMD [ "sh","-c","/etc/init.d/cups start && python3 /usr/src/app/exchange_connect.py" ]
|
CMD [ "sh","-c","/etc/init.d/cups start && waitress-serve --port=5000 app:app && python3 exchange_connect.py" ]
|
||||||
|
136
app/app.py
Normal file
136
app/app.py
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
from flask import Flask, flash, request, redirect, send_from_directory, get_flashed_messages
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import securecad_parser
|
||||||
|
import datetime
|
||||||
|
from hooks import webhook, alarminator_api, cups_print
|
||||||
|
from pathlib import Path
|
||||||
|
from flask_basicauth import BasicAuth
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.secret_key = 'super secret key'
|
||||||
|
app.config['SESSION_TYPE'] = 'filesystem'
|
||||||
|
app.config['BASIC_AUTH_USERNAME'] = 'admin'
|
||||||
|
app.config['BASIC_AUTH_PASSWORD'] = os.environ.get('BASIC_AUTH_PASSWORD','password')
|
||||||
|
basic_auth = BasicAuth(app)
|
||||||
|
|
||||||
|
def wrapHtml(innerHtml):
|
||||||
|
return '''<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>JFW Alarm</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
|
</head>
|
||||||
|
<body><div class="container text-center">
|
||||||
|
''' + flashMessages() +'''
|
||||||
|
''' + innerHtml + '''
|
||||||
|
</div>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||||
|
</body>
|
||||||
|
</html>'''
|
||||||
|
|
||||||
|
def flashMessages():
|
||||||
|
messages = get_flashed_messages(with_categories=True)
|
||||||
|
html = ""
|
||||||
|
if messages:
|
||||||
|
for category, message in messages:
|
||||||
|
html = html + category + ": "+message+"<br>"
|
||||||
|
return html
|
||||||
|
|
||||||
|
def alarmsPath():
|
||||||
|
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
return dir_path + "/alarms" + os.sep
|
||||||
|
|
||||||
|
def getAlarmFiles():
|
||||||
|
a_list = glob.glob(alarmsPath()+"*.html")
|
||||||
|
a_list.sort()
|
||||||
|
return [os.path.basename(f) for f in a_list]
|
||||||
|
|
||||||
|
def parseAlarm(f):
|
||||||
|
f = alarmsPath() + os.sep + f
|
||||||
|
with open(f, "r") as o:
|
||||||
|
_r: str = o.read()
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
_r = _r.replace('%DATUM%',now.strftime("%d.%m.%Y"))
|
||||||
|
_r = _r.replace('%UHRZEIT%',now.strftime("%H:%M"))
|
||||||
|
if _r != '':
|
||||||
|
return [securecad_parser.parse_securecad_message(_r),_r]
|
||||||
|
|
||||||
|
def allowed_file(filename:str):
|
||||||
|
print(filename.rsplit('.', 1)[1].lower())
|
||||||
|
return '.' in filename and \
|
||||||
|
filename.rsplit('.', 1)[1].lower() in ["html"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
@basic_auth.required
|
||||||
|
def root():
|
||||||
|
html = ""
|
||||||
|
file = request.args.get('sendalarm')
|
||||||
|
if file is not None:
|
||||||
|
parsed_body, raw = parseAlarm(file)
|
||||||
|
if parsed_body != None:
|
||||||
|
if 'ALARMDEPESCHE' in parsed_body:
|
||||||
|
webhook(parsed_body)
|
||||||
|
alarminator_api(parsed_body)
|
||||||
|
cups_print(parsed_body,raw)
|
||||||
|
flash("Alarm gesendet!")
|
||||||
|
return redirect('/')
|
||||||
|
|
||||||
|
html = html + '<div class="row align-items-start p-3 ">'
|
||||||
|
i: str
|
||||||
|
files = getAlarmFiles()
|
||||||
|
for f in files:
|
||||||
|
html = html + "<div class=\"col-6\" style='padding: 5px;'><a style='display:block; padding:20px' class=\"btn btn-block btn-danger\" href=\"/?sendalarm="+f+"\">" + f + "</a></div>"
|
||||||
|
html = html + "</div>"
|
||||||
|
return wrapHtml(html)
|
||||||
|
|
||||||
|
@app.route('/files', methods=['POST'])
|
||||||
|
@basic_auth.required
|
||||||
|
def upload_file():
|
||||||
|
# check if the post request has the file part
|
||||||
|
print(request.files)
|
||||||
|
if 'file' not in request.files:
|
||||||
|
flash('No file part')
|
||||||
|
return redirect(request.url)
|
||||||
|
file = request.files['file']
|
||||||
|
# If the user does not select a file, the browser submits an
|
||||||
|
# empty file without a filename.
|
||||||
|
print(file.filename)
|
||||||
|
if file.filename == '':
|
||||||
|
flash('No selected file')
|
||||||
|
return redirect(request.url)
|
||||||
|
if file and allowed_file(file.filename):
|
||||||
|
file.save(os.path.join(alarmsPath(), file.filename))
|
||||||
|
return redirect('/files')
|
||||||
|
|
||||||
|
@app.route('/files/<path:filename>', methods=['GET'])
|
||||||
|
@basic_auth.required
|
||||||
|
def download(filename):
|
||||||
|
uploads = alarmsPath()
|
||||||
|
return send_from_directory(uploads, filename, as_attachment=True)
|
||||||
|
|
||||||
|
@app.route("/files", methods=['GET'])
|
||||||
|
@basic_auth.required
|
||||||
|
def files():
|
||||||
|
Path(alarmsPath()).mkdir(parents=True, exist_ok=True)
|
||||||
|
file = request.args.get('del')
|
||||||
|
if file is not None:
|
||||||
|
try:
|
||||||
|
os.remove(alarmsPath()+os.sep+file)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
flash("Datei gelöscht!")
|
||||||
|
return redirect('/files')
|
||||||
|
|
||||||
|
files = getAlarmFiles()
|
||||||
|
html = '<ul class="list-group">'
|
||||||
|
for f in files:
|
||||||
|
html = html + '<li class="list-group-item"><a href="/files/'+f+'">'+f+'</a> <a href="/files?del='+f+'">löschen</a></li>'
|
||||||
|
html = html + '</ul><form method="post" enctype="multipart/form-data"><input type="file" name="file"><input type=submit value=Upload></form>'
|
||||||
|
return html
|
||||||
|
|
||||||
|
# if __name__ == "__main__":
|
||||||
|
# app.run(port=5000, host='0.0.0.0')
|
74
app/hooks.py
74
app/hooks.py
@ -2,9 +2,9 @@ import os
|
|||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
import cups
|
import cups
|
||||||
from weasyprint import HTML
|
|
||||||
from requests.adapters import Retry
|
from requests.adapters import Retry
|
||||||
import uuid
|
import uuid
|
||||||
|
import subprocess
|
||||||
|
|
||||||
retries = Retry(total=5,
|
retries = Retry(total=5,
|
||||||
backoff_factor=0.1,
|
backoff_factor=0.1,
|
||||||
@ -26,18 +26,18 @@ def alarminator_api(parsed_body: dict):
|
|||||||
alarminator_api = os.environ.get('alarminator_api') if os.environ.get('alarminator_api') else ""
|
alarminator_api = os.environ.get('alarminator_api') if os.environ.get('alarminator_api') else ""
|
||||||
alarminator_token = os.environ.get('alarminator_token') if os.environ.get('alarminator_token') else ""
|
alarminator_token = os.environ.get('alarminator_token') if os.environ.get('alarminator_token') else ""
|
||||||
alarminator_zvies_use_PEALGRP = True if os.environ.get('alarminator_zvies_use_PEALGRP') == 'True' else False
|
alarminator_zvies_use_PEALGRP = True if os.environ.get('alarminator_zvies_use_PEALGRP') == 'True' else False
|
||||||
|
maps_api_key = os.environ.get('MAPS_API_KEY',"")
|
||||||
if alarminator_api != "" and alarminator_token != "":
|
if alarminator_api != "" and alarminator_token != "":
|
||||||
if 'ALARMDEPESCHE' in parsed_body: # sendAlarm triggern
|
if 'ALARMDEPESCHE' in parsed_body: # sendAlarm triggern
|
||||||
logging.info("GET zu {}/operations/sendAlarm".format(alarminator_api))
|
logging.info("GET zu {}/operations/sendAlarm".format(alarminator_api))
|
||||||
s = requests.Session()
|
s = requests.Session()
|
||||||
s.mount('https://', requests.adapters.HTTPAdapter(max_retries=retries))
|
s.mount('https://', requests.adapters.HTTPAdapter(max_retries=retries))
|
||||||
#&object=Kirmesplatz &district=Oberlinxweilerstrasse &subject=THK (TH klein &street=Oberlinxweilerstrasse &ils=\"secur.CAD\" <leitstelle@zrf-saar.de>&connector=mailParser&token=ea2110e1-11b9-421f-a53d-96cc0fc82c31
|
|
||||||
req_string = ""
|
req_string = ""
|
||||||
req_string +="?token={}".format(alarminator_token)
|
req_string +="?token={}".format(alarminator_token)
|
||||||
if 'Einsatzbeginn(Soll)' in parsed_body:
|
if 'Einsatzbeginn(Soll)' in parsed_body:
|
||||||
req_string +="&alarmdate={}".format(parsed_body['Einsatzbeginn(Soll)'].split(" ")[0])
|
req_string +="&alarmdate={}".format(parsed_body['Einsatzbeginn(Soll)'].split(" ")[0])
|
||||||
req_string +="&alarmtime={}".format(parsed_body['Einsatzbeginn(Soll)'].split(" ")[1])
|
req_string +="&alarmtime={}".format(parsed_body['Einsatzbeginn(Soll)'].split(" ")[1])
|
||||||
if 'Auftragsnummer' in parsed_body:
|
if 'Auftragsnummer' in parsed_body and not (os.environ.get('IS_DEV') and os.environ.get('IS_DEV') == "True"):
|
||||||
req_string +="&operationnumber={}".format(parsed_body['Auftragsnummer'])
|
req_string +="&operationnumber={}".format(parsed_body['Auftragsnummer'])
|
||||||
if 'Sachverhalt' in parsed_body:
|
if 'Sachverhalt' in parsed_body:
|
||||||
req_string +="&message={}".format(parsed_body['Sachverhalt'])
|
req_string +="&message={}".format(parsed_body['Sachverhalt'])
|
||||||
@ -48,21 +48,29 @@ def alarminator_api(parsed_body: dict):
|
|||||||
req_string +="&location={}".format(parsed_body['Einsatzziel']['PLZ / Ort'])
|
req_string +="&location={}".format(parsed_body['Einsatzziel']['PLZ / Ort'])
|
||||||
if 'Objekt' in parsed_body['Einsatzziel']:
|
if 'Objekt' in parsed_body['Einsatzziel']:
|
||||||
req_string +="&object={}".format(parsed_body['Einsatzziel']['Objekt'])
|
req_string +="&object={}".format(parsed_body['Einsatzziel']['Objekt'])
|
||||||
|
street = []
|
||||||
if 'Strasse' in parsed_body['Einsatzziel']:
|
if 'Strasse' in parsed_body['Einsatzziel']:
|
||||||
req_string +="&street={}".format(parsed_body['Einsatzziel']['Strasse']) + (("\n"+parsed_body['Einsatzziel']['Info ']) if 'Info ' in parsed_body['Einsatzziel'] else "" )
|
street.append(parsed_body['Einsatzziel']['Strasse'])
|
||||||
|
if 'Zusatz Strasse' in parsed_body['Einsatzziel']:
|
||||||
|
street.append(parsed_body['Einsatzziel']['Zusatz Strasse'])
|
||||||
if 'Strasse / Hs.-Nr.' in parsed_body['Einsatzziel']:
|
if 'Strasse / Hs.-Nr.' in parsed_body['Einsatzziel']:
|
||||||
req_string +="&street={}".format(parsed_body['Einsatzziel']['Strasse / Hs.-Nr.'] + (("\n"+parsed_body['Einsatzziel']['Info ']) if 'Info ' in parsed_body['Einsatzziel'] else "" ))
|
street.append(parsed_body['Einsatzziel']['Strasse / Hs.-Nr.'])
|
||||||
|
if 'Info' in parsed_body['Einsatzziel']:
|
||||||
|
street.append(parsed_body['Einsatzziel']['Info'])
|
||||||
|
if street.__len__() > 0:
|
||||||
|
req_string +="&street={}".format("\n".join(street))
|
||||||
|
|
||||||
if 'Einsatzmittelliste' in parsed_body:
|
if 'Einsatzmittelliste' in parsed_body:
|
||||||
gear = []
|
gear = []
|
||||||
for r in parsed_body['Einsatzmittelliste']:
|
for r in parsed_body['Einsatzmittelliste']:
|
||||||
if r['Typ'] != 'PEALGRP':
|
#if r['Typ'] != 'PEALGRP':
|
||||||
|
if r['Ressourcen'] not in gear:
|
||||||
gear.append(r['Ressourcen'])
|
gear.append(r['Ressourcen'])
|
||||||
req_string +="&gear={}".format(';'.join(gear))
|
req_string +="&gear={}".format(';'.join(gear))
|
||||||
|
|
||||||
#req_string +="&district={}".format('district')
|
# req_string +="&district={}".format('district')
|
||||||
#req_string +="&floor={}".format('floor')
|
# req_string +="&floor={}".format('floor')
|
||||||
#req_string +="§ion={}".format('section')
|
# req_string +="§ion={}".format('section')
|
||||||
req_string +="&keywordRaw={}".format(parsed_body['Einsatzstichwort'])
|
req_string +="&keywordRaw={}".format(parsed_body['Einsatzstichwort'])
|
||||||
#req_string +="&keywordId={}".format('keywordId')
|
#req_string +="&keywordId={}".format('keywordId')
|
||||||
req_string +="&keywordCategory={}".format(parsed_body['Einsatzstichwort'].split("(")[0])
|
req_string +="&keywordCategory={}".format(parsed_body['Einsatzstichwort'].split("(")[0])
|
||||||
@ -76,35 +84,67 @@ def alarminator_api(parsed_body: dict):
|
|||||||
req_string +="&zveis={}".format(';'.join(zveis))
|
req_string +="&zveis={}".format(';'.join(zveis))
|
||||||
else:
|
else:
|
||||||
req_string +="&zveis={}".format(parsed_body['ALARMDEPESCHE'])
|
req_string +="&zveis={}".format(parsed_body['ALARMDEPESCHE'])
|
||||||
|
|
||||||
|
if maps_api_key != "":
|
||||||
|
try:
|
||||||
|
maps_address_param = []
|
||||||
|
if 'Objekt' in parsed_body['Einsatzziel']:
|
||||||
|
maps_address_param.append("{}".format(parsed_body['Einsatzziel']['Objekt']))
|
||||||
|
|
||||||
|
if street.__len__() > 0:
|
||||||
|
maps_address_param.append('{}'.format(",".join(street)))
|
||||||
|
if 'Stadt' in parsed_body['Einsatzziel']:
|
||||||
|
maps_address_param.append("{}".format(parsed_body['Einsatzziel']['Stadt']))
|
||||||
|
if 'PLZ / Ort' in parsed_body['Einsatzziel']:
|
||||||
|
maps_address_param.append("{}".format(parsed_body['Einsatzziel']['PLZ / Ort']))
|
||||||
|
|
||||||
|
maps_request = requests.get('https://maps.google.com/maps/api/geocode/json?address={}&key={}'.format(','.join(maps_address_param),maps_api_key))
|
||||||
|
if maps_request.json()['results'].__len__() == 1:
|
||||||
|
req_string +="&lat={}".format(maps_request.json()['results'][0]['geometry']['location']['lat'])
|
||||||
|
req_string +="&lon={}".format(maps_request.json()['results'][0]['geometry']['location']['lng'])
|
||||||
|
except Exception as maps_e:
|
||||||
|
logging.error('error getting maps',maps_e)
|
||||||
|
|
||||||
# req_string +="&gkx={}".format() if False
|
# req_string +="&gkx={}".format() if False
|
||||||
# req_string +="&gky={}".format() if False
|
# req_string +="&gky={}".format() if False
|
||||||
# req_string +="&lat={}".format() if False
|
# if False
|
||||||
# req_string +="&lon={}".format() if False
|
# req_string +="&lon={}".format() if False
|
||||||
subject = ""
|
subject = ""
|
||||||
if 'Notfallgeschehen' in parsed_body:
|
|
||||||
subject = parsed_body['Notfallgeschehen'] + "\n"
|
|
||||||
if 'Notfallgeschehen' in parsed_body:
|
if 'Notfallgeschehen' in parsed_body:
|
||||||
subject = parsed_body['Notfallgeschehen'] + "\n"
|
subject = parsed_body['Notfallgeschehen'] + "\n"
|
||||||
req_string +="&subject={}".format(subject)
|
req_string +="&subject={}".format(subject)
|
||||||
req_string +="&ils={}".format("ILS Saar")
|
req_string +="&ils={}".format("ILS Saar")
|
||||||
req_string +="&connector={}".format("MailParser")
|
req_string +="&connector={}".format("MailParser")
|
||||||
|
if os.environ.get('IS_DEV') and os.environ.get('IS_DEV') == "True":
|
||||||
|
req_string +="&isTest=1"
|
||||||
s.get(alarminator_api+"/operations/sendAlarm/"+req_string)
|
s.get(alarminator_api+"/operations/sendAlarm/"+req_string)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("alarminator_api", e)
|
logging.error("alarminator_api", e)
|
||||||
|
|
||||||
|
def generate_pdf(html_body, filename):
|
||||||
|
f = "/tmp/{}.html".format(uuid.uuid4())
|
||||||
|
with open(f,"w") as _f:
|
||||||
|
_f.write(html_body)
|
||||||
|
subprocess.run(["/usr/bin/google-chrome-stable", "--headless", "--no-sandbox", "--disable-gpu", "--print-to-pdf="+filename, "--no-pdf-header-footer", "--print-to-pdf-no-header", "--no-margins", f])
|
||||||
|
if os.path.exists(f):
|
||||||
|
os.remove(f)
|
||||||
|
|
||||||
def cups_print(parsed_body: dict, body: str):
|
def cups_print(parsed_body: dict, body: str):
|
||||||
|
if os.environ.get('IS_DEV') and os.environ.get('IS_DEV') == "True":
|
||||||
|
generate_pdf(body, "{}.pdf".format(uuid.uuid4()))
|
||||||
fname = "/tmp/{}.pdf".format(uuid.uuid4())
|
fname = "/tmp/{}.pdf".format(uuid.uuid4())
|
||||||
try:
|
try:
|
||||||
conn = cups.Connection ()
|
conn = cups.Connection ()
|
||||||
printer = os.environ.get('printer',"DEFAULT")
|
printer_arr = os.environ.get('printer',"DEFAULT").split(";")
|
||||||
print_num = int(os.environ.get('print_num',0))
|
print_num = int(os.environ.get('print_num',0))
|
||||||
|
if printer_arr.__len__() > 0:
|
||||||
|
generate_pdf(body, fname)
|
||||||
|
for printer in printer_arr:
|
||||||
if 'ALARMDEPESCHE' in parsed_body:
|
if 'ALARMDEPESCHE' in parsed_body:
|
||||||
with open(fname,"wb") as f:
|
|
||||||
f.write(HTML(string=body, base_url="").write_pdf())
|
|
||||||
for i in range(0, print_num):
|
for i in range(0, print_num):
|
||||||
conn.printFile (printer, fname, "Alarmfax", {})
|
conn.printFile (printer, fname, "Alarmfax", {})
|
||||||
os.remove(fname)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logging.error("cups_print", e)
|
||||||
|
finally:
|
||||||
if os.path.exists(fname):
|
if os.path.exists(fname):
|
||||||
os.remove(fname)
|
os.remove(fname)
|
||||||
logging.error("cups_print", e)
|
|
@ -2,9 +2,12 @@ version: "2"
|
|||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
build: ./
|
build: ./
|
||||||
image: gitea.simonzeyer.de/simon/wnd_ils_alarmfax_parser:latest
|
#image: gitea.simonzeyer.de/simon/wnd_ils_alarmfax_parser:latest
|
||||||
restart: always
|
restart: always
|
||||||
privileged: true
|
privileged: true
|
||||||
|
# ports:
|
||||||
|
# - 631:631
|
||||||
|
# - 5000:5000
|
||||||
environment:
|
environment:
|
||||||
- username=${username}
|
- username=${username}
|
||||||
- password=${password}
|
- password=${password}
|
||||||
@ -20,6 +23,8 @@ services:
|
|||||||
- alarminator_zvies_use_PEALGRP=${alarminator_zvies_use_PEALGRP}
|
- alarminator_zvies_use_PEALGRP=${alarminator_zvies_use_PEALGRP}
|
||||||
- printer=${printer}
|
- printer=${printer}
|
||||||
- print_num=${print_num}
|
- print_num=${print_num}
|
||||||
|
- MAPS_API_KEY=${MAPS_API_KEY}
|
||||||
|
- BASIC_AUTH_PASSWORD=${BASIC_AUTH_PASSWORD}
|
||||||
volumes:
|
volumes:
|
||||||
- ./cups:/etc/cups
|
- ./cups:/etc/cups
|
||||||
- ./cupsd.conf.txt:/etc/cups/cupsd.conf
|
- ./cupsd.conf.txt:/etc/cups/cupsd.conf
|
||||||
|
@ -1,20 +1,35 @@
|
|||||||
|
blinker==1.8.2
|
||||||
|
Brotli==1.1.0
|
||||||
cached-property==1.5.2
|
cached-property==1.5.2
|
||||||
certifi==2022.12.7
|
certifi==2022.12.7
|
||||||
cffi==1.15.1
|
cffi==1.15.1
|
||||||
charset-normalizer==3.0.1
|
charset-normalizer==3.0.1
|
||||||
|
click==8.1.7
|
||||||
cryptography==39.0.0
|
cryptography==39.0.0
|
||||||
|
cssselect2==0.7.0
|
||||||
defusedxml==0.7.1
|
defusedxml==0.7.1
|
||||||
dnspython==2.3.0
|
dnspython==2.3.0
|
||||||
exchangelib==4.9.0
|
exchangelib==4.9.0
|
||||||
|
Flask==3.0.3
|
||||||
|
Flask-BasicAuth==0.2.0
|
||||||
|
fonttools==4.54.1
|
||||||
|
html5lib==1.1
|
||||||
idna==3.4
|
idna==3.4
|
||||||
isodate==0.6.1
|
isodate==0.6.1
|
||||||
|
itsdangerous==2.2.0
|
||||||
|
Jinja2==3.1.4
|
||||||
lxml==4.9.2
|
lxml==4.9.2
|
||||||
|
MarkupSafe==3.0.1
|
||||||
ntlm-auth==1.5.0
|
ntlm-auth==1.5.0
|
||||||
numpy==1.24.1
|
numpy==1.24.1
|
||||||
oauthlib==3.2.2
|
oauthlib==3.2.2
|
||||||
pandas==1.5.2
|
pandas==1.5.2
|
||||||
|
pillow==10.4.0
|
||||||
pycparser==2.21
|
pycparser==2.21
|
||||||
|
pycups==2.0.1
|
||||||
|
pydyf==0.11.0
|
||||||
Pygments==2.14.0
|
Pygments==2.14.0
|
||||||
|
pyphen==0.16.0
|
||||||
python-dateutil==2.8.2
|
python-dateutil==2.8.2
|
||||||
pytz==2022.7.1
|
pytz==2022.7.1
|
||||||
pytz-deprecation-shim==0.1.0.post0
|
pytz-deprecation-shim==0.1.0.post0
|
||||||
@ -22,10 +37,12 @@ requests==2.28.2
|
|||||||
requests-ntlm==1.1.0
|
requests-ntlm==1.1.0
|
||||||
requests-oauthlib==1.3.1
|
requests-oauthlib==1.3.1
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
|
tinycss2==1.3.0
|
||||||
tzdata==2022.7
|
tzdata==2022.7
|
||||||
tzlocal==4.2
|
tzlocal==4.2
|
||||||
urllib3==1.26.14
|
urllib3==1.26.14
|
||||||
|
webencodings==0.5.1
|
||||||
|
Werkzeug==3.0.4
|
||||||
xmltodict==0.12.0
|
xmltodict==0.12.0
|
||||||
xmltojson==2.0.1
|
xmltojson==2.0.1
|
||||||
pycups==2.0.1
|
zopfli==0.2.3
|
||||||
weasyprint
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user