Example #1
0
        def _before_send(event, hint):
            if "exc_info" not in hint:
                # we only want exceptions
                return None

            handled = True
            logger = event.get("logger", "")
            plugin = event.get("extra", {}).get("plugin", None)
            callback = event.get("extra", {}).get("callback", None)

            for ignore in IGNORED_EXCEPTIONS:
                if isinstance(ignore, tuple):
                    ignored_exc, matcher = ignore
                else:
                    ignored_exc = ignore
                    matcher = lambda *args: True

                exc = hint["exc_info"][1]
                if isinstance(exc, ignored_exc) and matcher(
                    exc, logger, plugin, callback
                ):
                    # exception ignored for logger, plugin and/or callback
                    return None

                elif isinstance(ignore, type):
                    if isinstance(hint["exc_info"][1], ignore):
                        # exception ignored
                        return None

            if event.get("exception") and event["exception"].get("values"):
                handled = not any(
                    map(
                        lambda x: x.get("mechanism")
                        and not x["mechanism"].get("handled", True),
                        event["exception"]["values"],
                    )
                )

            if handled:
                # error is handled, restrict further based on logger
                if logger != "" and not (
                    logger.startswith("octoprint.") or logger.startswith("tornado.")
                ):
                    # we only want errors logged by loggers octoprint.* or tornado.*
                    return None

                if logger.startswith("octoprint.plugins."):
                    plugin_id = logger.split(".")[2]
                    plugin_info = plugin_manager().get_plugin_info(plugin_id)
                    if plugin_info is None or not plugin_info.bundled:
                        # we only want our active bundled plugins
                        return None

                if plugin is not None:
                    plugin_info = plugin_manager().get_plugin_info(plugin)
                    if plugin_info is None or not plugin_info.bundled:
                        # we only want our active bundled plugins
                        return None

            return event
Example #2
0
def getInstalledLanguagePacks():
	translation_folder = settings().getBaseFolder("translations")
	if not os.path.exists(translation_folder):
		return jsonify(language_packs=dict(_core=[]))

	core_packs = []
	plugin_packs = defaultdict(lambda: dict(identifier=None, display=None, languages=[]))
	for folder in os.listdir(translation_folder):
		path = os.path.join(translation_folder, folder)

		if not os.path.isdir(path):
			continue

		def load_meta(path, locale):
			meta = dict()

			meta_path = os.path.join(path, "meta.yaml")
			if os.path.isfile(meta_path):
				import yaml
				try:
					with open(meta_path) as f:
						meta = yaml.safe_load(f)
				except:
					pass
				else:
					import datetime
					if "last_update" in meta and isinstance(meta["last_update"], datetime.datetime):
						meta["last_update"] = (meta["last_update"] - datetime.datetime(1970,1,1)).total_seconds()

			l = Locale.parse(locale)
			meta["locale"] = locale
			meta["locale_display"] = l.display_name
			meta["locale_english"] = l.english_name
			return meta

		if folder == "_plugins":
			for plugin_folder in os.listdir(path):
				plugin_path = os.path.join(path, plugin_folder)
				if not os.path.isdir(plugin_path):
					continue

				if not plugin_folder in plugin_manager().plugins:
					continue

				plugin_info = plugin_manager().plugins[plugin_folder]

				plugin_packs[plugin_folder]["identifier"] = plugin_folder
				plugin_packs[plugin_folder]["display"] = plugin_info.name

				for language_folder in os.listdir(plugin_path):
					plugin_packs[plugin_folder]["languages"].append(load_meta(os.path.join(plugin_path, language_folder), language_folder))
		else:
			core_packs.append(load_meta(os.path.join(translation_folder, folder), folder))

	result = dict(_core=dict(identifier="_core", display="Core", languages=core_packs))
	result.update(plugin_packs)
	return jsonify(language_packs=result)
Example #3
0
def get_plugin_hash():
	from octoprint.plugin import plugin_manager

	plugin_signature = lambda impl: "{}:{}".format(impl._identifier, impl._plugin_version)
	template_plugins = map(plugin_signature, plugin_manager().get_implementations(octoprint.plugin.TemplatePlugin))
	asset_plugins = map(plugin_signature, plugin_manager().get_implementations(octoprint.plugin.AssetPlugin))
	ui_plugins = sorted(set(template_plugins + asset_plugins))

	import hashlib
	plugin_hash = hashlib.sha1()
	plugin_hash.update(",".join(ui_plugins))
	return plugin_hash.hexdigest()
Example #4
0
def get_plugin_hash():
	from octoprint.plugin import plugin_manager

	plugin_signature = lambda impl: "{}:{}".format(impl._identifier, impl._plugin_version)
	template_plugins = map(plugin_signature, plugin_manager().get_implementations(octoprint.plugin.TemplatePlugin))
	asset_plugins = map(plugin_signature, plugin_manager().get_implementations(octoprint.plugin.AssetPlugin))
	ui_plugins = sorted(set(template_plugins + asset_plugins))

	import hashlib
	plugin_hash = hashlib.sha1()
	plugin_hash.update(",".join(ui_plugins))
	return plugin_hash.hexdigest()
Example #5
0
		def _before_send(event, hint):
			if not "exc_info" in hint:
				# we only want exceptions
				return None

			handled = True
			logger = event.get("logger", "")
			plugin = event.get("extra", dict()).get("plugin", None)

			for ignore in IGNORED_EXCEPTIONS:
				if isinstance(ignore, tuple):
					ignored_exc, matcher = ignore
				else:
					ignored_exc = ignore
					matcher = lambda *args: True

				exc = hint["exc_info"][1]
				if isinstance(exc, ignored_exc) and matcher(exc, logger, plugin):
					# exception ignored for logger
					return None

				elif isinstance(ignore, type):
					if isinstance(hint["exc_info"][1], ignore):
						# exception ignored
						return None

			if event.get("exception") and event["exception"].get("values"):
				handled = not any(map(lambda x: x.get("mechanism") and x["mechanism"].get("handled", True) == False,
				                      event["exception"]["values"]))

			if handled:
				# error is handled, restrict further based on logger
				if logger != "" and not (logger.startswith("octoprint.") or logger.startswith("tornado.")):
					# we only want errors logged by loggers octoprint.* or tornado.*
					return None

				if logger.startswith("octoprint.plugins."):
					plugin_id = logger.split(".")[2]
					plugin_info = plugin_manager().get_plugin_info(plugin_id)
					if plugin_info is None or not plugin_info.bundled:
						# we only want our active bundled plugins
						return None

				if plugin is not None:
					plugin_info = plugin_manager().get_plugin_info(plugin)
					if plugin_info is None or not plugin_info.bundled:
						# we only want our active bundled plugins
						return None

			return event
Example #6
0
def get_user_for_apikey(apikey):
    if settings().getBoolean(["api", "enabled"]) and apikey is not None:
        if apikey == octoprint.server.UI_API_KEY:
            import flask_login
            if octoprint.server.userManager.enabled:
                return octoprint.server.userManager.find_user(
                    session=flask_login.current_user.session)
            else:
                return flask_login.current_user
        elif apikey == settings().get([
                "api", "key"
        ]) or octoprint.server.appSessionManager.validate(apikey):
            # master key or an app session key was used
            return ApiUser([octoprint.server.groupManager.admin_group])
        if octoprint.server.userManager.enabled:
            user = octoprint.server.userManager.find_user(apikey=apikey)
            if user is not None:
                # user key was used
                return user

        apikey_hooks = plugin_manager().get_hooks(
            "octoprint.accesscontrol.keyvalidator")
        for name, hook in apikey_hooks.items():
            try:
                user = hook(apikey)
                if user is not None:
                    return user
            except Exception:
                logging.getLogger(__name__).exception(
                    "Error running api key validator for plugin {} and key {}".
                    format(name, apikey))
    return None
Example #7
0
    def __init__(self,
                 analysis_queue,
                 slicing_manager,
                 printer_profile_manager,
                 initial_storage_managers=None):
        self._logger = logging.getLogger(__name__)
        self._analysis_queue = analysis_queue
        self._analysis_queue.register_finish_callback(
            self._on_analysis_finished)

        self._storage_managers = dict()
        if initial_storage_managers:
            self._storage_managers.update(initial_storage_managers)

        self._slicing_manager = slicing_manager
        self._printer_profile_manager = printer_profile_manager

        import threading
        self._slicing_jobs = dict()
        self._slicing_jobs_mutex = threading.Lock()

        self._slicing_progress_callbacks = []
        self._last_slicing_progress = None

        self._progress_plugins = plugin_manager().get_implementations(
            ProgressPlugin)

        for storage_type, storage_manager in self._storage_managers.items():
            self._determine_analysis_backlog(storage_type, storage_manager)
