Skip to content
Snippets Groups Projects
run.py 5.13 KiB
Newer Older
  • Learn to ignore specific revisions
  • #!/bin/sh
    ''''which python3.8 >/dev/null 2>&1 && exec python3.8 "$0" "$@"     # '''
    ''''which python3.7  >/dev/null 2>&1 && exec python3.7  "$0" "$@"   # '''
    ''''exec echo "Error: Snaaakey Python, where are you?"                # '''
    
    David Trattnig's avatar
    David Trattnig committed
    # Aura Engine (https://gitlab.servus.at/aura/engine)
    #
    # Copyright (C) 2017-2020 - The Aura Engine Team.
    
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU Affero General Public License as published by
    # the Free Software Foundation, either version 3 of the License, or
    # (at your option) any later version.
    
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU Affero General Public License for more details.
    
    # You should have received a copy of the GNU Affero General Public License
    # along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    
    import os
    import sys
    import signal
    import logging
    
    import subprocess
    
    from flask               import Flask
    from flask_sqlalchemy    import SQLAlchemy
    
    from src.base.logger import AuraLogger
    from src.base.config import AuraConfig
    from src.base.utils  import SimpleUtil as SU
    
    
    
    config = AuraConfig()
    def configure_flask():
        app.config["SQLALCHEMY_DATABASE_URI"] = config.get_database_uri()
        app.config['BABEL_DEFAULT_LOCALE'] = 'de'
        app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    
    # FIXME Instatiate SQLAlchemy without the need for Flask
    app = Flask(__name__)
    configure_flask()
    DB = SQLAlchemy(app)
    
    
    class EngineRunner:
    
        EngineRunner is in charge of
    
        1. Initializing the engine and all dependencies
        3. Starting Liquidsoap in a separate thread, if requested
    
    
        """
        logger = None
        config = None
    
    David Trattnig's avatar
    David Trattnig committed
        engine = None
    
            Constructor
    
            """
            self.config = config
    
    David Trattnig's avatar
    David Trattnig committed
            AuraLogger(self.config)
            self.logger = logging.getLogger("AuraEngine")
            
    
        def run(self, start_lqs, lqs_debug_flags):
    
            Starts Engine Core.
    
    David Trattnig's avatar
    David Trattnig committed
            """                
    
            from src.scheduling.scheduler import AuraScheduler
            from src.core.engine import Engine
    
    
            # Check if the database has to be re-created
            if self.config.get("recreate_db") is not None:
    
                AuraScheduler.init_database()
    
            if start_lqs:
                runner.run_lqs(lqs_debug_flags)        
            else:
                self.logger.info(SU.yellow("Please note, Liquidsoap needs to be started manually."))
    
            self.engine = Engine()
    
        def run_lqs(self, lqs_debug_flags):
    
            """
            Starts Liquidsoap.
            """
    
            debug_output = lqs_debug_flags.get("debug_output")
            verbose_output = lqs_debug_flags.get("verbose_output")
    
            lqs_path = self.config.get("liquidsoap_path")
            lqs_cwd = os.getcwd() + "/" + self.config.get("liquidsoap_working_dir")
            lqs_output = ""
            lqs_output = self.get_debug_flags(debug_output, verbose_output)
    
            self.lqs = subprocess.Popen([lqs_path, lqs_output, "engine.liq"], \
                cwd=lqs_cwd, \
                stdout=subprocess.PIPE, \
                shell=False)
    
    
    
        def get_lqs_cmd(self, debug_output, verbose_output):
            """
            Returns a shell command string to start Liquidsoap
            """
            lqs_path = self.config.get("liquidsoap_path")
            lqs_cwd = os.getcwd() + "/" + self.config.get("liquidsoap_working_dir")
            lqs_output = self.get_debug_flags(debug_output, verbose_output)
            return "(cd %s && %s %s ./engine.liq)" % (lqs_cwd, lqs_path, lqs_output)
    
    
    
        def get_debug_flags(self, debug_output, verbose_output):
            """
    
    David Trattnig's avatar
    David Trattnig committed
            Build Liquidsoap debug parameters.
    
            """
            output = ""
            if debug_output:
                output += "--debug " 
            if verbose_output:
                output += "--verbose "
            return output
    
    
    
    
        def exit_gracefully(self, signum, frame):
            """
    
            Shutdown of the engine. Also terminates the Liquidsoap thread.
    
            if self.engine:
                self.engine.terminate()
    
    
            if self.lqs:
                self.lqs.terminate()
                self.logger.info("Terminated Liquidsoap")
    
    
    David Trattnig's avatar
    David Trattnig committed
            self.logger.info("Gracefully terminated Aura Engine! (signum:%s, frame:%s)" % (signum, frame))
    
            sys.exit(0)        
    
    if __name__ == "__main__":        
    
        runner = EngineRunner()
        do_start_lqs = True
    
        lqs_cmd = False
    
        signal.signal(signal.SIGINT, runner.exit_gracefully)
        signal.signal(signal.SIGTERM, runner.exit_gracefully)
    
    
        if len(sys.argv) >= 2:
    
            if "--without-lqs" in sys.argv:
    
                do_start_lqs = False
    
            if "--get-lqs-command" in sys.argv:
                lqs_cmd = True
    
            if "--use-test-data" in sys.argv:
    
                runner.config.set("use_test_data", True)
    
            if "--recreate-database" in sys.argv:
    
                runner.config.set("recreate_db", True)
    
        if lqs_cmd:
    
            print(runner.get_lqs_cmd(True, True))
        else:                
            runner.run(do_start_lqs, { "debug_output": False, "verbose_output": False })