Exemplo n.º 1
0
def uploadFirmwareFile(target):
	print("lkj uploadFirmwareFile target:%s" % str(target))
	target = FileDestinations.LOCAL
	if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
		return make_response("Unknown target: %s" % target, 404)
	
	print("lkj post target:%s" % str(target))
	print("lkj post request.values:%s" % str(request.values))
	print("lkj post request.files:%s" % str(request.files))
	
	input_name = "file"
	input_upload_name = input_name + "." + settings().get(["server", "uploads", "nameSuffix"])
	input_upload_path = input_name + "." + settings().get(["server", "uploads", "pathSuffix"])
	if input_upload_name in request.values and input_upload_path in request.values:
		print("lkj here 1")
		import shutil
		upload = util.Object()
		upload.filename = request.values[input_upload_name]
		upload.save = lambda new_path: shutil.move(request.values[input_upload_path], new_path)
	elif input_name in request.files:
		print("lkj here 2")
		upload = request.files[input_name]
	else:
		return make_response("No file included", 400)
	print("lkj post 2")
	# determine future filename of file to be uploaded, abort if it can't be uploaded
	try:
		futureFilename = fileManager.sanitize_name(FileDestinations.LOCAL, upload.filename)
	except:
		futureFilename = None
		
	print("lkj futureFilename:%s" % futureFilename)
	
	try :
		added_file = fileManager.add_firmware_file(FileDestinations.LOCAL, upload.filename, upload, allow_overwrite=True)
	except :
		added_file = None
	if added_file is None:
		print("lkj post added_file is None")
		return make_response("Could not upload the file %s" % upload.filename, 500)
	print("lkj added_file: %s" % added_file)
	
	files = {}
	done = True
	files.update({
		FileDestinations.LOCAL: {
			"name": added_file,
			"origin": FileDestinations.LOCAL		
		}
	})
	r = make_response(jsonify(files=files, done=done), 201)
	#lkj 
	from octoprint.server import printer
	if printer.isOperational():
		#cmd = ("M205", param=added_file)
		#printer.command()
		pass
			
	#r.headers["Location"] = added_file
	return r
Exemplo n.º 2
0
def _validate(target, filename):
    if target == FileDestinations.SDCARD:
        # we make no assumptions about the shape of valid SDCard file names
        return True
    else:
        return filename == "/".join(
            map(lambda x: fileManager.sanitize_name(target, x),
                filename.split("/")))
Exemplo n.º 3
0
def upload_temp_curve_firmware(target):
    print("lkj upload_temp_curve_firmware target:%s" % str(target))

    print("lkj post request.values:%s" % str(request.values))
    print("lkj post request.files:%s" % str(request.files))

    input_name = "file"
    input_upload_name = input_name + "." + settings().get(
        ["server", "uploads", "nameSuffix"])
    input_upload_path = input_name + "." + settings().get(
        ["server", "uploads", "pathSuffix"])
    if input_upload_name in request.values and input_upload_path in request.values:
        print("lkj here 1")
        import shutil
        upload = util.Object()
        upload.filename = request.values[input_upload_name]
        upload.save = lambda new_path: shutil.move(
            request.values[input_upload_path], new_path)
    elif input_name in request.files:
        print("lkj here 2")
        upload = request.files[input_name]
    else:
        return make_response("No file included", 400)
    print("lkj post 2")
    # determine future filename of file to be uploaded, abort if it can't be uploaded
    try:
        futureFilename = fileManager.sanitize_name(FileDestinations.LOCAL,
                                                   upload.filename)
    except:
        futureFilename = None

    print("lkj futureFilename:%s" % futureFilename)

    try:
        added_file = fileManager.add_temp_curve_file(FileDestinations.LOCAL,
                                                     upload.filename,
                                                     upload,
                                                     allow_overwrite=True,
                                                     target=target)
    except:
        added_file = None
    if added_file is None:
        print("lkj post added_file is None")
        return make_response("Could not upload the file %s" % upload.filename,
                             500)
    print("lkj added_file: %s" % added_file)

    files = {}
    done = True
    files.update({
        FileDestinations.LOCAL: {
            "name": added_file,
            "origin": FileDestinations.LOCAL
        }
    })
    r = make_response(jsonify(files=files, done=done), 201)
    return r
Exemplo n.º 4
0
def upload_temp_curve_firmware(target):
	print("lkj upload_temp_curve_firmware target:%s" % str(target))

	print("lkj post request.values:%s" % str(request.values))
	print("lkj post request.files:%s" % str(request.files))
	
	input_name = "file"
	input_upload_name = input_name + "." + settings().get(["server", "uploads", "nameSuffix"])
	input_upload_path = input_name + "." + settings().get(["server", "uploads", "pathSuffix"])
	if input_upload_name in request.values and input_upload_path in request.values:
		print("lkj here 1")
		import shutil
		upload = util.Object()
		upload.filename = request.values[input_upload_name]
		upload.save = lambda new_path: shutil.move(request.values[input_upload_path], new_path)
	elif input_name in request.files:
		print("lkj here 2")
		upload = request.files[input_name]
	else:
		return make_response("No file included", 400)
	print("lkj post 2")
	# determine future filename of file to be uploaded, abort if it can't be uploaded
	try:
		futureFilename = fileManager.sanitize_name(FileDestinations.LOCAL, upload.filename)
	except:
		futureFilename = None
		
	print("lkj futureFilename:%s" % futureFilename)
	
	try :
		added_file = fileManager.add_temp_curve_file(FileDestinations.LOCAL, upload.filename, upload, allow_overwrite=True, target=target)
	except :
		added_file = None
	if added_file is None:
		print("lkj post added_file is None")
		return make_response("Could not upload the file %s" % upload.filename, 500)
	print("lkj added_file: %s" % added_file)
	
	files = {}
	done = True
	files.update({
		FileDestinations.LOCAL: {
			"name": added_file,
			"origin": FileDestinations.LOCAL		
		}
	})
	r = make_response(jsonify(files=files, done=done), 201)	
	return r
Exemplo n.º 5
0
def runFilesTest():
    valid_commands = {
        "sanitize": ["storage", "path", "filename"],
        "exists": ["storage", "path", "filename"],
    }

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

    def sanitize(storage, path, filename):
        sanitized_path = fileManager.sanitize_path(storage, path)
        sanitized_name = fileManager.sanitize_name(storage, filename)
        joined = fileManager.join_path(storage, sanitized_path, sanitized_name)
        return sanitized_path, sanitized_name, joined

    if command == "sanitize":
        _, _, sanitized = sanitize(data["storage"], data["path"],
                                   data["filename"])
        return jsonify(sanitized=sanitized)
    elif command == "exists":
        storage = data["storage"]
        path = data["path"]
        filename = data["filename"]

        sanitized_path, _, sanitized = sanitize(storage, path, filename)

        exists = fileManager.file_exists(storage, sanitized)
        if exists:
            suggestion = filename
            name, ext = os.path.splitext(filename)
            counter = 0
            while fileManager.file_exists(
                    storage,
                    fileManager.join_path(
                        storage,
                        sanitized_path,
                        fileManager.sanitize_name(storage, suggestion),
                    ),
            ):
                counter += 1
                suggestion = name + "_{}".format(counter) + ext
            return jsonify(exists=True, suggestion=suggestion)
        else:
            return jsonify(exists=False)
Exemplo n.º 6
0
def uploadGcodeFile(target):
	if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
		return make_response("Unknown target: %s" % target, 404)

	input_name = "file"
	input_upload_name = input_name + "." + settings().get(["server", "uploads", "nameSuffix"])
	input_upload_path = input_name + "." + settings().get(["server", "uploads", "pathSuffix"])
	if input_upload_name in request.values and input_upload_path in request.values:
		upload = octoprint.filemanager.util.DiskFileWrapper(request.values[input_upload_name], request.values[input_upload_path])
	else:
		return make_response("No file included", 400)

	# Store any additional user data the caller may have passed.
	userdata = None
	if "userdata" in request.values:
		import json
		try:
			userdata = json.loads(request.values["userdata"])
		except:
			return make_response("userdata contains invalid JSON", 400)

	if target == FileDestinations.SDCARD and not settings().getBoolean(["feature", "sdSupport"]):
		return make_response("SD card support is disabled", 404)

	sd = target == FileDestinations.SDCARD
	selectAfterUpload = "select" in request.values.keys() and request.values["select"] in valid_boolean_trues
	printAfterSelect = "print" in request.values.keys() and request.values["print"] in valid_boolean_trues

	if sd:
		# validate that all preconditions for SD upload are met before attempting it
		if not (printer.is_operational() and not (printer.is_printing() or printer.is_paused())):
			return make_response("Can not upload to SD card, printer is either not operational or already busy", 409)
		if not printer.is_sd_ready():
			return make_response("Can not upload to SD card, not yet initialized", 409)

	# determine current job
	currentFilename = None
	currentOrigin = None
	currentJob = printer.get_current_job()
	if currentJob is not None and "file" in currentJob.keys():
		currentJobFile = currentJob["file"]
		if "name" in currentJobFile.keys() and "origin" in currentJobFile.keys():
			currentFilename = currentJobFile["name"]
			currentOrigin = currentJobFile["origin"]

	# determine future filename of file to be uploaded, abort if it can't be uploaded
	try:
		futureFilename = fileManager.sanitize_name(FileDestinations.LOCAL, upload.filename)
	except:
		futureFilename = None
	if futureFilename is None:
		return make_response("Can not upload file %s, wrong format?" % upload.filename, 415)

	# prohibit overwriting currently selected file while it's being printed
	if futureFilename == currentFilename and target == currentOrigin and printer.is_printing() or printer.is_paused():
		return make_response("Trying to overwrite file that is currently being printed: %s" % currentFilename, 409)

	def fileProcessingFinished(filename, absFilename, destination):
		"""
		Callback for when the file processing (upload, optional slicing, addition to analysis queue) has
		finished.

		Depending on the file's destination triggers either streaming to SD card or directly calls selectAndOrPrint.
		"""

		if destination == FileDestinations.SDCARD and octoprint.filemanager.valid_file_type(filename, "gcode"):
			return filename, printer.add_sd_file(filename, absFilename, selectAndOrPrint)
		else:
			selectAndOrPrint(filename, absFilename, destination)
			return filename

	def selectAndOrPrint(filename, absFilename, destination):
		"""
		Callback for when the file is ready to be selected and optionally printed. For SD file uploads this is only
		the case after they have finished streaming to the printer, which is why this callback is also used
		for the corresponding call to addSdFile.

		Selects the just uploaded file if either selectAfterUpload or printAfterSelect are True, or if the
		exact file is already selected, such reloading it.
		"""
		if octoprint.filemanager.valid_file_type(added_file, "gcode") and (selectAfterUpload or printAfterSelect or (currentFilename == filename and currentOrigin == destination)):
			printer.select_file(absFilename, destination == FileDestinations.SDCARD, printAfterSelect)

	added_file = fileManager.add_file(FileDestinations.LOCAL, upload.filename, upload, allow_overwrite=True)
	if added_file is None:
		return make_response("Could not upload the file %s" % upload.filename, 500)
	if octoprint.filemanager.valid_file_type(added_file, "stl"):
		filename = added_file
		done = True
	else:
		filename = fileProcessingFinished(added_file, fileManager.path_on_disk(FileDestinations.LOCAL, added_file), target)
		done = not sd

	if userdata is not None:
		# upload included userdata, add this now to the metadata
		fileManager.set_additional_metadata(FileDestinations.LOCAL, added_file, "userdata", userdata)

	sdFilename = None
	if isinstance(filename, tuple):
		filename, sdFilename = filename

	eventManager.fire(Events.UPLOAD, {"file": filename, "target": target})

	files = {}
	location = url_for(".readGcodeFile", target=FileDestinations.LOCAL, filename=filename, _external=True)
	files.update({
		FileDestinations.LOCAL: {
			"name": filename,
			"origin": FileDestinations.LOCAL,
			"refs": {
				"resource": location,
				"download": url_for("index", _external=True) + "downloads/files/" + FileDestinations.LOCAL + "/" + filename
			}
		}
	})

	if sd and sdFilename:
		location = url_for(".readGcodeFile", target=FileDestinations.SDCARD, filename=sdFilename, _external=True)
		files.update({
			FileDestinations.SDCARD: {
				"name": sdFilename,
				"origin": FileDestinations.SDCARD,
				"refs": {
					"resource": location
				}
			}
		})

	r = make_response(jsonify(files=files, done=done), 201)
	r.headers["Location"] = location
	return r
