2016-08-19 162 views
0

我正在运行一个Flask应用程序,用户在上传文件时必须选择文件上传到网络驱动器的根文件夹路径。此路径是IIS可用的网络路径,也是所有用户计算机上的网络驱动器。用Flask上传HTML文件夹的文件夹选取器

我知道这不能用纯HTML完成,由于安全性,但想知道是否有与Flask解决这个问题的方法。目标是使用Python将上传文件移动到选择的文件夹路径。

我曾尝试:

<form><input type="file" name=dir webkitdirectory directory multiple/></form> 

但在Chrome这只作品。通过用户选择的路径,我可以将它传递给Python以将上传文件复制到那里。

+1

当然,列举在这里用户可以上传文件,将它们发送到客户端的地方,让他们挑一个。然后使用它。你有什么具体问题? – davidism

+0

需要这是动态的。可用路径将随着新文件夹的创建而改变。 – Infinity8

+0

好的,那么,你有什么具体问题?用户每次请求该页面时,都列举当前可用的文件夹。请阅读[问]和[mcve],你的问题缺乏细节。 – davidism

回答

2

由于现代浏览器的限制,我决定使用JSTree作为解决方案。它工作得很好。它具有一个树形结构浏览器。该结构是将文件夹输出为JSON的结果。您也可以添加搜索栏,以便用户只需键入要搜索的文件夹名称即可。
请参阅JSTree https://www.jstree.com/

如何用瓶

HTML/JS实现这一点:

<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css"> 
    <div> 
    <input class="search-input form-control" placeholder="Search for folder"></input> 
    </div> 
<script id="jstree1" name="jstree1"> 
         /*Search and JS Folder Tree*/ 
         $(function() { 
          $(".search-input").keyup(function() { 
           var searchString = $(this).val(); 
           console.log(searchString); 
           $('#container').jstree('search', searchString); 
          }); 
          $('#container').jstree({ 
           'core': { 
            "themes": { 
             "name": "default" 
             , "dots": true 
             , "icons": true 
            } 
            , 'data': { 
             'url': "static/JSONData.json" 
             , 'type': 'GET' 
             , 'dataType': 'JSON' 
            } 
           } 
           , "search": { 
            "case_insensitive": true 
            , "show_only_matches": true 
           } 
           , "plugins": ["search"] 
          }); 
         }); 

         { /* --- THIS IS FOLDER SELECTOR FOR ID "folderout" --- */ 
          $("#container").on("select_node.jstree", function (evt, data) { 
           var number = data.node.text 

           document.getElementById("folderout").value = number; 
          }); 

在瓶/ WTForms上的ID “folderout”电话。这将在用户单击该文件夹时返回到WTForms的路径。

folderout = TextField('Folder:', validators=[validators.required()]) 

创建使用Python的JSON JStree文件:

import os 

# path : string to relative or absolute path to be queried 
# subdirs: tuple or list containing all names of subfolders that need to be 
#   present in the directory 
def all_dirs_with_subdirs(path, subdirs): 
    # make sure no relative paths are returned, can be omitted 
    path = os.path.abspath(path) 

    result = [] 
    for root, dirs, files in os.walk(path): 
     if all(subdir in dirs for subdir in subdirs): 
       result.append(root) 
    return result 

def get_directory_listing(path): 
    output = {} 
    output["text"] = path.decode('latin1') 
    output["type"] = "directory" 
    output["children"] = all_dirs_with_subdirs(path, ('Maps', 'Reports')) 
    return output 

with open('test.json', 'w+') as f: 
    listing = get_directory_listing(".") 
    json.dump(listing, f) 
1

的Python运行在服务器上,therefoere它不会有可能使用移动客户端上的文件。如果你仔细想想,让我们假设你设法以某种方式(神奇地)发送python命令给客户端来移动文件,你知道他们是否安装了python来解释你的命令吗?

另一方面,Javascript正在客户端运行并用于实现此目的。但是,正如你所说,由于安全原因,现代browswers不会允许这样做。如果他们允许,那么任何网站都可能会看到您的整个文件系统。

这是一个article,解释了一下为什么。查找它的文件上传控制部分。希望这可以让事情变得更加清晰。

编辑:看到你的评论后,你可以使用os.walk来实现。注意它可能会很慢。

for root, dirs, files in os.walk(rootPath): # for example "C:/Users/" 
    for file in files: 
     if file == (wantedFile): 
      print(os.path.join(root,file)) 
      break 
+0

感谢limbo的帮助。不过,我只想让用户在服务器端移动文件时选择路径。服务器与客户端具有相同的网络文件夹访问权限,所以这不是问题。事实上,如果允许用户从服务器端看到文件夹路径,这也可以完成我期望的操作。 – Infinity8

+0

嗯,你可以使用os.walk来查找文件。我将编辑我的答案 – limbo

+0

谢谢,这将有助于列出文件夹。现在我只需要弄清楚如何为各种文件夹路径创建像列表和SelectField这样的下拉菜单。 – Infinity8