Форум сайта python.su
Пытаюсь сделать небольшой просмотрщик файлов и папок (с возможностью удаления, скачивания, загрузки, навигации по папкам) работающий в веб-браузере. Судя по всему при использовании Python, для этих целей более всего подходит Flask.
Удалось путем чтения туториалов и стековерфлоу реализовать следующее (загрузка файлов и просмотр папки, куда все загружается):
import os from flask import request, redirect, url_for, render_template, abort, send_file from werkzeug.utils import secure_filename from app import app @app.route('/') @app.route('/index/') def index(): path = os.path.expanduser('static') return render_template('index.html', tree=make_tree(path)) def make_tree(path): tree = dict(name=path, children=[]) try: lst = os.listdir(path) except OSError: pass 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=fn)) return tree UPLOAD_FOLDER = 'static' ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif']) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER def make_dirs(): # os.mkdir('static') # os.mkdir('tmp') # os.mkdir('app') # os.mkdir('app/templates') # os.mkdir('app/static') pass def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route('//', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': if 'file' not in request.files: flash('No file part') return redirect(request.url) file = request.files['file'] if file.filename == '': flash('No selected file') return redirect(request.url) if file and allowed_file(file.filename): filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) return redirect(url_for('index')) return
<html> <head> <title>Path: {{ tree.name }}</title> <h1>{{ tree.name }}</h1> </head> <body> <form method=post enctype=multipart/form-data> <input type=file name=file> <input type=submit value=Upload> </form> <ul> {%- for item in tree.children recursive %} <li><a href="{{ item.name }}">{{ item.name }}</a> {%- if item.children -%} <ul><a href="/static/{{ (item.children) }}">{{ loop(item.children) }}</a></ul> {%- endif %}</li> {%- endfor %} </ul> </body> </html>
Отредактировано gmaksim (Авг. 17, 2017 13:03:20)
Офлайн
gmaksimинтересное утверждение, как вы к нему пришли?
Судя по всему при использовании Python, для этих целей более всего подходит Flask.
Офлайн
JOHN_16google.ru + ya.ru
интересное утверждение, как вы к нему пришли?
JOHN_16
я для подобного брал iohttp.
JOHN_16Первое не сталкивался, надо посмотреть.
на заре использовал обычный BaseHttpServer
Офлайн
gmaksim
упрощенный вариант с навигацией
@app.route("/<paht:path>") def dir_viewer(path): entries = os.scandir(path) # тут нормальный шаблон с render_template return """{% for entry in entries %} {% if entry.is_file() %} <a href="{{ url_for("download_file", path=entry.path) }}">{{ entry.name }}</a> {% else %} <a href="{{ url_for("dir_viewer", path=entry.path) }}">{{ entry.name }}</a> {% endif %} {% endfor %} """ @app.route("/download/<path:path>") def download_file(path): return send_file(path)
Отредактировано sander (Авг. 17, 2017 21:47:58)
Офлайн
sander
Не удается воспользоваться, что-то не так в строчках
<a href="{{ url_for("download_file", path=entry.path) }}">{{ entry.name }}</a> <a href="{{ url_for("dir_viewer", path=entry.path) }}">{{ entry.name }}</a>
ValueError: View function did not return a responseПопробую разобраться сейчас.
@app.route("/<paht:path>")
Отредактировано gmaksim (Авг. 18, 2017 10:16:36)
Офлайн
gmaksimесли есть ошибка - кидай трейсбек.
Не удается воспользоваться, что-то не так в строчках
gmaksimопечатка, да.
Еще кажется тут должно быть path:path:
Офлайн
Не получается все равно воспользоваться, что вы подразумевается под нормальным шаблоном с render_template?
Данный код судя по всему в действующий не включить? Переход на /download/ тут:
@app.route("/download/<path:path>") def download_file(path):
Отредактировано gmaksim (Авг. 21, 2017 11:24:26)
Офлайн
gmaksim
gmaksimфайл с html шаблоном, который рендерится через вызов render_template
Не получается все равно воспользоваться, что вы подразумевается под нормальным шаблоном с render_template?
gmaksimвсе что идет после “/download/” будет считаться путем к файлу
Точнее сам download - это будет работать в виду перехода на url в адресной строке и дальше автоматически подставляться в зависимости от того, что мы выбрали?
Офлайн
sanderТ.е. после включения части
файл с html шаблоном, который рендерится через вызов render_template
{% for entry in entries %} {% if entry.is_file() %} <a href="{{ url_for("download_file", path=entry.path) }}">{{ entry.name }}</a> {% else %} <a href="{{ url_for("dir_viewer", path=entry.path) }}">{{ entry.name }}</a> {% endif %} {% endfor %}
Офлайн
gmaksim
да, если сделаешь
render_template("<template name>.html", entries=entries)
Офлайн