This commit is contained in:
Daniel Tsvetkov 2020-06-07 20:29:51 +02:00
parent f2ffea6c8f
commit a567739eaf
13 changed files with 89 additions and 90 deletions

View File

@ -8,9 +8,8 @@ from json import JSONEncoder
from uuid import uuid4
from config import SQLALCHEMY_DATABASE_URI, MAKEDIRS, DATABASE_FILE, SEARCH_INDEX_PATH, STATIC_DATA_DIR, basepath
from flask_migrate import Migrate, Manager, MigrateCommand
from flask_migrate import Migrate
from flask_migrate import upgrade as migrate_upgrade
from flask_migrate import migrate as migrate_migrate
from flask_migrate import init as migrate_init
from flask_security import RoleMixin, UserMixin
from flask_security import Security, SQLAlchemyUserDatastore
@ -24,6 +23,7 @@ from sqlalchemy_utils import Choice
from tww.lib import solve_query, resolve_timezone, dt_tz_translation, time_ago
from whooshalchemy import IndexService
from oshipka.util.strings import camel_case_to_snake_case
from vm_gen.vm_gen import order_from_process_order
db = SQLAlchemy()
migrate = Migrate()
@ -265,19 +265,7 @@ def init_db(app):
def populate_static(app):
with app.app_context():
models = import_module("webapp.models")
model_names = set([f.split('.csv')[0] for f in os.listdir(STATIC_DATA_DIR) if f.endswith(".csv")])
process_order_file = os.path.join(STATIC_DATA_DIR, "_process_order")
ordered_model_names = []
# process first ordered if exists
if os.path.exists(process_order_file):
with open(process_order_file) as f:
for line in f.readlines():
line = line.strip()
if line:
ordered_model_names.append(line)
model_names.remove(line)
for model_name in model_names:
ordered_model_names.append(model_name)
ordered_model_names = order_from_process_order('csv', STATIC_DATA_DIR)
for model_name in ordered_model_names:
model = getattr(models, model_name)
with open(os.path.join(STATIC_DATA_DIR, "{}.csv".format(model_name))) as f:

View File

@ -180,8 +180,11 @@ class ModelView(object):
self.model = model
p = inflect.engine()
self.model_name = camel_case_to_snake_case(model.__name__)
if hasattr(model, "__name__"):
_model_name = getattr(model, "__name__")
else:
_model_name = model.name
self.model_name = camel_case_to_snake_case(_model_name)
self.model_name_pl = p.plural(self.model_name)
MODEL_VIEWS[self.model_name] = self
@ -198,56 +201,17 @@ class ModelView(object):
self.app.add_url_rule(rule=api_url, endpoint=api_endpoint,
view_func=view_func(self, **kwargs), **url_args)
def register_get(self, **kwargs):
def register_verb(self, verb, methods=None, per_item=False, **kwargs):
if not methods:
methods = ["GET"]
rule = '/{}'.format(self.model_name_pl)
if per_item:
rule += '/<uuid>'
rule += '/{}'.format(verb)
url_args = dict(
rule='/{}/<uuid>/get'.format(self.model_name_pl),
methods=["GET"],
endpoint='get_{}'.format(self.model_name),
view_func=create_view,
)
self._register_rule(url_args, **kwargs)
def register_list(self, **kwargs):
url_args = dict(
rule='/{}/list'.format(self.model_name_pl),
methods=["GET"],
endpoint='list_{}'.format(self.model_name),
view_func=create_view,
)
self._register_rule(url_args, **kwargs)
def register_create(self, **kwargs):
url_args = dict(
rule='/{}/create'.format(self.model_name_pl),
methods=["GET", "POST"],
endpoint='create_{}'.format(self.model_name),
view_func=create_view,
)
self._register_rule(url_args, **kwargs)
def register_update(self, **kwargs):
url_args = dict(
rule='/{}/<uuid>/update'.format(self.model_name_pl),
methods=["GET", "POST"],
endpoint='update_{}'.format(self.model_name),
view_func=create_view,
)
self._register_rule(url_args, **kwargs)
def register_delete(self, **kwargs):
url_args = dict(
rule='/{}/<uuid>/delete'.format(self.model_name_pl),
methods=["GET", "POST"],
endpoint='delete_{}'.format(self.model_name),
view_func=create_view,
)
self._register_rule(url_args, **kwargs)
def register_search(self, **kwargs):
url_args = dict(
rule='/{}/search'.format(self.model_name_pl),
methods=["GET"],
endpoint='search_{}'.format(self.model_name),
rule=rule,
methods=methods,
endpoint='{}_{}'.format(verb, self.model_name),
view_func=create_view,
)
self._register_rule(url_args, **kwargs)

