Ejemplo n.º 1
0
 def on_event(self, event, payload):
     if event == Events.UPLOAD:
         if payload["target"] == "local" and payload[
                 "path"] == "custom-styles.css":
             source_file = self._file_manager.sanitize_path(
                 FileDestinations.LOCAL, payload["path"])
             destination_file = normalize("{}/custom-styles.css".format(
                 self._settings.get(["config_directory"])))
             self._logger.info("attempting copy of {} to {}".format(
                 source_file, destination_file))
             shutil.copyfile(source_file, destination_file)
             self._logger.info(
                 "attempting removal of {}".format(source_file))
             self._file_manager.remove_file(FileDestinations.LOCAL,
                                            payload["path"])
Ejemplo n.º 2
0
def utilTestPath():
	valid_commands = dict(
		path=["path"],
		url=["url"],
		server=["host", "port"]
	)

	command, data, response = get_json_command_from_request(request, valid_commands)
	if response is not None:
		return response

	if command == "path":
		import os
		from octoprint.util.paths import normalize

		path = normalize(data["path"])
		if not path:
			return jsonify(path=path, exists=False, typeok=False, access=False, result=False)

		check_type = None
		check_access = []

		if "check_type" in data and data["check_type"] in ("file", "dir"):
			check_type = data["check_type"]

		if "check_access" in data:
			request_check_access = data["check_access"]
			if not isinstance(request_check_access, list):
				request_check_access = list(request_check_access)

			check_access = [check for check in request_check_access if check in ("r", "w", "x")]

		exists = os.path.exists(path)

		# check if path exists
		type_mapping = dict(file=os.path.isfile, dir=os.path.isdir)
		if check_type:
			typeok = type_mapping[check_type](path)
		else:
			typeok = exists

		# check if path allows requested access
		access_mapping = dict(r=os.R_OK, w=os.W_OK, x=os.X_OK)
		if check_access:
			access = os.access(path, reduce(lambda x, y: x | y, map(lambda a: access_mapping[a], check_access)))
		else:
			access = exists

		return jsonify(path=path, exists=exists, typeok=typeok, access=access, result=exists and typeok and access)

	elif command == "url":
		import requests

		class StatusCodeRange(object):
			def __init__(self, start=None, end=None):
				self.start = start
				self.end = end

			def __contains__(self, item):
				if not isinstance(item, int):
					return False
				if self.start and self.end:
					return self.start <= item < self.end
				elif self.start:
					return self.start <= item
				elif self.end:
					return item < self.end
				else:
					return False

			def as_dict(self):
				return dict(
					start=self.start,
					end=self.end
				)

		status_ranges = dict(
			informational=StatusCodeRange(start=100,end=200),
			success=StatusCodeRange(start=200,end=300),
			redirection=StatusCodeRange(start=300,end=400),
			client_error=StatusCodeRange(start=400,end=500),
			server_error=StatusCodeRange(start=500,end=600),
			normal=StatusCodeRange(end=400),
			error=StatusCodeRange(start=400,end=600),
			any=StatusCodeRange(start=100),
			timeout=StatusCodeRange(start=0, end=1)
		)

		url = data["url"]
		method = data.get("method", "HEAD")
		timeout = 3.0
		valid_ssl = True
		check_status = [status_ranges["normal"]]

		if "timeout" in data:
			try:
				timeout = float(data["timeout"])
			except:
				return make_response("{!r} is not a valid value for timeout (must be int or float)".format(data["timeout"]), 400)

		if "validSsl" in data:
			valid_ssl = data["validSsl"] in valid_boolean_trues

		if "status" in data:
			request_status = data["status"]
			if not isinstance(request_status, list):
				request_status = [request_status]

			check_status = []
			for rs in request_status:
				if isinstance(rs, int):
					check_status.append([rs])
				else:
					if rs in status_ranges:
						check_status.append(status_ranges[rs])
					else:
						code = requests.codes[rs]
						if code is not None:
							check_status.append([code])

		try:
			response = requests.request(method=method, url=url, timeout=timeout, verify=valid_ssl)
			status = response.status_code
		except:
			status = 0

		result = dict(
			url=url,
			status=status,
			result=any(map(lambda x: status in x, check_status))
		)

		if "response" in data and (data["response"] in valid_boolean_trues or data["response"] in ("json", "bytes")):

			import base64
			content = base64.standard_b64encode(response.content)

			if data["response"] == "json":
				try:
					content = response.json()
				except:
					logging.getLogger(__name__).exception("Couldn't convert response to json")
					result["result"] = False

			result["response"] = dict(
				headers=dict(response.headers),
				content=content
			)
		return jsonify(**result)

	elif command == "server":
		host = data["host"]
		try:
			port = int(data["port"])
		except:
			return make_response("{!r} is not a valid value for port (must be int)".format(data["port"]), 400)

		timeout = 3.05
		if "timeout" in data:
			try:
				timeout = float(data["timeout"])
			except:
				return make_response("{!r} is not a valid value for timeout (must be int or float)".format(data["timeout"]), 400)

		protocol = data.get("protocol", "tcp")
		if protocol not in ("tcp", "udp"):
			return make_response("{!r} is not a valid value for protocol, must be tcp or udp".format(protocol), 400)

		from octoprint.util import server_reachable
		reachable = server_reachable(host, port, timeout=timeout, proto=protocol)

		result = dict(host=host,
		              port=port,
		              protocol=protocol,
		              result=reachable)

		return jsonify(**result)