Exemplo n.º 7
0
def gcodeFileCommand(filename, target):
    if target not in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
        abort(404)

    if not _validate(target, filename):
        abort(404)

    # valid file commands, dict mapping command name to mandatory parameters
    valid_commands = {
        "select": [],
        "unselect": [],
        "slice": [],
        "analyse": [],
        "copy": ["destination"],
        "move": ["destination"],
    }

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

    user = current_user.get_name()

    if command == "select":
        with Permissions.FILES_SELECT.require(403):
            if not _verifyFileExists(target, filename):
                abort(404)

            # selects/loads a file
            if not octoprint.filemanager.valid_file_type(filename,
                                                         type="machinecode"):
                abort(
                    415,
                    description=
                    "Cannot select file for printing, not a machinecode file",
                )

            if not printer.is_ready():
                abort(
                    409,
                    description=
                    "Printer is already printing, cannot select a new file",
                )

            printAfterLoading = False
            if "print" in data and data["print"] in valid_boolean_trues:
                with Permissions.PRINT.require(403):
                    if not printer.is_operational():
                        abort(
                            409,
                            description=
                            "Printer is not operational, cannot directly start printing",
                        )
                    printAfterLoading = True

            sd = False
            if target == FileDestinations.SDCARD:
                filenameToSelect = filename
                sd = True
            else:
                filenameToSelect = fileManager.path_on_disk(target, filename)
            printer.select_file(filenameToSelect, sd, printAfterLoading, user)

    elif command == "unselect":
        with Permissions.FILES_SELECT.require(403):
            if not printer.is_ready():
                return make_response(
                    "Printer is already printing, cannot unselect current file",
                    409)

            _, currentFilename = _getCurrentFile()
            if currentFilename is None:
                return make_response(
                    "Cannot unselect current file when there is no file selected",
                    409)

            if filename != currentFilename and filename != "current":
                return make_response(
                    "Only the currently selected file can be unselected", 400)

            printer.unselect_file()

    elif command == "slice":
        with Permissions.SLICE.require(403):
            if not _verifyFileExists(target, filename):
                abort(404)

            try:
                if "slicer" in data:
                    slicer = data["slicer"]
                    del data["slicer"]
                    slicer_instance = slicingManager.get_slicer(slicer)

                elif "cura" in slicingManager.registered_slicers:
                    slicer = "cura"
                    slicer_instance = slicingManager.get_slicer("cura")

                else:
                    abort(415,
                          description="Cannot slice file, no slicer available")
            except octoprint.slicing.UnknownSlicer:
                abort(404)

            if not any([
                    octoprint.filemanager.valid_file_type(
                        filename, type=source_file_type)
                    for source_file_type in slicer_instance.
                    get_slicer_properties().get("source_file_types", ["model"])
            ]):
                abort(415, description="Cannot slice file, not a model file")

            cores = psutil.cpu_count()
            if (slicer_instance.get_slicer_properties().get(
                    "same_device", True)
                    and (printer.is_printing() or printer.is_paused())
                    and (cores is None or cores < 2)):
                # slicer runs on same device as OctoPrint, slicing while printing is hence disabled
                abort(
                    409,
                    description=
                    "Cannot slice on this slicer while printing on single core systems or systems of unknown core count due to performance reasons",
                )

            if "destination" in data and data["destination"]:
                destination = data["destination"]
                del data["destination"]
            elif "gcode" in data and data["gcode"]:
                destination = data["gcode"]
                del data["gcode"]
            else:
                import os

                name, _ = os.path.splitext(filename)
                destination = (
                    name + "." + slicer_instance.get_slicer_properties().get(
                        "destination_extensions", ["gco", "gcode", "g"])[0])

            full_path = destination
            if "path" in data and data["path"]:
                full_path = fileManager.join_path(target, data["path"],
                                                  destination)
            else:
                path, _ = fileManager.split_path(target, filename)
                if path:
                    full_path = fileManager.join_path(target, path,
                                                      destination)

            canon_path, canon_name = fileManager.canonicalize(
                target, full_path)
            sanitized_name = fileManager.sanitize_name(target, canon_name)

            if canon_path:
                full_path = fileManager.join_path(target, canon_path,
                                                  sanitized_name)
            else:
                full_path = sanitized_name

            # prohibit overwriting the file that is currently being printed
            currentOrigin, currentFilename = _getCurrentFile()
            if (currentFilename == full_path and currentOrigin == target
                    and (printer.is_printing() or printer.is_paused())):
                abort(
                    409,
                    description=
                    "Trying to slice into file that is currently being printed",
                )

            if "profile" in data and data["profile"]:
                profile = data["profile"]
                del data["profile"]
            else:
                profile = None

            if "printerProfile" in data and data["printerProfile"]:
                printerProfile = data["printerProfile"]
                del data["printerProfile"]
            else:
                printerProfile = None

            if ("position" in data and data["position"]
                    and isinstance(data["position"], dict)
                    and "x" in data["position"] and "y" in data["position"]):
                position = data["position"]
                del data["position"]
            else:
                position = None

            select_after_slicing = False
            if "select" in data and data["select"] in valid_boolean_trues:
                if not printer.is_operational():
                    abort(
                        409,
                        description=
                        "Printer is not operational, cannot directly select for printing",
                    )
                select_after_slicing = True

            print_after_slicing = False
            if "print" in data and data["print"] in valid_boolean_trues:
                if not printer.is_operational():
                    abort(
                        409,
                        description=
                        "Printer is not operational, cannot directly start printing",
                    )
                select_after_slicing = print_after_slicing = True

            override_keys = [
                k for k in data
                if k.startswith("profile.") and data[k] is not None
            ]
            overrides = {}
            for key in override_keys:
                overrides[key[len("profile."):]] = data[key]

            def slicing_done(target, path, select_after_slicing,
                             print_after_slicing):
                if select_after_slicing or print_after_slicing:
                    sd = False
                    if target == FileDestinations.SDCARD:
                        filenameToSelect = path
                        sd = True
                    else:
                        filenameToSelect = fileManager.path_on_disk(
                            target, path)
                    printer.select_file(filenameToSelect, sd,
                                        print_after_slicing, user)

            try:
                fileManager.slice(
                    slicer,
                    target,
                    filename,
                    target,
                    full_path,
                    profile=profile,
                    printer_profile_id=printerProfile,
                    position=position,
                    overrides=overrides,
                    display=canon_name,
                    callback=slicing_done,
                    callback_args=(
                        target,
                        full_path,
                        select_after_slicing,
                        print_after_slicing,
                    ),
                )
            except octoprint.slicing.UnknownProfile:
                abort(404, description="Unknown profile")

            location = url_for(".readGcodeFile",
                               target=target,
                               filename=full_path,
                               _external=True)
            result = {
                "name": destination,
                "path": full_path,
                "display": canon_name,
                "origin": FileDestinations.LOCAL,
                "refs": {
                    "resource":
                    location,
                    "download":
                    url_for("index", _external=True) + "downloads/files/" +
                    target + "/" + full_path,
                },
            }

            r = make_response(jsonify(result), 202)
            r.headers["Location"] = location
            return r

    elif command == "analyse":
        with Permissions.FILES_UPLOAD.require(403):
            if not _verifyFileExists(target, filename):
                abort(404)

            printer_profile = None
            if "printerProfile" in data and data["printerProfile"]:
                printer_profile = data["printerProfile"]

            if not fileManager.analyse(
                    target, filename, printer_profile_id=printer_profile):
                abort(400, description="No analysis possible")

    elif command == "copy" or command == "move":
        with Permissions.FILES_UPLOAD.require(403):
            # Copy and move are only possible on local storage
            if target not in [FileDestinations.LOCAL]:
                abort(400,
                      description="Unsupported target for {}".format(command))

            if not _verifyFileExists(target,
                                     filename) and not _verifyFolderExists(
                                         target, filename):
                abort(404)

            path, name = fileManager.split_path(target, filename)

            destination = data["destination"]
            dst_path, dst_name = fileManager.split_path(target, destination)
            sanitized_destination = fileManager.join_path(
                target, dst_path, fileManager.sanitize_name(target, dst_name))

            # Check for exception thrown by _verifyFolderExists, if outside the root directory
            try:
                if (_verifyFolderExists(target, destination)
                        and sanitized_destination != filename):
                    # destination is an existing folder and not ourselves (= display rename), we'll assume we are supposed
                    # to move filename to this folder under the same name
                    destination = fileManager.join_path(
                        target, destination, name)

                if _verifyFileExists(target,
                                     destination) or _verifyFolderExists(
                                         target, destination):
                    abort(409, description="File or folder does already exist")

            except Exception:
                abort(409,
                      description=
                      "Exception thrown by storage, bad folder/file name?")

            is_file = fileManager.file_exists(target, filename)
            is_folder = fileManager.folder_exists(target, filename)

            if not (is_file or is_folder):
                abort(400,
                      description="Neither file nor folder, can't {}".format(
                          command))

            if command == "copy":
                # destination already there? error...
                if _verifyFileExists(target,
                                     destination) or _verifyFolderExists(
                                         target, destination):
                    abort(409, description="File or folder does already exist")

                if is_file:
                    fileManager.copy_file(target, filename, destination)
                else:
                    fileManager.copy_folder(target, filename, destination)

            elif command == "move":
                with Permissions.FILES_DELETE.require(403):
                    if _isBusy(target, filename):
                        abort(
                            409,
                            description=
                            "Trying to move a file or folder that is currently in use",
                        )

                    # destination already there AND not ourselves (= display rename)? error...
                    if (_verifyFileExists(target, destination)
                            or _verifyFolderExists(target, destination)
                        ) and sanitized_destination != filename:
                        abort(409,
                              description="File or folder does already exist")

                    # deselect the file if it's currently selected
                    currentOrigin, currentFilename = _getCurrentFile()
                    if currentFilename is not None and filename == currentFilename:
                        printer.unselect_file()

                    if is_file:
                        fileManager.move_file(target, filename, destination)
                    else:
                        fileManager.move_folder(target, filename, destination)

            location = url_for(".readGcodeFile",
                               target=target,
                               filename=destination,
                               _external=True)
            result = {
                "name": name,
                "path": destination,
                "origin": FileDestinations.LOCAL,
                "refs": {
                    "resource": location
                },
            }
            if is_file:
                result["refs"]["download"] = (
                    url_for("index", _external=True) + "downloads/files/" +
                    target + "/" + destination)

            r = make_response(jsonify(result), 201)
            r.headers["Location"] = location
            return r

    return NO_CONTENT
