def generate_urls_file(target_path, app_name, application, pages, i18n=False): url_imports = ImportSet() url_imports.add('django.conf.urls', 'url') for page in pages: url_imports.add('.views', page.view_name) context = { 'i18n': i18n, 'package_name': app_name, 'application': application, 'pages': pages, 'url_imports': url_imports.import_sting(), } filepath = os.path.join(package_to_path(app_name), 'urls_i18n.py' if i18n else 'urls.py') generate_file(target_path, filepath, 'urls.py.tpl', context)
def generate(target_path, project): for app_name, application in project.applications.items(): has_i18n = any([x.translatable for x in application.models.values()]) if not has_i18n: continue imports = ImportSet() imports.add('modeltranslation.translator', 'translator') imports.add('modeltranslation.translator', 'TranslationOptions') for col in application.models.values(): if not col.translatable: continue imports.add('{}.models'.format(app_name), col.class_name) generate_file(target_path, '{}/translation.py'.format(app_name), 'translation.py.tpl', { 'imports': imports.import_sting(), 'models': [(name, col) for name, col in application.models.items() if col.translatable] })
def generate(target_path, project): has_views = False for app_name, application in project.applications.items(): if not len(application.pages): # and not application.rest: continue has_views = True imports = ImportSet() for col in application.models.values(): imports.add('{}.models'.format(app_name), col.class_name) generated_templates = [] if len(application.pages.items()) > 0: imports.add('django.views.generic', 'TemplateView') for page in application.pages.values(): if not page.parent_name: imports.add('app.utils.views', 'Data') for import_spec in page.get_imports(): imports.add(*import_spec) for item in page.page_items.values(): for import_spec in item.get_imports(): imports.add(*import_spec) if page.template: template = page.defined_template_name if template: template_name = f'{app_name}/templates/{template}' generate_file( target_path, template_name, 'theme/default.html', { 'app_name': app_name, 'page': page, 'parent': application.resolve_page(page.parent_name) if page.parent_name else None }) generated_templates.append(template_name) generate_file( target_path, '{}/views.py'.format(app_name), 'views.py.tpl', { 'imports': imports.import_sting(), 'application': application, 'pages': application.pages.values() }) # urls pages_i18n = [ page for page in application.pages.values() if page.has_uri and page.i18n ] if len(pages_i18n) > 0: generate_urls_file(target_path, app_name, application, pages_i18n, i18n=True) # urls i18n pages = [ page for page in application.pages.values() if page.has_uri and not page.i18n ] if application.pages: generate_urls_file(target_path, app_name, application, pages, i18n=False) if len(application.pages) > 0: generate_file(target_path, '{}/templates/{}/_base.html'.format( app_name, app_name), template_name='theme/base_app.html', context={ 'application': application, }) if has_views: generate_package('app.utils', path=target_path) generate_file(target_path, 'app/utils/views.py', template_name='views.utils.py.tpl')
def generate(target_path, project): if not project.applications_support(ChannelsAppExtension): return streams = [] imports = ImportSet() for app in project.applications.values(): for page in app.pages_with(StreamPageExtension): streams.append((app, page)) imports.add(f'{app.app_name}.channels', f'{page.view_name}Consumer') generate_file(target_path, f'app/routing.py', 'channels.routing_main.tpl', context={ 'streams': streams, 'imports': imports, }) for app in project.applications.values(): if app.pages_support(StreamPageExtension): imports = ImportSet() imports.add('channels.layers', 'get_channel_layer') imports.add('channels.generic.websocket', 'AsyncWebsocketConsumer') imports.add('django.db.models.signals', 'post_save', 'm2m_changed', 'post_delete') imports.add('django_query_signals', 'post_bulk_create', 'post_delete as post_delete_bulk', 'post_get_or_create', 'post_update_or_create', 'post_update') imports.add('channels.db', 'database_sync_to_async') imports.add('asgiref.sync', 'async_to_sync') imports.add('asyncio', 'sleep') imports.add('django.dispatch', 'receiver') imports.add('app.utils.rest', 'ZmeiJsonEncoder') pages = app.pages_with(StreamPageExtension) for page in pages: for model in page[StreamPageExtension].models: imports.add(f'{model.model_app_name}.models', model.model_class_name) imports.add(f'.views', page.view_name) generate_file(target_path, f'{app.app_name}/channels.py', 'channels.py.tpl', context={ 'pages': pages, 'ext': StreamPageExtension, 'imports': imports, })
def generate(target_path, project): for app_name, application in project.applications.items(): if not application.models_support(AdminModelExtension): continue imports = ImportSet() imports.add('django.contrib', 'admin') imports.add('django', 'forms') for model in application.models_with(AdminModelExtension): imports.add('{}.models'.format(app_name), model.class_name) for class_import in model[AdminModelExtension].classes: imports.add(*class_import) if model.polymorphic: for child in model.child_models: imports.add('{}.models'.format(app_name), child.class_name) # inlines for inline in model[AdminModelExtension].inlines: for declaration in inline.type_declarations: imports.add(*declaration) if inline.inline_type == 'polymorphic': for target_model in inline.target_model.child_models: if target_model.translatable: imports.add('cratis_i18n.admin', 'TranslatableInlineModelAdmin') imports.add('{}.models'.format(app_name), target_model.class_name) imports.add('{}.models'.format(app_name), inline.target_model.class_name) for field in model.fields.values(): if field.get_admin_widget(): import_data, model_field = field.get_admin_widget() for source, what in import_data: imports.add(source, what) generate_file( target_path, '{}/admin.py'.format(app_name), 'admin.py.tpl', { 'imports': imports.import_sting(), 'ext': AdminModelExtension, 'application': application, 'models': [(name, model) for name, model in application.models.items() if model.supports(AdminModelExtension)] })
def generate(target_path, project): for app_name, application in project.applications.items(): if not len(application.models): continue imports = ImportSet() imports.add('django.db', 'models') for model in application.models.values(): # type: ModelDef for handlers, code in model.signal_handlers: for signal_import in handlers: imports.add('django.dispatch', 'receiver') imports.add(*signal_import) if model.polymorphic and model.tree: imports.add('polymorphic_tree.models', 'PolymorphicMPTTModel', 'PolymorphicTreeForeignKey') else: if model.polymorphic: imports.add('polymorphic.models', 'PolymorphicModel') if model.tree: imports.add('mptt.models', 'MPTTModel', 'TreeForeignKey') if model.validators: imports.add('django.core.exceptions', 'ValidationError') if model.mixin_classes: for import_decl in model.mixin_classes: pkg, cls, alias = import_decl if alias != cls: cls = '{} as {}'.format(cls, alias) imports.add(*(pkg, cls)) for field in model.own_fields: # type: FieldDef model_field = field.get_model_field() if model_field: import_data, model_field = model_field # type: FieldDeclaration for source, what in import_data: imports.add(source, what) generate_file( target_path, '{}/models.py'.format(app_name), 'models.py.tpl', { 'imports': imports.import_sting(), 'application': application, 'models': application.models.items() })
def generate(target_path, project): has_api = False for application in project.applications.values(): if not application.models_support( ApiModelExtension) and not application.models_support( RestModelExtension): continue app_name = application.app_name has_api = True imports = ImportSet() imports.add('rest_framework', 'serializers') for model in application.models_with(RestModelExtension): for name, rest_conf in model[RestModelExtension].rest_conf.items(): rest_conf.configure_model_imports(imports) generate_file( target_path, '{}/serializers.py'.format(app_name), 'serializers.py.tpl', { 'imports': imports.import_sting(), 'application': application, 'rest_ext': RestModelExtension, 'api_ext': ApiModelExtension, 'models': [(model.ref, model) for model in application.models_with(RestModelExtension)], }) url_imports = ImportSet() url_imports.add('django.conf.urls', 'url') url_imports.add('django.conf.urls', 'include') url_imports.add('rest_framework', 'routers') for model in application.models_with(RestModelExtension): for rest_conf in model[RestModelExtension].published_apis.values(): url_imports.add('.views_rest', f'{rest_conf.serializer_name}ViewSet') context = { 'package_name': app_name, 'application': application, 'ext': RestModelExtension, 'url_imports': url_imports.import_sting(), } filepath = os.path.join(package_to_path(app_name), 'urls_rest.py') generate_file(target_path, filepath, 'urls_rest.py.tpl', context) # views_rest.py imports = ImportSet() for model in application.models_with(RestModelExtension): for name, rest_conf in model[RestModelExtension].rest_conf.items(): rest_conf.configure_imports(imports) generate_file( target_path, f'{app_name}/views_rest.py', 'views_rest.py.tpl', { 'package_name': app_name, 'application': application, 'ext': RestModelExtension, 'models': [(name, model) for name, model in application.models.items() if model.supports(RestModelExtension)], 'imports': imports }) has_pages = False for application in project.applications.values(): if len(application.pages): has_pages = True if has_api or has_pages: generate_package('app.utils', path=target_path) generate_file(target_path, 'app/utils/rest.py', template_name='rest.utils.py.tpl')
def generate(target_path, project): has_react = False react_pages = [] react_pages_by_app = {} index_imports = ImportSet() for app_name, application in project.applications.items(): if not application.pages_support(ReactPageExtension): continue has_react = True react_pages_by_app[app_name] = {} app_cmp_name = to_camel_case(app_name) for name, page in application.pages.items(): ext = page.get_own_or_parent_extension(ReactPageExtension) if not ext: continue page_cmp_name = to_camel_case(page.name) name = f'{page_cmp_name}Page' name_ui = f'{page_cmp_name}Ui' if page.uri: react_pages.append( (app_cmp_name, name_ui, format_uri(page.uri))) react_pages_by_app[app_name][page.name] = format_uri(page.uri) page_component_name = f'Page{page_cmp_name}' react_components_imports = ImportSet() react_components_imports.add('react', 'React') # react_components_imports.add(f'../Components/{el.tag}', '*' + el.tag) imports = ImportSet() imports.add('react', 'React') imports.add(f'../../layout', 'BaseLayout') imports.add(f'../layouts/{app_cmp_name}Layout', f'{app_cmp_name}Layout') react_components_imports.add( f'../Reducers/{page_component_name}Reducers', f'*reloadPageDataAction') index_imports.add(f'./pages/{name}', '*' + name) wrappers = [ f'PageContextProvider', f'BaseLayout', f'{app_cmp_name}Layout' ] def wrap(source, cmp_list): source = indent(source, ' ') if not len(cmp_list): return dedent(source) w = cmp_list.pop() return wrap( f'<{w} {{...this.props}} page={{this}}>\n{source}\n</{w}>', wrappers) blocks_rendered = {} for area, blocks in page.get_blocks( platform=ReactPageExtension).items(): blocks_rendered[area] = [] for index, block in enumerate(blocks): rendered = block.render(area=area, index=index) try: import_section, rendered = rendered.split('<', maxsplit=1) except ValueError: pass else: for im in REACT_IMPORT_RX.findall(import_section): what = [ '*' + x.strip() for x in im[3].split(',') if x != '' ] def_what = im[0].strip(' ,') if len(def_what): what.append(def_what) src = im[5] imports.add(src, *what) rendered = '<' + rendered blocks_rendered[area].append((block.ref, rendered)) streams = page.list_own_or_parent_extensions(StreamPageExtension) generate_file( target_path, 'react/src/{}/pages/{}.jsx'.format(app_name, name), 'react/page.jsx.tpl', { 'imports': imports.import_sting_js(), 'name': name, 'page': page, 'blocks': blocks_rendered, 'ext': ReactPageExtension, 'app_name': app_name, 'streams': streams, 'to_camel_case': to_camel_case, 'source': wrap('{this.renderContent()}', wrappers) }) ui_imports = ImportSet() ui_imports.add('react', 'React') ui_imports.add(f'../pages/{name}', name) generate_file( target_path, f'react/src/{app_name}/ui/{name_ui}.jsx', 'react/ui.jsx.tpl', { 'imports': ui_imports.import_sting_js(), 'parent': name, 'name': name_ui }) generate_file( target_path, f'react/src/{app_name}/layouts/{app_cmp_name}Layout.jsx', 'react/cmp.jsx.tpl', { 'name': f'{app_cmp_name}Layout', 'source': '<>{children}</>' }) if not len(react_pages_by_app[app_name]): del react_pages_by_app[app_name] # sort react_pages react_pages = sorted(react_pages) # sort routes temp_dict = {} for key in sorted(react_pages_by_app): temp_dict.update({key: react_pages_by_app[key]}) react_pages_by_app = temp_dict if has_react: generate_file(target_path, f'react/src/layout.jsx', 'react/cmp.jsx.tpl', { 'name': f'BaseLayout', 'source': '<>{children}</>' }) generate_file(target_path, f'react/src/index.scss', 'react/index.scss.tpl', {'pages': react_pages}) generate_file(target_path, 'app/utils/react.py', 'react/utils.py.tpl') generate_file(target_path, 'react/src/index.jsx', 'react/index.jsx.tpl') generate_file(target_path, 'react/src/state.jsx', 'react/state.js.tpl') generate_file(target_path, 'react/src/streams.jsx', 'react/streams.js.tpl') generate_file(target_path, 'react/src/reducer.jsx', 'react/reducer.js.tpl', {'name': 'Root'}) generate_file( target_path, 'react/src/router.jsx', 'react/router.jsx.tpl', { 'name': 'Root', 'pages': react_pages, 'pages_index': react_pages_by_app, 'to_camel_case': to_camel_case }) generate_file(target_path, 'react/package.json', 'react/package.json.tpl', {'packages': {}}) generate_file(target_path, 'react/webpack.config.js', 'react/webpack.config.js.tpl', {'entries': { 'all': f'./src/index.jsx' }})