Is it possible to use flask to browse through a directory with files?
My code never seems to work correctly as weird appending between strings happens.
Also I don`t know how to implement a kind of check whether the path is a file or a folder.
Here is my Flask app.route:
@app.route('/files', defaults={'folder': None,'sub_folder': None}, methods=['GET']) @app.route('/files/<folder>', defaults={'sub_folder': None}, methods=['GET']) @app.route('/files/<folder>/<sub_folder>', methods=['GET']) def files(folder,sub_folder): basedir = 'files/' directory = '' if folder != None: directory = directory + '/' + folder if sub_folder != None: directory = directory + '/' + sub_folder files = os.listdir(basedir + directory) return render_template('files.html',files=files,directory=basedir + directory,currdir=directory) and here is my html template, if anyone could give me some pointers it would be greatly appreciated!
<body> <h2>Files {{ currdir }}</h2> </br> {% for name in files: %} <A HREF="{{ directory }}{{ name }}">{{ name }}</A> </br></br> {% endfor %} </body>s.html',files=files,directory=basedir + directory,currdir=directory) 3 Answers
A path converter (docs link) in the url structure is better than hardcoding all the different possible path structures.
os.path.exists can be used to check if the path is valid and os.path.isfile and os.path.isdir for checking if the path is a file or a directory, respectively.
Endpoint:
@app.route('/', defaults={'req_path': ''}) @app.route('/<path:req_path>') def dir_listing(req_path): BASE_DIR = '/Users/vivek/Desktop' # Joining the base and the requested path abs_path = os.path.join(BASE_DIR, req_path) # Return 404 if path doesn't exist if not os.path.exists(abs_path): return abort(404) # Check if path is a file and serve if os.path.isfile(abs_path): return send_file(abs_path) # Show directory contents files = os.listdir(abs_path) return render_template('files.html', files=files) Template (Now with directory browsing :) ):
<ul> {% for file in files %} <li> <a href="{{ (request.path + '/' if request.path != '/' else '') + file }}"> {{ (request.path + '/' if request.path != '/' else '') + file }} </a> </li> {% endfor %} </ul> Note: abort and send_file functions were imported from flask.
Here is a working example.
# app.py from flask import Flask from flask_autoindex import AutoIndex app = Flask(__name__) ppath = "/" # update your own parent directory here app = Flask(__name__) AutoIndex(app, browse_root=ppath) if __name__ == "__main__": app.run() Here is a working repo
2I created this function for my project ... it is working perfectly ... it start browsing at this folder /home/myuser/myfolder
@app.route('/myfolder/<path:folders>') @app.route('/myfolder/') def mybrowser(folders=''): environ = flask.request.environ path = environ.get('PATH_INFO') path = path.lower() #if path=='/myfolder': return flask.redirect(path+'/',code=307) os_path = '/home/myuser'+path.rstrip('/') if path.endswith('/'): HTML_HEADER = """<html><head><title>Index of {path_title}</title></head><body bgcolor="white"><h1>Index of {path_title}</h1><hr><pre><a href="../">../</a>\n""" HTML_FOOTER = "</pre><hr></body></html>" path_title = os_path.split('myuser')[1]+'/' html = HTML_HEADER.format(path_title=path_title) import os,time files = os.listdir(os_path) for file in files: path = os_path+'/'+file size = str(os.path.getsize(path)) date = os.path.getmtime(path) date = time.gmtime(date) date = time.strftime('%d-%b-%Y %H:%M',date) spaces1 = ' '*(50-len(file)) spaces2 = ' '*(20-len(size)) if os.path.isdir(path): html += '<a href="' + file + '/">' + file + '/</a>'+spaces1+date+spaces2+' -\n' else: html += '<a href="' + file + '">' + file + '</a>'+spaces1+' '+date+spaces2+size+'\n' html += HTML_FOOTER #open(os_path+'/index.html','w').write(html) response_headers = {'Content-Type':'text/html','Content-Length':str(len(html))} status = '200 OK' response = flask.Response(html,status=status,headers=response_headers) else: response = flask.send_file(os_path,conditional=True) return response 1