Example #8
0
def _get_plugin_command_specs(plugin=None):
    specs = collections.OrderedDict()

    hooks = plugin_manager().get_hooks("octoprint.system.additional_commands")
    if plugin is not None:
        if plugin in hooks:
            hooks = {plugin: hooks[plugin]}
        else:
            hooks = {}

    for name, hook in hooks.items():
        try:
            plugin_specs = hook()
            for spec in plugin_specs:
                action = spec.get("action")
                if (not action or action == "divider"
                        or not _plugin_action_regex.match(action)):
                    continue
                action = name.lower() + ":" + action

                copied = dict(spec)
                copied["source"] = "plugin"
                copied["action"] = action
                specs[action] = copied
        except Exception:
            logging.getLogger(__name__).exception(
                "Error while fetching additional actions from plugin {}".
                format(name),
                extra={"plugin": name},
            )
    return specs
Example #9
0
def get_user_for_apikey(apikey):
    if apikey is not None:
        if apikey == settings().get(["api", "key"]):
            # master key was used
            return octoprint.server.userManager.api_user_factory()

        user = octoprint.server.userManager.find_user(apikey=apikey)
        if user is not None:
            # user key was used
            return user

        apikey_hooks = plugin_manager().get_hooks(
            "octoprint.accesscontrol.keyvalidator")
        for name, hook in apikey_hooks.items():
            try:
                user = hook(apikey)
                if user is not None:
                    return user
            except Exception:
                logging.getLogger(__name__).exception(
                    "Error running api key validator "
                    "for plugin {} and key {}".format(name, apikey),
                    extra={"plugin": name},
                )
    return None
Example #10
0
def get_user_for_apikey(apikey):
    if apikey is not None:
        if apikey == settings().get([
                "api", "key"
        ]) or octoprint.server.appSessionManager.validate(apikey):
            # master key or an app session key was used
            return ApiUser()

        if octoprint.server.userManager.enabled:
            user = octoprint.server.userManager.findUser(apikey=apikey)
            if user is not None:
                # user key was used
                return user

        apikey_hooks = plugin_manager().get_hooks(
            "octoprint.accesscontrol.keyvalidator")
        for name, hook in apikey_hooks.items():
            try:
                user = hook(apikey)
                if user is not None:
                    return user
            except:
                logging.getLogger(__name__).exception(
                    "Error running api key validator "
                    "for plugin {} and key {}".format(name, apikey),
                    extra=dict(plugin=name))
    return None
Example #11
0
def setup_octoprint(persona):

    # Get the EventManager singleton
    event_manager = events.eventManager()

    #################################################################
    # This is the octoprint section

    # Initialize settings
    p_settings = settings(True)

    # Initialize plugin manager
    plugin.plugin_manager(True)

    # Initialize profile manager
    profile_manager = profile.PrinterProfileManager()
    profile_manager.save(gigabot_profile,
                         allow_overwrite=True,
                         make_default=True)

    # Create an analysis queue
    analysis_queue = analysis.AnalysisQueue({})

    # Set up the storage managers. The file manager will need a
    # storage manager, which is a dictionary.
    storage_managers = dict()

    # Create our local storage manager and add it to the dictionary.
    local_storage_manager = storage.LocalFileStorage(persona.localpath)
    storage_managers[FileDestinations.LOCAL] = local_storage_manager

    # Now we can create the file manager...
    file_manager = FileManager(analysis_queue,
                               None,
                               None,
                               initial_storage_managers=storage_managers)

    # And now we can create the printer.
    printer = Printer(file_manager, analysis_queue, profile_manager)

    # This has to happen to start the event dispatching. Prior to
    # dispatching a STARTUP event, events will be queued but not
    # sent.
    event_manager.fire(events.Events.STARTUP)

    # Caller needs the printer and storage manager objects.
    return (printer, local_storage_manager)
Example #12
0
def get_plugin_hash():
    from octoprint.plugin import plugin_manager

    plugin_signature = lambda impl: f"{impl._identifier}:{impl._plugin_version}"
    template_plugins = list(
        map(
            plugin_signature,
            plugin_manager().get_implementations(
                octoprint.plugin.TemplatePlugin),
        ))
    asset_plugins = list(
        map(
            plugin_signature,
            plugin_manager().get_implementations(octoprint.plugin.AssetPlugin),
        ))
    ui_plugins = sorted(set(template_plugins + asset_plugins))

    import hashlib

    plugin_hash = hashlib.sha1()
    plugin_hash.update(",".join(ui_plugins).encode("utf-8"))
    return plugin_hash.hexdigest()
Example #13
0
def init_print(absFilename):
	_settings = settings(init=True)
	pluginManager = plugin_manager(init=True)
	pluginManager.reload_plugins(startup=True, initialize_implementations=False)
	printerProfileManager = PrinterProfileManager()
	analysis_queue_factories = dict(gcode=GcodeAnalysisQueue)
	analysis_queue_hooks = pluginManager.get_hooks("octoprint.filemanager.analysis.factory")

	for name, hook in analysis_queue_hooks.items():
		try:
			additional_factories = hook()
			analysis_queue_factories.update(**additional_factories)
		except:
			print("Error while processing analysis queues from {}".format(name))

	analysisQueue = AnalysisQueue(analysis_queue_factories)

	slicingManager = SlicingManager(_settings.getBaseFolder("slicingProfiles"), printerProfileManager)

	storage_managers = dict()
	storage_managers[FileDestinations.LOCAL] = storage.LocalFileStorage(absFilename)

	fileManager = FileManager(analysisQueue, slicingManager, printerProfileManager,
							  initial_storage_managers=storage_managers)

	printer = Printer(fileManager, analysisQueue, printerProfileManager)

	printer_profile = printerProfileManager.get_default()
	connectionOptions = printer.__class__.get_connection_options()

	baselist = []
	baselist = baselist \
			   + glob.glob("/dev/ttyUSB*") \
			   + glob.glob("/dev/ttyACM*") \
			   + glob.glob("/dev/tty.usb*") \
			   + glob.glob("/dev/cu.*") \
			   + glob.glob("/dev/cuaU*") \
			   + glob.glob("/dev/rfcomm*")

	if len(baselist) == 1:
		port = baselist[0]

	print('Connecting to: %s' % port)

	baudrate = 115200

	printer.connect(port=port, baudrate=baudrate,
					profile=printer_profile["id"] if "id" in printer_profile else "_default")

	return printer
    def __init__(self,
                 seriallog_handler=None,
                 read_timeout=5.0,
                 write_timeout=10.0):
        import logging
        self._logger = logging.getLogger(
            "octoprint.plugins.virtual_printer.VirtualPrinter")

        self._seriallog = logging.getLogger(
            "octoprint.plugin.virtual_printer.VirtualPrinter.serial")
        self._seriallog.setLevel(logging.CRITICAL)
        self._seriallog.propagate = False

        if seriallog_handler is not None:
            import logging.handlers
            self._seriallog.addHandler(seriallog_handler)
            self._seriallog.setLevel(logging.INFO)

        self._seriallog.info("-" * 78)
        self._read_timeout = read_timeout
        self._write_timeout = write_timeout
        self.outgoing = queue.Queue()
        self.M28 = False
        self._folder = settings().getBaseFolder('uploads')
        self.www = settings().getBaseFolder("base") + "/www/"
        self._sdCardReady = False
        self._sdPrinter = None
        self._selectedSdFile = None
        self._selectedFile = None
        self._selectedSdFileSize = None
        self._selectedSdFilePos = None
        self._writingToSd = False
        self._writingToSdHandle = None
        self._newSdFilePos = None
        self._heatupThread = None
        self._action_hooks = plugin_manager().get_hooks(
            "octoprint.plugin.virtual_printer.custom_action")
        self._killed = False
        self.filePos = None
        # XYZ Settings
        self.file3wSize = 0
        self.file3w = None
        self.printer = printers.XYZ()
        self.status = None
        self.connected = self.connect()
        self.printing = False
Example #15
0
def valid_timelapse(path):
	global _extensions

	if _extensions is None:
		# create list of extensions
		extensions = ["mpg", "mpeg", "mp4", "m4v", "mkv"]

		hooks = plugin_manager().get_hooks("octoprint.timelapse.extensions")
		for name, hook in hooks.items():
			try:
				result = hook()
				if result is None or not isinstance(result, list):
					continue
				extensions += result
			except:
				logging.getLogger(__name__).exception("Exception while retrieving additional timelapse extensions from hook {name}".format(name=name))

		_extensions = list(set(extensions))

	return util.is_allowed_file(path, _extensions)
Example #16
0
def get_user_for_apikey(apikey):
	if settings().getBoolean(["api", "enabled"]) and apikey is not None:
		if apikey == settings().get(["api", "key"]) or octoprint.server.appSessionManager.validate(apikey):
			# master key or an app session key was used
			return ApiUser()
		
		if octoprint.server.userManager.enabled:
			user = octoprint.server.userManager.findUser(apikey=apikey)
			if user is not None:
				# user key was used
				return user
		
		apikey_hooks = plugin_manager().get_hooks("octoprint.accesscontrol.keyvalidator")
		for name, hook in apikey_hooks.items():
			try:
				user = hook(apikey)
				if user is not None:
					return user
			except:
				logging.getLogger(__name__).exception("Error running api key validator for plugin {} and key {}".format(name, apikey))
	return None
Example #17
0
def valid_timelapse(path):
    global _extensions

    if _extensions is None:
        # create list of extensions
        extensions = ["mpg", "mpeg", "mp4", "m4v", "mkv"]

        hooks = plugin_manager().get_hooks("octoprint.timelapse.extensions")
        for name, hook in hooks.items():
            try:
                result = hook()
                if result is None or not isinstance(result, list):
                    continue
                extensions += result
            except:
                logging.getLogger(__name__).exception(
                    "Exception while retrieving additional timelapse extensions from hook {name}"
                    .format(name=name))

        _extensions = list(set(extensions))

    return util.is_allowed_file(path, _extensions)
Example #18
0
	def __init__(self, analysis_queue, slicing_manager, printer_profile_manager, initial_storage_managers=None):
		self._logger = logging.getLogger(__name__)
		self._analysis_queue = analysis_queue
		self._analysis_queue.register_finish_callback(self._on_analysis_finished)

		self._storage_managers = dict()
		if initial_storage_managers:
			self._storage_managers.update(initial_storage_managers)

		self._slicing_manager = slicing_manager
		self._printer_profile_manager = printer_profile_manager

		import threading
		self._slicing_jobs = dict()
		self._slicing_jobs_mutex = threading.Lock()

		self._slicing_progress_callbacks = []
		self._last_slicing_progress = None

		self._progress_plugins = plugin_manager().get_implementations(ProgressPlugin)

		for storage_type, storage_manager in self._storage_managers.items():
			self._determine_analysis_backlog(storage_type, storage_manager)
Example #19
0
def getInstalledLanguagePacks():
    translation_folder = settings().getBaseFolder("translations",
                                                  check_writable=False)
    if not os.path.exists(translation_folder):
        return jsonify(language_packs={"_core": []})

    core_packs = []
    plugin_packs = defaultdict(lambda: {
        "identifier": None,
        "display": None,
        "languages": []
    })
    for entry in os.scandir(translation_folder):
        if not entry.is_dir():
            continue

        def load_meta(path, locale):
            meta = {}

            meta_path = os.path.join(path, "meta.yaml")
            if os.path.isfile(meta_path):
                try:
                    meta = yaml.load_from_file(path=meta_path)
                except Exception:
                    logging.getLogger(__name__).exception(
                        "Could not load %s", meta_path)
                    pass
                else:
                    import datetime

                    if "last_update" in meta and isinstance(
                            meta["last_update"], datetime.datetime):
                        meta["last_update"] = (
                            meta["last_update"] -
                            datetime.datetime(1970, 1, 1)).total_seconds()

            loc = Locale.parse(locale)
            meta["locale"] = locale
            meta["locale_display"] = loc.display_name
            meta["locale_english"] = loc.english_name
            return meta

        if entry.name == "_plugins":
            for plugin_entry in os.scandir(entry.path):
                if not plugin_entry.is_dir():
                    continue

                if plugin_entry.name not in plugin_manager().plugins:
                    continue

                plugin_info = plugin_manager().plugins[plugin_entry.name]

                plugin_packs[
                    plugin_entry.name]["identifier"] = plugin_entry.name
                plugin_packs[plugin_entry.name]["display"] = plugin_info.name

                for language_entry in os.scandir(plugin_entry.path):
                    try:
                        plugin_packs[plugin_entry.name]["languages"].append(
                            load_meta(language_entry.path,
                                      language_entry.name))
                    except Exception:
                        logging.getLogger(__name__).exception(
                            "Error while parsing metadata for language pack {} from {} for plugin {}"
                            .format(
                                language_entry.name,
                                language_entry.path,
                                plugin_entry.name,
                            ))
                        continue
        else:
            try:
                core_packs.append(load_meta(entry.path, entry.name))
            except ValueError:
                logging.getLogger(__name__).exception(
                    "Core language pack {} doesn't appear to actually be one".
                    format(entry.name))
            except Exception:
                logging.getLogger(__name__).exception(
                    "Error while parsing metadata for core language pack {} from {}"
                    .format(entry.name, entry.path))

    result = {
        "_core": {
            "identifier": "_core",
            "display": "Core",
            "languages": core_packs
        }
    }
    result.update(plugin_packs)
    return jsonify(language_packs=result)
Example #20
0
    def __init__(self, fileManager, analysisQueue, printerProfileManager):
        from collections import deque

        self._logger = logging.getLogger(__name__)

        self._analysisQueue = analysisQueue
        self._fileManager = fileManager
        self._printerProfileManager = printerProfileManager

        # state
        # TODO do we really need to hold the temperature here?
        self._temp = None
        self._bedTemp = None
        self._targetTemp = None
        self._targetBedTemp = None
        self._temps = TemperatureHistory(
            cutoff=settings().getInt(["temperature", "cutoff"]) * 60)
        self._tempBacklog = []

        self._latestMessage = None
        self._messages = deque([], 300)
        self._messageBacklog = []

        self._latestLog = None
        self._log = deque([], 300)
        self._logBacklog = []

        self._state = None

        self._currentZ = None

        self._progress = None
        self._printTime = None
        self._printTimeLeft = None

        self._printAfterSelect = False
        self._posAfterSelect = None

        # sd handling
        self._sdPrinting = False
        self._sdStreaming = False
        self._sdFilelistAvailable = threading.Event()
        self._streamingFinishedCallback = None

        self._selectedFile = None
        self._timeEstimationData = None

        # comm
        self._comm = None

        # callbacks
        self._callbacks = []

        # progress plugins
        self._lastProgressReport = None
        self._progressPlugins = plugin_manager().get_implementations(
            ProgressPlugin)

        self._stateMonitor = StateMonitor(
            interval=0.5,
            on_update=self._sendCurrentDataCallbacks,
            on_add_temperature=self._sendAddTemperatureCallbacks,
            on_add_log=self._sendAddLogCallbacks,
            on_add_message=self._sendAddMessageCallbacks)
        self._stateMonitor.reset(state={
            "text": self.get_state_string(),
            "flags": self._getStateFlags()
        },
                                 job_data={
                                     "file": {
                                         "name": None,
                                         "size": None,
                                         "origin": None,
                                         "date": None
                                     },
                                     "estimatedPrintTime": None,
                                     "lastPrintTime": None,
                                     "filament": {
                                         "length": None,
                                         "volume": None
                                     }
                                 },
                                 progress={
                                     "completion": None,
                                     "filepos": None,
                                     "printTime": None,
                                     "printTimeLeft": None
                                 },
                                 current_z=None)

        eventManager().subscribe(Events.METADATA_ANALYSIS_FINISHED,
                                 self._on_event_MetadataAnalysisFinished)
        eventManager().subscribe(Events.METADATA_STATISTICS_UPDATED,
                                 self._on_event_MetadataStatisticsUpdated)