Exemplo n.º 8
0
 def sanitize(storage, path, filename):
     sanitized_path = fileManager.sanitize_path(storage, path)
     sanitized_name = fileManager.sanitize_name(storage, filename)
     joined = fileManager.join_path(storage, sanitized_path, sanitized_name)
     return sanitized_path, sanitized_name, joined
Exemplo n.º 9
0
def uploadGcodeFile(target):
    input_name = "file"
    input_upload_name = (input_name + "." +
                         settings().get(["server", "uploads", "nameSuffix"]))
    input_upload_path = (input_name + "." +
                         settings().get(["server", "uploads", "pathSuffix"]))
    if input_upload_name in request.values and input_upload_path in request.values:
        if target not in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
            abort(404)

        upload = octoprint.filemanager.util.DiskFileWrapper(
            request.values[input_upload_name],
            request.values[input_upload_path])

        # Store any additional user data the caller may have passed.
        userdata = None
        if "userdata" in request.values:
            import json

            try:
                userdata = json.loads(request.values["userdata"])
            except Exception:
                abort(400, description="userdata contains invalid JSON")

        if target == FileDestinations.SDCARD and not settings().getBoolean(
            ["feature", "sdSupport"]):
            abort(404)

        sd = target == FileDestinations.SDCARD
        selectAfterUpload = ("select" in request.values and
                             request.values["select"] in valid_boolean_trues
                             and Permissions.FILES_SELECT.can())
        printAfterSelect = ("print" in request.values
                            and request.values["print"] in valid_boolean_trues
                            and Permissions.PRINT.can())

        if sd:
            # validate that all preconditions for SD upload are met before attempting it
            if not (printer.is_operational()
                    and not (printer.is_printing() or printer.is_paused())):
                abort(
                    409,
                    description=
                    "Can not upload to SD card, printer is either not operational or already busy",
                )
            if not printer.is_sd_ready():
                abort(
                    409,
                    description="Can not upload to SD card, not yet initialized"
                )

        # determine future filename of file to be uploaded, abort if it can't be uploaded
        try:
            # FileDestinations.LOCAL = should normally be target, but can't because SDCard handling isn't implemented yet
            canonPath, canonFilename = fileManager.canonicalize(
                FileDestinations.LOCAL, upload.filename)
            if request.values.get("path"):
                canonPath = request.values.get("path")
            if request.values.get("filename"):
                canonFilename = request.values.get("filename")

            futurePath = fileManager.sanitize_path(FileDestinations.LOCAL,
                                                   canonPath)
            futureFilename = fileManager.sanitize_name(FileDestinations.LOCAL,
                                                       canonFilename)
        except Exception:
            canonFilename = None
            futurePath = None
            futureFilename = None

        if futureFilename is None:
            abort(415, description="Can not upload file, wrong format?")

        # prohibit overwriting currently selected file while it's being printed
        futureFullPath = fileManager.join_path(FileDestinations.LOCAL,
                                               futurePath, futureFilename)
        futureFullPathInStorage = fileManager.path_in_storage(
            FileDestinations.LOCAL, futureFullPath)

        if not printer.can_modify_file(futureFullPathInStorage, sd):
            abort(
                409,
                description=
                "Trying to overwrite file that is currently being printed",
            )

        if (fileManager.file_exists(FileDestinations.LOCAL,
                                    futureFullPathInStorage)
                and request.values.get("noOverwrite") in valid_boolean_trues):
            abort(409,
                  description="File already exists and noOverwrite was set")

        reselect = printer.is_current_file(futureFullPathInStorage, sd)

        user = current_user.get_name()

        def fileProcessingFinished(filename, absFilename, destination):
            """
            Callback for when the file processing (upload, optional slicing, addition to analysis queue) has
            finished.

            Depending on the file's destination triggers either streaming to SD card or directly calls selectAndOrPrint.
            """

            if (destination == FileDestinations.SDCARD
                    and octoprint.filemanager.valid_file_type(
                        filename, "machinecode")):
                return filename, printer.add_sd_file(
                    filename,
                    absFilename,
                    on_success=selectAndOrPrint,
                    tags={"source:api", "api:files.sd"},
                )
            else:
                selectAndOrPrint(filename, absFilename, destination)
                return filename

        def selectAndOrPrint(filename, absFilename, destination):
            """
            Callback for when the file is ready to be selected and optionally printed. For SD file uploads this is only
            the case after they have finished streaming to the printer, which is why this callback is also used
            for the corresponding call to addSdFile.

            Selects the just uploaded file if either selectAfterUpload or printAfterSelect are True, or if the
            exact file is already selected, such reloading it.
            """
            if octoprint.filemanager.valid_file_type(
                    added_file, "gcode") and (selectAfterUpload
                                              or printAfterSelect or reselect):
                printer.select_file(
                    absFilename,
                    destination == FileDestinations.SDCARD,
                    printAfterSelect,
                    user,
                )

        try:
            added_file = fileManager.add_file(
                FileDestinations.LOCAL,
                futureFullPathInStorage,
                upload,
                allow_overwrite=True,
                display=canonFilename,
            )
        except octoprint.filemanager.storage.StorageError as e:
            if e.code == octoprint.filemanager.storage.StorageError.INVALID_FILE:
                abort(400, description="Could not upload file, invalid type")
            else:
                abort(500, description="Could not upload file")

        if octoprint.filemanager.valid_file_type(added_file, "stl"):
            filename = added_file
            done = True
        else:
            filename = fileProcessingFinished(
                added_file,
                fileManager.path_on_disk(FileDestinations.LOCAL, added_file),
                target,
            )
            done = not sd

        if userdata is not None:
            # upload included userdata, add this now to the metadata
            fileManager.set_additional_metadata(FileDestinations.LOCAL,
                                                added_file, "userdata",
                                                userdata)

        sdFilename = None
        if isinstance(filename, tuple):
            filename, sdFilename = filename

        payload = {
            "name": futureFilename,
            "path": filename,
            "target": target,
            "select": selectAfterUpload,
            "print": printAfterSelect,
        }
        if userdata is not None:
            payload["userdata"] = userdata
        eventManager.fire(Events.UPLOAD, payload)

        files = {}
        location = url_for(
            ".readGcodeFile",
            target=FileDestinations.LOCAL,
            filename=filename,
            _external=True,
        )
        files.update({
            FileDestinations.LOCAL: {
                "name": futureFilename,
                "path": filename,
                "origin": FileDestinations.LOCAL,
                "refs": {
                    "resource":
                    location,
                    "download":
                    url_for("index", _external=True) + "downloads/files/" +
                    FileDestinations.LOCAL + "/" + urlquote(filename),
                },
            }
        })

        if sd and sdFilename:
            location = url_for(
                ".readGcodeFile",
                target=FileDestinations.SDCARD,
                filename=sdFilename,
                _external=True,
            )
            files.update({
                FileDestinations.SDCARD: {
                    "name": sdFilename,
                    "path": sdFilename,
                    "origin": FileDestinations.SDCARD,
                    "refs": {
                        "resource": location
                    },
                }
            })

        r = make_response(jsonify(files=files, done=done), 201)
        r.headers["Location"] = location
        return r

    elif "foldername" in request.values:
        foldername = request.values["foldername"]

        if target not in [FileDestinations.LOCAL]:
            abort(400, description="target is invalid")

        canonPath, canonName = fileManager.canonicalize(target, foldername)
        futurePath = fileManager.sanitize_path(target, canonPath)
        futureName = fileManager.sanitize_name(target, canonName)
        if not futureName or not futurePath:
            abort(400, description="folder name is empty")

        if "path" in request.values and request.values["path"]:
            futurePath = fileManager.sanitize_path(FileDestinations.LOCAL,
                                                   request.values["path"])

        futureFullPath = fileManager.join_path(target, futurePath, futureName)
        if octoprint.filemanager.valid_file_type(futureName):
            abort(409,
                  description="Can't create folder, please try another name")

        try:
            added_folder = fileManager.add_folder(target,
                                                  futureFullPath,
                                                  display=canonName)
        except octoprint.filemanager.storage.StorageError as e:
            if e.code == octoprint.filemanager.storage.StorageError.INVALID_DIRECTORY:
                abort(400,
                      description="Could not create folder, invalid directory")
            else:
                abort(500, description="Could not create folder")

        location = url_for(
            ".readGcodeFile",
            target=FileDestinations.LOCAL,
            filename=added_folder,
            _external=True,
        )
        folder = {
            "name": futureName,
            "path": added_folder,
            "origin": target,
            "refs": {
                "resource": location
            },
        }

        r = make_response(jsonify(folder=folder, done=True), 201)
        r.headers["Location"] = location
        return r

    else:
        abort(400, description="No file to upload and no folder to create")
