Skip to content
Snippets Groups Projects

Reforma uploadů

1 unresolved thread
Merged Martin Mareš requested to merge mj/upload into devel
1 unresolved thread
1 file
+ 43
0
Compare changes
  • Side-by-side
  • Inline
  • 6444eef1
    Customizace uploadu souborů · 6444eef1
    Martin Mareš authored
    Donutit k něčemu takovému Flask je docela divoké, ale vlastně to jsou
    všechno dokumentované a doporučené postupy O:-)
+ 43
0
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
Loading