Example #21
0
def init_pluginsystem(settings, safe_mode=False):
	"""Initializes the plugin manager based on the settings."""

	import os

	logger = log.getLogger(__name__)

	plugin_folders = [(os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "plugins")), True),
	                  settings.getBaseFolder("plugins")]
	plugin_entry_points = ["octoprint.plugin"]
	plugin_disabled_list = settings.get(["plugins", "_disabled"])

	plugin_validators = []
	if safe_mode:
		def validator(phase, plugin_info):
			if phase == "after_load":
				setattr(plugin_info, "safe_mode_victim", not plugin_info.bundled)
				setattr(plugin_info, "safe_mode_enabled", False)
			elif phase == "before_enable":
				if not plugin_info.bundled:
					setattr(plugin_info, "safe_mode_enabled", True)
					return False
			return True
		plugin_validators.append(validator)

	from octoprint.plugin import plugin_manager
	pm = plugin_manager(init=True,
	                    plugin_folders=plugin_folders,
	                    plugin_entry_points=plugin_entry_points,
	                    plugin_disabled_list=plugin_disabled_list,
	                    plugin_validators=plugin_validators)

	settings_overlays = dict()
	disabled_from_overlays = dict()

	def handle_plugin_loaded(name, plugin):
		if hasattr(plugin.instance, "__plugin_settings_overlay__"):
			plugin.needs_restart = True

			# plugin has a settings overlay, inject it
			overlay_definition = getattr(plugin.instance, "__plugin_settings_overlay__")
			if isinstance(overlay_definition, (tuple, list)):
				overlay_definition, order = overlay_definition
			else:
				order = None

			overlay = settings.load_overlay(overlay_definition)

			if "plugins" in overlay and "_disabled" in overlay["plugins"]:
				disabled_plugins = overlay["plugins"]["_disabled"]
				del overlay["plugins"]["_disabled"]
				disabled_from_overlays[name] = (disabled_plugins, order)

			settings_overlays[name] = overlay
			logger.debug("Found settings overlay on plugin {}".format(name))

	def handle_plugins_loaded(startup=False, initialize_implementations=True, force_reload=None):
		if not startup:
			return

		sorted_disabled_from_overlays = sorted([(key, value[0], value[1]) for key, value in disabled_from_overlays.items()], key=lambda x: (x[2] is None, x[2], x[0]))

		disabled_list = pm.plugin_disabled_list
		already_processed = []
		for name, addons, _ in sorted_disabled_from_overlays:
			if not name in disabled_list and not name.endswith("disabled"):
				for addon in addons:
					if addon in disabled_list:
						continue

					if addon in already_processed:
						logger.info("Plugin {} wants to disable plugin {}, but that was already processed".format(name, addon))

					if not addon in already_processed and not addon in disabled_list:
						disabled_list.append(addon)
						logger.info("Disabling plugin {} as defined by plugin {} through settings overlay".format(addon, name))
				already_processed.append(name)

	def handle_plugin_enabled(name, plugin):
		if name in settings_overlays:
			settings.add_overlay(settings_overlays[name])
			logger.info("Added settings overlay from plugin {}".format(name))

	pm.on_plugin_loaded = handle_plugin_loaded
	pm.on_plugins_loaded = handle_plugins_loaded
	pm.on_plugin_enabled = handle_plugin_enabled
	pm.reload_plugins(startup=True, initialize_implementations=False)
	return pm
Example #22
0
def init_pluginsystem(settings, safe_mode=False, ignore_blacklist=True, connectivity_checker=None):
	"""Initializes the plugin manager based on the settings."""

	import os

	logger = log.getLogger(__name__ + ".startup")

	plugin_folders = [(os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "plugins")), True),
	                  settings.getBaseFolder("plugins")]
	plugin_entry_points = ["octoprint.plugin"]
	plugin_disabled_list = settings.get(["plugins", "_disabled"])

	plugin_blacklist = []
	if not ignore_blacklist and settings.getBoolean(["server", "pluginBlacklist", "enabled"]):
		plugin_blacklist = get_plugin_blacklist(settings, connectivity_checker=connectivity_checker)

	plugin_validators = []
	if safe_mode:
		def validator(phase, plugin_info):
			if phase in ("before_import", "before_load", "before_enable"):
				setattr(plugin_info, "safe_mode_victim", not plugin_info.bundled)
				if not plugin_info.bundled:
					return False
			return True
		plugin_validators.append(validator)

	from octoprint.plugin import plugin_manager
	pm = plugin_manager(init=True,
	                    plugin_folders=plugin_folders,
	                    plugin_entry_points=plugin_entry_points,
	                    plugin_disabled_list=plugin_disabled_list,
	                    plugin_blacklist=plugin_blacklist,
	                    plugin_validators=plugin_validators)

	settings_overlays = dict()
	disabled_from_overlays = dict()

	def handle_plugin_loaded(name, plugin):
		if plugin.instance and hasattr(plugin.instance, "__plugin_settings_overlay__"):
			plugin.needs_restart = True

			# plugin has a settings overlay, inject it
			overlay_definition = getattr(plugin.instance, "__plugin_settings_overlay__")
			if isinstance(overlay_definition, (tuple, list)):
				overlay_definition, order = overlay_definition
			else:
				order = None

			overlay = settings.load_overlay(overlay_definition)

			if "plugins" in overlay and "_disabled" in overlay["plugins"]:
				disabled_plugins = overlay["plugins"]["_disabled"]
				del overlay["plugins"]["_disabled"]
				disabled_from_overlays[name] = (disabled_plugins, order)

			settings_overlays[name] = overlay
			logger.debug("Found settings overlay on plugin {}".format(name))

	def handle_plugins_loaded(startup=False, initialize_implementations=True, force_reload=None):
		if not startup:
			return

		sorted_disabled_from_overlays = sorted([(key, value[0], value[1]) for key, value in disabled_from_overlays.items()], key=lambda x: (x[2] is None, x[2], x[0]))

		disabled_list = pm.plugin_disabled_list
		already_processed = []
		for name, addons, _ in sorted_disabled_from_overlays:
			if not name in disabled_list and not name.endswith("disabled"):
				for addon in addons:
					if addon in disabled_list:
						continue

					if addon in already_processed:
						logger.info("Plugin {} wants to disable plugin {}, but that was already processed".format(name, addon))

					if not addon in already_processed and not addon in disabled_list:
						disabled_list.append(addon)
						logger.info("Disabling plugin {} as defined by plugin {}".format(addon, name))
				already_processed.append(name)

	def handle_plugin_enabled(name, plugin):
		if name in settings_overlays:
			settings.add_overlay(settings_overlays[name])
			logger.info("Added settings overlay from plugin {}".format(name))

	pm.on_plugin_loaded = handle_plugin_loaded
	pm.on_plugins_loaded = handle_plugins_loaded
	pm.on_plugin_enabled = handle_plugin_enabled
	pm.reload_plugins(startup=True, initialize_implementations=False)
	return pm
Example #23
0
    def __init__(self, read_timeout=5.0, write_timeout=10.0):
        import logging
        self._logger = logging.getLogger(
            "octoprint.plugin.virtual_printer.VirtualPrinter")

        self._read_timeout = read_timeout
        self._write_timeout = write_timeout

        self.incoming = CharCountingQueue(settings().getInt(
            ["devel", "virtualPrinter", "rxBuffer"]),
                                          name="RxBuffer")
        self.outgoing = Queue.Queue()
        self.buffered = Queue.Queue(maxsize=settings().getInt(
            ["devel", "virtualPrinter", "commandBuffer"]))

        for item in [
                'start\n', 'Marlin: Virtual Marlin!\n', '\x80\n',
                'SD card ok\n'
        ]:
            self.outgoing.put(item)

        self.currentExtruder = 0
        self.temp = [0.0] * settings().getInt(
            ["devel", "virtualPrinter", "numExtruders"])
        self.targetTemp = [0.0] * settings().getInt(
            ["devel", "virtualPrinter", "numExtruders"])
        self.lastTempAt = time.time()
        self.bedTemp = 1.0
        self.bedTargetTemp = 1.0
        self.speeds = settings().get(
            ["devel", "virtualPrinter", "movementSpeed"])

        self._relative = True
        self._lastX = None
        self._lastY = None
        self._lastZ = None
        self._lastE = None

        self._unitModifier = 1

        self._virtualSd = settings().getBaseFolder("virtualSd")
        self._sdCardReady = True
        self._sdPrinter = None
        self._sdPrintingSemaphore = threading.Event()
        self._selectedSdFile = None
        self._selectedSdFileSize = None
        self._selectedSdFilePos = None
        self._writingToSd = False
        self._newSdFilePos = None
        self._heatupThread = None

        self._okBeforeCommandOutput = settings().get_boolean(
            ["devel", "virtualPrinter", "okBeforeCommandOutput"])

        self._sendWait = settings().get_boolean(
            ["devel", "virtualPrinter", "sendWait"])
        self._waitInterval = settings().getFloat(
            ["devel", "virtualPrinter", "waitInterval"])

        self.currentLine = 0
        self.lastN = 0

        self._incoming_lock = threading.RLock()

        self._sleepAfterNext = dict()
        self._sleepAfter = dict()

        self._dont_answer = False

        self._debug_drop_connection = False

        self._action_hooks = plugin_manager().get_hooks(
            "octoprint.plugin.virtual_printer.custom_action")

        waitThread = threading.Thread(target=self._sendWaitAfterTimeout)
        waitThread.start()

        readThread = threading.Thread(target=self._processIncoming)
        readThread.start()

        bufferThread = threading.Thread(target=self._processBuffer)
        bufferThread.start()
Example #24
0
def getInstalledLanguagePacks():
	translation_folder = settings().getBaseFolder("translations", check_writable=False)
	if not os.path.exists(translation_folder):
		return jsonify(language_packs=dict(_core=[]))

	core_packs = []
	plugin_packs = defaultdict(lambda: dict(identifier=None, display=None, languages=[]))
	for entry in scandir(translation_folder):
		if not entry.is_dir():
			continue

		def load_meta(path, locale):
			meta = dict()

			meta_path = os.path.join(path, "meta.yaml")
			if os.path.isfile(meta_path):
				import yaml
				try:
					with open(meta_path) as f:
						meta = yaml.safe_load(f)
				except:
					pass
				else:
					import datetime
					if "last_update" in meta and isinstance(meta["last_update"], datetime.datetime):
						meta["last_update"] = (meta["last_update"] - datetime.datetime(1970,1,1)).total_seconds()

			l = Locale.parse(locale)
			meta["locale"] = locale
			meta["locale_display"] = l.display_name
			meta["locale_english"] = l.english_name
			return meta

		if entry.name == "_plugins":
			for plugin_entry in scandir(entry.path):
				if not plugin_entry.is_dir():
					continue

				if not plugin_entry.name in plugin_manager().plugins:
					continue

				plugin_info = plugin_manager().plugins[plugin_entry.name]

				plugin_packs[plugin_entry.name]["identifier"] = plugin_entry.name
				plugin_packs[plugin_entry.name]["display"] = plugin_info.name

				for language_entry in scandir(plugin_entry.path):
					try:
						plugin_packs[plugin_entry.name]["languages"].append(load_meta(language_entry.path, language_entry.name))
					except Exception:
						logging.getLogger(__name__).exception("Error while parsing metadata for language pack {} from {} for plugin {}".format(language_entry.name,
						                                                                                                                       language_entry.path,
						                                                                                                                       plugin_entry.name))
						continue
		else:
			try:
				core_packs.append(load_meta(entry.path, entry.name))
			except Exception:
				logging.getLogger(__name__).exception("Error while parsing metadata for core language pack {} from {}".format(entry.name,
				                                                                                                              entry.path))

	result = dict(_core=dict(identifier="_core", display="Core", languages=core_packs))
	result.update(plugin_packs)
	return jsonify(language_packs=result)
Example #25
0
    def __init__(self, fileManager, analysisQueue, printerProfileManager):
        from collections import deque

        self._logger = logging.getLogger(__name__)
        #self._estimationLogger = logging.getLogger("ESTIMATIONS")
        #self._printTimeLogger = logging.getLogger("PRINT_TIME")

        self._analysisQueue = analysisQueue
        self._fileManager = fileManager
        self._printerProfileManager = printerProfileManager

        # state
        self._temps = deque([], 300)
        self._tempBacklog = []

        self._latestMessage = None
        self._messages = deque([], 300)
        self._messageBacklog = []

        self._latestLog = None
        self._log = deque([], 300)
        self._logBacklog = []

        self._state = None

        self._currentZ = None

        self._progress = None
        self._printTime = None
        self._printTimeLeft = None

        self._printAfterSelect = False

        # sd handling
        self._sdPrinting = False
        self._sdStreaming = False
        self._sdFilelistAvailable = threading.Event()
        self._streamingFinishedCallback = None

        self._selectedFile = None
        self._timeEstimationData = None

        # comm
        self._comm = None

        self._protocol = self._createProtocol()

        # callbacks
        self._callbacks = []

        #lkj
        self._cmdBeforePrint = []
        self._cmdAfterPrint = []

        # progress plugins
        self._lastProgressReport = None
        self._progressPlugins = plugin_manager().get_implementations(
            ProgressPlugin)

        self._stateMonitor = StateMonitor(
            ratelimit=0.5,
            updateCallback=self._sendCurrentDataCallbacks,
            addTemperatureCallback=self._sendAddTemperatureCallbacks,
            addLogCallback=self._sendAddLogCallbacks,
            addMessageCallback=self._sendAddMessageCallbacks)
        self._stateMonitor.reset(state={
            "text": self.getStateString(),
            "flags": self._getStateFlags()
        },
                                 jobData={
                                     "file": {
                                         "name": None,
                                         "size": None,
                                         "origin": None,
                                         "date": None
                                     },
                                     "estimatedPrintTime": None,
                                     "lastPrintTime": None,
                                     "filament": {
                                         "length": None,
                                         "volume": None
                                     }
                                 },
                                 progress={
                                     "completion": None,
                                     "filepos": None,
                                     "printTime": None,
                                     "printTimeLeft": None
                                 },
                                 currentZ=None)

        eventManager().subscribe(Events.METADATA_ANALYSIS_FINISHED,
                                 self.onMetadataAnalysisFinished)
        eventManager().subscribe(Events.METADATA_STATISTICS_UPDATED,
                                 self.onMetadataStatisticsUpdated)
Example #26
0
	def __init__(self, fileManager, analysisQueue, printerProfileManager):
		from collections import deque

		self._logger = logging.getLogger(__name__)

		self._analysisQueue = analysisQueue
		self._fileManager = fileManager
		self._printerProfileManager = printerProfileManager

		# state
		# TODO do we really need to hold the temperature here?
		self._temp = None
		self._bedTemp = None
		self._targetTemp = None
		self._targetBedTemp = None
		self._temps = TemperatureHistory(cutoff=settings().getInt(["temperature", "cutoff"])*60)
		self._tempBacklog = []

		self._latestMessage = None
		self._messages = deque([], 300)
		self._messageBacklog = []

		self._latestLog = None
		self._log = deque([], 300)
		self._logBacklog = []

		self._state = None

		self._currentZ = None

		self._printAfterSelect = False
		self._posAfterSelect = None

		# sd handling
		self._sdPrinting = False
		self._sdStreaming = False
		self._sdFilelistAvailable = threading.Event()
		self._streamingFinishedCallback = None

		self._selectedFile = None
		self._timeEstimationData = None

		# comm
		self._comm = None

		# callbacks
		self._callbacks = []

		# progress plugins
		self._lastProgressReport = None
		self._progressPlugins = plugin_manager().get_implementations(ProgressPlugin)

		self._stateMonitor = StateMonitor(
			interval=0.5,
			on_update=self._sendCurrentDataCallbacks,
			on_add_temperature=self._sendAddTemperatureCallbacks,
			on_add_log=self._sendAddLogCallbacks,
			on_add_message=self._sendAddMessageCallbacks,
			on_get_progress=self._updateProgressDataCallback
		)
		self._stateMonitor.reset(
			state={"text": self.get_state_string(), "flags": self._getStateFlags()},
			job_data={
				"file": {
					"name": None,
					"size": None,
					"origin": None,
					"date": None
				},
				"estimatedPrintTime": None,
				"lastPrintTime": None,
				"filament": {
					"length": None,
					"volume": None
				}
			},
			progress={"completion": None, "filepos": None, "printTime": None, "printTimeLeft": None},
			current_z=None
		)

		eventManager().subscribe(Events.METADATA_ANALYSIS_FINISHED, self._on_event_MetadataAnalysisFinished)
		eventManager().subscribe(Events.METADATA_STATISTICS_UPDATED, self._on_event_MetadataStatisticsUpdated)