0
shared/__init__.py Normal file
View File

18
shared/shared.py Normal file
View File

@ -0,0 +1,18 @@
import os
def order_from_process_order(file_ext, directory):
model_names = set([f.split('.{}'.format(file_ext))[0] for f in os.listdir(directory) if f.endswith(".{}".format(file_ext))])
process_order_file = os.path.join(directory, "_process_order")
ordered_model_names = []
# process first ordered if exists
if os.path.exists(process_order_file):
with open(process_order_file) as f:
for line in f.readlines():
line = line.strip()
if line:
ordered_model_names.append(line)
model_names.remove(line)
for model_name in model_names:
ordered_model_names.append(model_name)
return ordered_model_names

View File

@ -6,14 +6,18 @@ def get_template(vc):
vc.template = "{}/get.html".format(vc.model_view.model_name)
def search_template(vc):
vc.template = "{}/search.html".format(vc.model_view.model_name)
def list_template(vc):
vc.template = "{}/list.html".format(vc.model_view.model_name)
def table_template(vc):
vc.template = "{}/table.html".format(vc.model_view.model_name)
def search_template(vc):
vc.template = "{}/search.html".format(vc.model_view.model_name)
def create_template(vc):
vc.template = "{}/create.html".format(vc.model_view.model_name)
@ -36,6 +40,11 @@ list_view_context = ViewContext(
template_func=list_template,
)
table_view_context = ViewContext(
filter_func=default_list_func,
template_func=table_template,
)
search_view_context = ViewContext(
filter_func=default_search_func,
template_func=list_template,

View File

@ -1,5 +1,6 @@
[[ name ]] = db.Table('[[ name ]]',
[%- for column in columns %]
[[ secondary.name ]] = db.Table('[[ secondary.name|camel_to_snake ]]',
[%- for column in secondary.columns %]
db.Column('[[ column.name ]]_id', db.Integer(), db.ForeignKey('[[ column.name ]].id')),
[%- endfor %]
)

View File

@ -2,10 +2,6 @@
from sqlalchemy_utils import ChoiceType
[%- endif %]
[%- if _secondaries %]
from webapp.models import [% for secondary in _secondaries %][[ secondary ]][%- if not loop.last %], [% endif %][% endfor %]
[%- endif %]
class [[ name ]](db.Model, ModelController):
[%- include "_model_choice_header_py" %]
[%- include "_model_searchable_header_py" %]

View File

@ -2,7 +2,7 @@
[%- if not column.secondary %]
[[ column.name ]]_id = db.Column(db.Integer, db.ForeignKey('[%- if column.to %][[ column.to|camel_to_snake ]][%- else %][[ column.name ]][% endif %].id'))
[%- endif %]
[[ column.name ]] = db.relationship('[%- if column.to %][[ column.to ]][%- else %][[ column.name|snake_to_camel ]][% endif %]',
[[ column.name|pluralize if column.secondary else column.name ]] = db.relationship('[%- if column.to %][[ column.to ]][%- else %][[ column.name|snake_to_camel ]][% endif %]',
[%- if column.secondary %]secondary=[[ column.secondary ]], [%- endif %]
backref=db.backref("[%- if column.backref %][[ column.backref ]][%- else %][[ name|camel_to_snake|pluralize ]][%- endif %]"),
[%- if column.foreign_keys %]foreign_keys=[ [[ column.foreign_keys ]]_id],[%- endif %]

View File

@ -3,7 +3,7 @@
[%- for column in columns %]
<label for="input-[[ name|camel_to_snake ]]-[[ column.name ]]">[[ column.name ]]</label>:
[%- if column.type in ['relationship'] %]
<select id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
<select id="input-[[ name|camel_to_snake ]]-[[ column.name ]]" [%- if column.secondary %]multiple[%- endif %]
name="[[ column.name ]]_id">
<option selected="selected">Choose...</option>
{%- for sub_instance in model_views.[[ column.name ]].model.query.all() %}

View File

@ -0,0 +1,8 @@
{% extends "layout.html" %}
{% block content %}
<h2>[[ name|pluralize ]]</h2>
<a href="{{ url_for('create_[[ name|camel_to_snake ]]') }}">Create</a>
<br>
{% include "[[ name|camel_to_snake ]]/_table.html" %}
{% endblock %}

View File

@ -6,11 +6,11 @@ from oshipka.persistance import db, ModelController, index_service
[%- endfor %]
[%- endif %]
[%- if type == 'm_n' %]
[%- for secondary in _secondaries %]
[% include "_model_m_n_py" %]
[%- else %]
[%- endfor %]
[% include "_model_py" %]
[%- endif %]
[%- if searchable %]
index_service.searchables.append([[ name ]])

View File

@ -10,9 +10,10 @@ from webapp.models import [[ name ]]
from webapp.routes.[[ name|camel_to_snake ]]_hooks import *
[[ name|camel_to_snake ]] = ModelView(app, [[name]])
[[ name|camel_to_snake ]].register_get(view_context=get_view_context)
[[ name|camel_to_snake ]].register_list(view_context=list_view_context)
[[ name|camel_to_snake ]].register_search(view_context=search_view_context)
[[ name|camel_to_snake ]].register_create(view_context=create_view_context)
[[ name|camel_to_snake ]].register_update(view_context=update_view_context)
[[ name|camel_to_snake ]].register_delete(view_context=delete_view_context)
[[ name|camel_to_snake ]].register_verb(view_context=get_view_context, verb="get", per_item=True)
[[ name|camel_to_snake ]].register_verb(view_context=list_view_context, verb="list")
[[ name|camel_to_snake ]].register_verb(view_context=table_view_context, verb="table")
[[ name|camel_to_snake ]].register_verb(view_context=search_view_context, verb="search")
[[ name|camel_to_snake ]].register_verb(view_context=create_view_context, verb="create", methods=["GET", "POST"])
[[ name|camel_to_snake ]].register_verb(view_context=update_view_context, verb="update", methods=["GET", "POST"], per_item=True)
[[ name|camel_to_snake ]].register_verb(view_context=delete_view_context, verb="delete", methods=["GET", "POST"] , per_item=True)

View File

@ -7,6 +7,7 @@ import inflect
import yaml
from jinja2 import Environment, FileSystemLoader
from shared.shared import order_from_process_order
from oshipka.util.strings import snake_case_to_camel_case, camel_case_to_snake_case
pep_options = {'max_line_length': 120}
@ -23,6 +24,18 @@ def _process_choice(column):
}
def process_secondary(secondary):
col1, col2 = secondary.split('_')
return {
'name': secondary,
'columns': [{
'name': col1
}, {
'name': col2
}]
}
def enrich_view_model(view_model):
columns = []
for column in view_model.get('columns', {}):
@ -40,7 +53,8 @@ def enrich_view_model(view_model):
if secondary:
if '_secondaries' not in view_model:
view_model['_secondaries'] = []
view_model['_secondaries'].append(secondary)
secondary_model = process_secondary(secondary)
view_model['_secondaries'].append(secondary_model)
elif column_type in ['choice', ]:
if '_choice_types' not in view_model:
view_model['_choice_types'] = []
@ -95,11 +109,11 @@ def process_html_templates(view_model):
def main():
view_model_names = os.listdir(VIEW_MODELS_PATH)
all_model_imports = ['from oshipka.persistance import db']
all_route_imports = []
view_model_names = order_from_process_order('yaml', VIEW_MODELS_PATH)
for view_model_name in view_model_names:
with open(os.path.join(VIEW_MODELS_PATH, view_model_name), 'r') as stream:
with open(os.path.join(VIEW_MODELS_PATH, "{}.yaml".format(view_model_name)), 'r') as stream:
try:
view_models = yaml.safe_load_all(stream)
for view_model in view_models: