예제 #1
0
class App(object):

    MAIN_LOOP_SLEEP = 2
    LOG_FLUSH_TIME = 30

    @log.log_exception
    def __init__(self):
        self.set_reboot_flag(False)
        self.logger = log.create_logger("app", log.LOG_FILE)
        self.logger.info("Starting 3DPrinterOS client. Version %s_%s" % (version.version, version.build))
        self.logger.info('Operating system: ' + platform.system() + ' ' + platform.release())
        self.time_stamp()
        signal.signal(signal.SIGINT, self.intercept_signal)
        signal.signal(signal.SIGTERM, self.intercept_signal)
        self.detected_printers = []
        self.printer_interfaces = []
        self.stop_flag = False
        self.updater = updater.Updater()
        self.rights_checker_and_waiter = rights.RightsCheckerAndWaiter(self)
        self.conveyor_kill_waiter = makerware_utils.ConveyorKillWaiter(self)
        self.user_login = user_login.UserLogin(self)
        self.init_interface()
        self.rights_checker_and_waiter.wait()
        self.conveyor_kill_waiter.wait()
        if self.user_login.wait_for_login():
            config.Config.instance().set_profiles(self.user_login.profiles)
            if config.get_settings()["camera"]["enabled"]:
                self.camera_controller = camera_controller.CameraController()
            self.cloud_sync_controller = cloud_sync_controller.CloudSyncController()

    def init_interface(self):
        if config.get_settings()['web_interface']['enabled']:
            import webbrowser
            from web_interface import WebInterface
            self.web_interface = WebInterface(self)
            self.web_interface.start()
            self.logger.debug("Waiting for webserver to start...")
            while not self.web_interface.server:
                time.sleep(0.01)
                if self.stop_flag:
                    return
            self.logger.debug("...server is up and running. Connecting browser...")
            time.sleep(3)
            if config.get_settings()['web_interface']['browser_opening_on_start']:
                webbrowser.open("http://127.0.0.1:8008", 2, True)
            self.logger.debug("...done")

    @log.log_exception
    def start_main_loop(self):
        self.last_flush_time = 0
        self.detector = usb_detect.USBDetector()
        self.http_client = http_client.HTTPClient()
        while not self.stop_flag:
            self.updater.timer_check_for_updates()
            self.time_stamp()
            self.detected_printers = self.detector.get_printers_list()
            self.check_and_connect()
            for pi in self.printer_interfaces:
                if pi.usb_info not in self.detected_printers:
                    self.disconnect_printer(pi, 'not_detected')
                elif not pi.is_alive():
                    self.disconnect_printer(pi, 'error')
            if not self.stop_flag:
                time.sleep(self.MAIN_LOOP_SLEEP)
            now = time.time()
            if now - self.last_flush_time > self.LOG_FLUSH_TIME:
                self.last_flush_time = now
                self.flush_log()
        self.quit()

    def set_reboot_flag(self, value):
        global reboot_flag
        reboot_flag = value

    def flush_log(self):
        self.logger.info('Flushing logger handlers')
        for handler in self.logger.handlers:
            handler.flush()

    def time_stamp(self):
        self.logger.debug("Time stamp: " + time.strftime("%d %b %Y %H:%M:%S", time.localtime()))

    def check_and_connect(self):
        currently_connected_usb_info = [pi.usb_info for pi in self.printer_interfaces]
        for usb_info in self.detected_printers:
            if usb_info not in currently_connected_usb_info:
                pi = printer_interface.PrinterInterface(usb_info, self.user_login.user_token)
                pi.start()
                self.printer_interfaces.append(pi)

    def disconnect_printer(self, pi, reason):
        self.logger.info('Disconnecting because of %s %s' % (reason , str(pi.usb_info)))
        pi.report_error()
        pi.close()
        self.printer_interfaces.remove(pi)
        self.logger.info("Successful disconnection of " + str(pi.usb_info))

    def intercept_signal(self, signal_code, frame):
        self.logger.warning("SIGINT or SIGTERM received. Closing 3DPrinterOS Client version %s_%s" % \
                (version.version, version.build))
        self.stop_flag = True

    def quit(self):
        self.logger.info("Starting exit sequence...")
        if hasattr(self, 'cloud_sync_controller'):
            self.cloud_sync_controller.stop_cloud_sync_process()
        if hasattr(self, 'camera_controller'):
            self.camera_controller.stop_camera_process()
        for pi in self.printer_interfaces:
            pi.close()
        time.sleep(0.2) #to reduce logging spam in next
        self.time_stamp()
        self.logger.info("Waiting for gcode sending modules to close...")
        while True:
            ready_flag = True
            for pi in self.printer_interfaces:
                if pi.isAlive():
                    pi.close()
                    ready_flag = False
                    self.logger.debug("Waiting for %s" % str(pi.usb_info))
                else:
                    self.printer_interfaces.remove(pi)
                    self.logger.info("Printer on %s was closed." % str(pi.usb_info))
            if ready_flag:
                break
            time.sleep(0.1)
        self.logger.info("...all gcode sending modules closed.")
        self.shutdown_web_interface()
        self.logger.info("...all modules were closed correctly.")
        self.time_stamp()
        self.logger.info("Goodbye ;-)")
        self.shutdown_logging()

    #logging is a most awful module in python, it's an one way to prevent multiply of handlers on reboot
    def shutdown_logging(self):
        handlers = []
        for handler in self.logger.handlers:
            handlers.append(handler)
            handler.flush()
        self.logger.handlers = []
        #logging.shutdown()
        #del (self.logger)
        for handler in handlers:
            del(handler)

    def shutdown_web_interface(self):
        self.logger.debug("Waiting web interface server to shutdown")        
        try:
            self.web_interface.server.shutdown()
            self.web_interface.join()
        except:
            pass
        time.sleep(0.1)
        if hasattr(self, 'web_interface'):
            del(self.web_interface)
