flask-appbuilder 3.2.1rc1__py3-none-any.whl → 5.0.2rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flask_appbuilder/__init__.py +2 -3
- flask_appbuilder/_compat.py +0 -1
- flask_appbuilder/actions.py +14 -14
- flask_appbuilder/api/__init__.py +741 -527
- flask_appbuilder/api/convert.py +104 -98
- flask_appbuilder/api/manager.py +14 -8
- flask_appbuilder/api/schemas.py +12 -1
- flask_appbuilder/babel/manager.py +12 -16
- flask_appbuilder/base.py +353 -280
- flask_appbuilder/basemanager.py +1 -1
- flask_appbuilder/baseviews.py +241 -164
- flask_appbuilder/charts/jsontools.py +10 -10
- flask_appbuilder/charts/views.py +56 -60
- flask_appbuilder/cli.py +115 -70
- flask_appbuilder/const.py +52 -52
- flask_appbuilder/exceptions.py +67 -5
- flask_appbuilder/fields.py +32 -23
- flask_appbuilder/fieldwidgets.py +34 -27
- flask_appbuilder/filemanager.py +33 -45
- flask_appbuilder/filters.py +11 -13
- flask_appbuilder/forms.py +31 -35
- flask_appbuilder/hooks.py +90 -0
- flask_appbuilder/menu.py +35 -10
- flask_appbuilder/models/base.py +47 -57
- flask_appbuilder/models/decorators.py +13 -13
- flask_appbuilder/models/filters.py +42 -38
- flask_appbuilder/models/generic/__init__.py +29 -29
- flask_appbuilder/models/generic/filters.py +11 -3
- flask_appbuilder/models/generic/interface.py +1 -3
- flask_appbuilder/models/group.py +37 -39
- flask_appbuilder/models/mixins.py +22 -18
- flask_appbuilder/models/sqla/__init__.py +19 -72
- flask_appbuilder/models/sqla/base.py +24 -0
- flask_appbuilder/models/sqla/base_legacy.py +132 -0
- flask_appbuilder/models/sqla/filters.py +132 -19
- flask_appbuilder/models/sqla/interface.py +390 -276
- flask_appbuilder/security/api.py +31 -35
- flask_appbuilder/security/decorators.py +181 -83
- flask_appbuilder/security/forms.py +20 -31
- flask_appbuilder/security/manager.py +715 -489
- flask_appbuilder/security/registerviews.py +29 -112
- flask_appbuilder/security/schemas.py +43 -0
- flask_appbuilder/security/sqla/apis/__init__.py +8 -0
- flask_appbuilder/security/sqla/apis/group/__init__.py +1 -0
- flask_appbuilder/security/sqla/apis/group/api.py +227 -0
- flask_appbuilder/security/sqla/apis/group/schema.py +73 -0
- flask_appbuilder/security/sqla/apis/permission/__init__.py +1 -0
- flask_appbuilder/security/sqla/apis/permission/api.py +19 -0
- flask_appbuilder/security/sqla/apis/permission_view_menu/__init__.py +1 -0
- flask_appbuilder/security/sqla/apis/permission_view_menu/api.py +16 -0
- flask_appbuilder/security/sqla/apis/role/__init__.py +1 -0
- flask_appbuilder/security/sqla/apis/role/api.py +306 -0
- flask_appbuilder/security/sqla/apis/role/schema.py +27 -0
- flask_appbuilder/security/sqla/apis/user/__init__.py +1 -0
- flask_appbuilder/security/sqla/apis/user/api.py +292 -0
- flask_appbuilder/security/sqla/apis/user/schema.py +97 -0
- flask_appbuilder/security/sqla/apis/user/validator.py +27 -0
- flask_appbuilder/security/sqla/apis/view_menu/__init__.py +1 -0
- flask_appbuilder/security/sqla/apis/view_menu/api.py +18 -0
- flask_appbuilder/security/sqla/manager.py +421 -203
- flask_appbuilder/security/sqla/models.py +192 -57
- flask_appbuilder/security/utils.py +9 -0
- flask_appbuilder/security/views.py +232 -229
- flask_appbuilder/static/.DS_Store +0 -0
- flask_appbuilder/static/appbuilder/css/ab.css +20 -12
- flask_appbuilder/static/appbuilder/css/bootstrap-datepicker/bootstrap-datepicker3.min.css +7 -0
- flask_appbuilder/static/appbuilder/css/bootstrap.min.css.map +1 -0
- flask_appbuilder/static/appbuilder/css/flags/flags16.css +249 -245
- flask_appbuilder/static/appbuilder/css/fontawesome/all.min.css +6 -0
- flask_appbuilder/static/appbuilder/css/fontawesome/brands.min.css +6 -0
- flask_appbuilder/static/appbuilder/css/fontawesome/fontawesome.min.css +6 -0
- flask_appbuilder/static/appbuilder/css/fontawesome/regular.min.css +6 -0
- flask_appbuilder/static/appbuilder/css/fontawesome/solid.min.css +6 -0
- flask_appbuilder/static/appbuilder/css/fontawesome/svg-with-js.min.css +6 -0
- flask_appbuilder/static/appbuilder/css/fontawesome/v4-font-face.min.css +6 -0
- flask_appbuilder/static/appbuilder/css/fontawesome/v4-shims.min.css +6 -0
- flask_appbuilder/static/appbuilder/css/fontawesome/v5-font-face.min.css +6 -0
- flask_appbuilder/static/appbuilder/css/images/flags16.png +0 -0
- flask_appbuilder/static/appbuilder/css/select2/select2-bootstrap.min.css +7 -0
- flask_appbuilder/static/appbuilder/css/select2/select2.min.css +1 -0
- flask_appbuilder/static/appbuilder/css/swagger/swagger-ui.css +3 -0
- flask_appbuilder/static/appbuilder/css/webfonts/fa-brands-400.ttf +0 -0
- flask_appbuilder/static/appbuilder/css/webfonts/fa-brands-400.woff2 +0 -0
- flask_appbuilder/static/appbuilder/css/webfonts/fa-regular-400.ttf +0 -0
- flask_appbuilder/static/appbuilder/css/webfonts/fa-regular-400.woff2 +0 -0
- flask_appbuilder/static/appbuilder/css/webfonts/fa-solid-900.ttf +0 -0
- flask_appbuilder/static/appbuilder/css/webfonts/fa-solid-900.woff2 +0 -0
- flask_appbuilder/static/appbuilder/css/webfonts/fa-v4compatibility.ttf +0 -0
- flask_appbuilder/static/appbuilder/css/webfonts/fa-v4compatibility.woff2 +0 -0
- flask_appbuilder/static/appbuilder/js/ab.js +33 -23
- flask_appbuilder/static/appbuilder/js/ab_filters.js +91 -84
- flask_appbuilder/static/appbuilder/js/bootstrap-datepicker/bootstrap-datepicker.min.js +8 -0
- flask_appbuilder/static/appbuilder/js/jquery-latest.js +2 -2
- flask_appbuilder/static/appbuilder/js/select2/select2.min.js +2 -0
- flask_appbuilder/static/appbuilder/js/swagger-ui-bundle.js +3 -0
- flask_appbuilder/templates/appbuilder/baselib.html +9 -3
- flask_appbuilder/templates/appbuilder/general/lib.html +60 -34
- flask_appbuilder/templates/appbuilder/general/model/edit.html +1 -1
- flask_appbuilder/templates/appbuilder/general/model/edit_cascade.html +1 -1
- flask_appbuilder/templates/appbuilder/general/model/search.html +3 -2
- flask_appbuilder/templates/appbuilder/general/model/show.html +1 -1
- flask_appbuilder/templates/appbuilder/general/model/show_cascade.html +1 -1
- flask_appbuilder/templates/appbuilder/general/security/login_db.html +7 -7
- flask_appbuilder/templates/appbuilder/general/security/login_ldap.html +5 -5
- flask_appbuilder/templates/appbuilder/general/security/login_oauth.html +24 -49
- flask_appbuilder/templates/appbuilder/general/widgets/base_list.html +2 -1
- flask_appbuilder/templates/appbuilder/general/widgets/chart.html +4 -2
- flask_appbuilder/templates/appbuilder/general/widgets/direct_chart.html +4 -3
- flask_appbuilder/templates/appbuilder/general/widgets/multiple_chart.html +3 -2
- flask_appbuilder/templates/appbuilder/general/widgets/search.html +11 -10
- flask_appbuilder/templates/appbuilder/init.html +37 -43
- flask_appbuilder/templates/appbuilder/navbar_menu.html +1 -1
- flask_appbuilder/templates/appbuilder/navbar_right.html +2 -2
- flask_appbuilder/templates/appbuilder/swagger/swagger.html +22 -19
- flask_appbuilder/translations/de/LC_MESSAGES/messages.mo +0 -0
- flask_appbuilder/translations/de/LC_MESSAGES/messages.po +305 -161
- flask_appbuilder/translations/fa/LC_MESSAGES/messages.mo +0 -0
- flask_appbuilder/translations/fa/LC_MESSAGES/messages.po +802 -0
- flask_appbuilder/translations/fr/LC_MESSAGES/messages.po +461 -319
- flask_appbuilder/translations/pt_BR/LC_MESSAGES/messages.po +650 -650
- flask_appbuilder/translations/ru/LC_MESSAGES/messages.po +1 -1
- flask_appbuilder/translations/sl/LC_MESSAGES/messages.mo +0 -0
- flask_appbuilder/translations/sl/LC_MESSAGES/messages.po +690 -0
- flask_appbuilder/translations/tr/LC_MESSAGES/messages.mo +0 -0
- flask_appbuilder/translations/tr/LC_MESSAGES/messages.po +1015 -0
- flask_appbuilder/upload.py +20 -22
- flask_appbuilder/urltools.py +39 -19
- flask_appbuilder/utils/base.py +76 -0
- flask_appbuilder/utils/legacy.py +33 -0
- flask_appbuilder/utils/limit.py +20 -0
- flask_appbuilder/validators.py +73 -14
- flask_appbuilder/views.py +75 -424
- flask_appbuilder/widgets.py +50 -51
- {Flask_AppBuilder-3.2.1rc1.dist-info → flask_appbuilder-5.0.2rc1.dist-info}/METADATA +36 -76
- flask_appbuilder-5.0.2rc1.dist-info/RECORD +240 -0
- {Flask_AppBuilder-3.2.1rc1.dist-info → flask_appbuilder-5.0.2rc1.dist-info}/WHEEL +1 -1
- flask_appbuilder-5.0.2rc1.dist-info/entry_points.txt +2 -0
- Flask_AppBuilder-3.2.1rc1.dist-info/RECORD +0 -270
- Flask_AppBuilder-3.2.1rc1.dist-info/entry_points.txt +0 -6
- flask_appbuilder/console.py +0 -426
- flask_appbuilder/models/mongoengine/__init__.py +0 -0
- flask_appbuilder/models/mongoengine/fields.py +0 -65
- flask_appbuilder/models/mongoengine/filters.py +0 -145
- flask_appbuilder/models/mongoengine/interface.py +0 -328
- flask_appbuilder/security/mongoengine/__init__.py +0 -0
- flask_appbuilder/security/mongoengine/manager.py +0 -402
- flask_appbuilder/security/mongoengine/models.py +0 -120
- flask_appbuilder/static/appbuilder/css/font-awesome.min.css +0 -4
- flask_appbuilder/static/appbuilder/datepicker/bootstrap-datepicker.css +0 -9
- flask_appbuilder/static/appbuilder/datepicker/bootstrap-datepicker.js +0 -28
- flask_appbuilder/static/appbuilder/fonts/FontAwesome.otf +0 -0
- flask_appbuilder/static/appbuilder/fonts/fontawesome-webfont.eot +0 -0
- flask_appbuilder/static/appbuilder/fonts/fontawesome-webfont.svg +0 -2671
- flask_appbuilder/static/appbuilder/fonts/fontawesome-webfont.ttf +0 -0
- flask_appbuilder/static/appbuilder/fonts/fontawesome-webfont.woff +0 -0
- flask_appbuilder/static/appbuilder/fonts/fontawesome-webfont.woff2 +0 -0
- flask_appbuilder/static/appbuilder/img/aol.png +0 -0
- flask_appbuilder/static/appbuilder/img/flags/flags16.png +0 -0
- flask_appbuilder/static/appbuilder/img/flickr.png +0 -0
- flask_appbuilder/static/appbuilder/img/google.png +0 -0
- flask_appbuilder/static/appbuilder/img/myopenid.png +0 -0
- flask_appbuilder/static/appbuilder/img/yahoo.png +0 -0
- flask_appbuilder/static/appbuilder/js/_google_charts.js +0 -39
- flask_appbuilder/static/appbuilder/js/html5shiv.js +0 -8
- flask_appbuilder/static/appbuilder/js/respond.min.js +0 -6
- flask_appbuilder/static/appbuilder/select2/select2-spinner.gif +0 -0
- flask_appbuilder/static/appbuilder/select2/select2.css +0 -1205
- flask_appbuilder/static/appbuilder/select2/select2.js +0 -23
- flask_appbuilder/static/appbuilder/select2/select2.png +0 -0
- flask_appbuilder/static/appbuilder/select2/select2x2.png +0 -0
- flask_appbuilder/templates/appbuilder/general/security/login_oid.html +0 -129
- flask_appbuilder/templates/appbuilder/general/security/resetpassword.html +0 -29
- flask_appbuilder/tests/__init__.py +0 -0
- flask_appbuilder/tests/__pycache__/__init__.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/__init__.cpython-37.pyc +0 -0
- flask_appbuilder/tests/__pycache__/_test_auth_ldap.cpython-37.pyc +0 -0
- flask_appbuilder/tests/__pycache__/_test_auth_oauth.cpython-37.pyc +0 -0
- flask_appbuilder/tests/__pycache__/_test_ldapsearch.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/_test_oauth_registration_role.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/base.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/base.cpython-37.pyc +0 -0
- flask_appbuilder/tests/__pycache__/config_api.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/config_api.cpython-37.pyc +0 -0
- flask_appbuilder/tests/__pycache__/const.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/const.cpython-37.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_0_fixture.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_0_fixture.cpython-37.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_api.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_api.cpython-37.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_fab_cli.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_fab_cli.cpython-37.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_menu.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_menu.cpython-37.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_mongoengine.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_mvc.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_mvc.cpython-37.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_sqlalchemy.cpython-36.pyc +0 -0
- flask_appbuilder/tests/__pycache__/test_sqlalchemy.cpython-37.pyc +0 -0
- flask_appbuilder/tests/_test_auth_ldap.py +0 -1045
- flask_appbuilder/tests/_test_auth_oauth.py +0 -419
- flask_appbuilder/tests/_test_ldapsearch.py +0 -135
- flask_appbuilder/tests/_test_oauth_registration_role.py +0 -59
- flask_appbuilder/tests/app.db +0 -0
- flask_appbuilder/tests/base.py +0 -90
- flask_appbuilder/tests/config_api.py +0 -21
- flask_appbuilder/tests/const.py +0 -9
- flask_appbuilder/tests/mongoengine/__init__.py +0 -0
- flask_appbuilder/tests/mongoengine/__pycache__/__init__.cpython-36.pyc +0 -0
- flask_appbuilder/tests/mongoengine/__pycache__/__init__.cpython-37.pyc +0 -0
- flask_appbuilder/tests/mongoengine/__pycache__/models.cpython-36.pyc +0 -0
- flask_appbuilder/tests/mongoengine/models.py +0 -41
- flask_appbuilder/tests/sqla/__init__.py +0 -0
- flask_appbuilder/tests/sqla/__pycache__/__init__.cpython-36.pyc +0 -0
- flask_appbuilder/tests/sqla/__pycache__/__init__.cpython-37.pyc +0 -0
- flask_appbuilder/tests/sqla/__pycache__/models.cpython-36.pyc +0 -0
- flask_appbuilder/tests/sqla/__pycache__/models.cpython-37.pyc +0 -0
- flask_appbuilder/tests/sqla/models.py +0 -340
- flask_appbuilder/tests/test_0_fixture.py +0 -39
- flask_appbuilder/tests/test_api.py +0 -2790
- flask_appbuilder/tests/test_fab_cli.py +0 -72
- flask_appbuilder/tests/test_menu.py +0 -122
- flask_appbuilder/tests/test_mongoengine.py +0 -572
- flask_appbuilder/tests/test_mvc.py +0 -1710
- flask_appbuilder/tests/test_sqlalchemy.py +0 -24
- flask_appbuilder/translations/__pycache__/__init__.cpython-36.pyc +0 -0
- flask_appbuilder/translations/es/LC_MESSAGES/messages.po~ +0 -582
- {Flask_AppBuilder-3.2.1rc1.dist-info → flask_appbuilder-5.0.2rc1.dist-info}/LICENSE +0 -0
- {Flask_AppBuilder-3.2.1rc1.dist-info → flask_appbuilder-5.0.2rc1.dist-info}/top_level.txt +0 -0
flask_appbuilder/console.py
DELETED
|
@@ -1,426 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Console utility to help manage F.A.B's apps
|
|
3
|
-
|
|
4
|
-
use:
|
|
5
|
-
|
|
6
|
-
$ fabmanager --help
|
|
7
|
-
"""
|
|
8
|
-
from io import BytesIO
|
|
9
|
-
import os
|
|
10
|
-
import shutil
|
|
11
|
-
import sys
|
|
12
|
-
from zipfile import ZipFile
|
|
13
|
-
|
|
14
|
-
import click
|
|
15
|
-
|
|
16
|
-
from . import const as c
|
|
17
|
-
|
|
18
|
-
try:
|
|
19
|
-
# For Python 3.0 and later
|
|
20
|
-
from urllib.request import urlopen
|
|
21
|
-
except ImportError:
|
|
22
|
-
# Fall back to Python 2's urllib2
|
|
23
|
-
from urllib2 import urlopen
|
|
24
|
-
|
|
25
|
-
click.echo(
|
|
26
|
-
click.style(
|
|
27
|
-
"fabmanager is going to be deprecated in 2.2.X, you can use "
|
|
28
|
-
"the same commands on the improved 'flask fab <command>'",
|
|
29
|
-
fg="red",
|
|
30
|
-
)
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
SQLA_REPO_URL = (
|
|
34
|
-
"https://github.com/dpgaspar/Flask-AppBuilder-Skeleton/archive/master.zip"
|
|
35
|
-
)
|
|
36
|
-
MONGOENGIE_REPO_URL = (
|
|
37
|
-
"https://github.com/dpgaspar/Flask-AppBuilder-Skeleton-me/archive/master.zip"
|
|
38
|
-
)
|
|
39
|
-
ADDON_REPO_URL = (
|
|
40
|
-
"https://github.com/dpgaspar/Flask-AppBuilder-Skeleton-AddOn/archive/master.zip"
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def import_application(app_package, appbuilder):
|
|
45
|
-
sys.path.append(os.getcwd())
|
|
46
|
-
try:
|
|
47
|
-
_app = __import__(app_package)
|
|
48
|
-
except Exception as e:
|
|
49
|
-
click.echo(
|
|
50
|
-
click.style(
|
|
51
|
-
"Was unable to import {0} Error: {1}".format(app_package, e), fg="red"
|
|
52
|
-
)
|
|
53
|
-
)
|
|
54
|
-
exit(3)
|
|
55
|
-
if hasattr(_app, appbuilder):
|
|
56
|
-
return getattr(_app, appbuilder)
|
|
57
|
-
else:
|
|
58
|
-
click.echo(
|
|
59
|
-
click.style(
|
|
60
|
-
"There is no appbuilder var on your package, "
|
|
61
|
-
"you can use appbuilder parameter to config",
|
|
62
|
-
fg="red",
|
|
63
|
-
)
|
|
64
|
-
)
|
|
65
|
-
exit(3)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def echo_header(title):
|
|
69
|
-
click.echo(click.style(title, fg="green"))
|
|
70
|
-
click.echo(click.style("-" * len(title), fg="green"))
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
@click.group()
|
|
74
|
-
def cli_app():
|
|
75
|
-
"""
|
|
76
|
-
This is a set of commands to ease the creation and maintenance
|
|
77
|
-
of your flask-appbuilder applications.
|
|
78
|
-
|
|
79
|
-
All commands that import your app will assume by default that
|
|
80
|
-
you're running on your projects directory just before the app directory.
|
|
81
|
-
They will also assume that __init__.py initializes AppBuilder
|
|
82
|
-
like this (using a var named appbuilder) just like the skeleton app::
|
|
83
|
-
|
|
84
|
-
appbuilder = AppBuilder(......)
|
|
85
|
-
|
|
86
|
-
If you're using different namings use app and appbuilder parameters.
|
|
87
|
-
"""
|
|
88
|
-
pass
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
@cli_app.command("reset-password")
|
|
92
|
-
@click.option("--app", default="app", help="Your application init directory (package)")
|
|
93
|
-
@click.option("--appbuilder", default="appbuilder", help="your AppBuilder object")
|
|
94
|
-
@click.option(
|
|
95
|
-
"--username",
|
|
96
|
-
default="admin",
|
|
97
|
-
prompt="The username",
|
|
98
|
-
help="Resets the password for a particular user.",
|
|
99
|
-
)
|
|
100
|
-
@click.password_option()
|
|
101
|
-
def reset_password(app, appbuilder, username, password):
|
|
102
|
-
"""
|
|
103
|
-
Resets a user's password
|
|
104
|
-
"""
|
|
105
|
-
_appbuilder = import_application(app, appbuilder)
|
|
106
|
-
user = _appbuilder.sm.find_user(username=username)
|
|
107
|
-
if not user:
|
|
108
|
-
click.echo("User {0} not found.".format(username))
|
|
109
|
-
else:
|
|
110
|
-
_appbuilder.sm.reset_password(user.id, password)
|
|
111
|
-
click.echo(click.style("User {0} reseted.".format(username), fg="green"))
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
@cli_app.command("create-admin")
|
|
115
|
-
@click.option("--app", default="app", help="Your application init directory (package)")
|
|
116
|
-
@click.option("--appbuilder", default="appbuilder", help="your AppBuilder object")
|
|
117
|
-
@click.option("--username", default="admin", prompt="Username")
|
|
118
|
-
@click.option("--firstname", default="admin", prompt="User first name")
|
|
119
|
-
@click.option("--lastname", default="user", prompt="User last name")
|
|
120
|
-
@click.option("--email", default="admin@fab.org", prompt="Email")
|
|
121
|
-
@click.password_option()
|
|
122
|
-
def create_admin(app, appbuilder, username, firstname, lastname, email, password):
|
|
123
|
-
"""
|
|
124
|
-
Creates an admin user
|
|
125
|
-
"""
|
|
126
|
-
auth_type = {
|
|
127
|
-
c.AUTH_DB: "Database Authentications",
|
|
128
|
-
c.AUTH_OID: "OpenID Authentication",
|
|
129
|
-
c.AUTH_LDAP: "LDAP Authentication",
|
|
130
|
-
c.AUTH_REMOTE_USER: "WebServer REMOTE_USER Authentication",
|
|
131
|
-
c.AUTH_OAUTH: "OAuth Authentication",
|
|
132
|
-
}
|
|
133
|
-
_appbuilder = import_application(app, appbuilder)
|
|
134
|
-
click.echo(
|
|
135
|
-
click.style(
|
|
136
|
-
"Recognized {0}.".format(
|
|
137
|
-
auth_type.get(_appbuilder.sm.auth_type, "No Auth method")
|
|
138
|
-
),
|
|
139
|
-
fg="green",
|
|
140
|
-
)
|
|
141
|
-
)
|
|
142
|
-
role_admin = _appbuilder.sm.find_role(_appbuilder.sm.auth_role_admin)
|
|
143
|
-
user = _appbuilder.sm.add_user(
|
|
144
|
-
username, firstname, lastname, email, role_admin, password
|
|
145
|
-
)
|
|
146
|
-
if user:
|
|
147
|
-
click.echo(click.style("Admin User {0} created.".format(username), fg="green"))
|
|
148
|
-
else:
|
|
149
|
-
click.echo(click.style("No user created an error occured", fg="red"))
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
@cli_app.command("create-user")
|
|
153
|
-
@click.option("--app", default="app", help="Your application init directory (package)")
|
|
154
|
-
@click.option("--appbuilder", default="appbuilder", help="your AppBuilder object")
|
|
155
|
-
@click.option("--role", default="Public", prompt="Role")
|
|
156
|
-
@click.option("--username", prompt="Username")
|
|
157
|
-
@click.option("--firstname", prompt="User first name")
|
|
158
|
-
@click.option("--lastname", prompt="User last name")
|
|
159
|
-
@click.option("--email", prompt="Email")
|
|
160
|
-
@click.password_option()
|
|
161
|
-
def create_user(app, appbuilder, role, username, firstname, lastname, email, password):
|
|
162
|
-
"""
|
|
163
|
-
Create a user
|
|
164
|
-
"""
|
|
165
|
-
_appbuilder = import_application(app, appbuilder)
|
|
166
|
-
role_object = _appbuilder.sm.find_role(role)
|
|
167
|
-
user = _appbuilder.sm.add_user(
|
|
168
|
-
username, firstname, lastname, email, role_object, password
|
|
169
|
-
)
|
|
170
|
-
if user:
|
|
171
|
-
click.echo(click.style("User {0} created.".format(username), fg="green"))
|
|
172
|
-
else:
|
|
173
|
-
click.echo(click.style("Error! No user created", fg="red"))
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
@cli_app.command("run")
|
|
177
|
-
@click.option("--app", default="app", help="Your application init directory (package)")
|
|
178
|
-
@click.option("--appbuilder", default="appbuilder", help="your AppBuilder object")
|
|
179
|
-
@click.option("--host", default="0.0.0.0")
|
|
180
|
-
@click.option("--port", default=8080)
|
|
181
|
-
@click.option("--debug", default=True)
|
|
182
|
-
def run(app, appbuilder, host, port, debug):
|
|
183
|
-
"""
|
|
184
|
-
Runs Flask dev web server.
|
|
185
|
-
"""
|
|
186
|
-
_appbuilder = import_application(app, appbuilder)
|
|
187
|
-
_appbuilder.get_app.run(host=host, port=port, debug=debug)
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
@cli_app.command("create-db")
|
|
191
|
-
@click.option("--app", default="app", help="Your application init directory (package)")
|
|
192
|
-
@click.option("--appbuilder", default="appbuilder", help="your AppBuilder object")
|
|
193
|
-
def create_db(app, appbuilder):
|
|
194
|
-
"""
|
|
195
|
-
Create all your database objects (SQLAlchemy specific).
|
|
196
|
-
"""
|
|
197
|
-
from flask_appbuilder.models.sqla import Base
|
|
198
|
-
|
|
199
|
-
_appbuilder = import_application(app, appbuilder)
|
|
200
|
-
engine = _appbuilder.get_session.get_bind(mapper=None, clause=None)
|
|
201
|
-
Base.metadata.create_all(engine)
|
|
202
|
-
click.echo(click.style("DB objects created", fg="green"))
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
@cli_app.command("version")
|
|
206
|
-
@click.option("--app", default="app", help="Your application init directory (package)")
|
|
207
|
-
@click.option("--appbuilder", default="appbuilder", help="your AppBuilder object")
|
|
208
|
-
def version(app, appbuilder):
|
|
209
|
-
"""
|
|
210
|
-
Flask-AppBuilder package version
|
|
211
|
-
"""
|
|
212
|
-
_appbuilder = import_application(app, appbuilder)
|
|
213
|
-
click.echo(
|
|
214
|
-
click.style(
|
|
215
|
-
"F.A.B Version: {0}.".format(_appbuilder.version), bg="blue", fg="white"
|
|
216
|
-
)
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
@cli_app.command("security-cleanup")
|
|
221
|
-
@click.option("--app", default="app", help="Your application init directory (package)")
|
|
222
|
-
@click.option("--appbuilder", default="appbuilder", help="your AppBuilder object")
|
|
223
|
-
def security_cleanup(app, appbuilder):
|
|
224
|
-
"""
|
|
225
|
-
Cleanup unused permissions from views and roles.
|
|
226
|
-
"""
|
|
227
|
-
_appbuilder = import_application(app, appbuilder)
|
|
228
|
-
_appbuilder.security_cleanup()
|
|
229
|
-
click.echo(click.style("Finished security cleanup", fg="green"))
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
@cli_app.command("list-views")
|
|
233
|
-
@click.option("--app", default="app", help="Your application init directory (package)")
|
|
234
|
-
@click.option("--appbuilder", default="appbuilder", help="your AppBuilder object")
|
|
235
|
-
def list_views(app, appbuilder):
|
|
236
|
-
"""
|
|
237
|
-
List all registered views
|
|
238
|
-
"""
|
|
239
|
-
_appbuilder = import_application(app, appbuilder)
|
|
240
|
-
echo_header("List of registered views")
|
|
241
|
-
for view in _appbuilder.baseviews:
|
|
242
|
-
click.echo(
|
|
243
|
-
"View:{0} | Route:{1} | Perms:{2}".format(
|
|
244
|
-
view.__class__.__name__, view.route_base, view.base_permissions
|
|
245
|
-
)
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
@cli_app.command("list-users")
|
|
250
|
-
@click.option("--app", default="app", help="Your application init directory (package)")
|
|
251
|
-
@click.option("--appbuilder", default="appbuilder", help="your AppBuilder object")
|
|
252
|
-
def list_users(app, appbuilder):
|
|
253
|
-
"""
|
|
254
|
-
List all users on the database
|
|
255
|
-
"""
|
|
256
|
-
_appbuilder = import_application(app, appbuilder)
|
|
257
|
-
echo_header("List of users")
|
|
258
|
-
for user in _appbuilder.sm.get_all_users():
|
|
259
|
-
click.echo(
|
|
260
|
-
"username:{0} | email:{1} | role:{2}".format(
|
|
261
|
-
user.username, user.email, user.roles
|
|
262
|
-
)
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
@cli_app.command("babel-extract")
|
|
267
|
-
@click.option("--config", default="./babel/babel.cfg")
|
|
268
|
-
@click.option("--input", default=".")
|
|
269
|
-
@click.option("--output", default="./babel/messages.pot")
|
|
270
|
-
@click.option("--target", default="app/translations")
|
|
271
|
-
@click.option(
|
|
272
|
-
"--keywords", "-k", multiple=True, default=["lazy_gettext", "gettext", "_", "__"]
|
|
273
|
-
)
|
|
274
|
-
def babel_extract(config, input, output, target, keywords):
|
|
275
|
-
"""
|
|
276
|
-
Babel, Extracts and updates all messages marked for translation
|
|
277
|
-
"""
|
|
278
|
-
click.echo(
|
|
279
|
-
click.style(
|
|
280
|
-
"Starting Extractions config:{0} input:{1} output:{2} keywords:{3}".format(
|
|
281
|
-
config, input, output, keywords
|
|
282
|
-
),
|
|
283
|
-
fg="green",
|
|
284
|
-
)
|
|
285
|
-
)
|
|
286
|
-
keywords = " -k ".join(keywords)
|
|
287
|
-
os.popen(
|
|
288
|
-
"pybabel extract -F {0} -k {1} -o {2} {3}".format(
|
|
289
|
-
config, keywords, output, input
|
|
290
|
-
)
|
|
291
|
-
)
|
|
292
|
-
click.echo(click.style("Starting Update target:{0}".format(target), fg="green"))
|
|
293
|
-
os.popen("pybabel update -N -i {0} -d {1}".format(output, target))
|
|
294
|
-
click.echo(click.style("Finish, you can start your translations", fg="green"))
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
@cli_app.command("babel-compile")
|
|
298
|
-
@click.option(
|
|
299
|
-
"--target",
|
|
300
|
-
default="app/translations",
|
|
301
|
-
help="The target directory where translations reside",
|
|
302
|
-
)
|
|
303
|
-
def babel_compile(target):
|
|
304
|
-
"""
|
|
305
|
-
Babel, Compiles all translations
|
|
306
|
-
"""
|
|
307
|
-
click.echo(click.style("Starting Compile target:{0}".format(target), fg="green"))
|
|
308
|
-
os.popen("pybabel compile -f -d {0}".format(target))
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
@cli_app.command("create-app")
|
|
312
|
-
@click.option(
|
|
313
|
-
"--name",
|
|
314
|
-
prompt="Your new app name",
|
|
315
|
-
help="Your application name, directory will have this name",
|
|
316
|
-
)
|
|
317
|
-
@click.option(
|
|
318
|
-
"--engine",
|
|
319
|
-
prompt="Your engine type, SQLAlchemy or MongoEngine",
|
|
320
|
-
type=click.Choice(["SQLAlchemy", "MongoEngine"]),
|
|
321
|
-
default="SQLAlchemy",
|
|
322
|
-
help="Write your engine type",
|
|
323
|
-
)
|
|
324
|
-
def create_app(name, engine):
|
|
325
|
-
"""
|
|
326
|
-
Create a Skeleton application (needs internet connection to github)
|
|
327
|
-
"""
|
|
328
|
-
try:
|
|
329
|
-
if engine.lower() == "sqlalchemy":
|
|
330
|
-
url = urlopen(SQLA_REPO_URL)
|
|
331
|
-
dirname = "Flask-AppBuilder-Skeleton-master"
|
|
332
|
-
elif engine.lower() == "mongoengine":
|
|
333
|
-
url = urlopen(MONGOENGIE_REPO_URL)
|
|
334
|
-
dirname = "Flask-AppBuilder-Skeleton-me-master"
|
|
335
|
-
zipfile = ZipFile(BytesIO(url.read()))
|
|
336
|
-
zipfile.extractall()
|
|
337
|
-
os.rename(dirname, name)
|
|
338
|
-
click.echo(click.style("Downloaded the skeleton app, good coding!", fg="green"))
|
|
339
|
-
return True
|
|
340
|
-
except Exception as e:
|
|
341
|
-
click.echo(click.style("Something went wrong {0}".format(e), fg="red"))
|
|
342
|
-
if engine.lower() == "sqlalchemy":
|
|
343
|
-
click.echo(
|
|
344
|
-
click.style(
|
|
345
|
-
"Try downloading from {0}".format(SQLA_REPO_URL), fg="green"
|
|
346
|
-
)
|
|
347
|
-
)
|
|
348
|
-
elif engine.lower() == "mongoengine":
|
|
349
|
-
click.echo(
|
|
350
|
-
click.style(
|
|
351
|
-
"Try downloading from {0}".format(MONGOENGIE_REPO_URL), fg="green"
|
|
352
|
-
)
|
|
353
|
-
)
|
|
354
|
-
return False
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
@cli_app.command("create-addon")
|
|
358
|
-
@click.option(
|
|
359
|
-
"--name",
|
|
360
|
-
prompt="Your new addon name",
|
|
361
|
-
help="Your addon name will be prefixed by fab_addon_, directory will have this name",
|
|
362
|
-
)
|
|
363
|
-
def create_addon(name):
|
|
364
|
-
"""
|
|
365
|
-
Create a Skeleton AddOn (needs internet connection to github)
|
|
366
|
-
"""
|
|
367
|
-
try:
|
|
368
|
-
full_name = "fab_addon_" + name
|
|
369
|
-
dirname = "Flask-AppBuilder-Skeleton-AddOn-master"
|
|
370
|
-
url = urlopen(ADDON_REPO_URL)
|
|
371
|
-
zipfile = ZipFile(BytesIO(url.read()))
|
|
372
|
-
zipfile.extractall()
|
|
373
|
-
os.rename(dirname, full_name)
|
|
374
|
-
addon_path = os.path.join(full_name, full_name)
|
|
375
|
-
os.rename(os.path.join(full_name, "fab_addon"), addon_path)
|
|
376
|
-
f = open(os.path.join(full_name, "config.py"), "w")
|
|
377
|
-
f.write("ADDON_NAME='" + name + "'\n")
|
|
378
|
-
f.write("FULL_ADDON_NAME='fab_addon_' + ADDON_NAME\n")
|
|
379
|
-
f.close()
|
|
380
|
-
click.echo(
|
|
381
|
-
click.style("Downloaded the skeleton addon, good coding!", fg="green")
|
|
382
|
-
)
|
|
383
|
-
return True
|
|
384
|
-
except Exception as e:
|
|
385
|
-
click.echo(click.style("Something went wrong {0}".format(e), fg="red"))
|
|
386
|
-
return False
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
@cli_app.command("collect-static")
|
|
390
|
-
@click.option(
|
|
391
|
-
"--static_folder", default="app/static", help="Your projects static folder"
|
|
392
|
-
)
|
|
393
|
-
def collect_static(static_folder):
|
|
394
|
-
"""
|
|
395
|
-
Copies flask-appbuilder static files to your projects static folder
|
|
396
|
-
"""
|
|
397
|
-
appbuilder_static_path = os.path.join(
|
|
398
|
-
os.path.dirname(os.path.abspath(__file__)), "static/appbuilder"
|
|
399
|
-
)
|
|
400
|
-
app_static_path = os.path.join(os.getcwd(), static_folder)
|
|
401
|
-
if not os.path.isdir(app_static_path):
|
|
402
|
-
click.echo(
|
|
403
|
-
click.style(
|
|
404
|
-
"Static folder does not exist creating: %s" % app_static_path,
|
|
405
|
-
fg="green",
|
|
406
|
-
)
|
|
407
|
-
)
|
|
408
|
-
os.makedirs(app_static_path)
|
|
409
|
-
try:
|
|
410
|
-
shutil.copytree(
|
|
411
|
-
appbuilder_static_path, os.path.join(app_static_path, "appbuilder")
|
|
412
|
-
)
|
|
413
|
-
except Exception:
|
|
414
|
-
click.echo(
|
|
415
|
-
click.style(
|
|
416
|
-
"Appbuilder static folder already exists on your project", fg="red"
|
|
417
|
-
)
|
|
418
|
-
)
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
def cli():
|
|
422
|
-
cli_app()
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
if __name__ == "__main__":
|
|
426
|
-
cli_app()
|
|
File without changes
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
from werkzeug.datastructures import FileStorage
|
|
2
|
-
from wtforms import fields
|
|
3
|
-
|
|
4
|
-
from ...upload import BS3FileUploadFieldWidget, BS3ImageUploadFieldWidget
|
|
5
|
-
|
|
6
|
-
try:
|
|
7
|
-
from wtforms.fields.core import _unset_value as unset_value
|
|
8
|
-
except ImportError:
|
|
9
|
-
from wtforms.utils import unset_value
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def is_empty(file_object):
|
|
13
|
-
file_object.seek(0)
|
|
14
|
-
first_char = file_object.read(1)
|
|
15
|
-
file_object.seek(0)
|
|
16
|
-
return not bool(first_char)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class MongoFileField(fields.FileField):
|
|
20
|
-
"""
|
|
21
|
-
GridFS file field.
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
widget = BS3FileUploadFieldWidget()
|
|
25
|
-
|
|
26
|
-
def __init__(self, label=None, validators=None, **kwargs):
|
|
27
|
-
super(MongoFileField, self).__init__(label, validators, **kwargs)
|
|
28
|
-
|
|
29
|
-
self._should_delete = False
|
|
30
|
-
|
|
31
|
-
def process(self, formdata, data=unset_value):
|
|
32
|
-
if formdata:
|
|
33
|
-
marker = "_%s-delete" % self.name
|
|
34
|
-
if marker in formdata:
|
|
35
|
-
self._should_delete = True
|
|
36
|
-
|
|
37
|
-
return super(MongoFileField, self).process(formdata, data)
|
|
38
|
-
|
|
39
|
-
def populate_obj(self, obj, name):
|
|
40
|
-
field = getattr(obj, name, None)
|
|
41
|
-
if field is not None:
|
|
42
|
-
# If field should be deleted, clean it up
|
|
43
|
-
if self._should_delete:
|
|
44
|
-
field.delete()
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
if isinstance(self.data, FileStorage) and not is_empty(self.data.stream):
|
|
48
|
-
if not field.grid_id:
|
|
49
|
-
func = field.put
|
|
50
|
-
else:
|
|
51
|
-
func = field.replace
|
|
52
|
-
|
|
53
|
-
func(
|
|
54
|
-
self.data.stream,
|
|
55
|
-
filename=self.data.filename,
|
|
56
|
-
content_type=self.data.content_type,
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
class MongoImageField(MongoFileField):
|
|
61
|
-
"""
|
|
62
|
-
GridFS file field.
|
|
63
|
-
"""
|
|
64
|
-
|
|
65
|
-
widget = BS3ImageUploadFieldWidget()
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
from flask_babel import lazy_gettext
|
|
4
|
-
|
|
5
|
-
from ..filters import BaseFilter, BaseFilterConverter, FilterRelation
|
|
6
|
-
|
|
7
|
-
log = logging.getLogger(__name__)
|
|
8
|
-
|
|
9
|
-
__all__ = [
|
|
10
|
-
"MongoEngineFilterConverter",
|
|
11
|
-
"FilterEqual",
|
|
12
|
-
"FilterContains",
|
|
13
|
-
"FilterNotContains",
|
|
14
|
-
"FilterNotStartsWith",
|
|
15
|
-
"FilterStartsWith",
|
|
16
|
-
"FilterRelationOneToManyEqual",
|
|
17
|
-
"FilterRelationManyToManyEqual",
|
|
18
|
-
]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class FilterEqual(BaseFilter):
|
|
22
|
-
name = lazy_gettext("Equal to")
|
|
23
|
-
|
|
24
|
-
def apply(self, query, value):
|
|
25
|
-
if self.datamodel.is_boolean(self.column_name):
|
|
26
|
-
if value == "y":
|
|
27
|
-
value = True
|
|
28
|
-
flt = {"%s" % self.column_name: value}
|
|
29
|
-
return query.filter(**flt)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class FilterNotEqual(BaseFilter):
|
|
33
|
-
name = lazy_gettext("Not Equal to")
|
|
34
|
-
|
|
35
|
-
def apply(self, query, value):
|
|
36
|
-
if self.datamodel.is_boolean(self.column_name):
|
|
37
|
-
if value == "y":
|
|
38
|
-
value = True
|
|
39
|
-
flt = {"%s__ne" % self.column_name: value}
|
|
40
|
-
return query.filter(**flt)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class FilterGreater(BaseFilter):
|
|
44
|
-
name = lazy_gettext("Greater than")
|
|
45
|
-
|
|
46
|
-
def apply(self, query, value):
|
|
47
|
-
flt = {"%s__gt" % self.column_name: value}
|
|
48
|
-
return query.filter(**flt)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class FilterSmaller(BaseFilter):
|
|
52
|
-
name = lazy_gettext("Smaller than")
|
|
53
|
-
|
|
54
|
-
def apply(self, query, value):
|
|
55
|
-
flt = {"%s__lt" % self.column_name: value}
|
|
56
|
-
return query.filter(**flt)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
class FilterStartsWith(BaseFilter):
|
|
60
|
-
name = lazy_gettext("Starts with")
|
|
61
|
-
|
|
62
|
-
def apply(self, query, value):
|
|
63
|
-
flt = {"%s__%s" % (self.column_name, "startswith"): value}
|
|
64
|
-
return query.filter(**flt)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
class FilterNotStartsWith(BaseFilter):
|
|
68
|
-
name = lazy_gettext("Not Starts with")
|
|
69
|
-
|
|
70
|
-
def apply(self, query, value):
|
|
71
|
-
flt = {"%s__not__%s" % (self.column_name, "startswith"): value}
|
|
72
|
-
return query.filter(**flt)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
class FilterContains(BaseFilter):
|
|
76
|
-
name = lazy_gettext("Contains")
|
|
77
|
-
|
|
78
|
-
def apply(self, query, value):
|
|
79
|
-
flt = {"%s__%s" % (self.column_name, "icontains"): value}
|
|
80
|
-
return query.filter(**flt)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
class FilterNotContains(BaseFilter):
|
|
84
|
-
name = lazy_gettext("Not Contains")
|
|
85
|
-
|
|
86
|
-
def apply(self, query, value):
|
|
87
|
-
flt = {"%s__not__%s" % (self.column_name, "icontains"): value}
|
|
88
|
-
return query.filter(**flt)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
class FilterRelationOneToManyEqual(FilterRelation):
|
|
92
|
-
name = lazy_gettext("Relation")
|
|
93
|
-
|
|
94
|
-
def apply(self, query, value):
|
|
95
|
-
rel_obj = self.datamodel.get_related_obj(self.column_name, value)
|
|
96
|
-
flt = {"%s" % self.column_name: rel_obj}
|
|
97
|
-
return query.filter(**flt)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
class FilterRelationManyToManyEqual(FilterRelation):
|
|
101
|
-
name = lazy_gettext("Relation as Many")
|
|
102
|
-
|
|
103
|
-
def apply(self, query, value):
|
|
104
|
-
rel_obj = self.datamodel.get_related_obj(self.column_name, value)
|
|
105
|
-
flt = {"%s__%s" % (self.column_name, "icontains"): rel_obj}
|
|
106
|
-
return query.filter(**flt)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
class FilterEqualFunction(BaseFilter):
|
|
110
|
-
name = "Filter view with a function"
|
|
111
|
-
|
|
112
|
-
def apply(self, query, func):
|
|
113
|
-
flt = {"%s" % self.column_name: func()}
|
|
114
|
-
return query.filter(**flt)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
class MongoEngineFilterConverter(BaseFilterConverter):
|
|
118
|
-
"""
|
|
119
|
-
Class for converting columns into a supported list of filters
|
|
120
|
-
specific for SQLAlchemy.
|
|
121
|
-
|
|
122
|
-
"""
|
|
123
|
-
|
|
124
|
-
conversion_table = (
|
|
125
|
-
("is_relation_many_to_one", [FilterRelationOneToManyEqual]),
|
|
126
|
-
("is_relation_one_to_one", [FilterRelationOneToManyEqual]),
|
|
127
|
-
("is_relation_many_to_many", [FilterRelationManyToManyEqual]),
|
|
128
|
-
("is_relation_one_to_many", [FilterRelationManyToManyEqual]),
|
|
129
|
-
("is_object_id", [FilterEqual]),
|
|
130
|
-
(
|
|
131
|
-
"is_string",
|
|
132
|
-
[
|
|
133
|
-
FilterEqual,
|
|
134
|
-
FilterNotEqual,
|
|
135
|
-
FilterStartsWith,
|
|
136
|
-
FilterNotStartsWith,
|
|
137
|
-
FilterContains,
|
|
138
|
-
FilterNotContains,
|
|
139
|
-
],
|
|
140
|
-
),
|
|
141
|
-
("is_boolean", [FilterEqual, FilterNotEqual]),
|
|
142
|
-
("is_datetime", [FilterEqual, FilterNotEqual, FilterGreater, FilterSmaller]),
|
|
143
|
-
("is_integer", [FilterEqual, FilterNotEqual, FilterGreater, FilterSmaller]),
|
|
144
|
-
("is_float", [FilterEqual, FilterNotEqual, FilterGreater, FilterSmaller]),
|
|
145
|
-
)
|