Esempio n. 1
0
class Server():
    def __init__(self,
                 configfile=None,
                 basedir=None,
                 host="0.0.0.0",
                 port=5000,
                 debug=False,
                 allowRoot=False,
                 logConf=None):
        self._configfile = configfile
        self._basedir = basedir
        self._host = host
        self._port = port
        self._debug = debug
        self._allowRoot = allowRoot
        self._logConf = logConf
        self._ioLoop = None

    def stop(self):
        if self._ioLoop:
            self._ioLoop.stop()
            self._ioLoop = None

    def run(self):
        if not self._allowRoot:
            self._checkForRoot()

        global userManager
        global eventManager
        global loginManager
        global debug
        global softwareManager
        global discoveryManager
        global VERSION
        global UI_API_KEY

        from tornado.wsgi import WSGIContainer
        from tornado.httpserver import HTTPServer
        from tornado.ioloop import IOLoop
        from tornado.web import Application, FallbackHandler

        from astroprint.printfiles.watchdogs import UploadCleanupWatchdogHandler

        debug = self._debug

        # first initialize the settings singleton and make sure it uses given configfile and basedir if available
        self._initSettings(self._configfile, self._basedir)
        s = settings()

        if not s.getBoolean(['api', 'regenerate']) and s.getString(
            ['api', 'key']):
            UI_API_KEY = s.getString(['api', 'key'])
        else:
            UI_API_KEY = ''.join('%02X' % ord(z) for z in uuid.uuid4().bytes)

        # then initialize logging
        self._initLogging(self._debug, self._logConf)
        logger = logging.getLogger(__name__)

        if s.getBoolean(["accessControl", "enabled"]):
            userManagerName = s.get(["accessControl", "userManager"])
            try:
                clazz = util.getClass(userManagerName)
                userManager = clazz()
            except AttributeError, e:
                logger.exception(
                    "Could not instantiate user manager %s, will run with accessControl disabled!"
                    % userManagerName)

        softwareManager = swManager()
        VERSION = softwareManager.versionString

        logger.info("Starting AstroBox (%s) - Commit (%s)" %
                    (VERSION, softwareManager.commit))

        from astroprint.migration import migrateSettings
        migrateSettings()

        manufacturerPkgManager()
        ppm = printerProfileManager()
        pluginManager().loadPlugins()

        eventManager = events.eventManager()
        printer = printerManager(ppm.data['driver'])

        #Start some of the managers here to make sure there are no thread collisions
        from astroprint.network.manager import networkManager
        from astroprint.boxrouter import boxrouterManager

        networkManager()
        boxrouterManager()

        # configure timelapse
        #octoprint.timelapse.configureTimelapse()

        app.wsgi_app = ReverseProxied(app.wsgi_app)

        app.secret_key = boxrouterManager().boxId
        loginManager = LoginManager()
        loginManager.session_protection = "strong"
        loginManager.user_callback = load_user
        if userManager is None:
            loginManager.anonymous_user = users.DummyUser
            principals.identity_loaders.appendleft(users.dummy_identity_loader)
        loginManager.init_app(app)

        # setup command triggers
        events.CommandTrigger(printer)
        if self._debug:
            events.DebugEventListener()

        if networkManager().isOnline():
            softwareManager.checkForcedUpdate()

        if self._host is None:
            self._host = s.get(["server", "host"])
        if self._port is None:
            self._port = s.getInt(["server", "port"])

        app.debug = self._debug

        from octoprint.server.api import api

        app.register_blueprint(api, url_prefix="/api")

        boxrouterManager(
        )  # Makes sure the singleton is created here. It doesn't need to be stored
        self._router = SockJSRouter(self._createSocketConnection, "/sockjs")

        discoveryManager = DiscoveryManager()

        externalDriveManager()

        def access_validation_factory(validator):
            """
			Creates an access validation wrapper using the supplied validator.

			:param validator: the access validator to use inside the validation wrapper
			:return: an access validation wrapper taking a request as parameter and performing the request validation
			"""
            def f(request):
                """
				Creates a custom wsgi and Flask request context in order to be able to process user information
				stored in the current session.

				:param request: The Tornado request for which to create the environment and context
				"""
                wsgi_environ = tornado.wsgi.WSGIContainer.environ(request)
                with app.request_context(wsgi_environ):
                    app.session_interface.open_session(app, request)
                    loginManager.reload_user()
                    validator(request)

            return f

        self._tornado_app = Application(self._router.urls + [
            #(r"/downloads/timelapse/([^/]*\.mpg)", LargeResponseHandler, {"path": s.getBaseFolder("timelapse"), "as_attachment": True}),
            (r"/downloads/files/local/([^/]*\.(gco|gcode))",
             LargeResponseHandler, {
                 "path": s.getBaseFolder("uploads"),
                 "as_attachment": True
             }),
            (r"/downloads/logs/([^/]*)", LargeResponseHandler, {
                "path": s.getBaseFolder("logs"),
                "as_attachment": True,
                "access_validation": access_validation_factory(admin_validator)
            }),
            #(r"/downloads/camera/current", UrlForwardHandler, {"url": s.get(["webcam", "snapshot"]), "as_attachment": True, "access_validation": access_validation_factory(user_validator)}),
            (r".*", FallbackHandler, {
                "fallback": WSGIContainer(app.wsgi_app)
            })
        ])
        self._server = HTTPServer(self._tornado_app,
                                  max_buffer_size=1048576 *
                                  s.getInt(['server', 'maxUploadSize']))
        self._server.listen(self._port, address=self._host)

        logger.info("Listening on http://%s:%d" % (self._host, self._port))

        eventManager.fire(events.Events.STARTUP)
        if s.getBoolean(["serial", "autoconnect"]):
            t = threading.Thread(target=printer.connect)
            t.daemon = True
            t.start()

        # start up watchdogs
        observer = Observer()
        observer.daemon = True
        observer.schedule(UploadCleanupWatchdogHandler(),
                          s.getBaseFolder("uploads"))
        observer.start()

        #Load additional Tasks
        additionalTasksManager()

        #Load maintenance menu
        maintenanceMenuManager()

        try:
            self._ioLoop = IOLoop.instance()
            self._ioLoop.start()

        except SystemExit:
            pass

        except:
            logger.fatal(
                "Please report this including the stacktrace below in AstroPrint's bugtracker. Thanks!"
            )
            logger.exception("Stacktrace follows:")

        finally:
            observer.stop()
            self.cleanup()
            logger.info('Cleanup complete')

        observer.join(1.0)
        logger.info('Good Bye!')