예제 #2
0
class App(object):

    MAIN_LOOP_SLEEP = 2
    LOG_FLUSH_TIME = 30
    PRINTER_INTERFACES_CLOSING_TIMEOUT = 15

    @log.log_exception
    def __init__(self):
        config.Config.instance().set_app_pointer(self)
        self.logger = log.create_logger("app", log.LOG_FILE)
        self.logger.info("Starting 3DPrinterOS client. Version %s_%s" %
                         (version.version, version.build))
        self.logger.info('Operating system: ' + platform.system() + ' ' +
                         platform.release())
        self.time_stamp()
        signal.signal(signal.SIGINT, self.intercept_signal)
        signal.signal(signal.SIGTERM, self.intercept_signal)
        self.detected_printers = []
        self.printer_interfaces = []
        self.virtual_printer_enabled = False
        self.stop_flag = False
        self.rights_checker_waiter = rights.RightsCheckerWaiter(self)
        self.conveyor_kill_waiter = makerware_utils.ConveyorKillWaiter(self)
        self.network_connection_checker = http_client.NetworkConnectionChecker(
            self)
        self.init_interface()
        self.rights_checker_waiter.wait()
        self.conveyor_kill_waiter.wait()
        self.network_connection_checker.wait()
        self.updater = updater.Updater()
        self.user_login = user_login.UserLogin(self)
        self.user_login.wait()
        if self.user_login.user_token and hasattr(self.user_login, "profiles"):
            config.Config.instance().set_profiles(self.user_login.profiles)
            self.virtual_printer_enabled = False
            self.camera_controller = camera_controller.CameraController(
                self.user_login.user_token)
            self.cloud_sync_controller = cloud_sync_controller.CloudSyncController(
            )
        else:
            self.logger.error(
                "Can't retrieve user login or printer profiles. Exiting...")
            self.quit()

    def init_interface(self):
        if config.get_settings()['web_interface']['enabled']:
            import webbrowser
            from web_interface import WebInterface
            self.web_interface = WebInterface(self)
            self.web_interface.start()
            self.logger.debug("Waiting for webserver to start...")
            while not self.web_interface.server:
                time.sleep(0.01)
                if self.stop_flag:
                    return
            self.logger.debug(
                "...server is up and running. Connecting browser...")
            time.sleep(3)
            if config.get_settings(
            )['web_interface']['browser_opening_on_start']:
                webbrowser.open("http://" + self.web_interface.SERVER_IP \
                                + ':' + str(self.web_interface.SERVER_PORT), 2, True)
            self.logger.debug("...done")

    def intercept_signal(self, signal_code, frame):
        self.logger.warning("SIGINT or SIGTERM received. Closing 3DPrinterOS Client version %s_%s" % \
                (version.version, version.build))
        self.stop_flag = True

    @log.log_exception
    def start_main_loop(self):
        self.last_flush_time = 0
        self.detector = usb_detect.USBDetector()
        self.http_client = http_client.HTTPClient()
        while not self.stop_flag:
            self.updater.timer_check_for_updates()
            self.time_stamp()
            self.detected_printers = self.detector.get_printers_list()
            if self.virtual_printer_enabled:
                self.detected_printers.append({
                    "VID": "ZZZZ",
                    "PID": "ZZZZ",
                    "SNR": "0",
                    "COM": None
                })
            self.connect_new_printers()
            for pi in self.printer_interfaces:
                if pi.usb_info not in self.detected_printers:
                    if not pi.error_state == "error":
                        config.create_error_report(
                            99,
                            "Printer is no longer detected as USB device.",
                            pi.usb_info,
                            self.logger,
                            is_blocking=True)
                if not pi.is_alive():
                    if not pi.stop_flag:
                        self.logger.warning(
                            "Printer interface of %s had crushed" %
                            pi.usb_info)
                    self.logger.info('Removing %s from printer list' %
                                     pi.usb_info)
                    self.printer_interfaces.remove(pi)
            if not self.stop_flag:
                time.sleep(self.MAIN_LOOP_SLEEP)
            now = time.time()
            if now - self.last_flush_time > self.LOG_FLUSH_TIME:
                self.last_flush_time = now
                self.flush_log()
        self.quit()

    def connect_new_printers(self):
        currently_connected_usb_info = [
            pi.usb_info for pi in self.printer_interfaces
        ]
        for usb_info in self.detected_printers:
            if usb_info not in currently_connected_usb_info:
                pi = printer_interface.PrinterInterface(
                    usb_info, self.user_login)
                pi.start()
                self.printer_interfaces.append(pi)

    def flush_log(self):
        self.logger.info('Flushing logger handlers')
        for handler in self.logger.handlers:
            handler.flush()

    def time_stamp(self):
        self.logger.debug("Time stamp: " +
                          time.strftime("%d %b %Y %H:%M:%S", time.localtime()))

    def shutdown_web_interface(self):
        self.logger.debug("Waiting web interface server to shutdown...")
        self.time_stamp()
        try:
            self.web_interface.server.shutdown()
            self.web_interface.join()
        except:
            pass
        self.time_stamp()
        self.logger.debug("...done")

    def quit(self):
        self.logger.info("Starting exit sequence...")
        if hasattr(self, 'camera_controller'):
            self.camera_controller.stop_camera_process()
        if hasattr(self, 'cloud_sync_controller'):
            self.cloud_sync_controller.stop_cloud_sync_process()
        for pi in self.printer_interfaces:
            pi.close()
        for pi in self.printer_interfaces:
            pi.join(self.PRINTER_INTERFACES_CLOSING_TIMEOUT)
        time.sleep(0.2)  #to reduce logging spam in next
        self.shutdown_web_interface()
        self.logger.info("...everything is correctly closed.")
        self.logger.info("Goodbye ;-)")
        for handler in self.logger.handlers:
            handler.flush()
