0

I use Flask+Python to locate relevant files for further processing. Currently I'm only able to upload files to a specified directory with the following:

Backend:

from flask import Flask, render_template, request
from werkzeug import secure_filename
app = Flask(__name__)

@app.route('/upload')
def upload_file():
   return render_template('upload.html')

@app.route('/uploader', methods = ['GET', 'POST'])
def upload_file():
   if request.method == 'POST':
      f = request.files['file']
      f.save(secure_filename(f.filename))
      return 'file uploaded successfully'

if __name__ == '__main__':
   app.run(debug = True)

Frontend:

<html>
   <body>

      <form action = "http://localhost:5000/uploader" method = "POST" 
         enctype = "multipart/form-data">
         <input type = "file" name = "file" />
         <input type = "submit"/>
      </form>
   </body>
</html>

But I have several problems and questions with this solution:

  • I don't want actually touch (move/upload) any file, I only need the filenames of the selected files. How to discard the actual uploading and get the filenames as a list?
  • Is there any way to select a directory (and not specific files) for batch processing?
Hendrik
  • 766
  • 3
  • 10
  • 24
  • 1
    If you want only the names of the files which the user has selected without uploading the files, you will have to look into javascript to read the file name selected for input type file element. and post back to backend – Anbarasan Apr 10 '17 at 10:24

2 Answers2

0

You can do it with Javascript ;)

Change your server side code to this:

from flask import Flask, render_template, request
from werkzeug import secure_filename
app = Flask(__name__)

@app.route('/upload')
def upload_file():
   return render_template('upload.html')

@app.route('/uploader', methods = ['GET', 'POST'])
def uploader_file():
   print(request)
   if request.method == 'POST':
      f = request.form['filename']
      return f

if __name__ == '__main__':
   app.run(debug = True)

And change your upload.html like this:

<html>
<body>
<script type="text/javascript">
function readURL(){
  var fullPath = document.getElementById('upload').value;
  if (fullPath) {
      var startIndex = (fullPath.indexOf('\\') >= 0 ? fullPath.lastIndexOf('\\') : fullPath.lastIndexOf('/'));
      var filename = fullPath.substring(startIndex);
      if (filename.indexOf('\\') === 0 || filename.indexOf('/') === 0) {
          filename = filename.substring(1);
      }
     document.getElementById("filename").value = filename;
  }
}
</script>
      <input id="upload" type ="file" name = "file" onchange="readURL();" />
      <form action = "http://localhost:5000/uploader" method = "POST" 
         enctype = "multipart/form-data">
         <input id="filename" type="hidden" name="filename" />
         <input type = "submit"/>
      </form>
   </body>
</html>
RaminNietzsche
  • 2,429
  • 1
  • 16
  • 32
0

according to @RaminNietzsche's answer, I make a some changes.

frontend: input with attribute webkitdirectory enable web browser(Chrome, Firefox works, Safari doesn't) upload directory

<input id="directory" type='file' onchange="readFiles()" webkitdirectory>
<form action="{{ url_for('upload') }}" method="POST" enctype="multipart/form-data">
    <input id="filenames" type="hidden" name="filenames"/>
    <input type="submit"/>
</form>
<script type="text/javascript">
    function readFiles() {
        var directory = document.getElementById('directory').files;
        var filenames = [];
        for (var i = 0; i < directory.length; i++) {
            filenames.push(directory[i].name);
        }
        document.getElementById("filenames").value = filenames;
    }
</script>

backend:

@app.route("/upload", methods=["POST"])
def upload():
    filenames = request.form.get('filenames', '').split(',')
    # handle filenames here
    return 'file uploaded successfully'
Community
  • 1
  • 1
  • Thanks, it works, albeit there is no need to modify input to webkit directory, it works with folders as it is. One more question: how could I extract absolute path names for the filenames? – Hendrik Apr 11 '17 at 12:50
  • @Hendrik You can't do that in theory for security reasons. Check [How to get full path of selected file on change of using javascript, jquery-ajax?](http://stackoverflow.com/a/15201258/5654098), [Full path from file input using jQuery](http://stackoverflow.com/a/3489167/5654098), [How to get the full path of the file from a file input](http://stackoverflow.com/a/4176605/5654098) – aishenghuomeidaoli Apr 12 '17 at 01:19