How to Generate an HTML Directory List Using Python

How to generate an html directory list using Python

You could separate the directory tree generation and its rendering as html.

To generate the tree you could use a simple recursive function:

def make_tree(path):
tree = dict(name=os.path.basename(path), children=[])
try: lst = os.listdir(path)
except OSError:
pass #ignore errors
else:
for name in lst:
fn = os.path.join(path, name)
if os.path.isdir(fn):
tree['children'].append(make_tree(fn))
else:
tree['children'].append(dict(name=name))
return tree

To render it as html you could use jinja2's loop recursive feature:

<!doctype html>
<title>Path: {{ tree.name }}</title>
<h1>{{ tree.name }}</h1>
<ul>
{%- for item in tree.children recursive %}
<li>{{ item.name }}
{%- if item.children -%}
<ul>{{ loop(item.children) }}</ul>
{%- endif %}</li>
{%- endfor %}
</ul>

Put the html into templates/dirtree.html file.
To test it, run the following code and visit http://localhost:8888/:

import os
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def dirtree():
path = os.path.expanduser(u'~')
return render_template('dirtree.html', tree=make_tree(path))

if __name__=="__main__":
app.run(host='localhost', port=8888, debug=True)

Python - Create html page with hyperlinks from os.listdir

Don't do f.writelines(videoDirectory) and then regex. Besides you're only printing to the console with that regex subsitution.

Do

videoDirectory = os.listdir("videos")
f = open("videos.html", "w")
f.write('<html><head></head><body><ul>'
f.writelines(['<li><a href="videos/%s">%s</a></li>' % (f, f) for f in videoDirectory])
f.write('</ul></body></html>')

How to list files of a directory with flask (using bootstraps) and python?

You can indeed use a generator inside jinja2.

The example I wrote should meet your needs.

It displays the files within the directory as a list. Each entry is assigned its size and the time of upload. The uploads folder is inside the instance folder to separate the files from the application.

I use flask-moment to show the correct times. This uses moment.js and displays the timestamp in the respective time zone of the client.

I use a custom Jinja2 filter to display the file size.

If a file is clicked to download, a dialog opens that requests confirmation. This is done using JavaScript.

Have fun achieving your goals.

Flask (app.py)

from flask import (
Flask,
render_template,
send_from_directory
)
from flask_moment import Moment
from datetime import datetime
import os

def byte_units(value, units=-1):
UNITS=('Bytes', 'KB', 'MB', 'GB', 'TB', 'EB', 'ZB', 'YB')
i=1
value /= 1000.0
while value > 1000 and (units == -1 or i < units) and i+1 < len(UNITS):
value /= 1000.0
i += 1
return f'{round(value,3):.3f} {UNITS[i]}'

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = os.path.join(app.instance_path, 'uploads')
app.jinja_env.filters.update(byte_units = byte_units)
moment = Moment(app)

try:
os.makedirs(app.config['UPLOAD_FOLDER'])
except:
pass

def get_files(target):
for file in os.listdir(target):
path = os.path.join(target, file)
if os.path.isfile(path):
yield (
file,
datetime.utcfromtimestamp(os.path.getmtime(path)),
os.path.getsize(path)
)

@app.route('/')
def index():
files = get_files(app.config['UPLOAD_FOLDER'])
return render_template('index.html', **locals())

@app.route('/download/<path:filename>')
def download(filename):
return send_from_directory(
app.config['UPLOAD_FOLDER'],
filename,
as_attachment=True
)
HTML (templates/index.html)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index</title>
{{ moment.include_moment() }}
</head>
<body>

<table style="width:40%; margin:auto; table-layout: fixed;">
{% for filename, mtime, size in files -%}
<tr>
<td><a href="{{ url_for('download', filename=filename) }}" download>{{ filename }}</a></td>
<td>{{ moment(mtime, local=False).format('DD.MM.YYYY HH:mm') }}</td>
<td style="text-align:right;">{{ size | byte_units }}</td>
</tr>
{% endfor -%}
</table>

<script type="text/javascript">
(() => {
const elems = document.querySelectorAll('a[href][download]');
elems.forEach(elem => {
elem.addEventListener('click', evt => {
const isDonwload = window.confirm('Would you like to download this file?');
if (!isDonwload) { evt.preventDefault(); }
});
});
})();
</script>

</body>
</html>

I've added my code to your project. It should work now.

You should work on structuring your project so that you can find your way around the code more easily. I cannot relieve you of this task in this context.

(website/init.py)

from flask import Flask
from flask_login import LoginManager
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
import os

DB_NAME = "database.db"

db = SQLAlchemy()
moment = Moment()

def byte_units(value, units=-1):
UNITS=('Bytes', 'KB', 'MB', 'GB', 'TB', 'EB', 'ZB', 'YB')
i=1
value /= 1000.0
while value > 1000 and (units == -1 or i < units) and i+1 < len(UNITS):
value /= 1000.0
i += 1
return f'{round(value,3):.3f} {UNITS[i]}'

def create_app():
app = Flask(__name__)
app.config.from_mapping(
SECRET_KEY=b'your secret here',
SQLALCHEMY_DATABASE_URI='sqlite:///'+os.path.join(app.instance_path, DB_NAME),
SQLALCHEMY_TRACK_MODIFICATIONS=False,
UPLOAD_FOLDER=os.path.join(app.instance_path, 'uploads')
)
app.jinja_env.filters.update(byte_units = byte_units)

try:
os.makedirs(app.config['UPLOAD_FOLDER'])
except:
pass

db.init_app(app)
moment.init_app(app)

from .models import User, Note

create_database(app)

login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)

@login_manager.user_loader
def load_user(id):
return User.query.get(int(id))

from .views import views
from .auth import auth

app.register_blueprint(auth, url_prefix='/')
app.register_blueprint(views, url_prefix='/')

return app

def create_database(app):
if not os.path.exists(os.path.join(app.instance_path, DB_NAME)):
db.create_all(app=app)
print('Created Database!')
(website/auth.py)

import os
import json
from . import db
from .models import User
from flask import (
Blueprint,
flash,
redirect,
render_template,
request,
url_for
)
from flask_login import login_user, login_required, logout_user, current_user

auth = Blueprint('auth', __name__)

@auth.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
email = request.form.get('email')
password = request.form.get('password')

user = User.query.filter_by(email=email).first()
if user:
if check_password_hash(user.password, password):
flash('Logged in successfully!', category='success')
login_user(user, remember=True)
return redirect(url_for('views.home'))
else:
flash('Incorrect password, try again.', category='error')
else:
flash('Email does not exist.', category='error')

return render_template('login.html', user=current_user)

@auth.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('auth.login'))

@auth.route('/sign-up', methods=['GET', 'POST'])
def sign_up():
if request.method == 'POST':
email = request.form.get('email')
first_name = request.form.get('firstName')
password1 = request.form.get('password1')
password2 = request.form.get('password2')

user = User.query.filter_by(email=email).first()
if user:
flash('Email already exists.', category='error')
elif len(email) < 4:
flash('Email must be greater than 3 characters.', category='error')
elif len(first_name) < 2:
flash('First name must be greater than 1 character.', category='error')
elif password1 != password2:
flash('Passwords don\'t match.', category='error')
elif len(password1) < 7:
flash('Password must be at least 7 characters.', category='error')
else:
new_user = User(email=email, first_name=first_name, password=generate_password_hash(
password1, method='sha256'))
db.session.add(new_user)
db.session.commit()
login_user(new_user, remember=True)
flash('Account created!', category='success')
return redirect(url_for('views.home'))

return render_template('sign_up.html', user=current_user)
(website/views.py)

from . import db
from .models import Note
from flask import Blueprint, current_app, flash, jsonify, render_template, request
from flask_login import login_required, current_user
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename
import os

views = Blueprint('views', __name__)

@views.route('/', methods=['GET', 'POST'])
@login_required
def home():
if request.method == 'POST':
note = request.form.get('note')

if len(note) < 1:
flash('Note is too short!', category='error')
else:
new_note = Note(data=note, user_id=current_user.id)
db.session.add(new_note)
db.session.commit()
flash('Note added!', category='success')

user=current_user
files = get_files(current_app.config['UPLOAD_FOLDER'])
return render_template('home.html', **locals())

@views.route('/delete-note', methods=['POST'])
def delete_note():
note = json.loads(request.data)
noteId = note['noteId']
note = Note.query.get(noteId)
if note:
if note.user_id == current_user.id:
db.session.delete(note)
db.session.commit()

return jsonify({})

# ---

@views.route('/about')
def about():
return render_template('about.html', user=None)

# ---

@views.route('/upload', methods = ['GET', 'POST'])
def uploadfile():
upload_folder = current_app.config['UPLOAD_FOLDER']
if request.method == 'POST': # check if the method is post
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)

file = request.files['file'] # get the file from the files object
if file.filename == '':
flash('No selected file')
return redirect(request.url)

file.save(os.path.join(
upload_folder ,
secure_filename(file.filename))) # this will secure the file

flash('file uploaded successfully') # Display this message after uploading
return redirect('/')

def get_files(target):
for file in os.listdir(target):
path = os.path.join(target, file)
if os.path.isfile(path):
yield (
file,
datetime.utcfromtimestamp(os.path.getmtime(path)),
os.path.getsize(path)
)