예제 #3
0
class App(object):

    MAIN_LOOP_SLEEP = 2
    LOG_FLUSH_TIME = 30

    @log.log_exception
    def __init__(self):
        self.set_reboot_flag(False)
        self.logger = log.create_logger("app", log.LOG_FILE)
        self.logger.info("Starting 3DPrinterOS client. Version %s_%s" %
                         (version.version, version.build))
        self.logger.info('Operating system: ' + platform.system() + ' ' +
                         platform.release())
        self.time_stamp()
        signal.signal(signal.SIGINT, self.intercept_signal)
        signal.signal(signal.SIGTERM, self.intercept_signal)
        self.detected_printers = []
        self.printer_interfaces = []
        self.stop_flag = False
        self.updater = updater.Updater()
        self.rights_checker_and_waiter = rights.RightsCheckerAndWaiter(self)
        self.user_login = user_login.UserLogin(self)
        self.init_interface()
        self.rights_checker_and_waiter.wait()
        if self.user_login.wait_for_login():
            config.Config.instance().set_profiles(self.user_login.profiles)
            if config.get_settings()["camera"]["enabled"]:
                self.camera_controller = camera_controller.CameraController()
            self.cloud_sync_controller = cloud_sync_controller.CloudSyncController(
            )

    def init_interface(self):
        if config.get_settings()['web_interface']['enabled']:
            import webbrowser
            from web_interface import WebInterface
            self.web_interface = WebInterface(self)
            self.web_interface.start()
            self.logger.debug("Waiting for webserver to start...")
            while not self.web_interface.server:
                time.sleep(0.01)
                if self.stop_flag:
                    return
            self.logger.debug(
                "...server is up and running. Connecting browser...")
            time.sleep(3)
            if config.get_settings(
            )['web_interface']['browser_opening_on_start']:
                webbrowser.open("http://127.0.0.1:8008", 2, True)
            self.logger.debug("...done")

    @log.log_exception
    def start_main_loop(self):
        self.last_flush_time = 0
        self.detector = usb_detect.USBDetector()
        self.http_client = http_client.HTTPClient()
        while not self.stop_flag:
            self.updater.timer_check_for_updates()
            self.time_stamp()
            self.detected_printers = self.detector.get_printers_list()
            self.check_and_connect()
            for pi in self.printer_interfaces:
                if pi.usb_info not in self.detected_printers:
                    self.disconnect_printer(pi, 'not_detected')
                elif not pi.is_alive():
                    self.disconnect_printer(pi, 'error')
            if not self.stop_flag:
                time.sleep(self.MAIN_LOOP_SLEEP)
            now = time.time()
            if now - self.last_flush_time > self.LOG_FLUSH_TIME:
                self.last_flush_time = now
                self.flush_log()
        self.quit()

    def set_reboot_flag(self, value):
        global reboot_flag
        reboot_flag = value

    def flush_log(self):
        self.logger.info('Flushing logger handlers')
        for handler in self.logger.handlers:
            handler.flush()

    def time_stamp(self):
        self.logger.debug("Time stamp: " +
                          time.strftime("%d %b %Y %H:%M:%S", time.localtime()))

    def check_and_connect(self):
        currently_connected_usb_info = [
            pi.usb_info for pi in self.printer_interfaces
        ]
        for usb_info in self.detected_printers:
            if usb_info not in currently_connected_usb_info:
                pi = printer_interface.PrinterInterface(
                    usb_info, self.user_login.user_token)
                pi.start()
                self.printer_interfaces.append(pi)

    def disconnect_printer(self, pi, reason):
        self.logger.info('Disconnecting because of %s %s' %
                         (reason, str(pi.usb_info)))
        pi.report_error()
        pi.close()
        self.printer_interfaces.remove(pi)
        self.logger.info("Successful disconnection of " + str(pi.usb_info))

    def intercept_signal(self, signal_code, frame):
        self.logger.warning("SIGINT or SIGTERM received. Closing 3DPrinterOS Client version %s_%s" % \
                (version.version, version.build))
        self.stop_flag = True

    def quit(self):
        self.logger.info("Starting exit sequence...")
        if hasattr(self, 'cloud_sync_controller'):
            self.cloud_sync_controller.stop_cloud_sync_process()
        if hasattr(self, 'camera_controller'):
            self.camera_controller.stop_camera_process()
        for pi in self.printer_interfaces:
            pi.close()
        time.sleep(0.2)  #to reduce logging spam in next
        self.time_stamp()
        self.logger.info("Waiting for gcode sending modules to close...")
        while True:
            ready_flag = True
            for pi in self.printer_interfaces:
                if pi.isAlive():
                    pi.close()
                    ready_flag = False
                    self.logger.debug("Waiting for %s" % str(pi.usb_info))
                else:
                    self.printer_interfaces.remove(pi)
                    self.logger.info("Printer on %s was closed." %
                                     str(pi.usb_info))
            if ready_flag:
                break
            time.sleep(0.1)
        self.logger.info("...all gcode sending modules closed.")
        self.shutdown_web_interface()
        self.logger.info("...all modules were closed correctly.")
        self.time_stamp()
        self.logger.info("Goodbye ;-)")
        self.shutdown_logging()

    #logging is a most awful module in python, it's an one way to prevent multiply of handlers on reboot
    def shutdown_logging(self):
        handlers = []
        for handler in self.logger.handlers:
            handlers.append(handler)
            handler.flush()
        self.logger.handlers = []
        #logging.shutdown()
        #del (self.logger)
        for handler in handlers:
            del (handler)

    def shutdown_web_interface(self):
        self.logger.debug("Waiting web interface server to shutdown")
        try:
            self.web_interface.server.shutdown()
            self.web_interface.join()
        except:
            pass
        time.sleep(0.1)
        if hasattr(self, 'web_interface'):
            del (self.web_interface)