Ejemplo n.º 3
0
def _test_path(data):
    import os

    from octoprint.util.paths import normalize

    path = normalize(data["path"], real=False)
    if not path:
        return jsonify(
            path=path,
            exists=False,
            typeok=False,
            broken_symlink=False,
            access=False,
            result=False,
        )

    unreal_path = path
    path = os.path.realpath(path)

    check_type = None
    check_access = []

    if "check_type" in data and data["check_type"] in ("file", "dir"):
        check_type = data["check_type"]

    if "check_access" in data:
        request_check_access = data["check_access"]
        if not isinstance(request_check_access, list):
            request_check_access = list(request_check_access)

        check_access = [
            check for check in request_check_access if check in ("r", "w", "x")
        ]

    allow_create_dir = data.get("allow_create_dir",
                                False) and check_type == "dir"
    check_writable_dir = data.get("check_writable_dir",
                                  False) and check_type == "dir"
    if check_writable_dir and "w" not in check_access:
        check_access.append("w")

    # check if path exists
    exists = os.path.exists(path)
    if not exists:
        if os.path.islink(unreal_path):
            # broken symlink, see #2644
            logging.getLogger(__name__).error(
                "{} is a broken symlink pointing at non existing {}".format(
                    unreal_path, path))
            return jsonify(
                path=unreal_path,
                exists=False,
                typeok=False,
                broken_symlink=True,
                access=False,
                result=False,
            )

        elif check_type == "dir" and allow_create_dir:
            try:
                os.makedirs(path)
            except Exception:
                logging.getLogger(__name__).exception(
                    "Error while trying to create {}".format(path))
                return jsonify(
                    path=path,
                    exists=False,
                    typeok=False,
                    broken_symlink=False,
                    access=False,
                    result=False,
                )
            else:
                exists = True

    # check path type
    type_mapping = {"file": os.path.isfile, "dir": os.path.isdir}
    if check_type:
        typeok = type_mapping[check_type](path)
    else:
        typeok = exists

    # check if path allows requested access
    access_mapping = {"r": os.R_OK, "w": os.W_OK, "x": os.X_OK}
    if check_access:
        mode = 0
        for a in map(lambda x: access_mapping[x], check_access):
            mode |= a
        access = os.access(path, mode)
    else:
        access = exists

    if check_writable_dir and check_type == "dir":
        try:
            test_path = os.path.join(path, ".testballoon.txt")
            with io.open(test_path, "wb") as f:
                f.write(b"Test")
            os.remove(test_path)
        except Exception:
            logging.getLogger(__name__).exception(
                "Error while testing if {} is really writable".format(path))
            return jsonify(
                path=path,
                exists=exists,
                typeok=typeok,
                broken_symlink=False,
                access=False,
                result=False,
            )

    return jsonify(
        path=path,
        exists=exists,
        typeok=typeok,
        broken_symlink=False,
        access=access,
        result=exists and typeok and access,
    )