Exemplo n.º 10
0
def gcodeFileCommand(filename, target):
	if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
		return make_response("Unknown target: %s" % target, 404)

	# valid file commands, dict mapping command name to mandatory parameters
	valid_commands = {
		"select": [],
		"slice": [],
		"analyse": [],
		"copy": ["destination"],
		"move": ["destination"]
	}

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

	if command == "select":
		if not _verifyFileExists(target, filename):
			return make_response("File not found on '%s': %s" % (target, filename), 404)

		# selects/loads a file
		if not octoprint.filemanager.valid_file_type(filename, type="machinecode"):
			return make_response("Cannot select {filename} for printing, not a machinecode file".format(**locals()), 415)

		printAfterLoading = False
		if "print" in data.keys() and data["print"] in valid_boolean_trues:
			if not printer.is_operational():
				return make_response("Printer is not operational, cannot directly start printing", 409)
			printAfterLoading = True

		sd = False
		if target == FileDestinations.SDCARD:
			filenameToSelect = filename
			sd = True
		else:
			filenameToSelect = fileManager.path_on_disk(target, filename)
		printer.select_file(filenameToSelect, sd, printAfterLoading)

	elif command == "slice":
		if not _verifyFileExists(target, filename):
			return make_response("File not found on '%s': %s" % (target, filename), 404)

		try:
			if "slicer" in data:
				slicer = data["slicer"]
				del data["slicer"]
				slicer_instance = slicingManager.get_slicer(slicer)

			elif "cura" in slicingManager.registered_slicers:
				slicer = "cura"
				slicer_instance = slicingManager.get_slicer("cura")

			else:
				return make_response("Cannot slice {filename}, no slicer available".format(**locals()), 415)
		except octoprint.slicing.UnknownSlicer as e:
			return make_response("Slicer {slicer} is not available".format(slicer=e.slicer), 400)

		if not any([octoprint.filemanager.valid_file_type(filename, type=source_file_type) for source_file_type in slicer_instance.get_slicer_properties().get("source_file_types", ["model"])]):
			return make_response("Cannot slice {filename}, not a model file".format(**locals()), 415)

		if slicer_instance.get_slicer_properties().get("same_device", True) and (printer.is_printing() or printer.is_paused()):
			# slicer runs on same device as OctoPrint, slicing while printing is hence disabled
			return make_response("Cannot slice on {slicer} while printing due to performance reasons".format(**locals()), 409)

		if "destination" in data and data["destination"]:
			destination = data["destination"]
			del data["destination"]
		elif "gcode" in data and data["gcode"]:
			destination = data["gcode"]
			del data["gcode"]
		else:
			import os
			name, _ = os.path.splitext(filename)
			destination = name + "." + slicer_instance.get_slicer_properties().get("destination_extensions", ["gco", "gcode", "g"])[0]

		full_path = destination
		if "path" in data and data["path"]:
			full_path = fileManager.join_path(target, data["path"], destination)
		else:
			path, _ = fileManager.split_path(target, filename)
			if path:
				full_path = fileManager.join_path(target, path, destination)

		canon_path, canon_name = fileManager.canonicalize(target, full_path)
		sanitized_name = fileManager.sanitize_name(target, canon_name)

		if canon_path:
			full_path = fileManager.join_path(target, canon_path, sanitized_name)
		else:
			full_path = sanitized_name

		# prohibit overwriting the file that is currently being printed
		currentOrigin, currentFilename = _getCurrentFile()
		if currentFilename == full_path and currentOrigin == target and (printer.is_printing() or printer.is_paused()):
			make_response("Trying to slice into file that is currently being printed: %s" % full_path, 409)

		if "profile" in data.keys() and data["profile"]:
			profile = data["profile"]
			del data["profile"]
		else:
			profile = None

		if "printerProfile" in data.keys() and data["printerProfile"]:
			printerProfile = data["printerProfile"]
			del data["printerProfile"]
		else:
			printerProfile = None

		if "position" in data.keys() and data["position"] and isinstance(data["position"], dict) and "x" in data["position"] and "y" in data["position"]:
			position = data["position"]
			del data["position"]
		else:
			position = None

		select_after_slicing = False
		if "select" in data.keys() and data["select"] in valid_boolean_trues:
			if not printer.is_operational():
				return make_response("Printer is not operational, cannot directly select for printing", 409)
			select_after_slicing = True

		print_after_slicing = False
		if "print" in data.keys() and data["print"] in valid_boolean_trues:
			if not printer.is_operational():
				return make_response("Printer is not operational, cannot directly start printing", 409)
			select_after_slicing = print_after_slicing = True

		override_keys = [k for k in data if k.startswith("profile.") and data[k] is not None]
		overrides = dict()
		for key in override_keys:
			overrides[key[len("profile."):]] = data[key]

		def slicing_done(target, path, select_after_slicing, print_after_slicing):
			if select_after_slicing or print_after_slicing:
				sd = False
				if target == FileDestinations.SDCARD:
					filenameToSelect = path
					sd = True
				else:
					filenameToSelect = fileManager.path_on_disk(target, path)
				printer.select_file(filenameToSelect, sd, print_after_slicing)

		try:
			fileManager.slice(slicer, target, filename, target, full_path,
			                  profile=profile,
			                  printer_profile_id=printerProfile,
			                  position=position,
			                  overrides=overrides,
			                  display=canon_name,
			                  callback=slicing_done,
			                  callback_args=(target, full_path, select_after_slicing, print_after_slicing))
		except octoprint.slicing.UnknownProfile:
			return make_response("Profile {profile} doesn't exist".format(**locals()), 400)

		files = {}
		location = url_for(".readGcodeFile", target=target, filename=full_path, _external=True)
		result = {
			"name": sanitized_name,
			"path": full_path,
			"display": canon_name,
			"origin": FileDestinations.LOCAL,
			"refs": {
				"resource": location,
				"download": url_for("index", _external=True) + "downloads/files/" + target + "/" + full_path
			}
		}

		r = make_response(jsonify(result), 202)
		r.headers["Location"] = location
		return r

	elif command == "analyse":
		if not _verifyFileExists(target, filename):
			return make_response("File not found on '%s': %s" % (target, filename), 404)

		printer_profile = None
		if "printerProfile" in data and data["printerProfile"]:
			printer_profile = data["printerProfile"]

		if not fileManager.analyse(target, filename, printer_profile_id=printer_profile):
			return make_response("No analysis possible for {} on {}".format(filename, target), 400)

	elif command == "copy" or command == "move":
		# Copy and move are only possible on local storage
		if not target in [FileDestinations.LOCAL]:
			return make_response("Unsupported target for {}: {}".format(command, target), 400)

		if not _verifyFileExists(target, filename) and not _verifyFolderExists(target, filename):
			return make_response("File or folder not found on {}: {}".format(target, filename), 404)

		path, name = fileManager.split_path(target, filename)

		destination = data["destination"]
		dst_path, dst_name = fileManager.split_path(target, destination)
		sanitized_destination = fileManager.join_path(target, dst_path, fileManager.sanitize_name(target, dst_name))

		if _verifyFolderExists(target, destination) and sanitized_destination != filename:
			# destination is an existing folder and not ourselves (= display rename), we'll assume we are supposed
			# to move filename to this folder under the same name
			destination = fileManager.join_path(target, destination, name)

		is_file = fileManager.file_exists(target, filename)
		is_folder = fileManager.folder_exists(target, filename)

		if not (is_file or is_folder):
			return make_response("{} on {} is neither file or folder, can't {}".format(filename, target, command), 400)

		if command == "copy":
			# destination already there? error...
			if _verifyFileExists(target, destination) or _verifyFolderExists(target, destination):
				return make_response("File or folder does already exist on {}: {}".format(target, destination), 409)

			if is_file:
				fileManager.copy_file(target, filename, destination)
			else:
				fileManager.copy_folder(target, filename, destination)

		elif command == "move":
			if _isBusy(target, filename):
				return make_response("Trying to move a file or folder that is currently in use: {}".format(filename), 409)

			# destination already there AND not ourselves (= display rename)? error...
			if (_verifyFileExists(target, destination) or _verifyFolderExists(target, destination)) \
					and sanitized_destination != filename:
				return make_response("File or folder does already exist on {}: {}".format(target, destination), 409)

			# deselect the file if it's currently selected
			currentOrigin, currentFilename = _getCurrentFile()
			if currentFilename is not None and filename == currentFilename:
				printer.unselect_file()

			if is_file:
				fileManager.move_file(target, filename, destination)
			else:
				fileManager.move_folder(target, filename, destination)

		location = url_for(".readGcodeFile", target=target, filename=destination, _external=True)
		result = {
			"name": name,
			"path": destination,
			"origin": FileDestinations.LOCAL,
			"refs": {
				"resource": location
			}
		}
		if is_file:
			result["refs"]["download"] = url_for("index", _external=True) + "downloads/files/" + target + "/" + destination

		r = make_response(jsonify(result), 201)
		r.headers["Location"] = location
		return r

	return NO_CONTENT