@views.route('/download/<path:filename>')
def download(filename):
return send_from_directory(
app.config['UPLOAD_FOLDER'],
filename,
as_attachment=True
)
(templates/base.html)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
crossorigin="anonymous"
/>

<title>{% block title %}Home{% endblock %}</title>

{{ moment.include_moment() }}

</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbar"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar">
<div class="navbar-nav">
{% if user.is_authenticated %}
<a class="nav-item nav-link" id="home" href="/">Home</a>
<a class="nav-item nav-link" id="logout" href="/logout">Logout</a>
{% else %}
<a class="nav-item nav-link" id="login" href="/login">Login</a>
<a class="nav-item nav-link" id="signUp" href="/sign-up">Sign Up</a>
<a class="nav-item nav-link" id="Über Uns" href="/about">Über uns</a>
{% endif %}
</div>
</div>
</nav>

{% with messages = get_flashed_messages(with_categories=true) %} {% if
messages %} {% for category, message in messages %} {% if category ==
'error' %}
<div class="alert alert-danger alter-dismissable fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
</div>
{% else %}
<div class="alert alert-success alter-dismissable fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %} {% endfor %} {% endif %} {% endwith %}

<div class="container">{% block content %} {% endblock %}</div>

<script
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"
></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"
></script>

<script
type="text/javascript"
src="{{ url_for('static', filename='index.js') }}"
></script>
</body>
</html>
(templates/home.html)

{% extends "base.html" -%}
{% block title %}Home{% endblock -%}
{% block content -%}

<h1 align="center">Notes</h1>
<ul class="list-group list-group-flush" id="notes">
{% for note in user.notes %}
<li class="list-group-item">
{{ note.data }}
<button type="button" class="close" onClick="deleteNote({{ note.id }})">
<span aria-hidden="true">×</span>
</button>
</li>
{% endfor %}
</ul>

<form method="POST">
<textarea name="note" id="note" class="form-control"></textarea>
<br />
<div align="center">
<button type="submit" class="btn btn-primary">Add Note</button>
</div>
</form>

<br>
<br>
<br>
<br>

<!-- upload Folder-->
<div class="container">
<div class="row">
<div class="col">

<h1 align="center">Datei Upload</h1>
<hr>
<form
action="http://localhost:5000/upload"
method="POST"
enctype="multipart/form-data">

<input type="file" name="file" />
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
</div>
</div>

<br>
<br>
<br>
<br>
<!-- download Folder-->
<div align="center">
<image src="{{ url_for('static', filename='uploads/postgre.jpeg')}}">
</div>

<table style="width:40%; margin:auto; table-layout: fixed;">
{% for filename, mtime, size in files -%}
<tr>
<td><a href="{{ url_for('views.download', filename=filename) }}" download>{{ filename }}</a></td>
<td>{{ moment(mtime, local=False).format('DD.MM.YYYY HH:mm') }}</td>
<td style="text-align:right;">{{ size | byte_units }}</td>
</tr>
{% endfor -%}
</table>

<script type="text/javascript">
(() => {
const elems = document.querySelectorAll('a[href][download]');
elems.forEach(elem => {
elem.addEventListener('click', evt => {
const isDonwload = window.confirm('Would you like to download this file?');
if (!isDonwload) { evt.preventDefault(); }
});
});
})();
</script>
{% endblock -%}

List all HTML files in a directory python code not working

Something like this should work. BTW there are a already a couple of questions like this.

def read_directory():
matches =[]
directory = '/home/akallararajappan/www.mangalam.com/agriculture'
for root, dirs, files in os.walk(directory):
for file in files:
if file.endswith('.html'):
matches.append(os.path.join(root, file))
return matches

Print a list in HTML file using Django

  {% for item  in formulario %}
<li>{{ item }}</li>
{% endfor %}

How can I create a simple index.html file which lists all files/directories?

You can either:
Write a server-side script page like PHP, JSP, ASP.net etc to generate this HTML dynamically

or

Setup the web-server that you are using (e.g. Apache) to do exactly that automatically for directories that doesn't contain welcome-page (e.g. index.html)

Specifically in apache read more here:
Edit the httpd.conf:
http://justlinux.com/forum/showthread.php?s=&postid=502789#post502789 (updated link: https://forums.justlinux.com/showthread.php?94230-Make-apache-list-directory-contents&highlight=502789)

or add the autoindex mod:
http://httpd.apache.org/docs/current/mod/mod_autoindex.html

Create a tree-style directory listing in Python

Try the following:

for path, dirs, files in os.walk("."):
print path
for file in files:
print os.path.join(path, file)

You do not need to print entries from dirs because each directory will be visited as you walk the path, so you will print it later with print path.



Related Topics



Leave a reply



Submit