Ejemplo n.º 4
0
def utilTestPath():
	valid_commands = dict(
		path=["path"],
		url=["url"],
		server=["host", "port"]
	)

	command, data, response = get_json_command_from_request(request, valid_commands)
	if response is not None:
		return response

	if command == "path":
		import os
		from octoprint.util.paths import normalize

		path = normalize(data["path"])
		if not path:
			return jsonify(path=path, exists=False, typeok=False, access=False, result=False)

		check_type = None
		check_access = []

		if "check_type" in data and data["check_type"] in ("file", "dir"):
			check_type = data["check_type"]

		if "check_access" in data:
			request_check_access = data["check_access"]
			if not isinstance(request_check_access, list):
				request_check_access = list(request_check_access)

			check_access = [check for check in request_check_access if check in ("r", "w", "x")]

		exists = os.path.exists(path)

		# check if path exists
		type_mapping = dict(file=os.path.isfile, dir=os.path.isdir)
		if check_type:
			typeok = type_mapping[check_type](path)
		else:
			typeok = exists

		# check if path allows requested access
		access_mapping = dict(r=os.R_OK, w=os.W_OK, x=os.X_OK)
		if check_access:
			access = os.access(path, reduce(lambda x, y: x | y, map(lambda a: access_mapping[a], check_access)))
		else:
			access = exists

		return jsonify(path=path, exists=exists, typeok=typeok, access=access, result=exists and typeok and access)

	elif command == "url":
		import requests

		class StatusCodeRange(object):
			def __init__(self, start=None, end=None):
				self.start = start
				self.end = end

			def __contains__(self, item):
				if not isinstance(item, int):
					return False
				if self.start and self.end:
					return self.start <= item < self.end
				elif self.start:
					return self.start <= item
				elif self.end:
					return item < self.end
				else:
					return False

			def as_dict(self):
				return dict(
					start=self.start,
					end=self.end
				)

		status_ranges = dict(
			informational=StatusCodeRange(start=100,end=200),
			success=StatusCodeRange(start=200,end=300),
			redirection=StatusCodeRange(start=300,end=400),
			client_error=StatusCodeRange(start=400,end=500),
			server_error=StatusCodeRange(start=500,end=600),
			normal=StatusCodeRange(end=400),
			error=StatusCodeRange(start=400,end=600),
			any=StatusCodeRange(start=100),
			timeout=StatusCodeRange(start=0, end=1)
		)

		url = data["url"]
		method = data.get("method", "HEAD")
		timeout = 3.0
		check_status = [status_ranges["normal"]]

		if "timeout" in data:
			try:
				timeout = float(data["timeout"])
			except:
				return make_response("{!r} is not a valid value for timeout (must be int or float)".format(data["timeout"]), 400)

		if "status" in data:
			request_status = data["status"]
			if not isinstance(request_status, list):
				request_status = [request_status]

			check_status = []
			for rs in request_status:
				if isinstance(rs, int):
					check_status.append([rs])
				else:
					if rs in status_ranges:
						check_status.append(status_ranges[rs])
					else:
						code = requests.codes[rs]
						if code is not None:
							check_status.append([code])

		try:
			response = requests.request(method=method, url=url, timeout=timeout)
			status = response.status_code
		except:
			status = 0

		result = dict(
			url=url,
			status=status,
			result=any(map(lambda x: status in x, check_status))
		)

		if "response" in data and (data["response"] in valid_boolean_trues or data["response"] in ("json", "bytes")):

			import base64
			content = base64.standard_b64encode(response.content)

			if data["response"] == "json":
				try:
					content = response.json()
				except:
					logging.getLogger(__name__).exception("Couldn't convert response to json")
					result["result"] = False

			result["response"] = dict(
				headers=dict(response.headers),
				content=content
			)
		return jsonify(**result)

	elif command == "server":
		host = data["host"]
		try:
			port = int(data["port"])
		except:
			return make_response("{!r} is not a valid value for port (must be int)".format(data["port"]), 400)
		
		timeout = 3.05
		if "timeout" in data:
			try:
				timeout = float(data["timeout"])
			except:
				return make_response("{!r} is not a valid value for timeout (must be int or float)".format(data["timeout"]), 400)
		
		protocol = data.get("protocol", "tcp")
		if protocol not in ("tcp", "udp"):
			return make_response("{!r} is not a valid value for protocol, must be tcp or udp".format(protocol), 400)
		
		from octoprint.util import server_reachable
		reachable = server_reachable(host, port, timeout=timeout, proto=protocol)
		
		result = dict(host=host,
		              port=port,
		              protocol=protocol,
		              result=reachable)
		
		return jsonify(**result)
Ejemplo n.º 5
0
def _test_path(data):
	import os
	from octoprint.util.paths import normalize

	path = normalize(data["path"], real=False)
	if not path:
		return jsonify(path=path, exists=False, typeok=False, broken_symlink=False, access=False, result=False)

	unreal_path = path
	path = os.path.realpath(path)

	check_type = None
	check_access = []

	if "check_type" in data and data["check_type"] in ("file", "dir"):
		check_type = data["check_type"]

	if "check_access" in data:
		request_check_access = data["check_access"]
		if not isinstance(request_check_access, list):
			request_check_access = list(request_check_access)

		check_access = [check for check in request_check_access if check in ("r", "w", "x")]

	allow_create_dir = data.get("allow_create_dir", False) and check_type == "dir"
	check_writable_dir = data.get("check_writable_dir", False) and check_type == "dir"
	if check_writable_dir and "w" not in check_access:
		check_access.append("w")

	# check if path exists
	exists = os.path.exists(path)
	if not exists:
		if os.path.islink(unreal_path):
			# broken symlink, see #2644
			logging.getLogger(__name__).error("{} is a broken symlink pointing at non existing {}".format(unreal_path, path))
			return jsonify(path=unreal_path, exists=False, typeok=False, broken_symlink=True, access=False, result=False)

		elif check_type == "dir" and allow_create_dir:
			try:
				os.makedirs(path)
			except:
				logging.getLogger(__name__).exception("Error while trying to create {}".format(path))
				return jsonify(path=path, exists=False, typeok=False, broken_symlink=False, access=False, result=False)
			else:
				exists = True

	# check path type
	type_mapping = dict(file=os.path.isfile, dir=os.path.isdir)
	if check_type:
		typeok = type_mapping[check_type](path)
	else:
		typeok = exists

	# check if path allows requested access
	access_mapping = dict(r=os.R_OK, w=os.W_OK, x=os.X_OK)
	if check_access:
		mode = 0
		for a in map(lambda x: access_mapping[x], check_access):
			mode |= a
		access = os.access(path, mode)
	else:
		access = exists

	if check_writable_dir and check_type == "dir":
		try:
			test_path = os.path.join(path, ".testballoon.txt")
			with open(test_path, "wb") as f:
				f.write("Test")
			os.remove(test_path)
		except:
			logging.getLogger(__name__).exception("Error while testing if {} is really writable".format(path))
			return jsonify(path=path, exists=exists, typeok=typeok, broken_symlink=False, access=False, result=False)

	return jsonify(path=path, exists=exists, typeok=typeok, broken_symlink=False, access=access, result=exists and typeok and access)
Ejemplo n.º 6
0
 def get_settings_defaults(self):
     return dict(config_directory=normalize(_default_configdir("octodash")))
Ejemplo n.º 7
0
 def __init__(self):
     self.config_file = normalize("{}/config.json".format(
         _default_configdir("octodash")))