Merge branch 'master' of gitlab.com:pisquared/oshipka
This commit is contained in:
commit
bba6cb2e5a
@ -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>
|
||||||
|
34
oshipka.sh
34
oshipka.sh
@ -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 "$@"
|
||||||
|
@ -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
|
if view_context.is_json:
|
||||||
|
return view_context.jsonify_func(view_context)
|
||||||
|
view_context.template_func(view_context)
|
||||||
|
view_context.template_ctx_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
|
the_roles_required = [] if not the_roles_required else the_roles_required
|
||||||
|
|
||||||
def return_json_or_template():
|
|
||||||
if view_context.is_json:
|
|
||||||
return view_context.jsonify_func(view_context)
|
|
||||||
view_context.template_func(view_context)
|
|
||||||
view_context.template_ctx_func(view_context)
|
|
||||||
return view_context.render_func(view_context)
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
|
24
provision/provision_app/app.py
Normal file
24
provision/provision_app/app.py
Normal 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)
|
98
provision/provision_app/templates/bootstrap.html
Normal file
98
provision/provision_app/templates/bootstrap.html
Normal 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>
|
Loading…
Reference in New Issue
Block a user