Exemplo n.º 11
0
def uploadGcodeFile(target):
	input_name = "file"
	input_upload_name = input_name + "." + settings().get(["server", "uploads", "nameSuffix"])
	input_upload_path = input_name + "." + settings().get(["server", "uploads", "pathSuffix"])
	if input_upload_name in request.values and input_upload_path in request.values:
		if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
			return make_response("Unknown target: %s" % target, 404)

		upload = octoprint.filemanager.util.DiskFileWrapper(request.values[input_upload_name], request.values[input_upload_path])

		# Store any additional user data the caller may have passed.
		userdata = None
		if "userdata" in request.values:
			import json
			try:
				userdata = json.loads(request.values["userdata"])
			except:
				return make_response("userdata contains invalid JSON", 400)

		if target == FileDestinations.SDCARD and not settings().getBoolean(["feature", "sdSupport"]):
			return make_response("SD card support is disabled", 404)

		sd = target == FileDestinations.SDCARD
		selectAfterUpload = "select" in request.values.keys() and request.values["select"] in valid_boolean_trues
		printAfterSelect = "print" in request.values.keys() and request.values["print"] in valid_boolean_trues

		if sd:
			# validate that all preconditions for SD upload are met before attempting it
			if not (printer.is_operational() and not (printer.is_printing() or printer.is_paused())):
				return make_response("Can not upload to SD card, printer is either not operational or already busy", 409)
			if not printer.is_sd_ready():
				return make_response("Can not upload to SD card, not yet initialized", 409)

		# determine future filename of file to be uploaded, abort if it can't be uploaded
		try:
			# FileDestinations.LOCAL = should normally be target, but can't because SDCard handling isn't implemented yet
			canonPath, canonFilename = fileManager.canonicalize(FileDestinations.LOCAL, upload.filename)
			futurePath = fileManager.sanitize_path(FileDestinations.LOCAL, canonPath)
			futureFilename = fileManager.sanitize_name(FileDestinations.LOCAL, canonFilename)
		except:
			canonFilename = None
			futurePath = None
			futureFilename = None

		if futureFilename is None:
			return make_response("Can not upload file %s, wrong format?" % upload.filename, 415)

		if "path" in request.values and request.values["path"]:
			# we currently only support uploads to sdcard via local, so first target is local instead of "target"
			futurePath = fileManager.sanitize_path(FileDestinations.LOCAL, request.values["path"])

		# prohibit overwriting currently selected file while it's being printed
		futureFullPath = fileManager.join_path(FileDestinations.LOCAL, futurePath, futureFilename)
		futureFullPathInStorage = fileManager.path_in_storage(FileDestinations.LOCAL, futureFullPath)

		if not printer.can_modify_file(futureFullPathInStorage, sd):
			return make_response("Trying to overwrite file that is currently being printed: %s" % futureFullPath, 409)

		reselect = printer.is_current_file(futureFullPathInStorage, sd)

		def fileProcessingFinished(filename, absFilename, destination):
			"""
			Callback for when the file processing (upload, optional slicing, addition to analysis queue) has
			finished.

			Depending on the file's destination triggers either streaming to SD card or directly calls selectAndOrPrint.
			"""

			if destination == FileDestinations.SDCARD and octoprint.filemanager.valid_file_type(filename, "machinecode"):
				return filename, printer.add_sd_file(filename, absFilename, selectAndOrPrint)
			else:
				selectAndOrPrint(filename, absFilename, destination)
				return filename

		def selectAndOrPrint(filename, absFilename, destination):
			"""
			Callback for when the file is ready to be selected and optionally printed. For SD file uploads this is only
			the case after they have finished streaming to the printer, which is why this callback is also used
			for the corresponding call to addSdFile.

			Selects the just uploaded file if either selectAfterUpload or printAfterSelect are True, or if the
			exact file is already selected, such reloading it.
			"""
			if octoprint.filemanager.valid_file_type(added_file, "gcode") and (selectAfterUpload or printAfterSelect or reselect):
				printer.select_file(absFilename, destination == FileDestinations.SDCARD, printAfterSelect)

		try:
			added_file = fileManager.add_file(FileDestinations.LOCAL, futureFullPathInStorage, upload,
			                                  allow_overwrite=True,
			                                  display=canonFilename)
		except octoprint.filemanager.storage.StorageError as e:
			if e.code == octoprint.filemanager.storage.StorageError.INVALID_FILE:
				return make_response("Could not upload the file \"{}\", invalid type".format(upload.filename), 400)
			else:
				return make_response("Could not upload the file \"{}\"".format(upload.filename), 500)

		if octoprint.filemanager.valid_file_type(added_file, "stl"):
			filename = added_file
			done = True
		else:
			filename = fileProcessingFinished(added_file, fileManager.path_on_disk(FileDestinations.LOCAL, added_file), target)
			done = not sd

		if userdata is not None:
			# upload included userdata, add this now to the metadata
			fileManager.set_additional_metadata(FileDestinations.LOCAL, added_file, "userdata", userdata)

		sdFilename = None
		if isinstance(filename, tuple):
			filename, sdFilename = filename

		eventManager.fire(Events.UPLOAD, {"name": futureFilename,
		                                  "path": filename,
		                                  "target": target,

		                                  # TODO deprecated, remove in 1.4.0
		                                  "file": filename})

		files = {}
		location = url_for(".readGcodeFile", target=FileDestinations.LOCAL, filename=filename, _external=True)
		files.update({
			FileDestinations.LOCAL: {
				"name": futureFilename,
				"path": filename,
				"origin": FileDestinations.LOCAL,
				"refs": {
					"resource": location,
					"download": url_for("index", _external=True) + "downloads/files/" + FileDestinations.LOCAL + "/" + filename
				}
			}
		})

		if sd and sdFilename:
			location = url_for(".readGcodeFile", target=FileDestinations.SDCARD, filename=sdFilename, _external=True)
			files.update({
				FileDestinations.SDCARD: {
					"name": sdFilename,
					"path": sdFilename,
					"origin": FileDestinations.SDCARD,
					"refs": {
						"resource": location
					}
				}
			})

		r = make_response(jsonify(files=files, done=done), 201)
		r.headers["Location"] = location
		return r

	elif "foldername" in request.values:
		foldername = request.values["foldername"]

		if not target in [FileDestinations.LOCAL]:
			return make_response("Unknown target: %s" % target, 400)

		canonPath, canonName = fileManager.canonicalize(target, foldername)
		futurePath = fileManager.sanitize_path(target, canonPath)
		futureName = fileManager.sanitize_name(target, canonName)
		if not futureName or not futurePath:
			return make_response("Can't create a folder with an empty name", 400)

		if "path" in request.values and request.values["path"]:
			futurePath = fileManager.sanitize_path(FileDestinations.LOCAL,
			                                       request.values["path"])

		futureFullPath = fileManager.join_path(target, futurePath, futureName)
		if octoprint.filemanager.valid_file_type(futureName):
			return make_response("Can't create a folder named %s, please try another name" % futureName, 409)

		try:
			added_folder = fileManager.add_folder(target, futureFullPath, display=canonName)
		except octoprint.filemanager.storage.StorageError as e:
			if e.code == octoprint.filemanager.storage.StorageError.INVALID_DIRECTORY:
				return make_response("Could not create folder {}, invalid directory".format(futureName))
			else:
				return make_response("Could not create folder {}".format(futureName))

		location = url_for(".readGcodeFile",
		                   target=FileDestinations.LOCAL,
		                   filename=added_folder,
		                   _external=True)
		folder = dict(name=futureName,
		              path=added_folder,
		              origin=target,
		              refs=dict(resource=location))

		r = make_response(jsonify(folder=folder, done=True), 201)
		r.headers["Location"] = location
		return r

	else:
		return make_response("No file to upload and no folder to create", 400)
Exemplo n.º 12
0
def uploadFastBotSDCARD(target):
	print("lkj uploadFastBotSDCARD target:%s" % str(target))
	#target = FileDestinations.FastbotSDCARD
	
	print("lkj post request.values:%s" % str(request.values))
	print("lkj post request.files:%s" % str(request.files))


	input_name = "file"
	input_upload_name = input_name + "." + settings().get(["server", "uploads", "nameSuffix"])
	input_upload_path = input_name + "." + settings().get(["server", "uploads", "pathSuffix"])
	if input_upload_name in request.values and input_upload_path in request.values:
		import shutil
		upload = util.Object()
		upload.filename = request.values[input_upload_name]
		upload.save = lambda new_path: shutil.move(request.values[input_upload_path], new_path)
	elif input_name in request.files:
		upload = request.files[input_name]
	else:
		return make_response("No file included", 400)
	
	print("lkj post upload:%s" % str(upload))
	
	if target == FileDestinations.FastbotSDCARD and not settings().getBoolean(["feature", "sdSupport"]):
		return make_response("SD card support is disabled", 404)
	print("lkj uploadGcodeFile 2")
	sd = target == FileDestinations.FastbotSDCARD
	selectAfterUpload = "select" in request.values.keys() and request.values["select"] in valid_boolean_trues
	printAfterSelect = "print" in request.values.keys() and request.values["print"] in valid_boolean_trues

	print("lkj uploadGcodeFile 3")	
	# determine current job
	currentFilename = None
	currentOrigin = None
	currentJob = printer.getCurrentJob()
	if currentJob is not None and "file" in currentJob.keys():
		currentJobFile = currentJob["file"]
		if "name" in currentJobFile.keys() and "origin" in currentJobFile.keys():
			currentFilename = currentJobFile["name"]
			currentOrigin = currentJobFile["origin"]

	# determine future filename of file to be uploaded, abort if it can't be uploaded
	try:
		futureFilename = fileManager.sanitize_name(FileDestinations.FastbotSDCARD, upload.filename)
	except:
		futureFilename = None
	if futureFilename is None or not (slicingManager.slicing_enabled or octoprint.filemanager.valid_file_type(futureFilename, type="gcode")):
		return make_response("Can not upload file %s, wrong format?" % upload.filename, 415)
	print("lkj uploadGcodeFile 4")
	# prohibit overwriting currently selected file while it's being printed
	if futureFilename == currentFilename and target == currentOrigin and printer.isPrinting() or printer.isPaused():
		return make_response("Trying to overwrite file that is currently being printed: %s" % currentFilename, 409)
	print("lkj uploadGcodeFile 5")
	def fileProcessingFinished(filename, absFilename, destination):
		"""
		Callback for when the file processing (upload, optional slicing, addition to analysis queue) has
		finished.

		Depending on the file's destination triggers either streaming to SD card or directly calls selectAndOrPrint.
		"""
		selectAndOrPrint(filename, absFilename, destination)
		return filename

	def selectAndOrPrint(filename, absFilename, destination):
		"""
		Callback for when the file is ready to be selected and optionally printed. For SD file uploads this is only
		the case after they have finished streaming to the printer, which is why this callback is also used
		for the corresponding call to addSdFile.

		Selects the just uploaded file if either selectAfterUpload or printAfterSelect are True, or if the
		exact file is already selected, such reloading it.
		"""
		if octoprint.filemanager.valid_file_type(added_file, "gcode") and (selectAfterUpload or printAfterSelect or (currentFilename == filename and currentOrigin == destination)):
			printer.selectFile(absFilename, destination == FileDestinations.FastbotSDCARD, printAfterSelect)
	print("lkj uploadGcodeFile 6")		
	added_file = fileManager.add_file(FileDestinations.FastbotSDCARD, upload.filename, upload, allow_overwrite=True)
	if added_file is None:
		return make_response("Could not upload the file %s" % upload.filename, 500)
	
	print("lkj uploadGcodeFile 6.0, added_file:%s" % str(added_file))
	if octoprint.filemanager.valid_file_type(added_file, "stl"):
		filename = added_file
		done = True
		print("lkj uploadGcodeFile 6.1")
	else:
		filename = fileProcessingFinished(added_file, fileManager.get_absolute_path(FileDestinations.FastbotSDCARD, added_file), target)
		done = True

	sdFilename = filename

	eventManager.fire(Events.UPLOAD, {"file": filename, "target": target})

	files = {}
	'''
	location = url_for(".readGcodeFile", target=FileDestinations.LOCAL, filename=filename, _external=True)
	files.update({
                FileDestinations.LOCAL: {
                        "name": filename,
                        "origin": FileDestinations.LOCAL,
                        "refs": {
                                "resource": location,
                                "download": url_for("index", _external=True) + "downloads/files/" + FileDestinations.LOCAL + "/" + filename
                        }
                }
        })
	'''
	print("lkj uploadGcodeFile 7 sdFilename:%s" % sdFilename)
	if sd and sdFilename:
		print("lkj uploadGcodeFile 7.1")
		location = url_for(".readGcodeFile", target=FileDestinations.FastbotSDCARD, filename=sdFilename, _external=True)
		files.update({
	                FileDestinations.FastbotSDCARD: {
	                        "name": sdFilename,
	                        "origin": FileDestinations.FastbotSDCARD,
	                        "refs": {
	                                "resource": location
	                        }
	                }
	        })
	print("lkj uploadFastBotSDCARD 8")	
	r = make_response(jsonify(files=files, done=done), 201)
	r.headers["Location"] = location
	return r	