Example #27
0
	def __init__(self, fileManager, analysisQueue, printerProfileManager):
		from collections import deque

		self._logger = logging.getLogger(__name__)

		self._dict = frozendict if settings().getBoolean(["devel", "useFrozenDictForPrinterState"]) else dict

		self._analysisQueue = analysisQueue
		self._fileManager = fileManager
		self._printerProfileManager = printerProfileManager

		# state
		# TODO do we really need to hold the temperature here?
		self._temp = None
		self._bedTemp = None
		self._targetTemp = None
		self._targetBedTemp = None
		self._temps = TemperatureHistory(cutoff=settings().getInt(["temperature", "cutoff"])*60)
		self._tempBacklog = []

		self._messages = deque([], 300)
		self._messageBacklog = []

		self._log = deque([], 300)
		self._logBacklog = []

		self._state = None

		self._currentZ = None

		self._printAfterSelect = False
		self._posAfterSelect = None

		# sd handling
		self._sdPrinting = False
		self._sdStreaming = False
		self._sdFilelistAvailable = threading.Event()
		self._streamingFinishedCallback = None
		self._streamingFailedCallback = None

		# job handling & estimation
		self._selectedFileMutex = threading.RLock()
		self._selectedFile = None

		self._estimator_factory = PrintTimeEstimator
		self._estimator = None
		analysis_queue_hooks = plugin_manager().get_hooks("octoprint.printer.estimation.factory")
		for name, hook in analysis_queue_hooks.items():
			try:
				estimator = hook()
				if estimator is not None:
					self._logger.info("Using print time estimator provided by {}".format(name))
					self._estimator_factory = estimator
			except:
				self._logger.exception("Error while processing analysis queues from {}".format(name))

		# comm
		self._comm = None

		# callbacks
		self._callbacks = []

		# progress plugins
		self._lastProgressReport = None
		self._progressPlugins = plugin_manager().get_implementations(ProgressPlugin)

		self._stateMonitor = StateMonitor(
			interval=0.5,
			on_update=self._sendCurrentDataCallbacks,
			on_add_temperature=self._sendAddTemperatureCallbacks,
			on_add_log=self._sendAddLogCallbacks,
			on_add_message=self._sendAddMessageCallbacks,
			on_get_progress=self._updateProgressDataCallback
		)
		self._stateMonitor.reset(
			state=self._dict(text=self.get_state_string(), flags=self._getStateFlags()),
			job_data=self._dict(file=self._dict(name=None,
			                                    path=None,
			                                    size=None,
			                                    origin=None,
			                                    date=None),
			                    estimatedPrintTime=None,
			                    lastPrintTime=None,
			                    filament=self._dict(length=None,
			                                        volume=None),
			                    user=None),
			progress=self._dict(completion=None,
			                    filepos=None,
			                    printTime=None,
			                    printTimeLeft=None,
			                    printTimeOrigin=None),
			current_z=None,
			offsets=self._dict()
		)

		eventManager().subscribe(Events.METADATA_ANALYSIS_FINISHED, self._on_event_MetadataAnalysisFinished)
		eventManager().subscribe(Events.METADATA_STATISTICS_UPDATED, self._on_event_MetadataStatisticsUpdated)
Example #28
0
	def __init__(self, seriallog_handler=None, read_timeout=5.0, write_timeout=10.0):
		import logging
		self._logger = logging.getLogger("octoprint.plugins.virtual_printer.VirtualPrinter")

		self._seriallog = logging.getLogger("octoprint.plugin.virtual_printer.VirtualPrinter.serial")
		self._seriallog.setLevel(logging.CRITICAL)
		self._seriallog.propagate = False

		if seriallog_handler is not None:
			import logging.handlers
			self._seriallog.addHandler(seriallog_handler)
			self._seriallog.setLevel(logging.INFO)

		self._seriallog.info("-"*78)

		self._read_timeout = read_timeout
		self._write_timeout = write_timeout

		self._rx_buffer_size = settings().getInt(["devel", "virtualPrinter", "rxBuffer"])

		self.incoming = CharCountingQueue(self._rx_buffer_size, name="RxBuffer")
		self.outgoing = queue.Queue()
		self.buffered = queue.Queue(maxsize=settings().getInt(["devel", "virtualPrinter", "commandBuffer"]))

		if settings().getBoolean(["devel", "virtualPrinter", "simulateReset"]):
			for item in settings().get(["devel", "virtualPrinter", "resetLines"]):
				self._send(item + "\n")

		self._prepared_oks = []
		prepared = settings().get(["devel", "virtualPrinter", "preparedOks"])
		if prepared and isinstance(prepared, list):
			for prep in prepared:
				self._prepared_oks.append(prep)

		self._prepared_errors = []

		self._errors = settings().get(["devel", "virtualPrinter", "errors"], merged=True)

		self.currentExtruder = 0
		self.extruderCount = settings().getInt(["devel", "virtualPrinter", "numExtruders"])
		self.pinnedExtruders = settings().get(["devel", "virtualPrinter", "pinnedExtruders"])
		if self.pinnedExtruders is None:
			self.pinnedExtruders = dict()
		self.sharedNozzle = settings().getBoolean(["devel", "virtualPrinter", "sharedNozzle"])
		self.temperatureCount = (1 if self.sharedNozzle else self.extruderCount)

		self._ambient_temperature = settings().getFloat(["devel", "virtualPrinter", "ambientTemperature"])

		self.temp = [self._ambient_temperature] * self.temperatureCount
		self.targetTemp = [0.0] * self.temperatureCount
		self.bedTemp = self._ambient_temperature
		self.bedTargetTemp = 0.0
		self.lastTempAt = time.time()

		self._relative = True
		self._lastX = 0.0
		self._lastY = 0.0
		self._lastZ = 0.0
		self._lastE = [0.0] * self.extruderCount
		self._lastF = 200

		self._unitModifier = 1
		self._feedrate_multiplier = 100
		self._flowrate_multiplier = 100

		self._virtualSd = settings().getBaseFolder("virtualSd")
		self._sdCardReady = True
		self._sdPrinter = None
		self._sdPrintingSemaphore = threading.Event()
		self._selectedSdFile = None
		self._selectedSdFileSize = None
		self._selectedSdFilePos = None

		self._writingToSd = False
		self._writingToSdHandle = None
		self._newSdFilePos = None

		self._heatingUp = False

		self._okBeforeCommandOutput = settings().getBoolean(["devel", "virtualPrinter", "okBeforeCommandOutput"])
		self._supportM112 = settings().getBoolean(["devel", "virtualPrinter", "supportM112"])
		self._supportF = settings().getBoolean(["devel", "virtualPrinter", "supportF"])

		self._sendWait = settings().getBoolean(["devel", "virtualPrinter", "sendWait"])
		self._sendBusy = settings().getBoolean(["devel", "virtualPrinter", "sendBusy"])
		self._waitInterval = settings().getFloat(["devel", "virtualPrinter", "waitInterval"])
		self._busyInterval = settings().getFloat(["devel", "virtualPrinter", "busyInterval"])

		self._echoOnM117 = settings().getBoolean(["devel", "virtualPrinter", "echoOnM117"])

		self._brokenM29 = settings().getBoolean(["devel", "virtualPrinter", "brokenM29"])
		self._brokenResend = settings().getBoolean(["devel", "virtualPrinter", "brokenResend"])

		self._m115FormatString = settings().get(["devel", "virtualPrinter", "m115FormatString"])
		self._firmwareName = settings().get(["devel", "virtualPrinter", "firmwareName"])

		self._okFormatString = settings().get(["devel", "virtualPrinter", "okFormatString"])

		self._capabilities = settings().get(["devel", "virtualPrinter", "capabilities"], merged=True)

		self._temperature_reporter = None
		self._sdstatus_reporter = None

		self.currentLine = 0
		self.lastN = 0

		self._incoming_lock = threading.RLock()

		self._debug_awol = False
		self._debug_sleep = None
		self._sleepAfterNext = dict()
		self._sleepAfter = dict()

		self._dont_answer = False

		self._debug_drop_connection = False

		self._action_hooks = plugin_manager().get_hooks("octoprint.plugin.virtual_printer.custom_action")

		self._killed = False

		self._triggerResendAt100 = True
		self._triggerResendWithTimeoutAt105 = True
		self._triggerResendWithMissingLinenoAt110 = True
		self._triggerResendWithChecksumMismatchAt115 = True

		readThread = threading.Thread(target=self._processIncoming, name="octoprint.plugins.virtual_printer.wait_thread")
		readThread.start()

		bufferThread = threading.Thread(target=self._processBuffer, name="octoprint.plugins.virtual_printer.buffer_thread")
		bufferThread.start()
