Commit 818af843 authored by Florent Chehab's avatar Florent Chehab
Browse files

Merge branch 'clean' into 'master'

Removed nasty file generation and cleaned the frontend a bit.

See merge request !41
parents d85bfe58 9715fac0
...@@ -10,8 +10,5 @@ node_modules ...@@ -10,8 +10,5 @@ node_modules
htmlcov htmlcov
.vscode .vscode
.pytest_cache .pytest_cache
/backend/urls.py
/backend/admin.py
database.db database.db
database.db-journal database.db-journal
backend/permissions/__list_user_post_permission.py
{ {
"python.pythonPath": "~/Env/outgoing/bin/python", "python.pythonPath": "env/bin/python",
"files.exclude": { "files.exclude": {
"**/.git": true, "**/.git": true,
"**/.svn": true, "**/.svn": true,
......
...@@ -4,28 +4,19 @@ ...@@ -4,28 +4,19 @@
install_backend: install_backend:
pip install -r requirements.txt --quiet pip install -r requirements.txt --quiet
generate_backend: build_frontend:
export PYTHONPATH=$$PWD ; python ./backend/generate/generate_backend_files.py
generate_frontend_files:
export PYTHONPATH=$$PWD ; python ./frontend/generate/generate_frontend_files.py
generate_frontend: generate_frontend_files
npm run dev
build_frontend: generate_frontend_files
npm run build npm run build
test_backend: generate_backend test_backend:
pytest general/ frontend/ backend/ pytest general/ frontend/ backend/
test_backend_server: test_backend_server:
pytest -n 4 general/ frontend/ backend/ --cov-report html pytest -n 4 general/ frontend/ backend/ --cov-report html
check_backend: generate_backend check_backend:
./manage.py check ./manage.py check
run_backend: generate_backend run_backend:
./manage.py runserver ./manage.py runserver
......
{% autoescape off %}
# WARNING
# THIS FILE HAS BEEN AUTOMATICALLY GENERATED
# WITH /backend/generate/generate_backend_files.py
# MODIFY THE FILE ABOVE IF YOUR NOT SATISFIED
# THIS WARNING DOESN'T APPLY TO .tpl FILES...
from django.contrib import admin from django.contrib import admin
from dotmap import DotMap
from reversion_compare.admin import CompareVersionAdmin from reversion_compare.admin import CompareVersionAdmin
{% spaceless %} from shared import get_api_config
{% for model in data %} import importlib
from backend.models.{{model.import_location}} import {{model.model}}
{% endfor %}
{% endspaceless %}
api_config = get_api_config()
CLASSIC_MODELS = []
VERSIONNED_MODELS = []
CLASSIC_MODELS = [ for model in api_config:
{% for model in data %}{% if not model.versionned %} if "model" in model and model['model']:
{{model.model}}, model = DotMap(model)
{% endif %}{% endfor %} if (not model.requires_testing) and (not model.ignore_in_admin):
] module = importlib.import_module("backend.models.{}".format (model.import_location))
if model.versionned:
VERSIONNED_MODELS.append(getattr(module, model.model))
else:
CLASSIC_MODELS.append(getattr(module, model.model))
VERSIONNED_MODELS = [
{% for model in data %}{% if model.versionned %}
{{model.model}},
{% endif %}{% endfor %}
]
for model in CLASSIC_MODELS: for model in CLASSIC_MODELS:
admin.site.register(model) admin.site.register(model)
try: try:
model.get_serializer() model.get_serializer()
raise Exception("CLASSIX MODEL SHOULDN'T have this method") raise Exception("CLASSIC MODEL SHOULDN'T have this method")
except AttributeError: except AttributeError:
pass pass
for model in VERSIONNED_MODELS: for model in VERSIONNED_MODELS:
admin.site.register(model, CompareVersionAdmin) admin.site.register(model, CompareVersionAdmin)
if (model.get_serializer().Meta.model != model): if (model.get_serializer().Meta.model != model):
raise Exception( raise Exception(
"Get_serializer configuration incorrect in", str(model)) "Get_serializer configuration incorrect in", str(model))
{% endautoescape %}
#####
# This python file is used to generate some backend files
from django import template
from os.path import join, realpath, dirname
from general.api import get_api_config
############
# Need to do this first so that Django template engine is working
import django
from django.conf import settings
settings.configure(TEMPLATES=[
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['.'], # if you want the templates from a file
'APP_DIRS': False, # we have no apps
},
])
django.setup()
##########
def render_and_save(template_path, context, output_path):
with open(template_path, 'r') as f:
t = f.read()
t = template.Template(t)
c = template.Context({'data': context})
output = t.render(c)
with open(output_path, 'w') as f:
f.write(output)
current_dir = dirname(realpath(__file__))
templates_dir = current_dir + '/templates/'
saving_dir = realpath(current_dir + "/../")
api_config = get_api_config()
# Render urls.py
template_path = join(templates_dir, 'urls.tpl')
output_path = join(saving_dir, 'urls.py')
render_and_save(template_path, api_config, output_path)
# render list_user_post_permission.py
template_path = join(templates_dir, 'list_user_post_permission.tpl')
output_path = join(saving_dir, './permissions/__list_user_post_permission.py')
render_and_save(template_path, api_config, output_path)
# Render admin.py
data = []
for obj in api_config:
if 'model' in obj and obj['model']:
if obj['requires_testing']:
continue # we don't want testing models to be register in admin
if obj['ignore_in_admin']:
continue
data.append(obj)
template_path = join(templates_dir, 'admin.tpl')
output_path = join(saving_dir, 'admin.py')
render_and_save(template_path, data, output_path)
...@@ -2,8 +2,8 @@ from django.db import models ...@@ -2,8 +2,8 @@ from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.fields import GenericRelation
from .pendingModeration import PendingModeration from .pendingModeration import PendingModeration
from backend.permissions import OBJ_MODERATION_PERMISSIONS from shared import OBJ_MODERATION_PERMISSIONS
from backend.permissions import DEFAULT_OBJ_MODERATION_LV from shared import DEFAULT_OBJ_MODERATION_LV
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
......
from .obj_moderation_permission import OBJ_MODERATION_PERMISSIONS # noqa: F401 from .noDeleteIfNotStaff import NoDeleteIfNotStaff # noqa: F401
from .obj_moderation_permission import DEFAULT_OBJ_MODERATION_LV # noqa: F401 from .isOwner import IsOwner # noqa: F401
try: from .noDelete import NoDelete # noqa: F401
# the two imports are used outside of django from .isStaffOrReadOnly import IsStaffOrReadOnly # noqa: F401
# the try catch is here to prevent the raise of error from .readOnly import ReadOnly # noqa: F401
from .noDeleteIfNotStaff import NoDeleteIfNotStaff # noqa: F401 from .isDriOrReadOnly import IsDriOrReadOnly # noqa: F401
from .isOwner import IsOwner # noqa: F401 from .isDriOrNoPost import IsDriOrNoPost # noqa: F401
from .noDelete import NoDelete # noqa: F401 from .noPostIfNotStaff import NoPostIfNotStaff # noqa: F401
from .isStaffOrReadOnly import IsStaffOrReadOnly # noqa: F401 from .default_viewset_permissions import DEFAULT_VIEWSET_PERMISSIONS # noqa: F401
from .readOnly import ReadOnly # noqa: F401 from .__is_moderation_required import is_moderation_required # noqa: F401
from .isDriOrReadOnly import IsDriOrReadOnly # noqa: F401
from .isDriOrNoPost import IsDriOrNoPost # noqa: F401
from .noPostIfNotStaff import NoPostIfNotStaff # noqa: F401
from .default_viewset_permissions import DEFAULT_VIEWSET_PERMISSIONS # noqa: F401
from .__is_moderation_required import is_moderation_required # noqa: F401
except Exception:
pass
from backend.utils.__get_user_level import get_user_level from backend.utils.__get_user_level import get_user_level
from django.conf import settings from django.conf import settings
from .obj_moderation_permission import OBJ_MODERATION_PERMISSIONS from shared import OBJ_MODERATION_PERMISSIONS
###################################### ######################################
......
{% autoescape off %}
# WARNING
# THIS FILE HAS BEEN AUTOMATICALLY GENERATED
# WITH /backend/generate/generate_backend_files.py
# MODIFY THE FILE ABOVE IF YOUR NOT SATISFIED
# THIS WARNING DOESN'T APPLY TO .tpl FILES...
from django.conf import settings from django.conf import settings
from dotmap import DotMap
from shared import get_api_config
import importlib
api_config = get_api_config()
ALL_VIEWSETS = {} ALL_VIEWSETS = {}
{% for model in data %}{% if not model.requires_testing %}{% if model.viewset != 'UserDataViewSet' %}
from backend.models.{{model.import_location}} import {{model.viewset}} for model in api_config:
ALL_VIEWSETS["{{model.viewset}}"] = {{model.viewset}} model = DotMap(model)
{% endif %}{% endif %}{% endfor %} if not model.requires_testing:
if model.viewset != 'UserDataViewSet':
module = importlib.import_module("backend.models.{}".format (model.import_location))
ALL_VIEWSETS[model.viewset] = getattr(module, model.viewset)
if settings.TESTING: if settings.TESTING:
{% for model in data %}{% if model.requires_testing %} for model in api_config:
from backend.models.{{model.import_location}} import {{model.viewset}} model = DotMap(model)
ALL_VIEWSETS["{{model.viewset}}"] = {{model.viewset}} if model.requires_testing:
{% endif %}{% endfor %} if model.viewset != 'UserDataViewSet':
module = importlib.import_module("backend.models.{}".format (model.import_location))
ALL_VIEWSETS[model.viewset] = getattr(module, model.viewset)
class Request(object): class Request(object):
...@@ -25,6 +29,7 @@ class Request(object): ...@@ -25,6 +29,7 @@ class Request(object):
self.user = user self.user = user
self.method = method self.method = method
def list_user_post_permission(user): def list_user_post_permission(user):
viewsets_user_can_post = [] viewsets_user_can_post = []
request = Request(user, 'POST') request = Request(user, 'POST')
...@@ -40,5 +45,3 @@ def list_user_post_permission(user): ...@@ -40,5 +45,3 @@ def list_user_post_permission(user):
name = name[0].lower() + name[1:] name = name[0].lower() + name[1:]
viewsets_user_can_post.append(name) viewsets_user_can_post.append(name)
return viewsets_user_can_post return viewsets_user_can_post
{% endautoescape %}
...@@ -2,7 +2,7 @@ from django.test import TestCase ...@@ -2,7 +2,7 @@ from django.test import TestCase
from backend.models.abstract.my_model.myModel import validate_obj_model_lv from backend.models.abstract.my_model.myModel import validate_obj_model_lv
import pytest import pytest
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from backend.permissions import OBJ_MODERATION_PERMISSIONS from shared import OBJ_MODERATION_PERMISSIONS
class MyModelTestCase(TestCase): class MyModelTestCase(TestCase):
......
{% autoescape off %}
# WARNING
# THIS FILE HAS BEEN AUTOMATICALLY GENERATED
# WITH /backend/generate/generate_backend_files.py
# MODIFY THE FILE ABOVE IF YOUR NOT SATISFIED
# THIS WARNING DOESN'T APPLY TO .tpl FILES...
from django.conf.urls import url, include
from django.conf import settings from django.conf import settings
from rest_framework import routers from django.conf.urls import include, url
from django.urls import path from django.urls import path
from rest_framework import routers
from rest_framework.documentation import include_docs_urls
from backend.permissions import DEFAULT_VIEWSET_PERMISSIONS
from shared import get_api_config
from . import views from . import views
from dotmap import DotMap
import importlib
urlpatterns = [
url(r'^api-docs/', include_docs_urls(title='Outgoing API')),
]
router = routers.DefaultRouter()
ALL_MODELS = [] ALL_MODELS = []
ALL_VIEWSETS = [] ALL_VIEWSETS = []
{% for model in data %}
{% if not model.requires_testing %}
from backend.models.{{model.import_location}} import {{model.viewset}}
ALL_VIEWSETS.append({{model.viewset}})
{% if model.model is not None and not model.ignore_in_admin%}
from backend.models.{{model.import_location}} import {{model.model}}
ALL_MODELS.append({{model.model}})
{% endif %}
{% endif %}
{% endfor %}
from rest_framework.documentation import include_docs_urls # Automatically loading models based on API config file
api_config = get_api_config()
urlpatterns = [ for model in api_config:
url(r'^api-docs/', include_docs_urls(title='Outgoing API')) model = DotMap(model)
] if not model.requires_testing:
module = importlib.import_module("backend.models.{}".format(model.import_location))
Viewset = getattr(module, model.viewset)
ALL_VIEWSETS.append(Viewset)
if model.model is not None and not model.ignore_in_admin:
ALL_MODELS.append(getattr(module, model.model))
# print(viewset)
str_url = model.api_end_point
if 'api_attr' in model:
str_url += '/{}'.format(model.api_attr)
if 'api_name' in model:
router.register(str_url, Viewset, model.api_name)
else:
router.register(str_url, Viewset)
router = routers.DefaultRouter()
if settings.TESTING: if settings.TESTING:
{% for model in data %}{% if model.requires_testing %}
from backend.models.{{model.import_location}} import {{model.viewset}} for model in api_config:
ALL_VIEWSETS.append({{model.viewset}}) model = DotMap(model)
{% if model.model is not None %} if model.requires_testing:
from backend.models.{{model.import_location}} import {{model.model}} module = importlib.import_module("backend.models.{}".format(model.import_location))
ALL_MODELS.append({{model.model}}) Viewset = getattr(module, model.viewset)
{% endif %} ALL_VIEWSETS.append(Viewset)
router.register( if model.model is not None:
r'{{model.api_end_point}}{% if 'api_attr' in model %}/{{model.api_attr}}{% endif %}', ALL_MODELS.append(getattr(module, model.model))
{{model.viewset}}{%if 'api_name' in model%},"{{model.api_name}}"{% endif %}
){% endif %}{% endfor %} str_url = model.api_end_point
if 'api_attr' in model:
str_url += '/{}'.format(model.api_attr)
{% for model in data %}{% if not model.requires_testing %} if 'api_name' in model:
router.register( router.register(str_url, Viewset, model.api_name)
r'{{model.api_end_point}}{% if 'api_attr' in model %}/{{model.api_attr}}{% endif %}', else:
{{model.viewset}}{%if 'api_name' in model%},"{{model.api_name}}"{% endif %} router.register(str_url, Viewset, model.viewset)
){% endif %}{% endfor %}
urlpatterns += [url(r'^api/', include(router.urls))] urlpatterns += [url(r'^api/', include(router.urls))]
urlpatterns.append(path('api/serverModerationStatus/', views.app_moderation_status)) urlpatterns.append(path('api/serverModerationStatus/', views.app_moderation_status))
for model in ALL_MODELS: for Model in ALL_MODELS:
for key in model.model_config: for key in Model.model_config:
val = model.model_config[key] val = Model.model_config[key]
if val is None: if val is None:
raise Exception("You forgot to set the {} config variable in the model {}".format(key, str(model))) raise Exception("You forgot to set the {} config variable in the model {}".format(key, str(model)))
from backend.permissions import DEFAULT_VIEWSET_PERMISSIONS for Viewset in ALL_VIEWSETS:
for viewset in ALL_VIEWSETS:
for p in DEFAULT_VIEWSET_PERMISSIONS: for p in DEFAULT_VIEWSET_PERMISSIONS:
v_p = viewset.permission_classes v_p = Viewset.permission_classes
if p not in v_p: if p not in v_p:
raise Exception("Permission_classes are not defined correctly in the viewset {}".format(str(viewset))) raise Exception("Permission_classes are not defined correctly in the viewset {}".format(str(viewset)))
{% endautoescape %}
from general.api import get_api_config from shared import get_api_config
def find_api_end_point_for_viewset(viewset_name): def find_api_end_point_for_viewset(viewset_name):
......
from general.api import get_api_config from shared import get_api_config
def get_model_config(model): def get_model_config(model):
......
from .__is_member import is_member from .__is_member import is_member
from backend.permissions import OBJ_MODERATION_PERMISSIONS from shared import OBJ_MODERATION_PERMISSIONS
def get_user_level(user): def get_user_level(user):
......
from backend.permissions import IsOwner, IsStaffOrReadOnly, IsDriOrReadOnly, ReadOnly, IsDriOrNoPost, NoPostIfNotStaff from backend.permissions import IsOwner, IsStaffOrReadOnly, IsDriOrReadOnly, ReadOnly, IsDriOrNoPost, NoPostIfNotStaff
from rest_framework.permissions import IsAdminUser from rest_framework.permissions import IsAdminUser
from backend.permissions import DEFAULT_VIEWSET_PERMISSIONS from backend.permissions import DEFAULT_VIEWSET_PERMISSIONS
from general.api import get_api_config from shared import get_api_config
def get_viewset_permissions(viewset): def get_viewset_permissions(viewset):
......
...@@ -2,7 +2,7 @@ from django.conf import settings ...@@ -2,7 +2,7 @@ from django.conf import settings
from django.http import HttpResponse from django.http import HttpResponse
import json import json
from backend.permissions.obj_moderation_permission import OBJ_MODERATION_PERMISSIONS from shared import OBJ_MODERATION_PERMISSIONS
def app_moderation_status(request): def app_moderation_status(request):
......
#####
# This python file is used to generate js files for redux
from os import makedirs
from os.path import join, dirname, realpath, exists
from django import template
import re
from general.api import get_api_config
############
# Need to do this first so that Django template engine is working
import django
from django.conf import settings
settings.configure(TEMPLATES=[
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['.'], # if you want the templates from a file
'APP_DIRS': False, # we have no apps
},
])
django.setup()
##########
current_dir = dirname(realpath(__file__))
templates_dir = current_dir + '/templates/'
saving_dir = realpath(current_dir + "/../src/generated/")
if not exists(saving_dir):
makedirs(saving_dir)
templates = [
'action-types',
'actions',
'reducers',
'combinedReducers'
]
api_config = get_api_config()
API_BASE = "/api/"
contexts = []
for api in api_config:
if "requires_testing" in api and api["requires_testing"]:
continue
name = api['viewset'].split('ViewSet')[0]
name = name[0].lower() + name[1:]
contexts.append({
"name": api["api_end_point"],
"api_end_point": API_BASE + api["api_end_point"] + '/',
})
# API outside rest framework here