Refactorings based on Commit comments

This commit is contained in:
Salandora 2015-10-09 19:51:36 +02:00
parent d719e3cdbf
commit 3458f9af43
6 changed files with 242 additions and 230 deletions

View file

@ -391,12 +391,12 @@ class FileManager(object):
self._storage(destination).remove_file(path)
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
def copy_file(self, destination, source, dst, allow_overwrite=False):
self._storage(destination).copy_file(source, dst, allow_overwrite)
def copy_file(self, destination, source, dst):
self._storage(destination).copy_file(source, dst)
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
def move_file(self, destination, source, dst, allow_overwrite=False):
self._storage(destination).move_file(source, dst, allow_overwrite)
def move_file(self, destination, source, dst):
self._storage(destination).move_file(source, dst)
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
def add_folder(self, destination, path, ignore_existing=True):
@ -412,8 +412,8 @@ class FileManager(object):
self._storage(destination).copy_folder(source, dst)
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
def move_folder(self, destination, source, dst, allow_overwrite=False):
self._storage(destination).move_folder(source, dst, allow_overwrite)
def move_folder(self, destination, source, dst):
self._storage(destination).move_folder(source, dst)
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
def get_metadata(self, destination, path):

View file

@ -139,7 +139,7 @@ class StorageInterface(object):
"""
raise NotImplementedError()
def move_folder(self, source, destination, allow_overwrite=False):
def move_folder(self, source, destination):
"""
Moves the folder ``source`` to ``destination``
@ -172,7 +172,7 @@ class StorageInterface(object):
"""
raise NotImplementedError()
def copy_file(self, source, destination, allow_overwrite=False):
def copy_file(self, source, destination):
"""
Copys the file ``source`` to ``destination``
@ -181,7 +181,7 @@ class StorageInterface(object):
"""
raise NotImplementedError()
def move_file(self, source, destination, allow_overwrite=False):
def move_file(self, source, destination):
"""
Moves the file ``source`` to ``destination``
@ -429,6 +429,9 @@ class LocalFileStorage(StorageInterface):
yield self.join_path(entry, sub_entry[0]), sub_entry[1], sub_entry[2]
def file_in_path(self, path, filepath):
filepath = self.sanitize_path(filepath)
path = self.sanitize_path(path)
return filepath.startswith(path)
def file_exists(self, path):
@ -476,45 +479,69 @@ class LocalFileStorage(StorageInterface):
import shutil
shutil.rmtree(folder_path)
def _copyMove1(self, source, destination):
sourcepath, sourcename = self.sanitize(source)
destinationpath, destinationname = self.sanitize(destination)
source_path = os.path.join(sourcepath, sourcename)
if not os.path.exists(source_path):
raise RuntimeError("{sourcename} in {sourcepath} does not exist".format(**locals()))
destination_path = os.path.join(destinationpath, destinationname)
if os.path.exists(destination_path):
raise RuntimeError("{destinationname} does already exist in {destinationpath}".format(**locals()))
sourceObj = dict(
path=sourcepath,
name=sourcename,
fullpath=source_path,
)
destinationObj = dict(
path=destinationpath,
name=destinationname,
fullpath=destination_path,
)
return sourceObj, destinationObj
def _copyMove2(self, source, destination):
sourceObj, destinationObj = self._copyMove1(source, destination)
if not os.path.isfile(sourceObj["fullpath"]):
raise RuntimeError("%s in %s is not a file" % (sourceObj["name"], sourceObj["path"]))
sourcemetadata = self._get_metadata(sourceObj["path"])
if not sourcemetadata:
sourcemetadata = dict()
destinationmetadata = self._get_metadata(destinationObj["path"])
if not destinationmetadata:
destinationmetadata = dict()
sourceObj.update(dict(metadata=sourcemetadata))
destinationObj.update(dict(metadata=destinationmetadata))
return sourceObj, destinationObj
def copy_folder(self, source, destination):
sourcepath, sourcename = self.sanitize(source)
destinationpath, destinationname = self.sanitize(destination)
sourceObj, destinationObj = self._copyMove1(source, destination)
sourcefolder_path = os.path.join(sourcepath, sourcename)
if not os.path.exists(sourcefolder_path):
return
if not os.path.isdir(sourcefolder_path):
raise RuntimeError("{name} in {path} is not a folder".format(**locals()))
destinationfolder_path = os.path.join(destinationpath, destinationname)
if os.path.exists(destinationfolder_path):
raise RuntimeError("{newname} does already exist in {newpath}".format(**locals()))
if not os.path.isdir(sourceObj["fullpath"]):
raise RuntimeError("%s in %s is not a folder" % (sourceObj["name"], sourceObj["path"]))
try:
shutil.copytree(sourcefolder_path, destinationfolder_path)
shutil.copytree(sourceObj["fullpath"], destinationObj["fullpath"])
except Exception as e:
raise RuntimeError("Could not copy {oldname} in {oldpath} to {newname} in {newpath}".format(**locals()), e)
raise RuntimeError("Could not copy %s in %s to %s in %s" % (sourceObj["name"], sourceObj["path"], destinationObj["name"], destinationObj["path"]), e)
def move_folder(self, source, destination, allow_overwrite=False):
sourcepath, sourcename = self.sanitize(source)
destinationpath, destinationname = self.sanitize(destination)
def move_folder(self, source, destination):
sourceObj, destinationObj = self._copyMove1(source, destination)
sourcefolder_path = os.path.join(sourcepath, sourcename)
if not os.path.exists(sourcefolder_path):
return
if not os.path.isdir(sourcefolder_path):
raise RuntimeError("{name} in {path} is not a folder".format(**locals()))
destinationfolder_path = os.path.join(destinationpath, destinationname)
if os.path.exists(destinationfolder_path) and not allow_overwrite:
raise RuntimeError("{newname} does already exist in {newpath} and overwriting is prohibited".format(**locals()))
if not os.path.isdir(sourceObj["fullpath"]):
raise RuntimeError("%s in %s is not a folder" % (sourceObj["name"], sourceObj["path"]))
try:
shutil.move(sourcefolder_path, destinationfolder_path)
shutil.move(sourceObj["fullpath"], destinationObj["fullpath"])
except Exception as e:
raise RuntimeError("Could not move {oldname} in {oldpath} to {newname} in {newpath}".format(**locals()), e)
raise RuntimeError("Could not move %s in %s to %s in %s" % (sourceObj["name"], sourceObj["path"], destinationObj["name"], destinationObj["path"]), e)
def add_file(self, path, file_object, printer_profile=None, links=None, allow_overwrite=False):
path, name = self.sanitize(path)
@ -585,83 +612,41 @@ class LocalFileStorage(StorageInterface):
if not "links" in m:
continue
for link in m["links"]:
if "rel" in link and "hash" in link and (link["rel"] == "model" or link["rel"] == "machinecode") and link["hash"] == hash:
if "rel" in link and "hash" in link and (
link["rel"] == "model" or link["rel"] == "machinecode") and link["hash"] == hash:
m["links"].remove(link)
del metadata[name]
self._save_metadata(path, metadata)
def copy_file(self, source, destination, allow_overwrite=False):
sourcepath, sourcename = self.sanitize(source)
destinationpath, destinationname = self.sanitize(destination)
oldmetadata = self._get_metadata(sourcepath)
if not oldmetadata:
oldmetadata = dict()
newmetadata = self._get_metadata(destinationpath)
if not newmetadata:
newmetadata = dict()
sourcefile_path = os.path.join(sourcepath, sourcename)
if not os.path.exists(sourcefile_path):
return
if not os.path.isfile(sourcefile_path):
raise RuntimeError("{oldname} in {oldpath} is not a file".format(**locals()))
destinationfile_path = os.path.join(destinationpath, destinationname)
if os.path.exists(destinationfile_path) and not allow_overwrite:
raise RuntimeError("{newname} does already exist in {newpath} and overwriting is prohibited".format(**locals()))
def copy_file(self, source, destination):
sourceObj, destinationObj = self._copyMove2(source, destination)
try:
shutil.copy2(sourcefile_path, destinationfile_path)
shutil.copy2(sourceObj["fullpath"], destinationObj["fullpath"])
except Exception as e:
raise RuntimeError("Could not copy {oldname} in {oldpath} to {newname} in {newpath}".format(**locals()), e)
raise RuntimeError("Could not copy %s in %s to %s in %s" % (sourceObj["name"], sourceObj["path"], destinationObj["name"], destinationObj["path"]), e)
if sourcename in oldmetadata:
metadata = oldmetadata[sourcename]
newmetadata[destinationname] = metadata
newmetadata[destinationname]["hash"] = self._create_hash(destinationfile_path)
self._save_metadata(destinationpath, newmetadata)
if sourceObj["name"] in sourceObj["metadata"]:
destinationObj["metadata"][destinationObj["name"]] = sourceObj["metadata"][sourceObj["name"]]
destinationObj["metadata"][destinationObj["name"]]["hash"] = self._create_hash(destinationObj["fullpath"])
self._save_metadata(destinationObj["path"], destinationObj["metadata"])
def move_file(self, source, destination, allow_overwrite=False):
sourcepath, sourcename = self.sanitize(source)
destinationpath, destinationname = self.sanitize(destination)
oldmetadata = self._get_metadata(sourcepath)
if not oldmetadata:
oldmetadata = dict()
newmetadata = self._get_metadata(destinationpath)
if not newmetadata:
newmetadata = dict()
sourcefile_path = os.path.join(sourcepath, sourcename)
if not os.path.exists(sourcefile_path):
return
if not os.path.isfile(sourcefile_path):
raise RuntimeError("{oldname} in {oldpath} is not a file".format(**locals()))
destinationfile_path = os.path.join(destinationpath, destinationname)
if os.path.exists(destinationfile_path) and not allow_overwrite:
raise RuntimeError("{newname} does already exist in {newpath} and overwriting is prohibited".format(**locals()))
sourceObj, destinationObj = self._copyMove2(source, destination)
try:
shutil.move(sourcefile_path, destinationfile_path)
shutil.move(sourceObj["fullpath"], destinationObj["fullpath"])
except Exception as e:
raise RuntimeError("Could not move {oldname} in {oldpath} to {newname} in {newpath}".format(**locals()), e)
raise RuntimeError("Could not move %s in %s to %s in %s" % (sourceObj["name"], sourceObj["path"], destinationObj["name"], destinationObj["path"]), e)
if sourcename in oldmetadata:
metadata = oldmetadata[sourcename]
del oldmetadata[sourcename]
self._save_metadata(sourcepath, oldmetadata)
newmetadata[destinationname] = metadata
newmetadata[destinationname]["hash"] = self._create_hash(destinationfile_path)
self._save_metadata(destinationpath, newmetadata)
if sourceObj["name"] in sourceObj["metadata"]:
metadata = sourceObj["metadata"][sourceObj["name"]]
del sourceObj["metadata"][sourceObj["name"]]
self._save_metadata(sourceObj["path"], sourceObj["metadata"])
destinationObj["metadata"][destinationObj["name"]] = metadata
destinationObj["metadata"][destinationObj["name"]]["hash"] = self._create_hash(destinationObj["fullpath"])
self._save_metadata(destinationObj["path"], destinationObj["metadata"])
def get_metadata(self, path):
path, name = self.sanitize(path)
@ -1160,25 +1145,18 @@ class LocalFileStorage(StorageInterface):
)
if not filter or filter(entry, entry_data):
def get_size(start_path):
def get_size():
total_size = 0
for root, dirs, files in os.walk(start_path):
for f in files:
if f is ".metadata.yaml":
continue
fp = os.path.join(root, f)
total_size += os.path.getsize(fp)
for element in entry_data["children"].itervalues():
if "size" in element:
total_size += element["size"]
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)
stat = os.stat(entry_path)
if stat:
extended_entry_data["date"] = int(stat.st_ctime)
extended_entry_data["size"] = get_size()
result[entry] = extended_entry_data