Example #29
0
	def __init__(self, read_timeout=5.0, write_timeout=10.0):
		import logging
		self._logger = logging.getLogger("octoprint.plugin.virtual_printer.VirtualPrinter")

		self._read_timeout = read_timeout
		self._write_timeout = write_timeout

		self.incoming = CharCountingQueue(settings().getInt(["devel", "virtualPrinter", "rxBuffer"]), name="RxBuffer")
		self.outgoing = Queue.Queue()
		self.buffered = Queue.Queue(maxsize=settings().getInt(["devel", "virtualPrinter", "commandBuffer"]))

		for item in ['start\n', 'Marlin: Virtual Marlin!\n', '\x80\n', 'SD card ok\n']:
			self.outgoing.put(item)

		self.currentExtruder = 0
		self.temp = [0.0] * settings().getInt(["devel", "virtualPrinter", "numExtruders"])
		self.targetTemp = [0.0] * settings().getInt(["devel", "virtualPrinter", "numExtruders"])
		self.lastTempAt = time.time()
		self.bedTemp = 1.0
		self.bedTargetTemp = 1.0
		self.speeds = settings().get(["devel", "virtualPrinter", "movementSpeed"])

		self._relative = True
		self._lastX = None
		self._lastY = None
		self._lastZ = None
		self._lastE = None

		self._unitModifier = 1

		self._virtualSd = settings().getBaseFolder("virtualSd")
		self._sdCardReady = True
		self._sdPrinter = None
		self._sdPrintingSemaphore = threading.Event()
		self._selectedSdFile = None
		self._selectedSdFileSize = None
		self._selectedSdFilePos = None
		self._writingToSd = False
		self._newSdFilePos = None
		self._heatupThread = None

		self._okBeforeCommandOutput = settings().getBoolean(["devel", "virtualPrinter", "okBeforeCommandOutput"])

		self._sendWait = settings().getBoolean(["devel", "virtualPrinter", "sendWait"])
		self._waitInterval = settings().getFloat(["devel", "virtualPrinter", "waitInterval"])

		self.currentLine = 0
		self.lastN = 0

		self._incoming_lock = threading.RLock()

		self._sleepAfterNext = dict()
		self._sleepAfter = dict()

		self._dont_answer = False

		self._debug_drop_connection = False

		self._action_hooks = plugin_manager().get_hooks("octoprint.plugin.virtual_printer.custom_action")


		waitThread = threading.Thread(target=self._sendWaitAfterTimeout)
		waitThread.start()

		readThread = threading.Thread(target=self._processIncoming)
		readThread.start()

		bufferThread = threading.Thread(target=self._processBuffer)
		bufferThread.start()
Example #30
0
	def __init__(self, seriallog_handler=None, read_timeout=5.0, write_timeout=10.0):
		import logging
		self._logger = logging.getLogger("octoprint.plugins.virtual_printer.VirtualPrinter")

		self._seriallog = logging.getLogger("octoprint.plugin.virtual_printer.VirtualPrinter.serial")
		self._seriallog.setLevel(logging.CRITICAL)
		self._seriallog.propagate = False

		if seriallog_handler is not None:
			import logging.handlers
			self._seriallog.addHandler(seriallog_handler)
			self._seriallog.setLevel(logging.INFO)

		self._seriallog.info("-"*78)

		self._read_timeout = read_timeout
		self._write_timeout = write_timeout

		self._rx_buffer_size = settings().getInt(["devel", "virtualPrinter", "rxBuffer"])

		self.incoming = CharCountingQueue(self._rx_buffer_size, name="RxBuffer")
		self.outgoing = queue.Queue()
		self.buffered = queue.Queue(maxsize=settings().getInt(["devel", "virtualPrinter", "commandBuffer"]))

		if settings().getBoolean(["devel", "virtualPrinter", "simulateReset"]):
			for item in ['start\n', 'Marlin: Virtual Marlin!\n', '\x80\n', 'SD card ok\n']:
				self._send(item)

		self._prepared_oks = []
		prepared = settings().get(["devel", "virtualPrinter", "preparedOks"])
		if prepared and isinstance(prepared, list):
			for prep in prepared:
				self._prepared_oks.append(prep)

		self.currentExtruder = 0
		self.extruderCount = settings().getInt(["devel", "virtualPrinter", "numExtruders"])
		self.sharedNozzle = settings().getBoolean(["devel", "virtualPrinter", "sharedNozzle"])
		self.temperatureCount = (1 if self.sharedNozzle else self.extruderCount)

		self.temp = [0.0] * self.temperatureCount
		self.targetTemp = [0.0] * self.temperatureCount
		self.lastTempAt = time.time()
		self.bedTemp = 1.0
		self.bedTargetTemp = 1.0

		self._relative = True
		self._lastX = 0.0
		self._lastY = 0.0
		self._lastZ = 0.0
		self._lastE = 0.0
		self._lastF = 200

		self._unitModifier = 1
		self._feedrate_multiplier = 100
		self._flowrate_multiplier = 100

		self._virtualSd = settings().getBaseFolder("virtualSd")
		self._sdCardReady = True
		self._sdPrinter = None
		self._sdPrintingSemaphore = threading.Event()
		self._selectedSdFile = None
		self._selectedSdFileSize = None
		self._selectedSdFilePos = None
		self._writingToSd = False
		self._writingToSdHandle = None
		self._newSdFilePos = None
		self._heatupThread = None

		self._okBeforeCommandOutput = settings().getBoolean(["devel", "virtualPrinter", "okBeforeCommandOutput"])
		self._supportM112 = settings().getBoolean(["devel", "virtualPrinter", "supportM112"])
		self._supportF = settings().getBoolean(["devel", "virtualPrinter", "supportF"])

		self._sendWait = settings().getBoolean(["devel", "virtualPrinter", "sendWait"])
		self._sendBusy = settings().getBoolean(["devel", "virtualPrinter", "sendBusy"])
		self._waitInterval = settings().getFloat(["devel", "virtualPrinter", "waitInterval"])

		self._echoOnM117 = settings().getBoolean(["devel", "virtualPrinter", "echoOnM117"])

		self._brokenM29 = settings().getBoolean(["devel", "virtualPrinter", "brokenM29"])

		self._m115FormatString = settings().get(["devel", "virtualPrinter", "m115FormatString"])
		self._firmwareName = settings().get(["devel", "virtualPrinter", "firmwareName"])

		self._okFormatString = settings().get(["devel", "virtualPrinter", "okFormatString"])

		self.currentLine = 0
		self.lastN = 0

		self._incoming_lock = threading.RLock()

		self._debug_awol = False
		self._debug_sleep = None
		self._sleepAfterNext = dict()
		self._sleepAfter = dict()

		self._dont_answer = False

		self._debug_drop_connection = False

		self._action_hooks = plugin_manager().get_hooks("octoprint.plugin.virtual_printer.custom_action")

		self._killed = False

		self._triggerResendAt100 = True
		self._triggerResendWithTimeoutAt105 = True
		self._triggeredResendWithTimeoutAt105 = False

		readThread = threading.Thread(target=self._processIncoming, name="octoprint.plugins.virtual_printer.wait_thread")
		readThread.start()

		bufferThread = threading.Thread(target=self._processBuffer, name="octoprint.plugins.virtual_printer.buffer_thread")
		bufferThread.start()