예제 #4
0
class App(object):

    MAIN_LOOP_SLEEP = 1
    IDLE_RECORD_TIMEOUT = 120
    VIRTUAL_PRINTER_USB_INFO = {
        "VID": "ZZZZ",
        "PID": "ZZZZ",
        "SNR": "0",
        "COM": None
    }

    @log.log_exception
    def __init__(self):
        config.Config.instance().set_app_pointer(self)
        self.logger = log.create_logger('', log.LOG_FILE)
        self.logger.info("Starting 3DPrinterOS client. Version %s_%s" %
                         (version.version, version.build))
        self.logger.info('Operating system: ' + platform.system() + ' ' +
                         platform.release())
        signal.signal(signal.SIGINT, self.intercept_signal)
        signal.signal(signal.SIGTERM, self.intercept_signal)
        self.detected_printers = []
        self.network_printers = []
        self.printer_interfaces = []
        self.virtual_printer_enabled = False
        self.network_detect_flag = False
        self.stop_flag = False
        self.closing_status = []
        self.rights_checker_waiter = rights.RightsCheckerWaiter(self)
        self.conveyor_kill_waiter = makerware_utils.ConveyorKillWaiter(self)
        self.network_connection_checker = http_client.NetworkConnectionChecker(
            self)
        self.init_interface()
        self.rights_checker_waiter.wait()
        self.conveyor_kill_waiter.wait()
        self.network_connection_checker.wait()
        self.updater = updater.Updater()
        self.user_login = user_login.UserLogin(self)
        self.user_login.wait()
        if self.user_login.user_token and hasattr(self.user_login, "profiles"):
            config.Config.instance().set_profiles(self.user_login.profiles)
            self.virtual_printer_enabled = config.get_settings(
            )['virtual_printer']['enabled']
            self.tray_controller = tray_controller.TrayController()
            self.camera_controller = camera_controller.CameraController(self.user_login.user_token,\
                                                                        self.user_login.http_client.mac)
            self.cloud_sync_controller = cloud_sync_controller.CloudSyncController(
            )
        else:
            self.logger.error(
                "Can't retrieve user login or printer profiles. Exiting...")
            self.quit()

    def init_interface(self):
        if config.get_settings()['web_interface']['enabled']:
            import webbrowser
            from web_interface import WebInterface
            self.web_interface = WebInterface(self)
            self.web_interface.start()
            self.logger.debug("Waiting for webserver to start...")
            while not self.web_interface.server:
                time.sleep(0.01)
                if self.stop_flag:
                    return
            self.logger.debug(
                "...server is up and running. Connecting browser...")
            if config.get_settings(
            )['web_interface']['browser_opening_on_start']:
                webbrowser.open("http://" + config.SERVER_IP \
                                + ':' + str(config.SERVER_PORT), 2, True)
            self.logger.debug("...done")

    def intercept_signal(self, signal_code, frame):
        self.logger.warning("SIGINT or SIGTERM received. Closing 3DPrinterOS Client version %s_%s" % \
                (version.version, version.build))
        self.stop_flag = True

    def get_all_network_profiles(
            self):  #TODO move all network code to network detector
        self.logger.info("Getting all network printers profiles")
        while not hasattr(self, "user_login"):
            time.sleep(0.1)
        while not getattr(self.user_login, "profiles"):
            time.sleep(0.1)
        return filter(lambda x: x.get('network_detect'),
                      self.user_login.profiles)

    def connect_to_network_printer(self, printer_ip, printer_type):
        for profile in self.get_all_network_profiles():
            if printer_type in profile.get("name"):
                printer = {
                    'IP': printer_ip,
                    'SNR': "",
                    'VID': profile["vids_pids"][0][0],
                    'PID': profile["vids_pids"][0][1]
                }
                # {'IP': u'192.168.10.45', 'SNR': u'23C100043C705900B013', 'port': 55493, 'VID': '23C1', 'PID': '0004'}
                self.network_printers = [printer]
                return True
        return

    def toggle_virtual_printer(self):
        self.virtual_printer_enabled = not self.virtual_printer_enabled
        if not self.virtual_printer_enabled:
            for printer_interface in self.printer_interfaces:
                usb_info = getattr(printer_interface, 'usb_info', None)
                if usb_info and usb_info == self.VIRTUAL_PRINTER_USB_INFO:
                    printer_interface.close()
        settings = config.get_settings()
        settings['virtual_printer']['enabled'] = self.virtual_printer_enabled
        config.Config.instance().save_settings(settings)

    @log.log_exception
    def start_main_loop(
        self
    ):  #TODO cleanup from network and virtual code. main loop code should be short.
        self.detector = usb_detect.USBDetector()
        self.network_printers_detector = network_detect.NetworkDetector()
        self.last_time = 0
        while not self.stop_flag:
            self.updater.timer_check_for_updates()
            try:
                self.detected_printers = self.detector.get_printers_list()
            except Exception:
                self.logger.exception("USB detector error: ")
            else:
                if self.network_detect_flag:
                    self.network_printers = self.network_printers_detector.get_printers(
                    )
                    self.network_detect_flag = False
                for printer in self.network_printers:
                    if printer not in self.detected_printers:
                        self.detected_printers.append(printer)
                if self.virtual_printer_enabled:
                    self.detected_printers.append(
                        self.VIRTUAL_PRINTER_USB_INFO)
                self.connect_new_printers()
                for pi in self.printer_interfaces:
                    if pi.usb_info not in self.detected_printers:
                        if not pi.error_state == "error":
                            config.create_error_report(
                                99,
                                "Printer is no longer detected as USB device.",
                                pi.usb_info,
                                self.logger,
                                is_blocking=True)
                    if not pi.is_alive():
                        if not pi.stop_flag:
                            self.logger.warning(
                                "Printer interface of %s had crushed" %
                                pi.usb_info)
                        self.logger.info('Removing %s from printer list' %
                                         pi.usb_info)
                        self.printer_interfaces.remove(pi)
            if not self.stop_flag:
                time.sleep(self.MAIN_LOOP_SLEEP)
            now = time.time()
            if self.last_time + self.IDLE_RECORD_TIMEOUT > now:
                self.last_time = now
                self.logger.debug(
                    time.strftime("%d %b %Y %H:%M:%S", time.localtime()))
        self.quit()

    def connect_new_printers(self):
        currently_connected_usb_info = [
            pi.usb_info for pi in self.printer_interfaces
        ]
        for usb_info in self.detected_printers:
            if usb_info not in currently_connected_usb_info:
                pi = printer_interface.PrinterInterface(
                    usb_info, self.user_login)
                pi.start()
                self.printer_interfaces.append(pi)

    def shutdown_web_interface(self):
        self.logger.debug("Waiting web interface server to shutdown...")
        try:
            self.web_interface.server.shutdown()
            self.web_interface.join()
        except:
            pass
        self.logger.debug("...done")

    def quit(self):  # TODO reduce copy-paste
        self.logger.info("Starting exit sequence...")
        if hasattr(self, 'tray_controller'):
            state = 'Closing tray...'
            self.logger.info(state)
            self.closing_status.append(state)
            self.tray_controller.stop()
            self.closing_status[-1] += 'closed'
            time.sleep(0.5)
        if hasattr(self, 'camera_controller'):
            state = 'Closing camera...'
            self.logger.info(state)
            self.closing_status.append(state)
            self.camera_controller.stop_camera_process()
            self.closing_status[-1] += 'closed'
            time.sleep(0.5)
        if hasattr(self, 'cloud_sync_controller'):
            state = 'Closing CloudSync...'
            self.logger.info(state)
            self.closing_status.append(state)
            self.cloud_sync_controller.stop_cloud_sync_process()
            self.closing_status[-1] += 'closed'
            time.sleep(0.5)
        for pi in self.printer_interfaces:
            pi.close()
        for pi in self.printer_interfaces:
            printer_name = 'undefined printer'
            if pi.printer_profile and pi.printer_profile.get('name'):
                printer_name = pi.printer_profile['name']
            state = 'Closing ' + printer_name + '...'
            self.logger.info(state)
            self.closing_status.append(state)
            pi.join()
            self.closing_status[-1] += 'closed'
            time.sleep(0.5)
        time.sleep(0.2)  #to reduce logging spam in next
        self.shutdown_web_interface()
        self.logger.info("...everything is correctly closed.")
        self.logger.info("Goodbye ;-)")
        for handler in self.logger.handlers:
            handler.flush()