Esempio n. 2
0
class Server():
    def __init__(self,
                 configfile=None,
                 basedir=None,
                 host="0.0.0.0",
                 port=5000,
                 debug=False,
                 allowRoot=False,
                 logConf=None):
        self._configfile = configfile
        self._basedir = basedir
        self._host = host
        self._port = port
        self._debug = debug
        self._allowRoot = allowRoot
        self._logConf = logConf

    def run(self):
        if not self._allowRoot:
            self._checkForRoot()

        global userManager
        global eventManager
        global loginManager
        global debug
        global softwareManager
        global VERSION

        from tornado.wsgi import WSGIContainer
        from tornado.httpserver import HTTPServer
        from tornado.ioloop import IOLoop
        from tornado.web import Application, FallbackHandler

        from astroprint.printfiles.watchdogs import UploadCleanupWatchdogHandler

        debug = self._debug

        # first initialize the settings singleton and make sure it uses given configfile and basedir if available
        self._initSettings(self._configfile, self._basedir)
        s = settings()

        # then initialize logging
        self._initLogging(self._debug, self._logConf)
        logger = logging.getLogger(__name__)

        if s.getBoolean(["accessControl", "enabled"]):
            userManagerName = settings().get(["accessControl", "userManager"])
            try:
                clazz = util.getClass(userManagerName)
                userManager = clazz()
            except AttributeError, e:
                logger.exception(
                    "Could not instantiate user manager %s, will run with accessControl disabled!"
                    % userManagerName)

        softwareManager = swManager()
        VERSION = softwareManager.versionString

        logger.info("Starting AstroBox (%s)" % VERSION)

        eventManager = events.eventManager()
        printer = printerManager(printerProfileManager().data['driver'])

        # configure timelapse
        #octoprint.timelapse.configureTimelapse()

        app.wsgi_app = ReverseProxied(app.wsgi_app)

        app.secret_key = boxrouterManager().boxId
        loginManager = LoginManager()
        loginManager.session_protection = "strong"
        loginManager.user_callback = load_user
        if userManager is None:
            loginManager.anonymous_user = users.DummyUser
            principals.identity_loaders.appendleft(users.dummy_identity_loader)
        loginManager.init_app(app)

        # setup command triggers
        events.CommandTrigger(printer)
        if self._debug:
            events.DebugEventListener()

        if networkManager().isOnline():
            softwareManager.checkForcedUpdate()

        if self._host is None:
            self._host = s.get(["server", "host"])
        if self._port is None:
            self._port = s.getInt(["server", "port"])

        app.debug = self._debug

        from octoprint.server.api import api

        app.register_blueprint(api, url_prefix="/api")

        self._boxrouter = boxrouterManager()
        self._router = SockJSRouter(self._createSocketConnection, "/sockjs")

        self._discovery = discoveryManager()

        def access_validation_factory(validator):
            """
			Creates an access validation wrapper using the supplied validator.

			:param validator: the access validator to use inside the validation wrapper
			:return: an access validation wrapper taking a request as parameter and performing the request validation
			"""
            def f(request):
                """
				Creates a custom wsgi and Flask request context in order to be able to process user information
				stored in the current session.

				:param request: The Tornado request for which to create the environment and context
				"""
                wsgi_environ = tornado.wsgi.WSGIContainer.environ(request)
                with app.request_context(wsgi_environ):
                    app.session_interface.open_session(app, flask.request)
                    loginManager.reload_user()
                    validator(flask.request)

            return f

        self._tornado_app = Application(self._router.urls + [
            (r"/downloads/timelapse/([^/]*\.mpg)", LargeResponseHandler, {
                "path": s.getBaseFolder("timelapse"),
                "as_attachment": True
            }),
            (r"/downloads/files/local/([^/]*\.(gco|gcode))",
             LargeResponseHandler, {
                 "path": s.getBaseFolder("uploads"),
                 "as_attachment": True
             }),
            (r"/downloads/logs/([^/]*)", LargeResponseHandler, {
                "path": s.getBaseFolder("logs"),
                "as_attachment": True,
                "access_validation": access_validation_factory(admin_validator)
            }),
            (r"/downloads/camera/current", UrlForwardHandler, {
                "url": s.get(["webcam", "snapshot"]),
                "as_attachment": True,
                "access_validation": access_validation_factory(user_validator)
            }),
            (r".*", FallbackHandler, {
                "fallback": WSGIContainer(app.wsgi_app)
            })
        ])
        self._server = HTTPServer(self._tornado_app)
        self._server.listen(self._port, address=self._host)

        logger.info("Listening on http://%s:%d" % (self._host, self._port))

        eventManager.fire(events.Events.STARTUP)
        if s.getBoolean(["serial", "autoconnect"]):
            (port, baudrate) = s.get(["serial", "port"
                                      ]), s.getInt(["serial", "baudrate"])
            connectionOptions = printer.getConnectionOptions()
            if port in connectionOptions["ports"]:
                printer.connect(port, baudrate)

        # start up watchdogs
        observer = Observer()
        observer.schedule(UploadCleanupWatchdogHandler(),
                          s.getBaseFolder("uploads"))
        observer.start()

        try:
            IOLoop.instance().start()
        except KeyboardInterrupt:
            logger.info("Goodbye!")
        except:
            logger.fatal(
                "Now that is embarrassing... Something really really went wrong here. Please report this including the stacktrace below in OctoPrint's bugtracker. Thanks!"
            )
            logger.exception("Stacktrace follows:")
        finally:
            observer.stop()
        observer.join()
