Changes to the API to enchance folder support

This commit is contained in:
Salandora 2015-09-07 10:32:28 +02:00
parent b326b6bd33
commit fb2b44f3c1
2 changed files with 106 additions and 51 deletions

View file

@ -977,13 +977,29 @@ class LocalFileStorage(StorageInterface):
# folder recursion
elif os.path.isdir(entry_path) and recursive:
sub_result = self._list_folder(entry_path, filter=filter)
result[entry] = dict(
sub_result = self._list_folder(entry_path, filter=filter, recursive=recursive)
entry_data = dict(
name=entry,
type="folder",
children=sub_result
)
if not filter or filter(entry, entry_data):
def get_size(start_path):
total_size = 0
for dirpath, dirnames, filenames in os.walk(start_path):
for f in filenames:
fp = os.path.join(dirpath, f)
total_size += os.path.getsize(fp)
return total_size
# only add folders passing the optional filter
extended_entry_data = dict()
extended_entry_data.update(entry_data)
extended_entry_data["size"] = get_size(entry_path)
result[entry] = extended_entry_data
# TODO recreate links if we have metadata less entries
# save metadata

View file

@ -26,10 +26,16 @@ import psutil
@api.route("/files", methods=["GET"])
def readGcodeFiles():
filter = None
recursive = False
if "filter" in request.values:
filter = request.values["filter"]
files = _getFileList(FileDestinations.LOCAL, filter=filter)
if "recursive" in request.values:
recursive = request.values["recursive"] == 'true'
files = _getFileList(FileDestinations.LOCAL, filter=filter, recursive=recursive)
files.extend(_getFileList(FileDestinations.SDCARD))
usage = psutil.disk_usage(settings().getBaseFolder("uploads"))
return jsonify(files=files, free=usage.free, total=usage.total)
@ -39,7 +45,11 @@ def readGcodeFilesForOrigin(origin):
if origin not in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
return make_response("Unknown origin: %s" % origin, 404)
files = _getFileList(origin)
recursive = False
if "recursive" in request.values:
recursive = request.values["recursive"] == 'true'
files = _getFileList(origin, recursive=recursive)
if origin == FileDestinations.LOCAL:
usage = psutil.disk_usage(settings().getBaseFolder("uploads"))
@ -48,15 +58,24 @@ def readGcodeFilesForOrigin(origin):
return jsonify(files=files)
def _getFileDetails(origin, filename):
files = _getFileList(origin)
for file in files:
if file["name"] == filename:
return file
return None
def _getFileDetails(origin, path):
files = _getFileList(origin, recursive=True)
path = path.split('/')
def recursive_get_filedetails(files, path):
for file in files:
if file["name"] == path[0]:
if len(path) > 1:
return recursive_get_filedetails(file["children"], path[1:])
else:
return file
return None
return recursive_get_filedetails(files, path)
def _getFileList(origin, filter=None):
def _getFileList(origin, filter=None, recursive=False):
if origin == FileDestinations.SDCARD:
sdFileList = printer.get_sd_files()
@ -78,45 +97,56 @@ def _getFileList(origin, filter=None):
filter_func = None
if filter:
filter_func = lambda entry, entry_data: octoprint.filemanager.valid_file_type(entry, type=filter)
files = fileManager.list_files(origin, filter=filter_func, recursive=False)[origin].values()
for file in files:
file["origin"] = FileDestinations.LOCAL
if "analysis" in file and octoprint.filemanager.valid_file_type(file["name"], type="gcode"):
file["gcodeAnalysis"] = file["analysis"]
del file["analysis"]
files = fileManager.list_files(origin, filter=filter_func, recursive=recursive)[origin].values()
if "history" in file and octoprint.filemanager.valid_file_type(file["name"], type="gcode"):
# convert print log
history = file["history"]
del file["history"]
success = 0
failure = 0
last = None
for entry in history:
success += 1 if "success" in entry and entry["success"] else 0
failure += 1 if "success" in entry and not entry["success"] else 0
if not last or ("timestamp" in entry and "timestamp" in last and entry["timestamp"] > last["timestamp"]):
last = entry
if last:
prints = dict(
success=success,
failure=failure,
last=dict(
success=last["success"],
date=last["timestamp"]
def recursive_analysis(files, path):
for file in files:
file["origin"] = FileDestinations.LOCAL
if file["type"] == "folder":
file["children"] = recursive_analysis(file["children"].values(), path + file["name"] + "/")
if "analysis" in file and octoprint.filemanager.valid_file_type(file["name"], type="gcode"):
file["gcodeAnalysis"] = file["analysis"]
del file["analysis"]
if "history" in file and octoprint.filemanager.valid_file_type(file["name"], type="gcode"):
# convert print log
history = file["history"]
del file["history"]
success = 0
failure = 0
last = None
for entry in history:
success += 1 if "success" in entry and entry["success"] else 0
failure += 1 if "success" in entry and not entry["success"] else 0
if not last or ("timestamp" in entry and "timestamp" in last and entry["timestamp"] > last["timestamp"]):
last = entry
if last:
prints = dict(
success=success,
failure=failure,
last=dict(
success=last["success"],
date=last["timestamp"]
)
)
)
if "printTime" in last:
prints["last"]["printTime"] = last["printTime"]
file["prints"] = prints
if "printTime" in last:
prints["last"]["printTime"] = last["printTime"]
file["prints"] = prints
file.update({
"refs": {
"resource": url_for(".readGcodeFile", target=FileDestinations.LOCAL, filename=path + file["name"], _external=True),
"download": url_for("index", _external=True) + "downloads/files/" + FileDestinations.LOCAL + "/" + path + file["name"]
}
})
return files
files = recursive_analysis(files, "")
file.update({
"refs": {
"resource": url_for(".readGcodeFile", target=FileDestinations.LOCAL, filename=file["name"], _external=True),
"download": url_for("index", _external=True) + "downloads/files/" + FileDestinations.LOCAL + "/" + file["name"]
}
})
return files
@ -166,24 +196,33 @@ def uploadGcodeFile(target):
# determine current job
currentFilename = None
currentFullPath = 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"]
if currentJobFile is not None and "name" in currentJobFile.keys() and "origin" in currentJobFile.keys() and currentJobFile["name"] is not None and currentJobFile["origin"] is not None:
currentPath, currentFilename = fileManager.sanitize(currentJobFile["origin"], currentJobFile["name"])
currentFullPath = fileManager.join_path(target, currentPath, currentFilename)
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)
futurePath, futureFilename = fileManager.sanitize(target, upload.filename)
except:
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:
futurePath = fileManager.sanitize_path(target, request.values["path"])
futureFullPath = fileManager.join_path(target, futurePath, futureFilename)
# prohibit overwriting currently selected file while it's being printed
if futureFilename == currentFilename and target == currentOrigin and printer.is_printing() or printer.is_paused():
if futureFullPath == currentFullPath 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):
@ -212,7 +251,7 @@ def uploadGcodeFile(target):
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)
added_file = fileManager.add_file(FileDestinations.LOCAL, futureFullPath, 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"):