Merge branch 'master' of gitlab.com:pisquared/oshipka

This commit is contained in:
Daniel Tsvetkov 2020-07-01 10:32:17 +02:00
commit bba6cb2e5a
5 changed files with 175 additions and 17 deletions

View File

@ -205,9 +205,7 @@
<script src="{{ url_for('oshipka_bp.static', filename='js/fuse.js') }}"></script> <script src="{{ url_for('oshipka_bp.static', filename='js/fuse.js') }}"></script>
<script src="{{ url_for('oshipka_bp.static', filename='js/draggable.js') }}"></script> <script src="{{ url_for('oshipka_bp.static', filename='js/draggable.js') }}"></script>
<script src="{{ url_for('oshipka_bp.static', filename='js/oshipka.js') }}"></script> <script src="{{ url_for('oshipka_bp.static', filename='js/oshipka.js') }}"></script>
{% block script %}
<script> <script>
$("select").chosen({ $("select").chosen({
inherit_select_classes: true, inherit_select_classes: true,
}); });
@ -220,6 +218,6 @@ lightbox.option({
$('.data-table').DataTable(); $('.data-table').DataTable();
</script> </script>
{% endblock %} {% block script %}{% endblock %}
</body> </body>
</html> </html>

View File

@ -21,6 +21,8 @@ Usage $0 [ bootstrap | model | db_migrate | db_upgrade | db_populate | db_recrea
db_recreate Delete the database, recreate to latest migration and populate db_recreate Delete the database, recreate to latest migration and populate
db_purge_recreate Same as db_recreate but also purge the migrations db_purge_recreate Same as db_recreate but also purge the migrations
translate Translations subcommand
worker Start worker worker Start worker
web Start webapp web Start webapp
@ -33,6 +35,36 @@ Usage $0 [ bootstrap | model | db_migrate | db_upgrade | db_populate | db_recrea
cert [DOMAIN] Install certificate cert [DOMAIN] Install certificate
" "
#!/usr/bin/env bash
HELP_TRANSLATION="
USAGE ./manage.sh translate [extract|gen {lang}|compile|update]
extract Extract strings in files as defined in translations/babel.cfg
gen {lang} Init translations for {lang}
compile Compile all translations
update Use after a new extract - it may mark strings as fuzzy.
"
command_translate() {
TRANSLATE_COMMAND=$1
shift
case "$TRANSLATE_COMMAND" in
extract) pybabel extract -F translations/babel.cfg -o translations/messages.pot .
;;
gen) pybabel init -i translations/messages.pot -d translations -l "$@"
;;
compile) pybabel compile -d translations
;;
update) pybabel update -i translations/messages.pot -d translations
;;
*) >&2 echo -e "${HELP_TRANSLATION}"
;;
esac
return $?
}
worker () { worker () {
source venv/bin/activate source venv/bin/activate
python worker.py python worker.py
@ -287,6 +319,8 @@ command_main() {
;; ;;
db_purge_recreate) db_purge_recreate "$@" db_purge_recreate) db_purge_recreate "$@"
;; ;;
translate) command_translate "$@"
;;
init) init "$@" init) init "$@"
;; ;;
download_sensitive) download_sensitive "$@" download_sensitive) download_sensitive "$@"

View File