Esempio n. 3
0
class Server():
    def __init__(self,
                 configfile=None,
                 basedir=None,
                 host="127.0.0.1",
                 port=5000,
                 debug=False,
                 allowRoot=False,
                 logConf=None):
        self._configfile = configfile
        self._basedir = basedir
        self._host = host
        self._port = port
        self._debug = debug
        self._allowRoot = allowRoot
        self._logConf = logConf
        self._ioLoop = None

    def stop(self):
        if self._ioLoop:
            self._ioLoop.stop()
            self._ioLoop = None

    def run(self):
        if not self._allowRoot:
            self._checkForRoot()

        global userManager
        global eventManager
        global loginManager
        global debug
        global softwareManager
        global discoveryManager
        global VERSION
        global UI_API_KEY

        from tornado.wsgi import WSGIContainer
        from tornado.httpserver import HTTPServer
        from tornado.ioloop import IOLoop
        from tornado.web import Application, FallbackHandler

        from astroprint.printfiles.watchdogs import UploadCleanupWatchdogHandler
        from astroprint.printfiles.watchdogs import EtherBoxHandler

        debug = self._debug

        # first initialize the settings singleton and make sure it
        # uses given configfile and basedir if available
        self._initSettings(self._configfile, self._basedir)
        s = settings()

        if not s.getBoolean(['api', 'regenerate']) and s.getString(
            ['api', 'key']):
            UI_API_KEY = s.getString(['api', 'key'])
        else:
            UI_API_KEY = ''.join('%02X' % ord(z) for z in uuid.uuid4().bytes)

        # then initialize logging
        self._initLogging(self._debug, self._logConf)
        logger = logging.getLogger(__name__)

        if s.getBoolean(["accessControl", "enabled"]):
            userManagerName = s.get(["accessControl", "userManager"])
            try:
                clazz = util.getClass(userManagerName)
                userManager = clazz()
            except AttributeError, e:
                logger.exception(
                    "Could not instantiate user manager %s, will run "
                    "with accessControl disabled!" % userManagerName)

        softwareManager = swManager()
        VERSION = softwareManager.versionString

        logger.info("Starting AstroBox (%s) - Commit (%s)" %
                    (VERSION, softwareManager.commit))

        from astroprint.migration import migrateSettings
        migrateSettings()

        eventManager = events.eventManager()
        printer = printerManager(printerProfileManager().data['driver'])

        # Start some of the managers here to make sure there are
        # no thread collisions
        from astroprint.network.manager import networkManager
        from astroprint.boxrouter import boxrouterManager

        networkManager()
        machine_id = s.get(["setup", "machineId"])
        access_key = s.get(["setup", "accessCode"])
        _set_boxid = False
        if machine_id and access_key:
            api = s.get(["cloudSlicer", "apiHost"])
            _data = {
                'boxid': machine_id,
                'access_key': access_key,
            }
            try:
                logger.info("Trying to set printer id")
                logger.info(_data)
                headers = {'Content-type': 'application/json'}
                res = requests.post(
                    "%s/api/printerauth/" % api,
                    json=_data,
                    headers=headers,
                    timeout=10,
                    allow_redirects=False,
                )
                if res.status_code == 200:
                    logger.info("Printer's id is: %s", machine_id)
                    boxrouterManager()
                    boxrouterManager().boxId = machine_id

                    _set_boxid = True
                    logger.info("Done setting printer id")
                else:
                    logger.info("Could not authenticate the printer")
                    logger.info("Response status code: %s", res.status_code)
            except Exception as e:
                logger.error(
                    "Error setting up boxrouter, boxid could not be set")
                logger.error(e)

        app.wsgi_app = ReverseProxied(app.wsgi_app)

        app.secret_key = os.urandom(4096)
        loginManager = LoginManager()
        loginManager.session_protection = "strong"
        loginManager.user_callback = load_user
        if userManager is None:
            loginManager.anonymous_user = users.DummyUser
            principals.identity_loaders.appendleft(users.dummy_identity_loader)
        loginManager.init_app(app)

        # setup command triggers
        events.CommandTrigger(printer)
        if self._debug:
            events.DebugEventListener()

        if networkManager().isOnline() and _set_boxid:
            softwareManager.checkForcedUpdate()

        if self._host is None:
            self._host = s.get(["server", "host"])
        if self._port is None:
            self._port = s.getInt(["server", "port"])

        app.debug = self._debug

        from octoprint.server.api import api

        app.register_blueprint(api, url_prefix="/api")

        # Makes sure the singleton is created here. It doesn't need to be stored
        boxrouterManager(connect=False)
        self._router = SockJSRouter(self._createSocketConnection, "/sockjs")

        discoveryManager = DiscoveryManager()

        def access_validation_factory(validator):
            """
            Creates an access validation wrapper using the supplied validator.

            :param validator: the access validator to use inside the validation
            wrapper
            :return: an access validation wrapper taking a request as parameter
            and performing the request validation
            """
            def f(request):
                """
                Creates a custom wsgi and Flask request context in order to be
                able to process user information stored in the current session.

                :param request: The Tornado request for which to create
                the environment and context
                """
                wsgi_environ = tornado.wsgi.WSGIContainer.environ(request)
                with app.request_context(wsgi_environ):
                    app.session_interface.open_session(app, request)
                    loginManager.reload_user()
                    validator(request)

            return f

        self._tornado_app = Application(self._router.urls + [
            #(r"/downloads/timelapse/([^/]*\.mpg)",
            #   LargeResponseHandler,
            #   {"path": s.getBaseFolder("timelapse"),
            #   "as_attachment": True}),
            (r"/downloads/files/local/([^/]*\.(gco|gcode))",
             LargeResponseHandler, {
                 "path": s.getBaseFolder("uploads"),
                 "as_attachment": True
             }),
            (r"/downloads/logs/([^/]*)", LargeResponseHandler, {
                "path": s.getBaseFolder("logs"),
                "as_attachment": True,
                "access_validation": access_validation_factory(admin_validator)
            }),
            #(r"/downloads/camera/current",
            #   UrlForwardHandler,
            #   {"url": s.get(["webcam", "snapshot"]),
            #   "as_attachment": True,
            #   "access_validation": access_validation_factory(user_validator)}),
            (r".*", FallbackHandler, {
                "fallback": WSGIContainer(app.wsgi_app)
            })
        ])
        self._server = HTTPServer(self._tornado_app,
                                  max_buffer_size=1048576 *
                                  s.getInt(['server', 'maxUploadSize']))
        self._server.listen(self._port, address=self._host)

        logger.info("Listening on http://%s:%d" % (self._host, self._port))

        eventManager.fire(events.Events.STARTUP)
        if s.getBoolean(["serial", "autoconnect"]):
            (port, baudrate) = s.get(["serial", "port"
                                      ]), s.getInt(["serial", "baudrate"])
            connectionOptions = printer.getConnectionOptions()
            if port in connectionOptions["ports"]:
                printer.connect(port, baudrate)

        usbdetector = EtherBoxHandler()
        # start up watchdogs
        observer = Observer()
        observer.schedule(UploadCleanupWatchdogHandler(),
                          s.getBaseFolder("uploads"))
        #observer.schedule(
        #    usbdetector, s.get(['usb', 'folder']), recursive=True)
        observer.start()

        try:
            self._ioLoop = IOLoop.instance()
            self._ioLoop.start()

        except SystemExit:
            pass

        except:
            logger.fatal("Please report this including the stacktrace below "
                         "in AstroPrint's bugtracker. Thanks!")
            logger.exception("Stacktrace follows:")

        finally:
            observer.stop()
            self.cleanup()

        observer.join()
        logger.info('Good Bye!')