Exemplo n.º 13
0
def uploadFastBotSDCARD(target):
    print("lkj uploadFastBotSDCARD target:%s" % str(target))
    #target = FileDestinations.FastbotSDCARD

    print("lkj post request.values:%s" % str(request.values))
    print("lkj post request.files:%s" % str(request.files))

    input_name = "file"
    input_upload_name = input_name + "." + settings().get(
        ["server", "uploads", "nameSuffix"])
    input_upload_path = input_name + "." + settings().get(
        ["server", "uploads", "pathSuffix"])
    if input_upload_name in request.values and input_upload_path in request.values:
        import shutil
        upload = util.Object()
        upload.filename = request.values[input_upload_name]
        upload.save = lambda new_path: shutil.move(
            request.values[input_upload_path], new_path)
    elif input_name in request.files:
        upload = request.files[input_name]
    else:
        return make_response("No file included", 400)

    print("lkj post upload:%s" % str(upload))

    if target == FileDestinations.FastbotSDCARD and not settings().getBoolean(
        ["feature", "sdSupport"]):
        return make_response("SD card support is disabled", 404)
    print("lkj uploadGcodeFile 2")
    sd = target == FileDestinations.FastbotSDCARD
    selectAfterUpload = "select" in request.values.keys(
    ) and request.values["select"] in valid_boolean_trues
    printAfterSelect = "print" in request.values.keys(
    ) and request.values["print"] in valid_boolean_trues

    print("lkj uploadGcodeFile 3")
    # determine current job
    currentFilename = None
    currentOrigin = None
    currentJob = printer.getCurrentJob()
    if currentJob is not None and "file" in currentJob.keys():
        currentJobFile = currentJob["file"]
        if "name" in currentJobFile.keys() and "origin" in currentJobFile.keys(
        ):
            currentFilename = currentJobFile["name"]
            currentOrigin = currentJobFile["origin"]

    # determine future filename of file to be uploaded, abort if it can't be uploaded
    try:
        futureFilename = fileManager.sanitize_name(
            FileDestinations.FastbotSDCARD, upload.filename)
    except:
        futureFilename = None
    if futureFilename is None or not (slicingManager.slicing_enabled
                                      or octoprint.filemanager.valid_file_type(
                                          futureFilename, type="gcode")):
        return make_response(
            "Can not upload file %s, wrong format?" % upload.filename, 415)
    print("lkj uploadGcodeFile 4")
    # prohibit overwriting currently selected file while it's being printed
    if futureFilename == currentFilename and target == currentOrigin and printer.isPrinting(
    ) or printer.isPaused():
        return make_response(
            "Trying to overwrite file that is currently being printed: %s" %
            currentFilename, 409)
    print("lkj uploadGcodeFile 5")

    def fileProcessingFinished(filename, absFilename, destination):
        """
		Callback for when the file processing (upload, optional slicing, addition to analysis queue) has
		finished.

		Depending on the file's destination triggers either streaming to SD card or directly calls selectAndOrPrint.
		"""
        selectAndOrPrint(filename, absFilename, destination)
        return filename

    def selectAndOrPrint(filename, absFilename, destination):
        """
		Callback for when the file is ready to be selected and optionally printed. For SD file uploads this is only
		the case after they have finished streaming to the printer, which is why this callback is also used
		for the corresponding call to addSdFile.

		Selects the just uploaded file if either selectAfterUpload or printAfterSelect are True, or if the
		exact file is already selected, such reloading it.
		"""
        if octoprint.filemanager.valid_file_type(added_file, "gcode") and (
                selectAfterUpload or printAfterSelect or
            (currentFilename == filename and currentOrigin == destination)):
            printer.selectFile(absFilename,
                               destination == FileDestinations.FastbotSDCARD,
                               printAfterSelect)

    print("lkj uploadGcodeFile 6")
    added_file = fileManager.add_file(FileDestinations.FastbotSDCARD,
                                      upload.filename,
                                      upload,
                                      allow_overwrite=True)
    if added_file is None:
        return make_response("Could not upload the file %s" % upload.filename,
                             500)

    print("lkj uploadGcodeFile 6.0, added_file:%s" % str(added_file))
    if octoprint.filemanager.valid_file_type(added_file, "stl"):
        filename = added_file
        done = True
        print("lkj uploadGcodeFile 6.1")
    else:
        filename = fileProcessingFinished(
            added_file,
            fileManager.get_absolute_path(FileDestinations.FastbotSDCARD,
                                          added_file), target)
        done = True

    sdFilename = filename

    eventManager.fire(Events.UPLOAD, {"file": filename, "target": target})

    files = {}
    '''
	location = url_for(".readGcodeFile", target=FileDestinations.LOCAL, filename=filename, _external=True)
	files.update({
                FileDestinations.LOCAL: {
                        "name": filename,
                        "origin": FileDestinations.LOCAL,
                        "refs": {
                                "resource": location,
                                "download": url_for("index", _external=True) + "downloads/files/" + FileDestinations.LOCAL + "/" + filename
                        }
                }
        })
	'''
    print("lkj uploadGcodeFile 7 sdFilename:%s" % sdFilename)
    if sd and sdFilename:
        print("lkj uploadGcodeFile 7.1")
        location = url_for(".readGcodeFile",
                           target=FileDestinations.FastbotSDCARD,
                           filename=sdFilename,
                           _external=True)
        files.update({
            FileDestinations.FastbotSDCARD: {
                "name": sdFilename,
                "origin": FileDestinations.FastbotSDCARD,
                "refs": {
                    "resource": location
                }
            }
        })
    print("lkj uploadFastBotSDCARD 8")
    r = make_response(jsonify(files=files, done=done), 201)
    r.headers["Location"] = location
    return r
