Skip to content
Snippets Groups Projects
Commit 6444eef1 authored by Martin Mareš's avatar Martin Mareš
Browse files

Customizace uploadu souborů

Donutit k něčemu takovému Flask je docela divoké, ale vlastně to jsou
všechno dokumentované a doporučené postupy O:-)
parent ee729c0c
No related branches found
No related tags found
1 merge request!21Reforma uploadů
This commit is part of merge request !21. Comments created here will be created in the context of that merge request.
from flask import Flask, request, g, session from flask import Flask, request, g, session
import flask.logging import flask.logging
import flask.wrappers
from flask_bootstrap import Bootstrap from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
import locale import locale
import logging import logging
import os import os
import tempfile
from typing import Optional
import werkzeug.exceptions import werkzeug.exceptions
import werkzeug.formparser
import mo import mo
import mo.config as config import mo.config as config
...@@ -15,6 +19,44 @@ import mo.rights ...@@ -15,6 +19,44 @@ import mo.rights
import mo.users import mo.users
import mo.util import mo.util
# Ohýbáme Flask, aby uploadované soubory ukládal do adresáře podle našeho přání,
# aby se pak daly zařadit mezi datové soubory prostým hardlinkováním. Za tímto účelem
# subclassujeme Request, aby použil subclassovaný FormDataParser, který použije naši
# stream factory místo defaultní.
def mo_stream_factory(total_content_length, filename, content_type, content_length=None):
return tempfile.NamedTemporaryFile(dir=mo.util.data_dir('tmp'), prefix='upload-')
class FormDataParser(werkzeug.formparser.FormDataParser):
def __init__(self,
stream_factory=None,
charset='utf-8',
errors='replace',
max_form_memory_size=None,
max_content_length=None,
cls=None,
silent=True):
super().__init__(mo_stream_factory, charset, errors, max_form_memory_size, max_content_length, cls, silent)
class Request(flask.wrappers.Request):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form_data_parser_class = FormDataParser
# Můžeme zvýšit maximální velikost souboru pro dávkové uploady
custom_max_content_length: Optional[int] = None
# Původně atribut ve werkzeug.BaseRequest, předefinován na property ve flask.Request
@property
def max_content_length(self):
return self.custom_max_content_length or mo.config.MAX_CONTENT_LENGTH
# Flask interpretuje relativní cesty všelijak, tak mu vyrobíme absolutní # Flask interpretuje relativní cesty všelijak, tak mu vyrobíme absolutní
mo.config.DATA_DIR = os.path.abspath(mo.config.DATA_DIR) mo.config.DATA_DIR = os.path.abspath(mo.config.DATA_DIR)
static_dir = os.path.abspath('static') static_dir = os.path.abspath('static')
...@@ -22,6 +64,7 @@ static_dir = os.path.abspath('static') ...@@ -22,6 +64,7 @@ static_dir = os.path.abspath('static')
# Aplikační objekt # Aplikační objekt
app = Flask(__name__, instance_path=mo.config.DATA_DIR, static_folder=static_dir) app = Flask(__name__, instance_path=mo.config.DATA_DIR, static_folder=static_dir)
app.config.from_object(config) app.config.from_object(config)
app.request_class = Request
db.flask_db = SQLAlchemy(app, metadata=db.metadata) db.flask_db = SQLAlchemy(app, metadata=db.metadata)
Bootstrap(app) # make bootstrap libs accessible for the app Bootstrap(app) # make bootstrap libs accessible for the app
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment