import asyncio import pjsua2 as pj from threading import Thread from markupsafe import escape from unificontrol import UnifiClient from dotenv import load_dotenv from os import getenv from ssl import get_server_certificate from flask import Flask, request, render_template, Response, send_from_directory from queue import Queue from time import sleep import os app = Flask(__name__) app.config['TEMPLATES_AUTO_RELOAD'] = True global unifi QUEUE = Queue(1) VISITOR_COUNT_FILE = "visitor_count" LIB = None def call(): sip_server = str(getenv("SIP_SERVER")) sip_username = str(getenv("SIP_USERNAME")) sip_password = str(getenv("SIP_PASSWORD")) # Initialize lib LIB = pj.Endpoint() LIB.libCreate() ep_cfg = pj.EpConfig() LIB.libInit(ep_cfg) transport_cfg = pj.TransportConfig() transport_cfg.port = 5060 LIB.transportCreate(pj.PJSIP_TRANSPORT_UDP, transport_cfg) LIB.libStart() class MyAccount(pj.Account): def __init__(self): pj.Account.__init__(self) def onRegState(self, prm): print("Registration state:", prm.code) # Account config acc_cfg = pj.AccountConfig() acc_cfg.idUri = f"sip:{sip_username}@{sip_server}" acc_cfg.regConfig.registrarUri = f"sip:{sip_server}" cred = pj.AuthCredInfo("digest", "*", sip_username, 0, sip_password) acc_cfg.sipConfig.authCreds.append(cred) acc = MyAccount() acc.create(acc_cfg) while True: try: id = QUEUE.get(block = True) # Spawn audio on phone call_phone(sip_server, acc) # authorize guest after a certain amount of time unifi.authorize_guest(id, 1) except: sleep(5) def call_phone(hostname, acc): # Make call class MyCall(pj.Call): def __init__(self, acc, dest_uri): pj.Call.__init__(self, acc) self.makeCall(dest_uri, pj.CallOpParam(True)) def onCallState(self, prm): ci = self.getInfo() print("Call state:", ci.stateText) call = MyCall(acc, f"sip:3002@{hostname}") # Keep the program running for the duration of the ringtone sleep(18) del call def main(): if not os.path.exists(VISITOR_COUNT_FILE): os.mknod(VISITOR_COUNT_FILE) with open(VISITOR_COUNT_FILE, "w") as f: f.write("0") load_dotenv() HOSTNAME = str(getenv("HOSTNAME")) USERNAME = str(getenv("USERNAME")) PASSWORD = str(getenv("PASSWORD")) cert = get_server_certificate((HOSTNAME, 443)) global unifi unifi = UnifiClient(host=HOSTNAME, username=USERNAME, password=PASSWORD, cert=cert) Thread(target=call).start() app.run(host="0.0.0.0", port=80) def visitor_count(): visitor_count = 1337 # Yes there is a race condition here, I don't care try: with open(VISITOR_COUNT_FILE, "r+") as f: visitors = int(f.read().strip()) visitors += 1 f.seek(0) f.write(str(visitors)) f.truncate() visitor_count = visitors except Exception as e: print(f"error {e}") return visitor_count LANG_EN = { "Inbellen bij TechInc": "Dialup with TechInc", "TechInc inbel portaal": "TechInc dialup portal", "GRATIS": "FREE", "Gratis": "Free", "gratis": "freely", "Verbind": "Connect for", "met het wereldwijde web": "with the world wide web", "Openen van telefoonlijn...": "Opening the phone line...", "Bellen naar TechInc...": "Calling into TechInc...", "Ontvang verbindingsopties...": "Receiving the connection options...", "Uitzetten van echo onderdrukking...": "Disabling the echo suppression...", "Breedbandspectrum peilen...": "Probing wide-spectrum...", "Equalizer en echo-onderdrukkingstraining...": "Equalizer and echo-suppression training....", "Verbinding met TechInc is gelegd!": "Connection with TechInc has been established!", "openbaar": "publicly", "Welkom, surfer!": "Welcome, surfer!", "Onze snelle telefoon lijn is": "Our fast phone line is", "en": "and", "beschikbaar": "available", "Via onderstaande knop kan je inbellen via je modem.": "With the buttom below you can dial up with your modem", "Inbellen via TechInc heeft de volgende voordelen": "Dial up via TechInc has the following advantages", "Altijd en overal toegang": "Always and everywhere access", "tot het internet via uw telefoonlijn": "to the internet via your telephone line", "Compatibel met alle gangbare 14.4k, 28.8k en 56k modems": "Compatible with all common 14.4k, 28.8k and 56k modems", "Geen installatie nodig": "No installation required!", "werkt direct met Windows 95/98 en Netscape Navigator": "works instantly with Windows 95/98 and Netscape Navigator", "Ondersteuning voor e-mail, nieuwsgroepen en Internet Relay Chat (IRC)": "Support for e-mail, newsgroups and Internet Relay Chat (IRC)", "Beveiligde verbinding via ons eigen TechInc-netwerk": "Secure connecton with our own TechInc network", "u betaalt helemaal niets": "you don't pay anything", "ook niet voor de gespreksduur!": "not even for the duration of the call!", "doe-het-zelf helpdesk voor al uw internetvragen": "do-it-yourself helpdesk for all your internet questions", "Verbind nu!": "Connect now!", "/afbeeldingen/verbind.gif": "/afbeeldingen/connect.gif", "U BENT BEZOEKER NUMMER": "YOU ARE VISITOR NUMBER" } LANG_NL = { "Inbellen bij TechInc": "Inbellen bij TechInc", "TechInc inbel portaal": "TechInc inbel portaal", "GRATIS": "GRATIS", "Gratis": "Gratis", "gratis": "gratis", "Verbind": "Verbind", "met het wereldwijde web": "met het wereldwijde web", "Openen van telefoonlijn...": "Openen van telefoonlijn...", "Bellen naar TechInc...": "Bellen naar TechInc...", "Ontvang verbindingsopties...": "Ontvang verbindingsopties...", "Uitzetten van echo onderdrukking...": "Uitzetten van echo onderdrukking...", "Breedbandspectrum peilen...": "Breedbandspectrum peilen...", "Equalizer en echo-onderdrukkingstraining...": "Equalizer en echo-onderdrukkingstraining...", "Verbinding met TechInc is gelegd!": "Verbinding met TechInc is gelegd!", "openbaar": "openbaar", "Welkom, surfer!": "Welkom, surfer!", "Onze snelle telefoon lijn is": "Onze snelle telefoon lijn is", "en": "en", "beschikbaar": "beschikbaar", "Via onderstaande knop kan je inbellen via je modem.": "Via onderstaande knop kan je inbellen via je modem.", "Inbellen via TechInc heeft de volgende voordelen": "Inbellen via TechInc heeft de volgende voordelen", "Altijd en overal toegang": "Altijd en overal toegang", "tot het internet via uw telefoonlijn": "tot het internet via uw telefoonlijn", "Compatibel met alle gangbare 14.4k, 28.8k en 56k modems": "Compatibel met alle gangbare 14.4k, 28.8k en 56k modems", "Geen installatie nodig": "Geen installatie nodig", "werkt direct met Windows 95/98 en Netscape Navigator": "werkt direct met Windows 95/98 en Netscape Navigator", "Ondersteuning voor e-mail, nieuwsgroepen en Internet Relay Chat (IRC)": "Ondersteuning voor e-mail, nieuwsgroepen en Internet Relay Chat (IRC)", "Beveiligde verbinding via ons eigen TechInc-netwerk": "Beveiligde verbinding via ons eigen TechInc-netwerk", "u betaalt helemaal niets": "u betaalt helemaal niets", "ook niet voor de gespreksduur!": "ook niet voor de gespreksduur!", "doe-het-zelf helpdesk voor al uw internetvragen": "doe-het-zelf helpdesk voor al uw internetvragen", "Verbind nu!": "Verbind nu!", "/afbeeldingen/verbind.gif": "/afbeeldingen/verbind.gif", "U BENT BEZOEKER NUMMER": "U BENT BEZOEKER NUMMER" } LANG = { 'nl': LANG_NL, 'en': LANG_EN } @app.route('/guest/s/default/', methods=["GET"]) def root(): supported_languages = ["en", "nl"] lang = request.accept_languages.best_match(supported_languages) id = escape(request.args.get('id')) page = render_template("index.html", dialing_up=False, id=id, lang=LANG[lang], visitor_count=visitor_count()) response = Response(page, mimetype="text/html") return response @app.route("/dialup", methods=["POST"]) def dialup(): supported_languages = ["en", "nl"] lang = request.accept_languages.best_match(supported_languages) id = escape(request.args.get('id')) page = render_template("index.html", dialing_up=True, id=id, lang=LANG[lang], visitor_count=visitor_count()) response = Response(page, mimetype="text/html") QUEUE.put(id) return response @app.route('/afbeeldingen/') def static_folder(path): return send_from_directory('static', path) if __name__ == "__main__": main()