Server side file browser
This commit is contained in:
parent
2508c1abb2
commit
d3986ca14a
35
cps/admin.py
35
cps/admin.py
|
@ -520,13 +520,21 @@ def list_restriction(res_type):
|
||||||
response.headers["Content-Type"] = "application/json; charset=utf-8"
|
response.headers["Content-Type"] = "application/json; charset=utf-8"
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@admi.route("/basicconfig/pathchooser/")
|
||||||
|
@unconfigured
|
||||||
|
def config_pathchooser():
|
||||||
|
return pathchooser()
|
||||||
|
|
||||||
@admi.route("/ajax/pathchooser/", endpoint="pathchooser")
|
@admi.route("/ajax/pathchooser/")
|
||||||
@admi.route("/ajax/filechooser/", endpoint="filechooser")
|
|
||||||
@login_required
|
@login_required
|
||||||
@admin_required
|
@admin_required
|
||||||
|
def ajax_pathchooser():
|
||||||
|
return pathchooser()
|
||||||
|
|
||||||
def pathchooser():
|
def pathchooser():
|
||||||
browse_for = "folder" if request.endpoint == "admin.pathchooser" else "file"
|
browse_for = "folder" # if request.endpoint == "admin.pathchooser" else "file"
|
||||||
|
folder_only = request.args.get('folder', False) == "true"
|
||||||
|
file_filter = request.args.get('filter', "")
|
||||||
path = os.path.normpath(request.args.get('path', ""))
|
path = os.path.normpath(request.args.get('path', ""))
|
||||||
|
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
|
@ -538,11 +546,11 @@ def pathchooser():
|
||||||
abs = False
|
abs = False
|
||||||
|
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
if os.path.isabs(path):
|
#if os.path.isabs(path):
|
||||||
cwd = os.path.realpath(path)
|
cwd = os.path.realpath(path)
|
||||||
abs = True
|
abs = True
|
||||||
else:
|
#else:
|
||||||
cwd = os.path.relpath(path)
|
# cwd = os.path.relpath(path)
|
||||||
else:
|
else:
|
||||||
cwd = os.getcwd()
|
cwd = os.getcwd()
|
||||||
|
|
||||||
|
@ -564,18 +572,19 @@ def pathchooser():
|
||||||
folders = []
|
folders = []
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
locale = get_locale()
|
# locale = get_locale()
|
||||||
for f in folders:
|
for f in folders:
|
||||||
try:
|
try:
|
||||||
data = {"name": f, "fullpath": os.path.join(cwd, f)}
|
data = {"name": f, "fullpath": os.path.join(cwd, f)}
|
||||||
data["sort"] = data["fullpath"].lower()
|
data["sort"] = data["fullpath"].lower()
|
||||||
data["modified"] = format_datetime(datetime.fromtimestamp(int(os.path.getmtime(os.path.join(cwd, f)))),
|
|
||||||
format='short', locale=locale)
|
|
||||||
data["ext"] = os.path.splitext(f)[1]
|
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if os.path.isfile(os.path.join(cwd, f)):
|
if os.path.isfile(os.path.join(cwd, f)):
|
||||||
|
if folder_only:
|
||||||
|
continue
|
||||||
|
if file_filter != "" and file_filter != f:
|
||||||
|
continue
|
||||||
data["type"] = "file"
|
data["type"] = "file"
|
||||||
data["size"] = os.path.getsize(os.path.join(cwd, f))
|
data["size"] = os.path.getsize(os.path.join(cwd, f))
|
||||||
|
|
||||||
|
@ -604,7 +613,7 @@ def pathchooser():
|
||||||
return json.dumps(context)
|
return json.dumps(context)
|
||||||
|
|
||||||
|
|
||||||
@admi.route("/config", methods=["GET", "POST"])
|
@admi.route("/basicconfig", methods=["GET", "POST"])
|
||||||
@unconfigured
|
@unconfigured
|
||||||
def basic_configuration():
|
def basic_configuration():
|
||||||
logout_user()
|
logout_user()
|
||||||
|
|
|
@ -213,22 +213,33 @@ $(function() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillFileTable(path, type) {
|
function fillFileTable(path, type, folder, filt) {
|
||||||
if (type === "dir") {
|
if (window.location.pathname.endsWith("/basicconfig")) {
|
||||||
var request_path = "/../../ajax/pathchooser/";
|
var request_path = "/../basicconfig/pathchooser/";
|
||||||
} else {
|
} else {
|
||||||
var request_path = "/../../ajax/filechooser/";
|
var request_path = "/../../ajax/pathchooser/";
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: {
|
data: {
|
||||||
path: path,
|
path: path,
|
||||||
|
folder: folder,
|
||||||
|
filter: filt
|
||||||
},
|
},
|
||||||
url: window.location.pathname + request_path,
|
url: window.location.pathname + request_path,
|
||||||
success: function success(data) {
|
success: function success(data) {
|
||||||
|
if ($("#element_selected").text() ==="") {
|
||||||
|
$("#element_selected").text(data.cwd);
|
||||||
|
}
|
||||||
$("#file_table > tbody > tr").each(function () {
|
$("#file_table > tbody > tr").each(function () {
|
||||||
if ($(this).attr("id") !== "parent") {
|
if ($(this).attr("id") !== "parent") {
|
||||||
$(this).closest("tr").remove();
|
$(this).closest("tr").remove();
|
||||||
|
} else {
|
||||||
|
if(data.absolute && data.parentdir !== "") {
|
||||||
|
$(this)[0].attributes['data-path'].value = data.parentdir;
|
||||||
|
} else {
|
||||||
|
$(this)[0].attributes['data-path'].value = "..";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (data.parentdir !== "") {
|
if (data.parentdir !== "") {
|
||||||
|
@ -444,83 +455,42 @@ $(function() {
|
||||||
|
|
||||||
|
|
||||||
$("#fileModal").on("show.bs.modal", function(e) {
|
$("#fileModal").on("show.bs.modal", function(e) {
|
||||||
//get data-id attribute of the clicked element and store in button
|
var target = $(e.relatedTarget);
|
||||||
//var submit = true;
|
var path = $("#" + target.data("link"))[0].value;
|
||||||
//var cwd = "{{oldfile|default(cwd, True)|abspath|replace('\\', '\\\\')}}";
|
var folder = target.data("folderonly");
|
||||||
//var isabsolute = true;
|
var filter = target.data("filefilter");
|
||||||
fillFileTable("","dir");
|
$("#element_selected").text(path);
|
||||||
|
$("#file_confirm")[0].attributes["data-link"].value = target.data("link");
|
||||||
|
$("#file_confirm")[0].attributes["data-folderonly"].value = (typeof folder === 'undefined') ? false : true;
|
||||||
|
$("#file_confirm")[0].attributes["data-filefilter"].value = (typeof filter === 'undefined') ? "" : filter;
|
||||||
|
$("#file_confirm")[0].attributes["data-newfile"].value = target.data("newfile");
|
||||||
|
fillFileTable(path,"dir", folder, filter);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#file_confirm").click(function() {
|
||||||
|
$("#" + $(this).data("link"))[0].value = $("#element_selected").text()
|
||||||
});
|
});
|
||||||
|
|
||||||
//(".tr-clickable").on("click",
|
|
||||||
$(document).on("click", ".tr-clickable", function() {
|
$(document).on("click", ".tr-clickable", function() {
|
||||||
var path = this.attributes['data-path'].value;
|
var path = this.attributes["data-path"].value;
|
||||||
var type = this.attributes['data-type'].value;
|
var type = this.attributes["data-type"].value;
|
||||||
fillFileTable(path, type);
|
var folder = $(file_confirm).data("folderonly");
|
||||||
|
var filter = $(file_confirm).data("filefilter");
|
||||||
|
var newfile = $(file_confirm).data("newfile");
|
||||||
|
if (newfile !== 'undefined') {
|
||||||
|
$("#element_selected").text(path + $("#new_file".text()));
|
||||||
|
} else {
|
||||||
|
$("#element_selected").text(path);
|
||||||
|
}
|
||||||
|
if(type === "dir") {
|
||||||
|
fillFileTable(path, type, folder, filter);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/*{% if type == 'folder' %} {# browsing for folder #}
|
|
||||||
var abspath = "{{url_for('app.pathchooser') + '?path=' + cwd|abspath|quote_plus}}";
|
|
||||||
var relpath = "{{url_for('app.pathchooser') + '?path=' + cwd|relpath|quote_plus}}";
|
|
||||||
{% else %} {# browsing for file #}
|
|
||||||
var abspath = "{{url_for('app.filechooser') + '?path=' + oldfile|default(cwd, True)|abspath|quote_plus}}";
|
|
||||||
var relpath = "{{url_for('app.filechooser') + '?path=' + oldfile|default(cwd, True)|relpath|quote_plus}}";
|
|
||||||
{% endif %}*/
|
|
||||||
/*document.addEventListener("readystatechange", function(event) {
|
|
||||||
if (this.readyState === "complete") {
|
|
||||||
document.getElementById("tbody").style.height = (window.innerHeight - 25) + "px";
|
|
||||||
window.onresize = function (event) {
|
|
||||||
document.getElementById("tbody").style.height = (window.innerHeight - 25) + "px";
|
|
||||||
};
|
|
||||||
var clickables = document.getElementsByClassName("tr-clickable");
|
|
||||||
for (var i = 0; i < clickables.length; i++) {
|
|
||||||
clickables[i].onclick = (function () {
|
|
||||||
var onclick = clickables[i].onclick;
|
|
||||||
return function (e) {
|
|
||||||
if (onclick != null && !onclick()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (this.dataset.href !== undefined && this.dataset.href !== "#") {
|
|
||||||
window.location.href = this.dataset.href;
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
function updateParent()
|
|
||||||
{
|
|
||||||
if (window.top.SettingsUI !== undefined) {
|
|
||||||
window.top.SettingsUI.prototype.pathchooserChanged(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function setInvalid() {
|
|
||||||
submit = false;
|
|
||||||
cwd = "";
|
|
||||||
updateParent();
|
|
||||||
}
|
|
||||||
function setValid() {
|
|
||||||
submit = true;
|
|
||||||
updateParent();
|
|
||||||
}
|
|
||||||
function setFile(fullpath, name)
|
|
||||||
{
|
|
||||||
cwd = fullpath;
|
|
||||||
/*{*% if type == "file" %} {# browsing for file #}
|
|
||||||
abspath = "{{url_for('app.filechooser')}}?path={{cwd|abspath|quote_plus}}" + encodeURIComponent(name);
|
|
||||||
relpath = "{{url_for('app.filechooser')}}?path={{cwd|relpath|quote_plus}}" + encodeURIComponent(name);
|
|
||||||
{% endif %}*/
|
|
||||||
/*setValid();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
$("#btndeletetoken").click(function() {
|
$("#btndeletetoken").click(function() {
|
||||||
//get data-id attribute of the clicked element
|
//get data-id attribute of the clicked element
|
||||||
var pathname = document.getElementsByTagName("script"), src = pathname[pathname.length - 1].src;
|
var pathname = document.getElementsByTagName("script"), src = pathname[pathname.length - 1].src;
|
||||||
var path = src.substring(0, src.lastIndexOf("/"));
|
var path = src.substring(0, src.lastIndexOf("/"));
|
||||||
// var domainId = $(this).value("domainId");
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method:"get",
|
method:"get",
|
||||||
url: path + "/../../kobo_auth/deleteauthtoken/" + this.value,
|
url: path + "/../../kobo_auth/deleteauthtoken/" + this.value,
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<div class="form-group required input-group">
|
<div class="form-group required input-group">
|
||||||
<input type="text" class="form-control" id="config_calibre_dir" name="config_calibre_dir" value="{% if config.config_calibre_dir != None %}{{ config.config_calibre_dir }}{% endif %}" autocomplete="off">
|
<input type="text" class="form-control" id="config_calibre_dir" name="config_calibre_dir" value="{% if config.config_calibre_dir != None %}{{ config.config_calibre_dir }}{% endif %}" autocomplete="off">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" id="library_path" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
<button type="button" data-toggle="modal" id="converter_modal_path" data-link="config_calibre_dir" data-filefilter="metadata.db" data-target="#fileModal" id="library_path" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{% if feature_support['gdrive'] %}
|
{% if feature_support['gdrive'] %}
|
||||||
|
@ -94,14 +94,14 @@
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
<input type="text" class="form-control" id="config_certfile" name="config_certfile" value="{% if config.config_certfile != None %}{{ config.config_certfile }}{% endif %}" autocomplete="off">
|
<input type="text" class="form-control" id="config_certfile" name="config_certfile" value="{% if config.config_certfile != None %}{{ config.config_certfile }}{% endif %}" autocomplete="off">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" id="certfile_path" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
<button type="button" data-toggle="modal" data-link="config_certfile" data-target="#fileModal" id="certfile_path" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<label for="config_calibre_dir" >{{_('SSL Keyfile location (leave it empty for non-SSL Servers)')}}</label>
|
<label for="config_calibre_dir" >{{_('SSL Keyfile location (leave it empty for non-SSL Servers)')}}</label>
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
<input type="text" class="form-control" id="config_keyfile" name="config_keyfile" value="{% if config.config_keyfile != None %}{{ config.config_keyfile }}{% endif %}" autocomplete="off">
|
<input type="text" class="form-control" id="config_keyfile" name="config_keyfile" value="{% if config.config_keyfile != None %}{{ config.config_keyfile }}{% endif %}" autocomplete="off">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" id="keyfile_path" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
<button type="button" id="keyfile_path" data-toggle="modal" data-link="config_keyfile" data-target="#fileModal" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -268,21 +268,21 @@
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
<input type="text" class="form-control" id="config_ldap_cacert_path" name="config_ldap_cacert_path" value="{% if config.config_ldap_cacert_path != None %}{{ config.config_ldap_cacert_path }}{% endif %}" autocomplete="off">
|
<input type="text" class="form-control" id="config_ldap_cacert_path" name="config_ldap_cacert_path" value="{% if config.config_ldap_cacert_path != None %}{{ config.config_ldap_cacert_path }}{% endif %}" autocomplete="off">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" id="library_path" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
<button type="button" id="library_path" data-toggle="modal" data-link="config_ldap_cacert_path" data-target="#fileModal" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<label for="config_ldap_cert_path">{{_('LDAP Certificate Path (Only needed for Client Certificate Authentication)')}}</label>
|
<label for="config_ldap_cert_path">{{_('LDAP Certificate Path (Only needed for Client Certificate Authentication)')}}</label>
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
<input type="text" class="form-control" id="config_ldap_cert_path" name="config_ldap_cert_path" value="{% if config.config_ldap_cert_path != None %}{{ config.config_ldap_cert_path }}{% endif %}" autocomplete="off">
|
<input type="text" class="form-control" id="config_ldap_cert_path" name="config_ldap_cert_path" value="{% if config.config_ldap_cert_path != None %}{{ config.config_ldap_cert_path }}{% endif %}" autocomplete="off">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" id="library_path" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
<button type="button" id="library_path" data-toggle="modal" data-link="config_ldap_cert_path" data-target="#fileModal" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<label for="config_ldap_key_path">{{_('LDAP Keyfile Path (Only needed for Client Certificate Authentication)')}}</label>
|
<label for="config_ldap_key_path">{{_('LDAP Keyfile Path (Only needed for Client Certificate Authentication)')}}</label>
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
<input type="text" class="form-control" id="config_ldap_key_path" name="config_ldap_key_path" value="{% if config.config_ldap_key_path != None %}{{ config.config_ldap_key_path }}{% endif %}" autocomplete="off">
|
<input type="text" class="form-control" id="config_ldap_key_path" name="config_ldap_key_path" value="{% if config.config_ldap_key_path != None %}{{ config.config_ldap_key_path }}{% endif %}" autocomplete="off">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" id="library_path" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
<button type="button" id="library_path" data-toggle="modal" data-link="config_ldap_key_path" data-target="#fileModal" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -384,7 +384,7 @@
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
<input type="text" class="form-control" id="config_converterpath" name="config_converterpath" value="{% if config.config_converterpath != None %}{{ config.config_converterpath }}{% endif %}" autocomplete="off">
|
<input type="text" class="form-control" id="config_converterpath" name="config_converterpath" value="{% if config.config_converterpath != None %}{{ config.config_converterpath }}{% endif %}" autocomplete="off">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" id="converter_modal_path" data-toggle="modal" data-target="#fileModal" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
<button type="button" data-toggle="modal" id="converter_modal_path" data-link="config_converterpath" data-target="#fileModal" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -395,7 +395,7 @@
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
<input type="text" class="form-control" id="config_kepubifypath" name="config_kepubifypath" value="{% if config.config_kepubifypath != None %}{{ config.config_kepubifypath }}{% endif %}" autocomplete="off">
|
<input type="text" class="form-control" id="config_kepubifypath" name="config_kepubifypath" value="{% if config.config_kepubifypath != None %}{{ config.config_kepubifypath }}{% endif %}" autocomplete="off">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" id="kepubify_path" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
<button type="button" id="kepubify_path" data-toggle="modal" data-link="config_kepubifypath" data-target="#fileModal" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{% if feature_support['rar'] %}
|
{% if feature_support['rar'] %}
|
||||||
|
@ -403,7 +403,7 @@
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
<input type="text" class="form-control" id="config_rarfile_location" name="config_rarfile_location" value="{% if config.config_rarfile_location != None %}{{ config.config_rarfile_location }}{% endif %}" autocomplete="off">
|
<input type="text" class="form-control" id="config_rarfile_location" name="config_rarfile_location" value="{% if config.config_rarfile_location != None %}{{ config.config_rarfile_location }}{% endif %}" autocomplete="off">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" id="unrar_path" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
<button type="button" id="unrar_path" data-toggle="modal" data-link="config_rarfile_location" data-target="#fileModal" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -94,7 +94,8 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<input type="button" class="btn btn-primary" value="{{_('Select')}}" name="file_confirm" id="file_confirm" data-dismiss="modal">
|
<div class="text-left" id="element_selected"></div>
|
||||||
|
<input type="button" class="btn btn-primary" data-path="" data-link="" data-folderonly="" data-filefilter="" data-newfile="" value="{{_('Select')}}" name="file_confirm" id="file_confirm" data-dismiss="modal">
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{_('Cancel')}}</button>
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{_('Cancel')}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -304,7 +304,7 @@ def before_request():
|
||||||
g.shelves_access = ub.session.query(ub.Shelf).filter(
|
g.shelves_access = ub.session.query(ub.Shelf).filter(
|
||||||
or_(ub.Shelf.is_public == 1, ub.Shelf.user_id == current_user.id)).order_by(ub.Shelf.name).all()
|
or_(ub.Shelf.is_public == 1, ub.Shelf.user_id == current_user.id)).order_by(ub.Shelf.name).all()
|
||||||
if not config.db_configured and request.endpoint not in (
|
if not config.db_configured and request.endpoint not in (
|
||||||
'admin.basic_configuration', 'login') and '/static/' not in request.path:
|
'admin.basic_configuration', 'login', "admin.config_pathchooser") and '/static/' not in request.path:
|
||||||
return redirect(url_for('admin.basic_configuration'))
|
return redirect(url_for('admin.basic_configuration'))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user