예제 #5
0
class App(object):

    MAIN_LOOP_SLEEP = 1
    IDLE_RECORD_TIMEOUT = 120
    VIRTUAL_PRINTER_USB_INFO = {"VID" : "ZZZZ", "PID": "ZZZZ", "SNR": "0", "COM": None}

    @log.log_exception
    def __init__(self):
        config.Config.instance().set_app_pointer(self)
        self.logger = log.create_logger('', log.LOG_FILE)
        self.logger.info("Starting 3DPrinterOS client. Version %s_%s" % (version.version, version.build))
        self.logger.info('Operating system: ' + platform.system() + ' ' + platform.release())
        signal.signal(signal.SIGINT, self.intercept_signal)
        signal.signal(signal.SIGTERM, self.intercept_signal)
        self.detected_printers = []
        self.network_printers = []
        self.printer_interfaces = []
        self.virtual_printer_enabled = False
        self.network_detect_flag = False
        self.stop_flag = False
        self.closing_status = []
        self.rights_checker_waiter = rights.RightsCheckerWaiter(self)
        self.conveyor_kill_waiter = makerware_utils.ConveyorKillWaiter(self)
        self.network_connection_checker = http_client.NetworkConnectionChecker(self)
        self.init_interface()
        self.rights_checker_waiter.wait()
        self.conveyor_kill_waiter.wait()
        self.network_connection_checker.wait()
        self.updater = updater.Updater()
        self.user_login = user_login.UserLogin(self)
        self.user_login.wait()
        if self.user_login.user_token and hasattr(self.user_login, "profiles"):
            config.Config.instance().set_profiles(self.user_login.profiles)
            self.virtual_printer_enabled = config.get_settings()['virtual_printer']['enabled']
            self.tray_controller = tray_controller.TrayController()
            self.camera_controller = camera_controller.CameraController(self.user_login.user_token,\
                                                                        self.user_login.http_client.mac)
            self.cloud_sync_controller = cloud_sync_controller.CloudSyncController()
        else:
            self.logger.error("Can't retrieve user login or printer profiles. Exiting...")
            self.quit()

    def init_interface(self):
        if config.get_settings()['web_interface']['enabled']:
            import webbrowser
            from web_interface import WebInterface
            self.web_interface = WebInterface(self)
            self.web_interface.start()
            self.logger.debug("Waiting for webserver to start...")
            while not self.web_interface.server:
                time.sleep(0.01)
                if self.stop_flag:
                    return
            self.logger.debug("...server is up and running. Connecting browser...")
            if config.get_settings()['web_interface']['browser_opening_on_start']:
                webbrowser.open("http://" + config.SERVER_IP \
                                + ':' + str(config.SERVER_PORT), 2, True)
            self.logger.debug("...done")

    def intercept_signal(self, signal_code, frame):
        self.logger.warning("SIGINT or SIGTERM received. Closing 3DPrinterOS Client version %s_%s" % \
                (version.version, version.build))
        self.stop_flag = True

    def get_all_network_profiles(self): #TODO move all network code to network detector
        self.logger.info("Getting all network printers profiles")
        while not hasattr(self, "user_login"):
            time.sleep(0.1)
        while not getattr(self.user_login, "profiles"):
            time.sleep(0.1)
        return filter(lambda x: x.get('network_detect'), self.user_login.profiles)

    def connect_to_network_printer(self, printer_ip, printer_type):
        for profile in self.get_all_network_profiles():
            if printer_type in profile.get("name"):
                printer = {
                    'IP': printer_ip,
                    'SNR': "",
                    'VID': profile["vids_pids"][0][0],
                    'PID': profile["vids_pids"][0][1]
                }
                # {'IP': u'192.168.10.45', 'SNR': u'23C100043C705900B013', 'port': 55493, 'VID': '23C1', 'PID': '0004'}
                self.network_printers = [printer]
                return True
        return

    def toggle_virtual_printer(self):
        self.virtual_printer_enabled = not self.virtual_printer_enabled
        if not self.virtual_printer_enabled:
            for printer_interface in self.printer_interfaces:
                usb_info = getattr(printer_interface, 'usb_info', None)
                if usb_info and usb_info == self.VIRTUAL_PRINTER_USB_INFO:
                    printer_interface.close()
        settings = config.get_settings()
        settings['virtual_printer']['enabled'] = self.virtual_printer_enabled
        config.Config.instance().save_settings(settings)

    @log.log_exception
    def start_main_loop(self): #TODO cleanup from network and virtual code. main loop code should be short.
        self.detector = usb_detect.USBDetector()
        self.network_printers_detector = network_detect.NetworkDetector()
        self.last_time = 0
        while not self.stop_flag:
            self.updater.timer_check_for_updates()
            try:
                self.detected_printers = self.detector.get_printers_list()
            except Exception:
                self.logger.exception("USB detector error: ")
            else:
                if self.network_detect_flag:
                    self.network_printers = self.network_printers_detector.get_printers()
                    self.network_detect_flag = False
                for printer in self.network_printers:
                    if printer not in self.detected_printers:
                        self.detected_printers.append(printer)
                if self.virtual_printer_enabled:
                    self.detected_printers.append(self.VIRTUAL_PRINTER_USB_INFO)
                self.connect_new_printers()
                for pi in self.printer_interfaces:
                    if pi.usb_info not in self.detected_printers:
                        if not pi.error_state == "error":
                            config.create_error_report(99, "Printer is no longer detected as USB device.",
                                                       pi.usb_info, self.logger, is_blocking=True)
                    if not pi.is_alive():
                        if not pi.stop_flag:
                            self.logger.warning("Printer interface of %s had crushed" % pi.usb_info)
                        self.logger.info('Removing %s from printer list' % pi.usb_info)
                        self.printer_interfaces.remove(pi)
            if not self.stop_flag:
                time.sleep(self.MAIN_LOOP_SLEEP)
            now = time.time()
            if self.last_time + self.IDLE_RECORD_TIMEOUT > now:
                self.last_time = now
                self.logger.debug(time.strftime("%d %b %Y %H:%M:%S", time.localtime()))
        self.quit()

    def connect_new_printers(self):
        currently_connected_usb_info = [pi.usb_info for pi in self.printer_interfaces]
        for usb_info in self.detected_printers:
            if usb_info not in currently_connected_usb_info:
                pi = printer_interface.PrinterInterface(usb_info, self.user_login)
                pi.start()
                self.printer_interfaces.append(pi)

    def shutdown_web_interface(self):
        self.logger.debug("Waiting web interface server to shutdown...")
        try:
            self.web_interface.server.shutdown()
            self.web_interface.join()
        except:
            pass
        self.logger.debug("...done")

    def quit(self): # TODO reduce copy-paste
        self.logger.info("Starting exit sequence...")
        if hasattr(self, 'tray_controller'):
            state = 'Closing tray...'
            self.logger.info(state)
            self.closing_status.append(state)
            self.tray_controller.stop()
            self.closing_status[-1] += 'closed'
            time.sleep(0.5)
        if hasattr(self, 'camera_controller'):
            state = 'Closing camera...'
            self.logger.info(state)
            self.closing_status.append(state)
            self.camera_controller.stop_camera_process()
            self.closing_status[-1] += 'closed'
            time.sleep(0.5)
        if hasattr(self, 'cloud_sync_controller'):
            state = 'Closing CloudSync...'
            self.logger.info(state)
            self.closing_status.append(state)
            self.cloud_sync_controller.stop_cloud_sync_process()
            self.closing_status[-1] += 'closed'
            time.sleep(0.5)
        for pi in self.printer_interfaces:
            pi.close()
        for pi in self.printer_interfaces:
            printer_name = 'undefined printer'
            if pi.printer_profile and pi.printer_profile.get('name'):
                printer_name = pi.printer_profile['name']
            state = 'Closing ' + printer_name + '...'
            self.logger.info(state)
            self.closing_status.append(state)
            pi.join()
            self.closing_status[-1] += 'closed'
            time.sleep(0.5)
        time.sleep(0.2) #to reduce logging spam in next
        self.shutdown_web_interface()
        self.logger.info("...everything is correctly closed.")
        self.logger.info("Goodbye ;-)")
        for handler in self.logger.handlers:
            handler.flush()