Example #31
0
def getInstalledLanguagePacks():
    translation_folder = settings().getBaseFolder("translations")
    if not os.path.exists(translation_folder):
        return jsonify(language_packs=dict(_core=[]))

    core_packs = []
    plugin_packs = defaultdict(
        lambda: dict(identifier=None, display=None, languages=[]))
    for entry in scandir(translation_folder):
        if not entry.is_dir():
            continue

        def load_meta(path, locale):
            meta = dict()

            meta_path = os.path.join(path, "meta.yaml")
            if os.path.isfile(meta_path):
                import yaml
                try:
                    with open(meta_path) as f:
                        meta = yaml.safe_load(f)
                except:
                    pass
                else:
                    import datetime
                    if "last_update" in meta and isinstance(
                            meta["last_update"], datetime.datetime):
                        meta["last_update"] = (
                            meta["last_update"] -
                            datetime.datetime(1970, 1, 1)).total_seconds()

            l = Locale.parse(locale)
            meta["locale"] = locale
            meta["locale_display"] = l.display_name
            meta["locale_english"] = l.english_name
            return meta

        if entry.name == "_plugins":
            for plugin_entry in scandir(entry.path):
                if not plugin_entry.is_dir():
                    continue

                if not plugin_entry.name in plugin_manager().plugins:
                    continue

                plugin_info = plugin_manager().plugins[plugin_entry.name]

                plugin_packs[
                    plugin_entry.name]["identifier"] = plugin_entry.name
                plugin_packs[plugin_entry.name]["display"] = plugin_info.name

                for language_entry in scandir(plugin_entry.path):
                    plugin_packs[plugin_entry.name]["languages"].append(
                        load_meta(language_entry.path, language_entry.name))
        else:
            core_packs.append(load_meta(entry.path, entry.name))

    result = dict(
        _core=dict(identifier="_core", display="Core", languages=core_packs))
    result.update(plugin_packs)
    return jsonify(language_packs=result)
Example #32
0
    def __init__(self,
                 seriallog_handler=None,
                 read_timeout=5.0,
                 write_timeout=10.0):
        import logging
        self._logger = logging.getLogger(
            "octoprint.plugins.virtual_printer.VirtualPrinter")

        self._seriallog = logging.getLogger(
            "octoprint.plugin.virtual_printer.VirtualPrinter.serial")
        self._seriallog.setLevel(logging.CRITICAL)
        self._seriallog.propagate = False

        if seriallog_handler is not None:
            import logging.handlers
            self._seriallog.addHandler(seriallog_handler)
            self._seriallog.setLevel(logging.INFO)

        self._seriallog.info("-" * 78)

        self._read_timeout = read_timeout
        self._write_timeout = write_timeout

        self._rx_buffer_size = settings().getInt(
            ["devel", "virtualPrinter", "rxBuffer"])

        self.incoming = CharCountingQueue(self._rx_buffer_size,
                                          name="RxBuffer")
        self.outgoing = queue.Queue()
        self.buffered = queue.Queue(maxsize=settings().getInt(
            ["devel", "virtualPrinter", "commandBuffer"]))

        for item in [
                'start\n', 'Marlin: Virtual Marlin!\n', '\x80\n',
                'SD card ok\n'
        ]:
            self._send(item)

        self.currentExtruder = 0
        self.temp = [0.0] * settings().getInt(
            ["devel", "virtualPrinter", "numExtruders"])
        self.targetTemp = [0.0] * settings().getInt(
            ["devel", "virtualPrinter", "numExtruders"])
        self.lastTempAt = time.time()
        self.bedTemp = 1.0
        self.bedTargetTemp = 1.0

        self._relative = True
        self._lastX = 0.0
        self._lastY = 0.0
        self._lastZ = 0.0
        self._lastE = 0.0
        self._lastF = 200

        self._unitModifier = 1
        self._feedrate_multiplier = 100
        self._flowrate_multiplier = 100

        self._virtualSd = settings().getBaseFolder("virtualSd")
        self._sdCardReady = True
        self._sdPrinter = None
        self._sdPrintingSemaphore = threading.Event()
        self._selectedSdFile = None
        self._selectedSdFileSize = None
        self._selectedSdFilePos = None
        self._writingToSd = False
        self._writingToSdHandle = None
        self._newSdFilePos = None
        self._heatupThread = None

        self._okBeforeCommandOutput = settings().getBoolean(
            ["devel", "virtualPrinter", "okBeforeCommandOutput"])
        self._supportM112 = settings().getBoolean(
            ["devel", "virtualPrinter", "supportM112"])
        self._supportF = settings().getBoolean(
            ["devel", "virtualPrinter", "supportF"])

        self._sendWait = settings().getBoolean(
            ["devel", "virtualPrinter", "sendWait"])
        self._waitInterval = settings().getFloat(
            ["devel", "virtualPrinter", "waitInterval"])

        self._echoOnM117 = settings().getBoolean(
            ["devel", "virtualPrinter", "echoOnM117"])

        self._brokenM29 = settings().getBoolean(
            ["devel", "virtualPrinter", "brokenM29"])

        self._firmwareName = settings().get(
            ["devel", "virtualPrinter", "firmwareName"])

        self.currentLine = 0
        self.lastN = 0

        self._incoming_lock = threading.RLock()

        self._debug_awol = False
        self._debug_sleep = None
        self._sleepAfterNext = dict()
        self._sleepAfter = dict()

        self._dont_answer = False

        self._debug_drop_connection = False

        self._action_hooks = plugin_manager().get_hooks(
            "octoprint.plugin.virtual_printer.custom_action")

        self._killed = False

        self._triggerResendAt100 = True
        self._triggerResendWithTimeoutAt105 = True
        self._triggeredResendWithTimeoutAt105 = False

        readThread = threading.Thread(
            target=self._processIncoming,
            name="octoprint.plugins.virtual_printer.wait_thread")
        readThread.start()

        bufferThread = threading.Thread(
            target=self._processBuffer,
            name="octoprint.plugins.virtual_printer.buffer_thread")
        bufferThread.start()
Example #33
0
	def __init__(self, fileManager, analysisQueue, printerProfileManager):
		from collections import deque

		self._logger = logging.getLogger(__name__)
		#self._estimationLogger = logging.getLogger("ESTIMATIONS")
		#self._printTimeLogger = logging.getLogger("PRINT_TIME")

		self._analysisQueue = analysisQueue
		self._fileManager = fileManager
		self._printerProfileManager = printerProfileManager

		# state
		self._temps = deque([], 300)
		self._tempBacklog = []

		self._latestMessage = None
		self._messages = deque([], 300)
		self._messageBacklog = []

		self._latestLog = None
		self._log = deque([], 300)
		self._logBacklog = []

		self._state = None

		self._currentZ = None

		self._progress = None
		self._printTime = None
		self._printTimeLeft = None

		self._printAfterSelect = False

		# sd handling
		self._sdPrinting = False
		self._sdStreaming = False
		self._sdFilelistAvailable = threading.Event()
		self._streamingFinishedCallback = None

		self._selectedFile = None
		self._timeEstimationData = None

		# comm
		self._comm = None

		self._protocol = self._createProtocol()

		# callbacks
		self._callbacks = []
		
		#lkj
		self._cmdBeforePrint = []
		self._cmdAfterPrint = []
		
		# progress plugins
		self._lastProgressReport = None
		self._progressPlugins = plugin_manager().get_implementations(ProgressPlugin)

		self._stateMonitor = StateMonitor(
			ratelimit=0.5,
			updateCallback=self._sendCurrentDataCallbacks,
			addTemperatureCallback=self._sendAddTemperatureCallbacks,
			addLogCallback=self._sendAddLogCallbacks,
			addMessageCallback=self._sendAddMessageCallbacks
		)
		self._stateMonitor.reset(
			state={"text": self.getStateString(), "flags": self._getStateFlags()},
			jobData={
				"file": {
					"name": None,
					"size": None,
					"origin": None,
					"date": None
				},
				"estimatedPrintTime": None,
				"lastPrintTime": None,
				"filament": {
					"length": None,
					"volume": None
				}
			},
			progress={"completion": None, "filepos": None, "printTime": None, "printTimeLeft": None},
			currentZ=None
		)

		eventManager().subscribe(Events.METADATA_ANALYSIS_FINISHED, self.onMetadataAnalysisFinished)
		eventManager().subscribe(Events.METADATA_STATISTICS_UPDATED, self.onMetadataStatisticsUpdated)