2016-08-19 156 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