Exemplo n.º 14
0
def uploadGcodeFile(target):
	input_name = "file"
	input_upload_name = input_name + "." + settings().get(["server", "uploads", "nameSuffix"])
	input_upload_path = input_name + "." + settings().get(["server", "uploads", "pathSuffix"])
	if input_upload_name in request.values and input_upload_path in request.values:
		if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
			return make_response("Unknown target: %s" % target, 404)

		upload = octoprint.filemanager.util.DiskFileWrapper(request.values[input_upload_name], request.values[input_upload_path])

		# Store any additional user data the caller may have passed.
		userdata = None
		if "userdata" in request.values:
			import json
			try:
				userdata = json.loads(request.values["userdata"])
			except:
				return make_response("userdata contains invalid JSON", 400)

		if target == FileDestinations.SDCARD and not settings().getBoolean(["feature", "sdSupport"]):
			return make_response("SD card support is disabled", 404)

		sd = target == FileDestinations.SDCARD
		selectAfterUpload = "select" in request.values.keys() and request.values["select"] in valid_boolean_trues
		printAfterSelect = "print" in request.values.keys() and request.values["print"] in valid_boolean_trues

		if sd:
			# validate that all preconditions for SD upload are met before attempting it
			if not (printer.is_operational() and not (printer.is_printing() or printer.is_paused())):
				return make_response("Can not upload to SD card, printer is either not operational or already busy", 409)
			if not printer.is_sd_ready():
				return make_response("Can not upload to SD card, not yet initialized", 409)

		# determine future filename of file to be uploaded, abort if it can't be uploaded
		try:
			# FileDestinations.LOCAL = should normally be target, but can't because SDCard handling isn't implemented yet
			canonPath, canonFilename = fileManager.canonicalize(FileDestinations.LOCAL, upload.filename)
			futurePath = fileManager.sanitize_path(FileDestinations.LOCAL, canonPath)
			futureFilename = fileManager.sanitize_name(FileDestinations.LOCAL, canonFilename)
		except:
			canonFilename = None
			futurePath = None
			futureFilename = None

		if futureFilename is None:
			return make_response("Can not upload file %s, wrong format?" % upload.filename, 415)

		if "path" in request.values and request.values["path"]:
			# we currently only support uploads to sdcard via local, so first target is local instead of "target"
			futurePath = fileManager.sanitize_path(FileDestinations.LOCAL, request.values["path"])

		# prohibit overwriting currently selected file while it's being printed
		futureFullPath = fileManager.join_path(FileDestinations.LOCAL, futurePath, futureFilename)
		futureFullPathInStorage = fileManager.path_in_storage(FileDestinations.LOCAL, futureFullPath)

		if not printer.can_modify_file(futureFullPathInStorage, sd):
			return make_response("Trying to overwrite file that is currently being printed: %s" % futureFullPath, 409)

		reselect = printer.is_current_file(futureFullPathInStorage, sd)

		user = current_user.get_name()

		def fileProcessingFinished(filename, absFilename, destination):
			"""
			Callback for when the file processing (upload, optional slicing, addition to analysis queue) has
			finished.

			Depending on the file's destination triggers either streaming to SD card or directly calls selectAndOrPrint.
			"""

			if destination == FileDestinations.SDCARD and octoprint.filemanager.valid_file_type(filename, "machinecode"):
				return filename, printer.add_sd_file(filename, absFilename, selectAndOrPrint, tags={"source:api", "api:files.sd"})
			else:
				selectAndOrPrint(filename, absFilename, destination)
				return filename

		def selectAndOrPrint(filename, absFilename, destination):
			"""
			Callback for when the file is ready to be selected and optionally printed. For SD file uploads this is only
			the case after they have finished streaming to the printer, which is why this callback is also used
			for the corresponding call to addSdFile.

			Selects the just uploaded file if either selectAfterUpload or printAfterSelect are True, or if the
			exact file is already selected, such reloading it.
			"""
			if octoprint.filemanager.valid_file_type(added_file, "gcode") and (selectAfterUpload or printAfterSelect or reselect):
				printer.select_file(absFilename, destination == FileDestinations.SDCARD, printAfterSelect, user)

		try:
			added_file = fileManager.add_file(FileDestinations.LOCAL, futureFullPathInStorage, upload,
			                                  allow_overwrite=True,
			                                  display=canonFilename)
		except octoprint.filemanager.storage.StorageError as e:
			if e.code == octoprint.filemanager.storage.StorageError.INVALID_FILE:
				return make_response("Could not upload the file \"{}\", invalid type".format(upload.filename), 400)
			else:
				return make_response("Could not upload the file \"{}\"".format(upload.filename), 500)

		if octoprint.filemanager.valid_file_type(added_file, "stl"):
			filename = added_file
			done = True
		else:
			filename = fileProcessingFinished(added_file, fileManager.path_on_disk(FileDestinations.LOCAL, added_file), target)
			done = not sd

		if userdata is not None:
			# upload included userdata, add this now to the metadata
			fileManager.set_additional_metadata(FileDestinations.LOCAL, added_file, "userdata", userdata)

		sdFilename = None
		if isinstance(filename, tuple):
			filename, sdFilename = filename

		eventManager.fire(Events.UPLOAD, {"name": futureFilename,
		                                  "path": filename,
		                                  "target": target,

		                                  # TODO deprecated, remove in 1.4.0
		                                  "file": filename})

		files = {}
		location = url_for(".readGcodeFile", target=FileDestinations.LOCAL, filename=filename, _external=True)
		files.update({
			FileDestinations.LOCAL: {
				"name": futureFilename,
				"path": filename,
				"origin": FileDestinations.LOCAL,
				"refs": {
					"resource": location,
					"download": url_for("index", _external=True) + "downloads/files/" + FileDestinations.LOCAL + "/" + filename
				}
			}
		})

		if sd and sdFilename:
			location = url_for(".readGcodeFile", target=FileDestinations.SDCARD, filename=sdFilename, _external=True)
			files.update({
				FileDestinations.SDCARD: {
					"name": sdFilename,
					"path": sdFilename,
					"origin": FileDestinations.SDCARD,
					"refs": {
						"resource": location
					}
				}
			})

		r = make_response(jsonify(files=files, done=done), 201)
		r.headers["Location"] = location
		return r

	elif "foldername" in request.values:
		foldername = request.values["foldername"]

		if not target in [FileDestinations.LOCAL]:
			return make_response("Unknown target: %s" % target, 400)

		canonPath, canonName = fileManager.canonicalize(target, foldername)
		futurePath = fileManager.sanitize_path(target, canonPath)
		futureName = fileManager.sanitize_name(target, canonName)
		if not futureName or not futurePath:
			return make_response("Can't create a folder with an empty name", 400)

		if "path" in request.values and request.values["path"]:
			futurePath = fileManager.sanitize_path(FileDestinations.LOCAL,
			                                       request.values["path"])

		futureFullPath = fileManager.join_path(target, futurePath, futureName)
		if octoprint.filemanager.valid_file_type(futureName):
			return make_response("Can't create a folder named %s, please try another name" % futureName, 409)

		try:
			added_folder = fileManager.add_folder(target, futureFullPath, display=canonName)
		except octoprint.filemanager.storage.StorageError as e:
			if e.code == octoprint.filemanager.storage.StorageError.INVALID_DIRECTORY:
				return make_response("Could not create folder {}, invalid directory".format(futureName))
			else:
				return make_response("Could not create folder {}".format(futureName))

		location = url_for(".readGcodeFile",
		                   target=FileDestinations.LOCAL,
		                   filename=added_folder,
		                   _external=True)
		folder = dict(name=futureName,
		              path=added_folder,
		              origin=target,
		              refs=dict(resource=location))

		r = make_response(jsonify(folder=folder, done=True), 201)
		r.headers["Location"] = location
		return r

	else:
		return make_response("No file to upload and no folder to create", 400)
Exemplo n.º 15
0
def uploadGcodeFile(target):
    if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
        return make_response("Unknown target: %s" % target, 404)

    input_name = "file"
    input_upload_name = input_name + "." + settings().get(
        ["server", "uploads", "nameSuffix"])
    input_upload_path = input_name + "." + settings().get(
        ["server", "uploads", "pathSuffix"])
    if input_upload_name in request.values and input_upload_path in request.values:
        upload = octoprint.filemanager.util.DiskFileWrapper(
            request.values[input_upload_name],
            request.values[input_upload_path])
    else:
        return make_response("No file included", 400)

    # Store any additional user data the caller may have passed.
    userdata = None
    if "userdata" in request.values:
        import json
        try:
            userdata = json.loads(request.values["userdata"])
        except:
            return make_response("userdata contains invalid JSON", 400)

    if target == FileDestinations.SDCARD and not settings().getBoolean(
        ["feature", "sdSupport"]):
        return make_response("SD card support is disabled", 404)

    sd = target == FileDestinations.SDCARD
    selectAfterUpload = "select" in request.values.keys(
    ) and request.values["select"] in valid_boolean_trues
    printAfterSelect = "print" in request.values.keys(
    ) and request.values["print"] in valid_boolean_trues

    if sd:
        # validate that all preconditions for SD upload are met before attempting it
        if not (printer.is_operational()
                and not (printer.is_printing() or printer.is_paused())):
            return make_response(
                "Can not upload to SD card, printer is either not operational or already busy",
                409)
        if not printer.is_sd_ready():
            return make_response(
                "Can not upload to SD card, not yet initialized", 409)

    # determine current job
    currentFilename = None
    currentOrigin = None
    currentJob = printer.get_current_job()
    if currentJob is not None and "file" in currentJob.keys():
        currentJobFile = currentJob["file"]
        if "name" in currentJobFile.keys() and "origin" in currentJobFile.keys(
        ):
            currentFilename = currentJobFile["name"]
            currentOrigin = currentJobFile["origin"]

    # determine future filename of file to be uploaded, abort if it can't be uploaded
    try:
        futureFilename = fileManager.sanitize_name(FileDestinations.LOCAL,
                                                   upload.filename)
    except:
        futureFilename = None
    if futureFilename is None:
        return make_response(
            "Can not upload file %s, wrong format?" % upload.filename, 415)

    # prohibit overwriting currently selected file while it's being printed
    if futureFilename == currentFilename and target == currentOrigin and printer.is_printing(
    ) or printer.is_paused():
        return make_response(
            "Trying to overwrite file that is currently being printed: %s" %
            currentFilename, 409)

    def fileProcessingFinished(filename, absFilename, destination):
        """
		Callback for when the file processing (upload, optional slicing, addition to analysis queue) has
		finished.

		Depending on the file's destination triggers either streaming to SD card or directly calls selectAndOrPrint.
		"""

        if destination == FileDestinations.SDCARD and octoprint.filemanager.valid_file_type(
                filename, "gcode"):
            return filename, printer.add_sd_file(filename, absFilename,
                                                 selectAndOrPrint)
        else:
            selectAndOrPrint(filename, absFilename, destination)
            return filename

    def selectAndOrPrint(filename, absFilename, destination):
        """
		Callback for when the file is ready to be selected and optionally printed. For SD file uploads this is only
		the case after they have finished streaming to the printer, which is why this callback is also used
		for the corresponding call to addSdFile.

		Selects the just uploaded file if either selectAfterUpload or printAfterSelect are True, or if the
		exact file is already selected, such reloading it.
		"""
        if octoprint.filemanager.valid_file_type(added_file, "gcode") and (
                selectAfterUpload or printAfterSelect or
            (currentFilename == filename and currentOrigin == destination)):
            printer.select_file(absFilename,
                                destination == FileDestinations.SDCARD,
                                printAfterSelect)

    added_file = fileManager.add_file(FileDestinations.LOCAL,
                                      upload.filename,
                                      upload,
                                      allow_overwrite=True)
    if added_file is None:
        return make_response("Could not upload the file %s" % upload.filename,
                             500)
    if octoprint.filemanager.valid_file_type(added_file, "stl"):
        filename = added_file
        done = True
    else:
        filename = fileProcessingFinished(
            added_file,
            fileManager.path_on_disk(FileDestinations.LOCAL, added_file),
            target)
        done = True

    if userdata is not None:
        # upload included userdata, add this now to the metadata
        fileManager.set_additional_metadata(FileDestinations.LOCAL, added_file,
                                            "userdata", userdata)

    sdFilename = None
    if isinstance(filename, tuple):
        filename, sdFilename = filename

    eventManager.fire(Events.UPLOAD, {"file": filename, "target": target})

    files = {}
    location = url_for(".readGcodeFile",
                       target=FileDestinations.LOCAL,
                       filename=filename,
                       _external=True)
    files.update({
        FileDestinations.LOCAL: {
            "name": filename,
            "origin": FileDestinations.LOCAL,
            "refs": {
                "resource":
                location,
                "download":
                url_for("index", _external=True) + "downloads/files/" +
                FileDestinations.LOCAL + "/" + filename
            }
        }
    })

    if sd and sdFilename:
        location = url_for(".readGcodeFile",
                           target=FileDestinations.SDCARD,
                           filename=sdFilename,
                           _external=True)
        files.update({
            FileDestinations.SDCARD: {
                "name": sdFilename,
                "origin": FileDestinations.SDCARD,
                "refs": {
                    "resource": location
                }
            }
        })

    r = make_response(jsonify(files=files, done=done), 201)
    r.headers["Location"] = location
    return r
