diff --git a/composer.json b/composer.json index 8a5ec973..d1e3fe69 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,6 @@ "vendor-dir": "connectors/php/vendor" }, "require": { - "servocoder/richfilemanager-php": "1.1.*" + "servocoder/richfilemanager-php": "dev-dev" } } \ No newline at end of file diff --git a/config/filemanager.config.default.json b/config/filemanager.config.default.json index da532437..9737d5d9 100644 --- a/config/filemanager.config.default.json +++ b/config/filemanager.config.default.json @@ -5,7 +5,6 @@ "showTitleAttr": false, "showConfirmation": true, "browseOnly": false, - "searchBox": true, "fileSorting": "NAME_ASC", "folderPosition": "bottom", "quickSelect": false, @@ -20,12 +19,18 @@ "copy", "move", "delete", - "extract" + "extract", + "createFolder" ] }, "language": { "default": "en", - "available": ["ar", "bs", "ca", "cs", "da", "de", "el", "en", "es", "fa", "fi", "fr", "he", "hu", "it", "ja", "nl", "pl", "pt", "ru", "sv", "th", "tr", "vn", "zh-cn", "zh-tw"] + "available": ["ar", "bs", "ca", "cs", "da", "de", "el", "en", "es", "fa", "fi", "fr", "he", "hu", "it", "ja", "nl", "pl", "pt", "ru", "sv", "th", "tr", "vi", "zh-CN", "zh-TW"] + }, + "formatter": { + "datetime": { + "skeleton": "yMMMdHm" + } }, "filetree": { "enabled": true, @@ -74,6 +79,12 @@ "audio": ["ogg", "mp3", "wav"], "video": ["ogv", "avi", "mkv", "mp4", "webm", "m4v"] }, + "search": { + "enabled": true, + "recursive": false, + "caseSensitive": false, + "typingDelay": 500 + }, "viewer": { "absolutePath": true, "previewUrl": false, @@ -181,5 +192,5 @@ "extra_js_async": true }, "url": "https://github.com/servocoder/RichFilemanager", - "version": "2.6.5" + "version": "2.7.0" } diff --git a/connectors/ashx/filemanager.ashx b/connectors/ashx/filemanager.ashx index fecc4f86..157c5c66 100644 --- a/connectors/ashx/filemanager.ashx +++ b/connectors/ashx/filemanager.ashx @@ -378,7 +378,7 @@ public class filemanager : IHttpHandler context.Response.ContentEncoding = Encoding.UTF8; context.Response.Write(Initiate()); break; - case "getfolder": + case "readfolder": context.Response.ContentType = "plain/text"; context.Response.ContentEncoding = Encoding.UTF8; context.Response.Write(getInfo(context.Request["path"])); diff --git a/connectors/asp/FileManagerController.cs b/connectors/asp/FileManagerController.cs index 67306b19..833673d8 100644 --- a/connectors/asp/FileManagerController.cs +++ b/connectors/asp/FileManagerController.cs @@ -39,8 +39,8 @@ public IActionResult Index(string mode, string path, string name, List + Title = "DIRECTORY_ALREADY_EXISTS", + Meta = new { - name + Arguments = new List + { + name + } } }); @@ -239,10 +230,13 @@ private async Task Upload(string path, IEnumerable files) errorResult.Errors.Add(new { Code = "500", - Message = "FILE_ALREADY_EXISTS", - Arguments = new List + Title = "FILE_ALREADY_EXISTS", + Meta = new { - file.FileName + Arguments = new List + { + file.FileName + } } }); @@ -297,10 +291,13 @@ private dynamic Rename(string old, string @new) errorResult.Errors.Add(new { Code = "500", - Message = "DIRECTORY_ALREADY_EXISTS", - Arguments = new List + Title = "DIRECTORY_ALREADY_EXISTS", + Meta = new { - @new + Arguments = new List + { + @new + } } }); @@ -345,10 +342,13 @@ private dynamic Rename(string old, string @new) errorResult.Errors.Add(new { Code = "500", - Message = "FILE_ALREADY_EXISTS", - Arguments = new List + Title = "FILE_ALREADY_EXISTS", + Meta = new { - @new + Arguments = new List + { + @new + } } }); @@ -400,10 +400,13 @@ private dynamic Move(string old, string @new) errorResult.Errors.Add(new { Code = "500", - Message = "DIRECTORY_ALREADY_EXISTS", - Arguments = new List + Title = "DIRECTORY_ALREADY_EXISTS", + Meta = new { - directoryName + Arguments = new List + { + directoryName + } } }); @@ -451,10 +454,13 @@ private dynamic Move(string old, string @new) errorResult.Errors.Add(new { Code = "500", - Message = "FILE_ALREADY_EXISTS", - Arguments = new List + Title = "FILE_ALREADY_EXISTS", + Meta = new { - fileName + Arguments = new List + { + fileName + } } }); @@ -506,10 +512,13 @@ private dynamic Copy(string source, string target) errorResult.Errors.Add(new { Code = "500", - Message = "DIRECTORY_ALREADY_EXISTS", - Arguments = new List + Title = "DIRECTORY_ALREADY_EXISTS", + Meta = new { - directoryName + Arguments = new List + { + directoryName + } } }); @@ -553,10 +562,13 @@ private dynamic Copy(string source, string target) errorResult.Errors.Add(new { Code = "500", - Message = "FILE_ALREADY_EXISTS", - Arguments = new List + Title = "FILE_ALREADY_EXISTS", + Meta = new { - fileName + Arguments = new List + { + fileName + } } }); @@ -588,36 +600,6 @@ private dynamic Copy(string source, string target) } } - private dynamic EditFile(string path) - { - var fileName = Path.GetFileName(path); - var fileExtension = Path.GetExtension(path).Replace(".", ""); - var filePath = Path.Combine(_webRootPath, path); - - var content = System.IO.File.ReadAllText(filePath, Encoding.UTF8); - - var result = new - { - Data = new - { - Id = path, - Type = "file", - Attributes = new - { - Name = fileName, - Extension = fileExtension, - Writable = 1, - Readable = 1, - // created vb. - Content = content, - Path = $"/{Path.Combine(path)}" - } - } - }; - - return result; - } - private dynamic SaveFile(string path, string content) { var filePath = Path.Combine(_webRootPath, path); @@ -707,56 +689,43 @@ private dynamic Delete(string path) } } - private dynamic Download(string path) + private dynamic ReadFile(string path) { - var fileName = Path.GetFileName(Path.Combine(_webRootPath, path)); - var fileExtension = Path.GetExtension(fileName).Replace(".", ""); - - // undone dosya var m kontrol... + var filePath = Path.Combine(_webRootPath, path); + var fileName = Path.GetFileName(filePath); + byte[] fileBytes = System.IO.File.ReadAllBytes(filePath); - var result = new + var cd = new ContentDisposition { - Data = new - { - Id = path, - Type = "file", - Attributes = new - { - Name = fileName, - Extension = fileExtension, - Readable = 1, - Writable = 1, - // created date, size vb. - Modified = DateTime.Now.ToString(CultureInfo.InvariantCulture), - //Path = $"{path}" - } - } + Inline = true, + FileName = fileName }; + Response.AddHeader("Content-Disposition", cd.ToString()); - return result; - + return File(fileBytes, "application/octet-stream"); } - private dynamic DownloadFile(string path) + private IActionResult GetImage(string path, bool thumbnail) { - var filepath = Path.Combine(_webRootPath, path); - var fileName = Path.GetFileName(filepath); - byte[] fileBytes = System.IO.File.ReadAllBytes(filepath); + var filePath = Path.Combine(_webRootPath, path); + var fileName = Path.GetFileName(filePath); + byte[] fileBytes = System.IO.File.ReadAllBytes(filePath); - var file = new + var cd = new ContentDisposition { - FileName = fileName, - FileBytes = fileBytes + Inline = true, + FileName = fileName }; + Response.AddHeader("Content-Disposition", cd.ToString()); - return file; + return File(fileBytes, "image/*"); } - private IActionResult GetImage(string path, bool thumbnail) + private dynamic Download(string path) { - var filepath = Path.Combine(_webRootPath, path); - var fileName = Path.GetFileName(filepath); - byte[] fileBytes = System.IO.File.ReadAllBytes(filepath); + var filePath = Path.Combine(_webRootPath, path); + var fileName = Path.GetFileName(filePath); + byte[] fileBytes = System.IO.File.ReadAllBytes(filePath); return File(fileBytes, "application/x-msdownload", fileName); } @@ -769,8 +738,6 @@ private dynamic Summarize() var files = directoryInfo.GetFiles("*", SearchOption.AllDirectories); var allSize = files.Select(f => f.Length).Sum(); - - var result = new { Data = new diff --git a/connectors/java/src/main/java/com/fabriceci/fmc/AbstractFileManager.java b/connectors/java/src/main/java/com/fabriceci/fmc/AbstractFileManager.java index 12f86301..321bc524 100644 --- a/connectors/java/src/main/java/com/fabriceci/fmc/AbstractFileManager.java +++ b/connectors/java/src/main/java/com/fabriceci/fmc/AbstractFileManager.java @@ -126,14 +126,14 @@ public final void handleRequest(HttpServletRequest request, HttpServletResponse case "initiate": responseData = actionInitiate(request); break; - case "getfile": + case "getinfo": if (!StringUtils.isEmpty(request.getParameter("path"))) { - responseData = actionGetFile(request); + responseData = actionGetInfo(request); } break; - case "getfolder": + case "readfolder": if (!StringUtils.isEmpty(request.getParameter("path"))) { - responseData = actionGetFolder(request); + responseData = actionReadFolder(request); } break; case "rename": @@ -233,7 +233,7 @@ protected final JSONObject getErrorResponse(String msg) { try { errorInfo.put("id", "server"); errorInfo.put("code", "500"); - errorInfo.put("message", msg); + errorInfo.put("title", msg); } catch (JSONException e) { logger.error("JSONObject error"); @@ -303,12 +303,12 @@ protected final boolean hasPermission(String action){ } @Override - public JSONObject actionGetFile(HttpServletRequest request) throws FileManagerException { + public JSONObject actionGetInfo(HttpServletRequest request) throws FileManagerException { throw new UnsupportedOperationException(); } @Override - public JSONObject actionGetFolder(HttpServletRequest request) throws FileManagerException { + public JSONObject actionReadFolder(HttpServletRequest request) throws FileManagerException { throw new UnsupportedOperationException(); } diff --git a/connectors/java/src/main/java/com/fabriceci/fmc/IFileManager.java b/connectors/java/src/main/java/com/fabriceci/fmc/IFileManager.java index c318fde6..6a2d28e4 100644 --- a/connectors/java/src/main/java/com/fabriceci/fmc/IFileManager.java +++ b/connectors/java/src/main/java/com/fabriceci/fmc/IFileManager.java @@ -12,9 +12,9 @@ public interface IFileManager { JSONObject actionInitiate(HttpServletRequest request) throws FileManagerException; - JSONObject actionGetFile(HttpServletRequest request) throws FileManagerException; + JSONObject actionGetInfo(HttpServletRequest request) throws FileManagerException; - JSONObject actionGetFolder(HttpServletRequest request) throws FileManagerException; + JSONObject actionReadFolder(HttpServletRequest request) throws FileManagerException; JSONObject actionReadFile(HttpServletRequest request, HttpServletResponse response) throws FileManagerException; diff --git a/connectors/java/src/main/java/com/fabriceci/fmc/impl/LocalFileManager.java b/connectors/java/src/main/java/com/fabriceci/fmc/impl/LocalFileManager.java index f62db4b1..3d9805e2 100644 --- a/connectors/java/src/main/java/com/fabriceci/fmc/impl/LocalFileManager.java +++ b/connectors/java/src/main/java/com/fabriceci/fmc/impl/LocalFileManager.java @@ -57,7 +57,7 @@ public LocalFileManager(Locale locale, Map options) throws FMInit } @Override - public JSONObject actionGetFolder(HttpServletRequest request) throws FileManagerException { + public JSONObject actionReadFolder(HttpServletRequest request) throws FileManagerException { String path = getPath(request, "path"); String type = request.getParameter("type"); @@ -109,15 +109,11 @@ public JSONObject actionGetFolder(HttpServletRequest request) throws FileManager } @Override - public JSONObject actionGetFile(HttpServletRequest request) throws FileManagerException { + public JSONObject actionGetInfo(HttpServletRequest request) throws FileManagerException { String path = getPath(request, "path"); File file = new File(docRoot.getPath() + path); - if (file.isDirectory()) { - return getErrorResponse(dictionnary.getProperty("FORBIDDEN_ACTION_DIR")); - } - // check if the name is not in "excluded" list String filename = file.getName(); @@ -440,50 +436,44 @@ public JSONObject actionDownload(HttpServletRequest request, HttpServletResponse } } - // Ajax - if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) { - return new JSONObject().put("data", new JSONObject(getFileInfo(path))); - } else { - - try { - response.setHeader("Content-Description", "File Transfer"); - if (file.isFile()) { - String fileExt = filename.substring(filename.lastIndexOf(".") + 1); - String mimeType = (!StringUtils.isEmpty(FileManagerUtils.mimetypes.get(fileExt))) ? FileManagerUtils.mimetypes.get(fileExt) : "application/octet-stream"; - response.setContentLength((int) file.length()); - response.setContentType(mimeType); - response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); - response.setContentLength((int) file.length()); - - FileUtils.copy(new BufferedInputStream(new FileInputStream(file)), response.getOutputStream()); - } else { - String[] files = file.list(); - - if (files == null || files.length == 0) { - return getErrorResponse(String.format(dictionnary.getProperty("DIRECTORY_EMPTY"), file.getName())); - } + try { + response.setHeader("Content-Description", "File Transfer"); + if (file.isFile()) { + String fileExt = filename.substring(filename.lastIndexOf(".") + 1); + String mimeType = (!StringUtils.isEmpty(FileManagerUtils.mimetypes.get(fileExt))) ? FileManagerUtils.mimetypes.get(fileExt) : "application/octet-stream"; + response.setContentLength((int) file.length()); + response.setContentType(mimeType); + response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); + response.setContentLength((int) file.length()); + + FileUtils.copy(new BufferedInputStream(new FileInputStream(file)), response.getOutputStream()); + } else { + String[] files = file.list(); - String zipFileName = FileUtils.getBaseName(path.substring(0, path.length() - 1)) + ".zip"; - String mimType = FileManagerUtils.mimetypes.get("zip"); - response.setContentType(mimType); - response.setHeader("Content-Disposition", "attachment; filename=\"" + zipFileName + "\""); - byte[] zipFileByteArray; - try { - zipFileByteArray = ZipUtils.zipFolder(file); - } catch (IOException e) { - throw new FMIOException("Exception during ZipFiles", e); - } - response.setContentLength(zipFileByteArray.length); + if (files == null || files.length == 0) { + return getErrorResponse(String.format(dictionnary.getProperty("DIRECTORY_EMPTY"), file.getName())); + } - FileUtils.copy(new ByteArrayInputStream(zipFileByteArray), response.getOutputStream()); + String zipFileName = FileUtils.getBaseName(path.substring(0, path.length() - 1)) + ".zip"; + String mimType = FileManagerUtils.mimetypes.get("zip"); + response.setContentType(mimType); + response.setHeader("Content-Disposition", "attachment; filename=\"" + zipFileName + "\""); + byte[] zipFileByteArray; + try { + zipFileByteArray = ZipUtils.zipFolder(file); + } catch (IOException e) { + throw new FMIOException("Exception during ZipFiles", e); } + response.setContentLength(zipFileByteArray.length); - } catch (IOException e) { - throw new FMIOException("Download error: " + file.getName(), e); + FileUtils.copy(new ByteArrayInputStream(zipFileByteArray), response.getOutputStream()); } - return null; + } catch (IOException e) { + throw new FMIOException("Download error: " + file.getName(), e); } + + return null; } @Override diff --git a/connectors/java/src/main/resources/filemanager.config.default.properties b/connectors/java/src/main/resources/filemanager.config.default.properties index 98696c8b..e3b401a4 100644 --- a/connectors/java/src/main/resources/filemanager.config.default.properties +++ b/connectors/java/src/main/resources/filemanager.config.default.properties @@ -55,7 +55,7 @@ editRestrictions=txt,csv,md # Filter section # ------------------------ -# File types that are filtered out from the output list based on the type of filter ('getfolder' request) +# File types that are filtered out from the output list based on the type of filter ('readfolder' request) outputFilter_images=jpg,jpe,jpeg,gif,png,svg,bmp # ------------------------ diff --git a/connectors/java/src/main/resources/filemanager.lang.en.properties b/connectors/java/src/main/resources/filemanager.lang.en.properties index 7a1f5f25..d379b749 100644 --- a/connectors/java/src/main/resources/filemanager.lang.en.properties +++ b/connectors/java/src/main/resources/filemanager.lang.en.properties @@ -14,7 +14,6 @@ ERROR_MOVING_DIRECTORY:Error while moving the directory %s to %s. ERROR_MOVING_FILE:Error while moving the file %s to %s. ERROR_RENAMING_DIRECTORY:Error while renaming the directory %s to %s. ERROR_RENAMING_FILE:Error while renaming the file %s to %s. -ERROR_REPLACING_FILE:Please provide a file having the following extension: ERROR_SAVING_FILE:Error saving file. ERROR_SERVER:Server error. ERROR_UPLOADING_FILE:Error uploading file. diff --git a/connectors/java/src/main/resources/filemanager.lang.fr.properties b/connectors/java/src/main/resources/filemanager.lang.fr.properties index ff157287..af692439 100644 --- a/connectors/java/src/main/resources/filemanager.lang.fr.properties +++ b/connectors/java/src/main/resources/filemanager.lang.fr.properties @@ -14,7 +14,6 @@ ERROR_MOVING_DIRECTORY:Erreur lors du déplacement du dossier %s vers %s. ERROR_MOVING_FILE:Erreur lors du déplacement du fichier %s vers %s. ERROR_RENAMING_DIRECTORY:Erreur lors du renommage du répertoire %s vers %s. ERROR_RENAMING_FILE:Erreur lors du renommage du fichier %s vers %s. -ERROR_REPLACING_FILE:Veuillez fournir un fichier ayant l'extension suivante : ERROR_SAVING_FILE:Erreur lors de l'enregistrement du fichier. ERROR_SERVER:Erreur du serveur. ERROR_UPLOADING_FILE:Erreur durant le transfert. diff --git a/connectors/jsp/config.properties b/connectors/jsp/config.properties index aff62d9f..060e49c3 100644 --- a/connectors/jsp/config.properties +++ b/connectors/jsp/config.properties @@ -32,7 +32,7 @@ icons-default = default.png # Filter section # ------------------------ -# File types that are filtered out from the output list based on the type of filter ('getfolder' request) +# File types that are filtered out from the output list based on the type of filter ('readfolder' request) outputFilter_images=jpg,jpe,jpeg,gif,png,svg,bmp # ------------------------ diff --git a/connectors/jsp/filemanager.jsp b/connectors/jsp/filemanager.jsp index f194fe52..2f3d5f5a 100644 --- a/connectors/jsp/filemanager.jsp +++ b/connectors/jsp/filemanager.jsp @@ -46,8 +46,7 @@ } } try { - // renamed getinfo to getfile - if (mode.equals("getinfo") || mode.equals("getfile")){ + if (mode.equals("getinfo")){ if(fm.setGetVar("path", (strictServletCompliance)? qpm.get("path"): request.getParameter("path"))) { responseData = fm.getInfo(); } @@ -55,9 +54,9 @@ else if (mode.equals("initiate")){ responseData = fm.initiate(request); } - else if (mode.equals("getfolder")){ + else if (mode.equals("readfolder")){ if(fm.setGetVar("path", (strictServletCompliance)? qpm.get("path"):request.getParameter("path"))) { - responseData = fm.getFolder(request); + responseData = fm.readFolder(request); } } else if (mode.equals("rename")){ diff --git a/connectors/jsp/libraries/java/src/edu/fuberlin/AbstractFileManager.java b/connectors/jsp/libraries/java/src/edu/fuberlin/AbstractFileManager.java index d8cf0e22..bbc8fa89 100644 --- a/connectors/jsp/libraries/java/src/edu/fuberlin/AbstractFileManager.java +++ b/connectors/jsp/libraries/java/src/edu/fuberlin/AbstractFileManager.java @@ -59,15 +59,15 @@ protected final JSONObject getErrorResponse(String msg, Exception ex) throws JSO try { errorInfo.put("id", "server"); errorInfo.put("code", "500"); - errorInfo.put("message", msg); + errorInfo.put("title", msg); if (propertiesConfig.getProperty("errorObject_arguments_redirect") != null && !propertiesConfig.getProperty("errorObject_arguments_redirect").equals("")) { - JSONObject redirect = new JSONObject(); - redirect.put("redirect", propertiesConfig.getProperty("errorObject_arguments_redirect")); - errorInfo.put("arguments",redirect); + JSONObject arguments = new JSONObject(); + arguments.put("redirect", propertiesConfig.getProperty("errorObject_arguments_redirect")); + errorInfo.put("meta", arguments); } else { - errorInfo.put("arguments", new JSONObject()); + errorInfo.put("meta", new JSONObject()); } if (ex != null) { diff --git a/connectors/jsp/libraries/java/src/edu/fuberlin/FileManagerI.java b/connectors/jsp/libraries/java/src/edu/fuberlin/FileManagerI.java index 6ba5dd0b..9f0f8290 100644 --- a/connectors/jsp/libraries/java/src/edu/fuberlin/FileManagerI.java +++ b/connectors/jsp/libraries/java/src/edu/fuberlin/FileManagerI.java @@ -38,7 +38,7 @@ public interface FileManagerI { JSONObject getInfo() throws JSONException, FileManagerException; - JSONObject getFolder(HttpServletRequest request) throws JSONException, IOException, FileManagerException; + JSONObject readFolder(HttpServletRequest request) throws JSONException, IOException, FileManagerException; JSONObject rename() throws JSONException, FileManagerException; diff --git a/connectors/jsp/libraries/java/src/edu/fuberlin/RichFileManager.java b/connectors/jsp/libraries/java/src/edu/fuberlin/RichFileManager.java index 677381eb..31579261 100644 --- a/connectors/jsp/libraries/java/src/edu/fuberlin/RichFileManager.java +++ b/connectors/jsp/libraries/java/src/edu/fuberlin/RichFileManager.java @@ -147,7 +147,7 @@ protected JSONObject readSmallFile(HttpServletResponse resp, Path file) throws J @Override - public JSONObject getFolder(HttpServletRequest request) throws JSONException, IOException, FileManagerException { + public JSONObject readFolder(HttpServletRequest request) throws JSONException, IOException, FileManagerException { JSONArray array = new JSONArray(); boolean showThumbs = false; @@ -224,10 +224,6 @@ private Map getFileInfo(String path) throws FileManagerException { // get file File file = getFile(path); - if(file.isDirectory() && !path.endsWith("/")){ - throw new FMIOException("Error reading the file (file as directory not allowed): " + file.getAbsolutePath()); - } - BasicFileAttributes attr; try { attr = Files.readAttributes(file.toPath(), BasicFileAttributes.class); @@ -300,30 +296,21 @@ private String getDynamicPath(String path) { public JSONObject download(HttpServletRequest request, HttpServletResponse resp) throws JSONException, FileManagerException { File file = this.documentRoot.resolve(this.get.get("path")).toFile(); if (this.get.get("path") != null && file.exists()) { - - // Ajax - if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) { - return new JSONObject().put("data", new JSONObject(getFileInfo( - this.get.get("path") - ))); - } else { - - resp.setHeader("Content-Description", "File Transfer"); - //resp.setHeader("Content-Type", "application/force-download"); - //resp.setHeader("Content-Disposition", "inline;filename=\"" + documentRoot.resolve(this.get.get("path")).toString() + "\""); - resp.setHeader("Content-Transfer-Encoding", "Binary"); - resp.setHeader("Content-Length", "" + file.length()); - resp.setHeader("Content-Type", "application/octet-stream"); - resp.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\""); - // handle caching - resp.setHeader("Pragma", "public"); - resp.setHeader("Expires", "0"); - resp.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); - this.error = null; - readFile(resp, file); - log("file downloaded \""+ file.getAbsolutePath() + "\""); - return null; - } + resp.setHeader("Content-Description", "File Transfer"); + //resp.setHeader("Content-Type", "application/force-download"); + //resp.setHeader("Content-Disposition", "inline;filename=\"" + documentRoot.resolve(this.get.get("path")).toString() + "\""); + resp.setHeader("Content-Transfer-Encoding", "Binary"); + resp.setHeader("Content-Length", "" + file.length()); + resp.setHeader("Content-Type", "application/octet-stream"); + resp.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\""); + // handle caching + resp.setHeader("Pragma", "public"); + resp.setHeader("Expires", "0"); + resp.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); + this.error = null; + readFile(resp, file); + log("file downloaded \""+ file.getAbsolutePath() + "\""); + return null; } else { return getErrorResponse(sprintf(lang("FILE_DOES_NOT_EXIST"), this.get.get("path"))); } diff --git a/connectors/nodejs/filemanager.js b/connectors/nodejs/filemanager.js index aed20440..1b32070b 100644 --- a/connectors/nodejs/filemanager.js +++ b/connectors/nodejs/filemanager.js @@ -159,7 +159,7 @@ module.exports = (__appRoot) => { // eslint-disable-line max-statements });// parsePath }// getIndividualFileInfo - function getfolder(pp, callback) { + function readfolder(pp, callback) { fs.readdir(pp.osFullPath, (err, files) => { if (err) { console.log('err -> ', err); // eslint-disable-line no-console @@ -356,24 +356,11 @@ module.exports = (__appRoot) => { // eslint-disable-line max-statements });// getinfo });// parsePath break; -case 'getfolder': +case 'readFolder': parsePath(path, (pp) => { - getfolder(pp, (result) => { + readfolder(pp, (result) => { respond(res, {data: result}); - });// getfolder -});// parsePath - break; -case 'editfile': - parsePath(path, (pp) => { - getinfo(pp, (result) => { - fs.readFile(paths.resolve(pp.osFullPath), (err, f) => { - if (err) { - res.status(500).send(err); - } - result.attributes.content = f.toString(); - respond(res, {data: result}); - }); - });// getinfo + });// readfolder });// parsePath break; case 'getimage': @@ -387,21 +374,11 @@ case 'readfile': });// parsePath break; case 'download': - // to make it works, you need to change filemanager.js downloadItem function, like this: - /* - var downloadItem = function(resourceObject) { - var queryParams = {mode: 'download', path: resourceObject.id}; - var link = document.createElement("a"); - link.download = resourceObject && resourceObject.attributes && resourceObject.attributes.name; - link.href = buildConnectorUrl(queryParams); - link.click(); - }; - */ parsePath(path, (pp) => { - getinfo(pp, (result) => { res.setHeader('content-type', 'text/html; charset=UTF-8'); - res.send(JSON.stringify({data: result})); - });// getinfo + res.setHeader('content-description', 'File Transfer'); + res.setHeader('content-disposition', 'attachment; filename="' + pp.filename + '"'); + res.sendFile(paths.resolve(pp.osFullPath)); });// parsePath break; case 'addfolder': diff --git a/connectors/php/events.php b/connectors/php/events.php new file mode 100644 index 00000000..9b57e697 --- /dev/null +++ b/connectors/php/events.php @@ -0,0 +1,115 @@ + + * @copyright Authors + */ + +/** + * Event listener on after "readfolder" API method successfully executed. + * + * @param \RFM\Event\Api\AfterFolderReadEvent $event + */ +function fm_event_api_after_folder_read($event) +{ + $data = $event->getFolderData(); + $list = $event->getFolderContent(); +} + +/** + * Event listener on after "seekfolder" API method successfully executed. + * + * @param \RFM\Event\Api\AfterFolderSeekEvent $event + */ +function fm_event_api_after_folder_seek($event) +{ + $data = $event->getFolderData(); + $list = $event->getSearchResult(); + $string = $event->getSearchString(); +} + +/** + * Event listener on after "addfolder" API method successfully executed. + * + * @param \RFM\Event\Api\AfterFolderCreateEvent $event + */ +function fm_event_api_after_folder_create($event) +{ + $data = $event->getFolderData(); +} + +/** + * Event listener on after "upload" API method successfully executed. + * + * @param \RFM\Event\Api\AfterFileUploadEvent $event + */ +function fm_event_api_after_file_upload($event) +{ + $data = $event->getUploadedFileData(); +} + +/** + * Event listener on after "extract" API method successfully executed. + * + * @param \RFM\Event\Api\AfterFileExtractEvent $event + */ +function fm_event_api_after_file_extract($event) +{ + $data = $event->getArchiveData(); + $list = $event->getArchiveContent(); +} + +/** + * Event listener on after "rename" API method successfully executed. + * + * @param \RFM\Event\Api\AfterItemRenameEvent $event + */ +function fm_event_api_after_item_rename($event) +{ + $data = $event->getItemData(); + $originalData = $event->getOriginalItemData(); +} + +/** + * Event listener on after "copy" API method successfully executed. + * + * @param \RFM\Event\Api\AfterItemCopyEvent $event + */ +function fm_event_api_after_item_copy($event) +{ + $data = $event->getItemData(); + $originalData = $event->getOriginalItemData(); +} + +/** + * Event listener on after "move" API method successfully executed. + * + * @param \RFM\Event\Api\AfterItemMoveEvent $event + */ +function fm_event_api_after_item_move($event) +{ + $data = $event->getItemData(); + $originalData = $event->getOriginalItemData(); +} + +/** + * Event listener on after "delete" API method successfully executed. + * + * @param \RFM\Event\Api\AfterItemDeleteEvent $event + */ +function fm_event_api_after_item_delete($event) +{ + $data = $event->getOriginalItemData(); +} + +/** + * Event listener on after "download" API method successfully executed. + * + * @param \RFM\Event\Api\AfterItemDownloadEvent $event + */ +function fm_event_api_after_item_download($event) +{ + $data = $event->getDownloadedItemData(); +} \ No newline at end of file diff --git a/connectors/php/filemanager.php b/connectors/php/filemanager.php index 7f4f73f9..88c5c378 100644 --- a/connectors/php/filemanager.php +++ b/connectors/php/filemanager.php @@ -11,7 +11,8 @@ // error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); // ini_set('display_errors', '1'); -require 'vendor/autoload.php'; +require_once 'vendor/autoload.php'; +require_once __DIR__ . '/events.php'; // fix display non-latin chars correctly // https://github.com/servocoder/RichFilemanager/issues/7 @@ -104,6 +105,9 @@ function fm_has_write_permission($filepath) $app = new \RFM\Application(); +// uncomment to use events +//$app->registerEventsListeners(); + $local = new \RFM\Repository\Local\Storage($config); // example to setup files root folder diff --git a/connectors/python/filemanager.py b/connectors/python/filemanager.py deleted file mode 100644 index 4f6531c5..00000000 --- a/connectors/python/filemanager.py +++ /dev/null @@ -1,290 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import with_statement # This isn't required in Python 2.6 -__metaclass__ = type - - -from contextlib import closing, contextmanager -import os, sys, traceback -import os.path - -from mod_python import apache, util -from util import parse_qs - -today = date.today - -ver = sys.version_info -if ver[0]<2 and ver[1]<5: - raise EnvironmentError('Must have Python version 2.5 or higher.') - - -try: - import json -except ImportError: - raise EnvironmentError('Must have the json module. (It is included in Python 2.6 or can be installed on version 2.5.)') - - -try: - from PIL import Image -except ImportError: - raise EnvironmentError('Must have the PIL (Python Imaging Library).') - - -path_exists = os.path.exists -normalize_path = os.path.normpath -absolute_path = os.path.abspath -make_url = urlparse.urljoin -split_path = os.path.split -split_ext = os.path.splitext - - -euncode_urlpath = urllib.quote_plus - -encode_json = json.JSONEcoder().encode - - -def encodeURLsafeBase64(data): - return base64.urlsafe_b64encode(data).replace('=','').replace(r'\x0A','') - -def image(*args): - raise NotImplementedError - - - -class Filemanager: - - """Replacement for FCKEditor's built-in file manager.""" - - def __init__(self, fileroot= '/'): - self.fileroot = fileroot - self.patherror = encode_json( - { - 'Error' : 'No permission to operate on specified path.', - 'Code' : -1 - } - ) - - def isvalidrequest(self, **kwargs): - """Returns an error if the given path is not within the specified root path.""" - - assert split_path(kwargs['path'])[0]==self.fileroot - assert not kwargs['req'] is None - - - - def getinfo(self, path=None, getsize=true, req=None): - """Returns a JSON object containing information about the given file.""" - - if not self.isvalidrequest(path,req): - return (self.patherror, None, 'application/json') - - thefile = { - 'Filename' : split_path(path)[-1], - 'File Type' : '', - 'Preview' : path if split_path(path)[-1] else 'images/fileicons/_Open.png', - 'Path' : path, - 'Error' : '', - 'Code' : 0, - 'Properties' : { - 'Date Created' : '', - 'Date Modified' : '', - 'Width' : '', - 'Height' : '', - 'Size' : '' - } - } - - imagetypes = set('gif','jpg','jpeg','png') - - - if not path_exists(path): - thefile['Error'] = 'File does not exist.' - return (encode_json(thefile), None, 'application/json') - - - if split_path(path)[-1]=='/': - thefile['File Type'] = 'Directory' - else: - thefile['File Type'] = split_ext(path) - - if ext in imagetypes: - img = Image(path).size() - thefile['Properties']['Width'] = img[0] - thefile['Properties']['Height'] = img[1] - - else: - previewPath = 'images/fileicons/' + ext.upper + '.png' - thefile['Preview'] = previewPath if path_exists('../../' + previewPath) else 'images/fileicons/default.png' - - thefile['Properties']['Date Created'] = os.path.getctime(path) - thefile['Properties']['Date Modified'] = os.path.getmtime(path) - thefile['Properties']['Size'] = os.path.getsize(path) - - req.content_type('application/json') - req.write(encode_json(thefile)) - - - def getfolder(self, path=None, getsizes=true, req=None): - - if not self.isvalidrequest(path,req): - return (self.patherror, None, 'application/json') - - result = [] - filtlist = file_listdirectory(path) - - for i in filelist: - if i[0]=='.': - result += literal(self.getinfo(path + i, getsize=getsizes)) - - req.content_type('application/json') - req.write(encode_json(result)) - - - def rename(self, old=None, new=None, req=None): - - if not self.isvalidrequest(path=new,req=req): - return (self.patherror, None, 'application/json') - - if old[-1]=='/': - old=old[:-1] - - oldname = split_path(path)[-1] - path = string(old) - path = split_path(path)[0] - - if not path[-1]=='/': - path += '/' - - newname = encode_urlpath(new) - newpath = path + newname - - os.path.rename(old, newpath) - - result = { - 'Old Path' : old, - 'Old Name' : oldname, - 'New Path' : newpath, - 'New Name' : newname, - 'Error' : 'There was an error renaming the file.' # todo: get the actual error - } - - req.content_type('application/json') - req.write(encode_json(result)) - - - def delete(self, path=None, req=None): - - if not self.isvalidrequest(path,req): - return (self.patherror, None, 'application/json') - - os.path.remove(path) - - result = { - 'Path' : path, - 'Error' : 'There was an error renaming the file.' # todo: get the actual error - } - - req.content_type('application/json') - req.write(encode_json(result)) - - - def add(self, path=None, req=None): - - if not self.isvalidrequest(path,req): - return (self.patherror, None, 'application/json') - - - try: - thefile = util.FieldStorage(req)['file'] #TODO get the correct param name for the field holding the file - newName = thefile.filename - - with open(newName, 'rb') as f: - f.write(thefile.value) - - except: - - result = { - 'Path' : path, - 'Name' : newName, - 'Error' : file_currenterror - } - - else: - result = { - 'Path' : path, - 'Name' : newName, - 'Error' : 'No file was uploaded.' - } - - req.content_type('text/html') - req.write(('')) - - - def addfolder(self, path, name): - - if not self.isvalidrequest(path,req): - return (self.patherror, None, 'application/json') - - newName = encode_urlpath(name) - newPath = path + newName + '/' - - if not path_exists(newPath): - try: - os.mkdir(newPath) - except: - - result = { - 'Path' : path, - 'Name' : newName, - 'Error' : 'There was an error creating the directory.' # TODO grab the actual traceback. - } - - - def download(self, path=None, req=None): - - if not self.isvalidrequest(path,req): - return (self.patherror, None, 'application/json') - - name = path.split('/')[-1] - - req.content_type('application/x-download') - req.filename=name - req.sendfile(path) - - - - - -myFilemanager = Filemanager(fileroot='/var/www/html/dev/fmtest/UserFiles/') #modify fileroot as a needed - - -def handler(req): - #req.content_type = 'text/plain' - #req.write("Hello World!") - - if req.method == 'POST': - kwargs = parse_qs(req.read()) - elif req.method == 'GET': - kwargs = parse_qs(req.args) - - #oldid = os.getuid() - #os.setuid(501) - - try: - method=str(kwargs['mode'][0]) - methodKWargs=kwargs.remove('mode') - methodKWargs['req']=req - - myFilemanager.__dict__['method'](**methodKWargs) - - return apache.OK - - - except KeyError: - return apache.HTTP_BAD_REQUEST - - except Exception, (errno, strerror): - apache.log_error(strerror, apache.APLOG_CRIT) - return apache.HTTP_INTERNAL_SERVER_ERROR - - #os.setuid(oldid) - diff --git a/images/search_dark.png b/images/search_dark.png new file mode 100644 index 00000000..9f9e81aa Binary files /dev/null and b/images/search_dark.png differ diff --git a/index.html b/index.html index 2716cab3..cabd0904 100644 --- a/index.html +++ b/index.html @@ -32,7 +32,7 @@