예제 #6
0
class App(object):

    MAIN_LOOP_SLEEP = 2
    LOG_FLUSH_TIME = 30
    PRINTER_INTERFACES_CLOSING_TIMEOUT = 15

    @log.log_exception
    def __init__(self):
        config.Config.instance().set_app_pointer(self)
        self.logger = log.create_logger("app", log.LOG_FILE)
        self.logger.info("Starting 3DPrinterOS client. Version %s_%s" % (version.version, version.build))
        self.logger.info('Operating system: ' + platform.system() + ' ' + platform.release())
        self.time_stamp()
        signal.signal(signal.SIGINT, self.intercept_signal)
        signal.signal(signal.SIGTERM, self.intercept_signal)
        self.detected_printers = []
        self.printer_interfaces = []
        self.virtual_printer_enabled = False
        self.stop_flag = False
        self.rights_checker_waiter = rights.RightsCheckerWaiter(self)
        self.conveyor_kill_waiter = makerware_utils.ConveyorKillWaiter(self)
        self.network_connection_checker = http_client.NetworkConnectionChecker(self)
        self.init_interface()
        self.rights_checker_waiter.wait()
        self.conveyor_kill_waiter.wait()
        self.network_connection_checker.wait()
        self.updater = updater.Updater()
        self.user_login = user_login.UserLogin(self)
        self.user_login.wait()
        if self.user_login.user_token and hasattr(self.user_login, "profiles"):
            config.Config.instance().set_profiles(self.user_login.profiles)
            self.virtual_printer_enabled = False
            self.camera_controller = camera_controller.CameraController(self.user_login.user_token)
            self.cloud_sync_controller = cloud_sync_controller.CloudSyncController()
        else:
            self.logger.error("Can't retrieve user login or printer profiles. Exiting...")
            self.quit()

    def init_interface(self):
        if config.get_settings()['web_interface']['enabled']:
            import webbrowser
            from web_interface import WebInterface
            self.web_interface = WebInterface(self)
            self.web_interface.start()
            self.logger.debug("Waiting for webserver to start...")
            while not self.web_interface.server:
                time.sleep(0.01)
                if self.stop_flag:
                    return
            self.logger.debug("...server is up and running. Connecting browser...")
            time.sleep(3)
            if config.get_settings()['web_interface']['browser_opening_on_start']:
                webbrowser.open("http://" + self.web_interface.SERVER_IP \
                                + ':' + str(self.web_interface.SERVER_PORT), 2, True)
            self.logger.debug("...done")

    def intercept_signal(self, signal_code, frame):
        self.logger.warning("SIGINT or SIGTERM received. Closing 3DPrinterOS Client version %s_%s" % \
                (version.version, version.build))
        self.stop_flag = True

    @log.log_exception
    def start_main_loop(self):
        self.last_flush_time = 0
        self.detector = usb_detect.USBDetector()
        self.http_client = http_client.HTTPClient()
        while not self.stop_flag:
            self.updater.timer_check_for_updates()
            self.time_stamp()
            self.detected_printers = self.detector.get_printers_list()
            if self.virtual_printer_enabled:
                self.detected_printers.append( {"VID" : "ZZZZ", "PID": "ZZZZ", "SNR": "0", "COM": None} )
            self.connect_new_printers()
            for pi in self.printer_interfaces:
                if pi.usb_info not in self.detected_printers:
                    if not pi.error_state == "error":
                        config.create_error_report(99, "Printer is no longer detected as USB device.", pi.usb_info, self.logger, is_blocking=True)
                if not pi.is_alive():
                    if not pi.stop_flag:
                        self.logger.warning("Printer interface of %s had crushed" % pi.usb_info)
                    self.logger.info('Removing %s from printer list' % pi.usb_info)
                    self.printer_interfaces.remove(pi)
            if not self.stop_flag:
                time.sleep(self.MAIN_LOOP_SLEEP)
            now = time.time()
            if now - self.last_flush_time > self.LOG_FLUSH_TIME:
                self.last_flush_time = now
                self.flush_log()
        self.quit()

    def connect_new_printers(self):
        currently_connected_usb_info = [pi.usb_info for pi in self.printer_interfaces]
        for usb_info in self.detected_printers:
            if usb_info not in currently_connected_usb_info:
                pi = printer_interface.PrinterInterface(usb_info, self.user_login)
                pi.start()
                self.printer_interfaces.append(pi)

    def flush_log(self):
        self.logger.info('Flushing logger handlers')
        for handler in self.logger.handlers:
            handler.flush()

    def time_stamp(self):
        self.logger.debug("Time stamp: " + time.strftime("%d %b %Y %H:%M:%S", time.localtime()))

    def shutdown_web_interface(self):
        self.logger.debug("Waiting web interface server to shutdown...")
        self.time_stamp()
        try:
            self.web_interface.server.shutdown()
            self.web_interface.join()
        except:
            pass
        self.time_stamp()
        self.logger.debug("...done")

    def quit(self):
        self.logger.info("Starting exit sequence...")
        if hasattr(self, 'camera_controller'):
            self.camera_controller.stop_camera_process()
        if hasattr(self, 'cloud_sync_controller'):
            self.cloud_sync_controller.stop_cloud_sync_process()
        for pi in self.printer_interfaces:
            pi.close()
        for pi in self.printer_interfaces:
            pi.join(self.PRINTER_INTERFACES_CLOSING_TIMEOUT)
        time.sleep(0.2) #to reduce logging spam in next
        self.shutdown_web_interface()
        self.logger.info("...everything is correctly closed.")
        self.logger.info("Goodbye ;-)")
        for handler in self.logger.handlers:
            handler.flush()