View file

@ -25,13 +25,8 @@ import psutil
@api.route("/files", methods=["GET"])
def readGcodeFiles():
filter = None
recursive = False
if "filter" in request.values:
filter = request.values["filter"]
if "recursive" in request.values:
recursive = request.values["recursive"] == 'true'
filter = "filter" in request.values and request.values["recursive"] in valid_boolean_trues
recursive = "recursive" in request.values and request.values["recursive"] in valid_boolean_trues
files = _getFileList(FileDestinations.LOCAL, filter=filter, recursive=recursive)
files.extend(_getFileList(FileDestinations.SDCARD))
@ -62,17 +57,40 @@ 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
if len(path) == 1:
# shortcut for files in the root folder
name = path[0]
for f in files:
if f["name"] == name:
return f
return None
return recursive_get_filedetails(files, path)
node = files
while path:
segment = path.pop(0)
for f in node:
if not f["name"] == segment:
# wrong name => next!
continue
if not path:
# no path left and name matches => found it!
return f
if not f["type"] == "folder":
# path left but not a folder => that doesn't work
return None
# we'll use this folder's children as the next iteration
node = f["children"]
break
else:
# nothing matched the name, we can't find it
return None
# nothing returned until now => not found
return None
def _getFileList(origin, filter=None, recursive=False):
@ -100,52 +118,55 @@ def _getFileList(origin, filter=None, recursive=False):
files = fileManager.list_files(origin, filter=filter_func, recursive=recursive)[origin].values()
def recursive_analysis(files, path):
def analyse_recursively(files, path=None):
if path is None:
path = ""
for file in files:
file["origin"] = FileDestinations.LOCAL
if file["type"] == "folder":
file["children"] = recursive_analysis(file["children"].values(), path + file["name"] + "/")
file["children"] = analyse_recursively(file["children"].values(), path + file["name"] + "/")
else:
if "analysis" in file and octoprint.filemanager.valid_file_type(file["name"], type="gcode"):
file["gcodeAnalysis"] = file["analysis"]
del file["analysis"]
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 "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"]
}
})
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, "")
analyse_recursively(files)
return files
@ -164,13 +185,17 @@ def _verifyFolderExists(origin, foldername):
return fileManager.folder_exists(origin, foldername)
def _verifyFolderNotBusy(target, foldername):
def _isBusy(target, path):
currentOrigin, currentFilename = _getCurrentFile()
if currentFilename is not None and fileManager.file_in_path(target, path, currentFilename) and currentOrigin == target and (printer.is_printing() or printer.is_paused()):
return True
busy_files = fileManager.get_busy_files()
for item in busy_files:
if target == item[0] and fileManager.file_in_path(target, foldername, item[1]):
return False
if target == item[0] and fileManager.file_in_path(target, path, item[1]):
return True
return True
return False
@api.route("/files/<string:target>", methods=["POST"])
@restricted_access
@ -312,14 +337,13 @@ def uploadGcodeFile(target):
r = make_response(jsonify(files=files, done=done), 201)
r.headers["Location"] = location
return r
else:
if "foldername" not in request.json:
return make_response("No path information or no file included", 409)
elif "foldername" in request.values:
foldername = request.values["foldername"]
if not target in [FileDestinations.LOCAL]:
return make_response("Unknown target: %s" % target, 404)
return make_response("Unknown target: %s" % target, 400)
futurePath, futureName = fileManager.sanitize(target, request.json["foldername"])
futurePath, futureName = fileManager.sanitize(target, foldername)
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)
@ -327,6 +351,8 @@ def uploadGcodeFile(target):
added_folder = fileManager.add_folder(target, futureFullPath)
if added_folder is None:
return make_response("Could not create folder %s" % futureName, 500)
else:
return make_response("No file to upload and no folder to create", 400)
return NO_CONTENT
@ -496,44 +522,37 @@ def gcodeFileCommand(filename, target):
elif command == "copy" or command == "move":
# Copy and move are only possible on local storage
if not target in [FileDestinations.LOCAL]:
return make_response("Unknown target: %s" % target, 404)
return make_response("Unsupported target for {}: {}".format(command, target), 400)
if not _verifyFileExists(target, filename) and not _verifyFolderExists(target, filename):
return make_response("File/Folder not found on '%s': %s" % (target, filename), 404)
overwrite = data["overwrite"] if "overwrite" in data else False
destination = data["destination"]
if _verifyFolderExists(target, destination):
path, name = fileManager.split_path(target, filename)
destination = fileManager.join_path(target, destination, name)
if fileManager.file_exists(target, destination) and not overwrite:
return make_response("File already exists and overwrite is prohibited: %s" % filename, 409)
if _verifyFileExists(target, destination) or _verifyFolderExists(target, destination):
return make_response("File/Folder already exists: %s" % filename, 409)
if command == "copy":
if fileManager.file_exists(target, filename):
fileManager.copy_file(target, filename, destination, overwrite)
fileManager.copy_file(target, filename, destination)
elif fileManager.folder_exists(target, filename):
fileManager.copy_folder(target, filename, destination)
elif command == "move":
# prohibit deleting or moving files that are currently in use
currentOrigin, currentFilename = _getCurrentFile()
if currentFilename is not None and fileManager.file_in_path(target, filename, currentFilename) and currentOrigin == target and (printer.is_printing() or printer.is_paused()):
return make_response("Trying to delete a folder that contains a file that is currently being printed: %s" % filename, 409)
if not _verifyFolderNotBusy(target, filename):
return make_response("Trying to delete a folder that contains a file that is currently in use: %s" % filename, 409)
if _isBusy(target, filename):
return make_response("Trying to move a file/folder that is currently in use: %s" % filename, 409)
# deselect the file if it's currently selected
currentOrigin, currentFilename = _getCurrentFile()
if currentFilename is not None and filename == currentFilename:
printer.unselect_file()
if fileManager.file_exists(target, filename):
fileManager.move_file(target, filename, destination, overwrite)
fileManager.move_file(target, filename, destination)
elif fileManager.folder_exists(target, filename):
fileManager.move_folder(target, filename, destination, overwrite)
fileManager.move_folder(target, filename, destination)
return NO_CONTENT
@ -546,18 +565,13 @@ def deleteGcodeFile(filename, target):
if _verifyFileExists(target, filename):
if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
return make_response("Unknown target: %s" % target, 404)
return make_response("Unknown target: %s" % target, 400)
# prohibit deleting files that are currently in use
currentOrigin, currentFilename = _getCurrentFile()
if currentFilename is not None and currentFilename == filename and currentOrigin == target and (printer.is_printing() or printer.is_paused()):
return make_response("Trying to delete file that is currently being printed: %s" % filename, 409)
if not _verifyFolderNotBusy(target, filename):
if _isBusy(target, filename):
return make_response("Trying to delete a file that is currently in use: %s" % filename, 409)
# deselect the file if it's currently selected
currentOrigin, currentFilename = _getCurrentFile()
if currentFilename is not None and filename == currentFilename:
printer.unselect_file()
@ -569,19 +583,14 @@ def deleteGcodeFile(filename, target):
elif _verifyFolderExists(target, filename):
if not target in [FileDestinations.LOCAL]:
return make_response("Unknown target: %s" % target, 404)
return make_response("Unknown target: %s" % target, 400)
folderpath = filename
# prohibit deleting folders that are currently in use
currentOrigin, currentFilename = _getCurrentFile()
if currentFilename is not None and fileManager.file_in_path(target, folderpath, currentFilename) and currentOrigin == target and (printer.is_printing() or printer.is_paused()):
return make_response("Trying to delete a folder that contains a file that is currently being printed: %s" % folderpath, 409)
if not _verifyFolderNotBusy(target, folderpath):
if _isBusy(target, folderpath):
return make_response("Trying to delete a folder that contains a file that is currently in use: %s" % folderpath, 409)
# deselect the file if it's currently selected
currentOrigin, currentFilename = _getCurrentFile()
if currentFilename is not None and fileManager.file_in_path(target, folderpath, currentFilename):
printer.unselect_file()

View file

@ -47,11 +47,13 @@
get: getFile,
list: function (opts) {
return OctoPrint.get(url, opts).done(preProcessList);
return OctoPrint.get(url, opts)
.done(preProcessList);
},
listForLocation: function (location, opts) {
return OctoPrint.get(resourceForLocation(location), opts).done(preProcessList);
return OctoPrint.get(resourceForLocation(location), opts)
.done(preProcessList);
},
select: function (location, filename, print, opts) {
@ -73,6 +75,23 @@
return OctoPrint.delete(resourceForFile(location, filename), opts);
},
copy: function(location, filename, destination, opts) {
return issueFileCommand(location, filename, "copy", { destination: destination }, opts);
},
move: function(location, filename, destination, opts) {
return issueFileCommand(location, filename, "move", { destination: destination }, opts);
},
createFolder: function (location, name, path) {
var data = "foldername=" + name;
if (path != undefined && path != "") {
data = "foldername:" + path + "/" + name;
}
return OctoPrint.post(resourceForLocation(location), data);
},
upload: function (location, file, data) {
data = data || {};

View file

@ -99,10 +99,7 @@ $(function() {
return data["type"] && (data["type"] == "model" || data["type"] == "folder");
},
"emptyFolder": function(data) {
if (data["type"] && data["type"] != "folder")
return true;
return data.children.length != 0;
return data["type"] && (data["type"] != "folder" || data["children"].length != 0);
}
},
"name",
@ -115,6 +112,7 @@ $(function() {
var filter = function(data) { return data["type"] && data["type"] == "folder"; };
return _.filter(self.listHelper.paginatedItems(), filter);
});
self.filesOnlyList = ko.dependentObservable(function() {
var filter = function(data) { return data["type"] && data["type"] != "folder"; };
return _.filter(self.listHelper.paginatedItems(), filter);
@ -215,6 +213,7 @@ $(function() {
self.currentPath(OctoPrint.files.pathForElement(data));
self.listHelper.updateItems(data.children);
};
self.changeFolderByPath = function(path) {
var element = OctoPrint.files.elementByPath(path, { children: self.allItems() });
if (element) {
@ -245,15 +244,18 @@ $(function() {
}
var index = self.listHelper.paginatedItems().indexOf(file) + 1;
if (index >= self.listHelper.paginatedItems().length)
if (index >= self.listHelper.paginatedItems().length) {
index = index - 2;
if (index < 0)
}
if (index < 0) {
index = 0;
}
var filenameToFocus = undefined;
var fileToFocus = self.listHelper.paginatedItems()[index];
if (fileToFocus)
if (fileToFocus) {
filenameToFocus = fileToFocus.name;
}
OctoPrint.files.delete(file.origin, OctoPrint.files.pathForElement(file))
.done(function() {

View file

@ -7,25 +7,27 @@
<!-- /ko -->
<!-- ko if: listStyle() == 'folders_files' -->
<!-- ko slimScrolledForeach: foldersOnlyList -->
<div class="entry" data-bind="attr: { id: $root.getEntryId($data) }, template: { name: $root.templateFor($data), data: $data }"></div>
<!-- /ko -->
<!-- ko slimScrolledForeach: filesOnlyList -->
<div class="entry" data-bind="attr: { id: $root.getEntryId($data) }, template: { name: $root.templateFor($data), data: $data }"></div>
<!-- /ko -->
<!-- ko slimScrolledForeach: foldersOnlyList -->
<div class="entry" data-bind="attr: { id: $root.getEntryId($data) }, template: { name: $root.templateFor($data), data: $data }"></div>
<!-- /ko -->
<!-- ko slimScrolledForeach: filesOnlyList -->
<div class="entry" data-bind="attr: { id: $root.getEntryId($data) }, template: { name: $root.templateFor($data), data: $data }"></div>
<!-- /ko -->
<!-- /ko -->
<!-- ko if: listStyle() == 'files_folders' -->
<!-- ko slimScrolledForeach: filesOnlyList -->
<div class="entry" data-bind="attr: { id: $root.getEntryId($data) }, template: { name: $root.templateFor($data), data: $data }"></div>
<!-- /ko -->
<!-- ko slimScrolledForeach: foldersOnlyList -->
<div class="entry" data-bind="attr: { id: $root.getEntryId($data) }, template: { name: $root.templateFor($data), data: $data }"></div>
<!-- /ko -->
<!-- ko slimScrolledForeach: filesOnlyList -->
<div class="entry" data-bind="attr: { id: $root.getEntryId($data) }, template: { name: $root.templateFor($data), data: $data }"></div>
<!-- /ko -->
<!-- ko slimScrolledForeach: foldersOnlyList -->
<div class="entry" data-bind="attr: { id: $root.getEntryId($data) }, template: { name: $root.templateFor($data), data: $data }"></div>
<!-- /ko -->
<!-- /ko -->
<!-- ko if: listStyle() == 'mixed' -->
<!-- ko slimScrolledForeach: listHelper.paginatedItems -->
<div class="entry" data-bind="attr: { id: $root.getEntryId($data) }, template: { name: $root.templateFor($data), data: $data }"></div>
<!-- /ko -->
<!-- ko slimScrolledForeach: listHelper.paginatedItems -->
<div class="entry" data-bind="attr: { id: $root.getEntryId($data) }, template: { name: $root.templateFor($data), data: $data }"></div>
<!-- /ko -->
<!-- /ko -->
<script type="text/html" id="files_template_machinecode">
@ -54,8 +56,10 @@
</script>
<script type="text/html" id="files_template_folder">
<div class="title" data-bind="click: $root.changeFolder"><i class="icon-folder-open"></i> <span data-bind="text: name"></span></div>
<div class="size">{{ _('Size') }}: <span data-bind="text: formatSize(size)"></span></div>
<div data-bind="click: $root.changeFolder">
<div class="title"><i class="icon-folder-open"></i> <span data-bind="text: name"></span></div>
<div class="size">{{ _('Size') }}: <span data-bind="text: formatSize(size)"></span></div>
</div>
</script>
</div>
<div class="text-right muted" data-bind="attr: {title: diskusageString}, css: {'text-error': diskusageCritical}, style: {'font-weight': diskusageCritical() || diskusageWarning() ? 'bold' : 'normal'}">