@ -144,7 +144,7 @@ class ViewContext(object):
jsonify_func=None, render_func=None, template_func=None, template_ctx_func=None, jsonify_func=None, render_func=None, template_func=None, template_ctx_func=None,
should_redirect_no_instances_func=None, should_redirect_no_instances_func=None,
should_redirect_at_end_func=None, should_redirect_at_end_func=None,
is_json=False, **kwargs): is_json=False, model_view=None, **kwargs):
self.args_get_func = args_get_func or default_get_args_func self.args_get_func = args_get_func or default_get_args_func
self.args_process_func = args_process_func or default_none_func self.args_process_func = args_process_func or default_none_func
self.filter_func = filter_func or default_none_func self.filter_func = filter_func or default_none_func
@ -161,6 +161,7 @@ class ViewContext(object):
self.template_ctx_func = template_ctx_func or default_none_func self.template_ctx_func = template_ctx_func or default_none_func
self.should_redirect_at_end_func = should_redirect_at_end_func or default_none_func self.should_redirect_at_end_func = should_redirect_at_end_func or default_none_func
self.is_json = is_json self.is_json = is_json
self.model_view = model_view
self.serialized_args = {} self.serialized_args = {}
self.url_args = {} self.url_args = {}
@ -169,22 +170,23 @@ class ViewContext(object):
self.should_redirect_at_end = not is_json self.should_redirect_at_end = not is_json
self.template = None self.template = None
self.template_ctx = {} self.template_ctx = {}
self.model_view = None
self.redirect_next = None self.redirect_next = None
def create_view(model_view, view_context, is_login_required=False, the_roles_required=None, **kwargs): def return_json_or_template(view_context):
view_context.model_view = model_view
the_roles_required = [] if not the_roles_required else the_roles_required
def return_json_or_template():
if view_context.is_json: if view_context.is_json:
return view_context.jsonify_func(view_context) return view_context.jsonify_func(view_context)
view_context.template_func(view_context) view_context.template_func(view_context)
view_context.template_ctx_func(view_context) view_context.template_ctx_func(view_context)
return view_context.render_func(view_context) return view_context.render_func(view_context)
def create_view(model_view, view_context_kwargs, is_login_required=False, the_roles_required=None, **kwargs):
view_context_kwargs['model_view'] = model_view
the_roles_required = [] if not the_roles_required else the_roles_required
def inner(**kwargs): def inner(**kwargs):
view_context = ViewContext(**view_context_kwargs)
view_context.url_args = kwargs view_context.url_args = kwargs
view_context.args_get_func(view_context) view_context.args_get_func(view_context)
view_context.args_process_func(view_context) view_context.args_process_func(view_context)
@ -195,7 +197,7 @@ def create_view(model_view, view_context, is_login_required=False, the_roles_req
return view_context.redirect_func(view_context) return view_context.redirect_func(view_context)
if request.method == "GET": if request.method == "GET":
return return_json_or_template() return return_json_or_template(view_context)
view_context.should_execute_func(view_context) view_context.should_execute_func(view_context)
if not view_context.should_execute: if not view_context.should_execute:
@ -213,7 +215,7 @@ def create_view(model_view, view_context, is_login_required=False, the_roles_req
if view_context.should_redirect_at_end: if view_context.should_redirect_at_end:
return view_context.redirect_func(view_context) return view_context.redirect_func(view_context)
return return_json_or_template() return return_json_or_template(view_context)
if is_login_required: if is_login_required:
if the_roles_required: if the_roles_required:
inner = roles_required(*the_roles_required)(inner) inner = roles_required(*the_roles_required)(inner)
@ -243,12 +245,14 @@ class ModelView(object):
endpoint = url_args.pop('endpoint') endpoint = url_args.pop('endpoint')
api_endpoint = 'api_{}'.format(endpoint) api_endpoint = 'api_{}'.format(endpoint)
view_func = url_args.pop('view_func') view_func = url_args.pop('view_func')
view_context_kwargs = copy(kwargs['view_context'].__dict__)
kwargs['view_context_kwargs'] = view_context_kwargs
self.app.add_url_rule(rule=url, endpoint=endpoint, self.app.add_url_rule(rule=url, endpoint=endpoint,
view_func=view_func(self, **kwargs), **url_args) view_func=view_func(self, **kwargs), **url_args)
view_context_kwargs = copy(kwargs['view_context'].__dict__) view_context_kwargs = copy(kwargs['view_context'].__dict__)
view_context_kwargs['is_json'] = True view_context_kwargs['is_json'] = True
kwargs['view_context'] = ViewContext(**view_context_kwargs) kwargs['view_context_kwargs'] = view_context_kwargs
self.app.add_url_rule(rule=api_url, endpoint=api_endpoint, self.app.add_url_rule(rule=api_url, endpoint=api_endpoint,
view_func=view_func(self, **kwargs), **url_args) view_func=view_func(self, **kwargs), **url_args)

View File

@ -0,0 +1,24 @@
import json
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
@app.route('/')
def home():
return render_template("bootstrap.html")
@app.route('/config', methods=["post"])
def post_config():
config = json.loads(request.form)
return jsonify(
{
"raw": config,
})
if __name__ == "__main__":
app.run(debug=True, port=4999)

View File

@ -0,0 +1,98 @@
<h1>New project</h1>
<form action="{{ url_for('post_config') }}" method="post" enctype='application/json'>
<p>Project name: <input type="text" name="project_name" required placeholder="name for your new project"
style="width: 50%;"/>
<p>Project path: <input type="text" name="project_path" required placeholder="path for your new project"
style="width: 50%;"/>
<h2>Development</h2>
<input type="radio" name="dev_env" value="local" checked="checked"> Local machine<br>
<small>This will install all required system packages on your local machine and all python packages in a virtual environment</small>
<br><br>
<input type="radio" name="dev_env" value="docker"> Docker containers<br>
<small>This will install docker on your local machine and start containers for development</small>
<br><br>
<input type="radio" name="dev_env" value="vagrant_vbox"> Using <a
href="https://www.vagrantup.com/downloads.html">Vagrant</a> + <a
href="https://www.virtualbox.org/wiki/Downloads">Virtualbox</a><br>
<small>This will create a virtual machine on your machine</small>
<br><br>
<h2>Production environment</h2>
<input type="radio" name="prod_env" value="systemd" checked="checked"> Using systemd services + nginx<br>
<small>This will create systemd services and nginx as reverse proxy</small>
<br><br>
<input type="radio" name="prod_env" value="docker">Docker containers<br>
<small>This will create docker containers for all services</small>
<br><br>
<input type="radio" name="prod_env" value="kubernetes">Using Kubernetes<br>
<small>This will create pods, deployments and other k8s objects for your services</small>
<br>
<input type="checkbox" name="ssl_enabled">SSL for development<br>
<h2>Components</h2>
<h3>Back end</h3>
<div style="display: none;">
<input type="checkbox" name="webapp_enabled" disabled checked>
</div>
<input type="checkbox" name="database_enabled" checked>Database | type
<select name="database_type">
<option value="sqlite">sqlite</option>
<option value="postgres">postgres</option>
</select><br>
<input type="checkbox" name="authentication_enabled" checked>Authentication<br>
<input type="checkbox" name="workers_enabled">Workers and Queue | type
<select name="workers_type">
<option value="filesystem">filesystem</option>
<option value="celery">celery</option>
<option value="redis_queue">redis queue</option>
</select><br>
<input type="checkbox" name="schedule_service_enabled">Scheduling | type: celery beat<br>
<input type="checkbox" name="search_enabled">Search
<select name="search_type">
<option value="whooshalchemy">whooshalchemy</option>
<option value="elasticsearch">elastic search</option>
</select><br>
<input type="checkbox" name="translations_enabled">Translations<br>
<input type="checkbox" name="limiter">Limiter <br>
<input type="checkbox" name="caching">Caching <br>
<h3>Management</h3>
<input type="checkbox" name="webapp_debug_enabled">Debugtoolbar for development<br>
<input type="checkbox" name="database_mgmt_enabled">Database managemt | type: pgadmin<br>
<input type="checkbox" name="workers_mgmt_enabled">Workers managemt | type: flower<br>
<input type="checkbox" name="queue_mgmt_enabled">Queue managemt | type: rabbitmq-mgmt<br>
<input type="checkbox" name="admin_webapp_enabled">Admin webapp <br>
<input type="checkbox" name="monitoring_mgmt_enabled">Monitoring | type: monit <br>
<input type="checkbox" name="error_tracking_enabled">Error tracking | type: sentry<br>
<hr>
<h3>Front end</h3>
<p>JS:
<input type="checkbox" name="js_jquery_enabled" checked="checked">Jquery<br>
<input type="checkbox" name="js_chosen_enabled" checked="checked">Chosen<br>
<input type="checkbox" name="js_datatables_enabled" checked="checked">Datatables<br>
<input type="checkbox" name="js_fuse_enabled">Fuse (front-end search)<br>
<input type="checkbox" name="js_draggable">Draggable<br>
<input type="checkbox" name="js_lightbox">Lightbox<br>
<input type="checkbox" name="js_autocomplete">Autocomplete JS<br>
<input type="checkbox" name="js_backbone">Backbone JS<br>
<input type="checkbox" name="js_crudy_enabled">CRUDy<br>
<p>CSS:
<select name="css_framework">
<option value="none">none</option>
<option value="bootstrap">bootstrap</option>
<option value="materialize">materialize</option>
</select><br>
<input type="checkbox" name="font_awesome_enabled">Font Awesome<br>
<input type="checkbox" name="websockets_enabled">Websockets<br>
<hr>
<input type="checkbox" name="gravatar_enabled">Gravatar Enabled<br>
<br>
<input type="submit">
<br><br>
</form>