Exemplo n.º 16
0
def gcodeFileCommand(filename, target):
	if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
		return make_response("Unknown target: %s" % target, 404)

	# valid file commands, dict mapping command name to mandatory parameters
	valid_commands = {
		"select": [],
		"slice": [],
		"analyse": [],
		"copy": ["destination"],
		"move": ["destination"]
	}

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

	user = current_user.get_name()

	if command == "select":
		if not _verifyFileExists(target, filename):
			return make_response("File not found on '%s': %s" % (target, filename), 404)

		# selects/loads a file
		if not octoprint.filemanager.valid_file_type(filename, type="machinecode"):
			return make_response("Cannot select {filename} for printing, not a machinecode file".format(**locals()), 415)

		printAfterLoading = False
		if "print" in data.keys() and data["print"] in valid_boolean_trues:
			if not printer.is_operational():
				return make_response("Printer is not operational, cannot directly start printing", 409)
			printAfterLoading = True

		sd = False
		if target == FileDestinations.SDCARD:
			filenameToSelect = filename
			sd = True
		else:
			filenameToSelect = fileManager.path_on_disk(target, filename)
		printer.select_file(filenameToSelect, sd, printAfterLoading, user)

	elif command == "slice":
		if not _verifyFileExists(target, filename):
			return make_response("File not found on '%s': %s" % (target, filename), 404)

		try:
			if "slicer" in data:
				slicer = data["slicer"]
				del data["slicer"]
				slicer_instance = slicingManager.get_slicer(slicer)

			elif "cura" in slicingManager.registered_slicers:
				slicer = "cura"
				slicer_instance = slicingManager.get_slicer("cura")

			else:
				return make_response("Cannot slice {filename}, no slicer available".format(**locals()), 415)
		except octoprint.slicing.UnknownSlicer as e:
			return make_response("Slicer {slicer} is not available".format(slicer=e.slicer), 400)

		if not any([octoprint.filemanager.valid_file_type(filename, type=source_file_type) for source_file_type in slicer_instance.get_slicer_properties().get("source_file_types", ["model"])]):
			return make_response("Cannot slice {filename}, not a model file".format(**locals()), 415)

		if slicer_instance.get_slicer_properties().get("same_device", True) and (printer.is_printing() or printer.is_paused()):
			# slicer runs on same device as OctoPrint, slicing while printing is hence disabled
			return make_response("Cannot slice on {slicer} while printing due to performance reasons".format(**locals()), 409)

		if "destination" in data and data["destination"]:
			destination = data["destination"]
			del data["destination"]
		elif "gcode" in data and data["gcode"]:
			destination = data["gcode"]
			del data["gcode"]
		else:
			import os
			name, _ = os.path.splitext(filename)
			destination = name + "." + slicer_instance.get_slicer_properties().get("destination_extensions", ["gco", "gcode", "g"])[0]

		full_path = destination
		if "path" in data and data["path"]:
			full_path = fileManager.join_path(target, data["path"], destination)
		else:
			path, _ = fileManager.split_path(target, filename)
			if path:
				full_path = fileManager.join_path(target, path, destination)

		canon_path, canon_name = fileManager.canonicalize(target, full_path)
		sanitized_name = fileManager.sanitize_name(target, canon_name)

		if canon_path:
			full_path = fileManager.join_path(target, canon_path, sanitized_name)
		else:
			full_path = sanitized_name

		# prohibit overwriting the file that is currently being printed
		currentOrigin, currentFilename = _getCurrentFile()
		if currentFilename == full_path and currentOrigin == target and (printer.is_printing() or printer.is_paused()):
			make_response("Trying to slice into file that is currently being printed: %s" % full_path, 409)

		if "profile" in data.keys() and data["profile"]:
			profile = data["profile"]
			del data["profile"]
		else:
			profile = None

		if "printerProfile" in data.keys() and data["printerProfile"]:
			printerProfile = data["printerProfile"]
			del data["printerProfile"]
		else:
			printerProfile = None

		if "position" in data.keys() and data["position"] and isinstance(data["position"], dict) and "x" in data["position"] and "y" in data["position"]:
			position = data["position"]
			del data["position"]
		else:
			position = None

		select_after_slicing = False
		if "select" in data.keys() and data["select"] in valid_boolean_trues:
			if not printer.is_operational():
				return make_response("Printer is not operational, cannot directly select for printing", 409)
			select_after_slicing = True

		print_after_slicing = False
		if "print" in data.keys() and data["print"] in valid_boolean_trues:
			if not printer.is_operational():
				return make_response("Printer is not operational, cannot directly start printing", 409)
			select_after_slicing = print_after_slicing = True

		override_keys = [k for k in data if k.startswith("profile.") and data[k] is not None]
		overrides = dict()
		for key in override_keys:
			overrides[key[len("profile."):]] = data[key]

		def slicing_done(target, path, select_after_slicing, print_after_slicing):
			if select_after_slicing or print_after_slicing:
				sd = False
				if target == FileDestinations.SDCARD:
					filenameToSelect = path
					sd = True
				else:
					filenameToSelect = fileManager.path_on_disk(target, path)
				printer.select_file(filenameToSelect, sd, print_after_slicing, user)

		try:
			fileManager.slice(slicer, target, filename, target, full_path,
			                  profile=profile,
			                  printer_profile_id=printerProfile,
			                  position=position,
			                  overrides=overrides,
			                  display=canon_name,
			                  callback=slicing_done,
			                  callback_args=(target, full_path, select_after_slicing, print_after_slicing))
		except octoprint.slicing.UnknownProfile:
			return make_response("Profile {profile} doesn't exist".format(**locals()), 400)

		files = {}
		location = url_for(".readGcodeFile", target=target, filename=full_path, _external=True)
		result = {
			"name": sanitized_name,
			"path": full_path,
			"display": canon_name,
			"origin": FileDestinations.LOCAL,
			"refs": {
				"resource": location,
				"download": url_for("index", _external=True) + "downloads/files/" + target + "/" + full_path
			}
		}

		r = make_response(jsonify(result), 202)
		r.headers["Location"] = location
		return r

	elif command == "analyse":
		if not _verifyFileExists(target, filename):
			return make_response("File not found on '%s': %s" % (target, filename), 404)

		printer_profile = None
		if "printerProfile" in data and data["printerProfile"]:
			printer_profile = data["printerProfile"]

		if not fileManager.analyse(target, filename, printer_profile_id=printer_profile):
			return make_response("No analysis possible for {} on {}".format(filename, target), 400)

	elif command == "copy" or command == "move":
		# Copy and move are only possible on local storage
		if not target in [FileDestinations.LOCAL]:
			return make_response("Unsupported target for {}: {}".format(command, target), 400)

		if not _verifyFileExists(target, filename) and not _verifyFolderExists(target, filename):
			return make_response("File or folder not found on {}: {}".format(target, filename), 404)

		path, name = fileManager.split_path(target, filename)

		destination = data["destination"]
		dst_path, dst_name = fileManager.split_path(target, destination)
		sanitized_destination = fileManager.join_path(target, dst_path, fileManager.sanitize_name(target, dst_name))

		if _verifyFolderExists(target, destination) and sanitized_destination != filename:
			# destination is an existing folder and not ourselves (= display rename), we'll assume we are supposed
			# to move filename to this folder under the same name
			destination = fileManager.join_path(target, destination, name)

		is_file = fileManager.file_exists(target, filename)
		is_folder = fileManager.folder_exists(target, filename)

		if not (is_file or is_folder):
			return make_response("{} on {} is neither file or folder, can't {}".format(filename, target, command), 400)

		if command == "copy":
			# destination already there? error...
			if _verifyFileExists(target, destination) or _verifyFolderExists(target, destination):
				return make_response("File or folder does already exist on {}: {}".format(target, destination), 409)

			if is_file:
				fileManager.copy_file(target, filename, destination)
			else:
				fileManager.copy_folder(target, filename, destination)

		elif command == "move":
			if _isBusy(target, filename):
				return make_response("Trying to move a file or folder that is currently in use: {}".format(filename), 409)

			# destination already there AND not ourselves (= display rename)? error...
			if (_verifyFileExists(target, destination) or _verifyFolderExists(target, destination)) \
					and sanitized_destination != filename:
				return make_response("File or folder does already exist on {}: {}".format(target, destination), 409)

			# deselect the file if it's currently selected
			currentOrigin, currentFilename = _getCurrentFile()
			if currentFilename is not None and filename == currentFilename:
				printer.unselect_file()

			if is_file:
				fileManager.move_file(target, filename, destination)
			else:
				fileManager.move_folder(target, filename, destination)

		location = url_for(".readGcodeFile", target=target, filename=destination, _external=True)
		result = {
			"name": name,
			"path": destination,
			"origin": FileDestinations.LOCAL,
			"refs": {
				"resource": location
			}
		}
		if is_file:
			result["refs"]["download"] = url_for("index", _external=True) + "downloads/files/" + target + "/" + destination

		r = make_response(jsonify(result), 201)
		r.headers["Location"] = location
		return r

	return NO_CONTENT
Exemplo n.º 17
0
def uploadFirmwareFile(target):
    print("lkj uploadFirmwareFile target:%s" % str(target))
    target = FileDestinations.LOCAL
    if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
        return make_response("Unknown target: %s" % target, 404)

    print("lkj post target:%s" % str(target))
    print("lkj post request.values:%s" % str(request.values))
    print("lkj post request.files:%s" % str(request.files))

    input_name = "file"
    input_upload_name = input_name + "." + settings().get(
        ["server", "uploads", "nameSuffix"])
    input_upload_path = input_name + "." + settings().get(
        ["server", "uploads", "pathSuffix"])
    if input_upload_name in request.values and input_upload_path in request.values:
        print("lkj here 1")
        import shutil
        upload = util.Object()
        upload.filename = request.values[input_upload_name]
        upload.save = lambda new_path: shutil.move(
            request.values[input_upload_path], new_path)
    elif input_name in request.files:
        print("lkj here 2")
        upload = request.files[input_name]
    else:
        return make_response("No file included", 400)
    print("lkj post 2")
    # determine future filename of file to be uploaded, abort if it can't be uploaded
    try:
        futureFilename = fileManager.sanitize_name(FileDestinations.LOCAL,
                                                   upload.filename)
    except:
        futureFilename = None

    print("lkj futureFilename:%s" % futureFilename)

    try:
        added_file = fileManager.add_firmware_file(FileDestinations.LOCAL,
                                                   upload.filename,
                                                   upload,
                                                   allow_overwrite=True)
    except:
        added_file = None
    if added_file is None:
        print("lkj post added_file is None")
        return make_response("Could not upload the file %s" % upload.filename,
                             500)
    print("lkj added_file: %s" % added_file)

    files = {}
    done = True
    files.update({
        FileDestinations.LOCAL: {
            "name": added_file,
            "origin": FileDestinations.LOCAL
        }
    })
    r = make_response(jsonify(files=files, done=done), 201)
    #lkj
    from octoprint.server import printer
    if printer.isOperational():
        #cmd = ("M205", param=added_file)
        #printer.command()
        pass

    #r.headers["Location"] = added_file
    return r