def user_model_file(): cfg = get_cfg() fields = cfg['current_scaffold']['model']['fields'] # title_list = ["name", "email", "etc"] title_list = [field['title'] for field in fields] # quoted_list = ['"name"', '"email"', '"etc"'] quoted_list = [quote(field['title']) for field in fields] # required_list = ['"email"', '"etc"'] required_list = [field['title'] for field in fields] required_list.remove('name') required_list = [quote(field) for field in required_list] # assignment_list = ["email=email", "name=name"] assignment_list = [f'{title}={title}' for title in title_list] field_strings = [field['string'] for field in fields] model = f('$assets/models/UserProfile.py', 'r').replace( 'title_list', ', '.join(title_list)).replace( 'required_list', ', '.join(required_list)).replace( 'field_strings', ''.join(field_strings)).replace( 'assignment_list', ', '.join(assignment_list)) f('$api/models.py', 'a', model) wl('Added UserProfile model')
def scaffold_details_page(): cfg = get_cfg() title = cfg['current_scaffold']['model']['title'] title_singular = title.lower() details_page = parse_content(f('$assets/pages/content_details.js', 'r')) f('$pages/' + title_singular + '.js', 'w', details_page) wl('Built the details page')
def scaffold_view(): cfg = get_cfg() new_view = f('$assets/views/new.py', 'r').format(title=cfg['current_scaffold']['model']['title']) f('$api/views.py', 'a', new_view) wl('Created a view') # Urls only make sense if there is a view. Putting it here. scaffold_url()
def user_routes(): # Puts the user routes below the router, but above urlpatterns route_flag = '# Register new routes below' route_start = f('$api/urls.py','r').find(route_flag)+len(route_flag)+1 old_urls = f('$api/urls.py', 'r') begin = old_urls[:route_start] mid = f('$assets/urls/user_urls.py', 'r') end = old_urls[route_start:] f('$api/urls.py', 'w', begin + mid + end) f('$api/urls.py', 'w', '$assets/urls/app_urls_with_users.py') wl('Added user routes')
def scaffold_url(): cfg = get_cfg() title = cfg['current_scaffold']['model']['title'] route = f('$assets/urls/new_api_url.py', 'r').format(title=title, title_lower=title.lower()) data = { 'target': '# Register new routes below', 'content': '# Register new routes below\n' + route } f('$api/urls.py', 'w', data) wl('Created url route')
def scaffold_model(): cfg = get_cfg() # Add title title = string_input('What will you call your model? ').capitalize() cfg['current_scaffold']['model']['title'] = title cfg['current_scaffold']['model']['fields'] = [] set_cfg(cfg) # Should never be necessary, but just in case. if 'models' not in cfg: cfg['models'] = [] set_cfg(cfg) # Add owner field if necessary need_owner = False if cfg['need_users']: need_owner = boolean_input('Will users own instances of this model?') if need_owner: cfg['current_scaffold']['model']['fields'].append({ 'title': 'owner', 'type': 'ForeignKey', 'options': ['UserProfile', 'on_delete = models.CASCADE'], 'string': f"owner = models.ForeignKey('UserProfile', on_delete = models.CASCADE)\n " }) cfg['current_scaffold']['need_owner'] = 'True' else: cfg['current_scaffold']['need_owner'] = 'False' set_cfg(cfg) # Add other fields print(' ') print('Let\'s create at least one model field now.') get_model_field() # Refresh config cfg = get_cfg() # Put the model in models.py f('$api/models.py', 'a', return_model()) wl('Created the ' + title + ' model') # Put the model in config.json fields = cfg['current_scaffold']['model']['fields'] title = cfg['current_scaffold']['model']['title'] str_method = cfg['current_scaffold']['model']['__str__'] cfg['models'].append({ 'title': title, 'fields': fields, '__str__': str(str_method), }) set_cfg(cfg)
def scaffold_serializer(): cfg = get_cfg() fields_arr = cfg['current_scaffold']['model']['fields'] titles = [quote(field['title']) for field in fields_arr] if cfg['current_scaffold']['need_owner'] == 'True': titles.append(quote('owner_name')) fields_str = ', '.join(titles) fields_str = "'pk', " + fields_str new_serializer = f('$assets/serializers/new.py', 'r').format( title=cfg['current_scaffold']['model']['title'], fields=fields_str) f('$api/serializers.py', 'a', new_serializer) wl('Created new serializer')
def scaffold_list_page(): cfg = get_cfg() title = cfg['current_scaffold']['model']['title'] title_plural = pluralize(title.lower()) list_page = parse_content(f('$assets/pages/content_list.js', 'r')) f('$pages/' + title_plural + '.js', 'w', list_page) wl('Built the list page') # Add content type to server.js data = { 'target': ['const content_types'], 'content': quote(title.lower()) + ',' } f('$out/server.js', 'a', data) wl('Add frontend CRUD routes')
def scaffold_menu_item(): cfg = get_cfg() title = cfg['current_scaffold']['model']['title'] title_plural = pluralize(title.capitalize()) st = "import { list_type_permission } from '../services/permissions.js'\n" f('$out/components/Navbar.js', 'p', st.replace('type', title.lower())) st = "\n {title: 'title_plural', permissions: list_type_permission}," st = st.replace('title_plural', title_plural).replace('type', title.lower()) data = {'target': ['const content_types'], 'content': st} f('$out/components/Navbar.js', 'a', data) wl(f'Added {title} menu item')
def user_serializers(): serializer = f('$assets/serializers/user_profile.py', 'r') cfg = get_cfg() fields = cfg['current_scaffold']['model']['fields'] titles = [field['title'] for field in fields] fields_list = [',\n ' + quote(t) for t in titles] # validated_list = [ name=validated_data['name'], etc ] validated_list = [ f"\n {t}=validated_data['{t}']," for t in titles ] serializer = serializer.replace( 'fields_list', ''.join(fields_list)).replace( 'validated_list', ''.join(validated_list)) f('$api/serializers.py', 'a', serializer) wl('Added user serializer')
def content(): cfg = get_cfg() cfg['current_scaffold'] = {'model': {}} set_cfg(cfg) scaffold_model() prev_path = os.getcwd() os.chdir(f('$out', '$')) subprocess.run([cfg['py_cmd'], 'manage.py', 'makemigrations']) subprocess.run([cfg['py_cmd'], 'manage.py', 'migrate']) os.chdir(prev_path) wl('Ran migrations') scaffold_permission() scaffold_view() scaffold_serializer() scaffold_admin()
def build_structure(): prev_path = os.getcwd() cfg = get_cfg() frontend_name = string_input('Name the frontend Node.js app', 'frontend') cfg['frontend_name'] = frontend_name set_cfg(cfg) project_name = cfg['project_name'] # directories mkdir('$out') mkdir('$out/__tests__') mkdir('$out/components') mkdir('$out/components/users') mkdir('$out/middleware') mkdir('$out/pages') mkdir('$out/redux') mkdir('$out/services') mkdir('$out/styles') mkdir('$out/styles/base') mkdir('$out/styles/hacks') mkdir('$out/styles/layout') mkdir('$out/styles/module') mkdir('$out/styles/state') mkdir('$out/styles/vendor') # Component assets f('$out/components/Head.js', 'w', '$assets/components/Head.js') f('$out/components/Navbar.js', 'w', '$assets/components/Navbar.js') # Middleware f('$out/middleware/set_uri.js', 'w', '$assets/middleware/set_uri.js') res_current_user = f('$assets/middleware/res_current_user.js', 'r').replace('reactjo', project_name) f('$out/middleware/res_current_user.js', 'w', res_current_user) # Misc assets f('$out/.env', 'w', '$assets/env.txt') f('$out/.babelrc', 'w', '$assets/babel.js') f('$out/.gitignore', 'w', '$assets/gitignore.txt') f('$out/.eslintrc.json', 'w', '$assets/eslint.js') f('$out/app.json', 'w', '$assets/app.js') f('$out/next.config.js', 'w', '$assets/next.config.js') f('$out/package.json', 'w', '$assets/package.js') f('$out/postcss.config.js', 'w', '$assets/postcss.config.js') f('$out/shim.js', 'w', '$assets/shim.js') # Redux f('$out/redux/store.js', 'w', '$assets/redux/store.js') f('$out/pages/redux_demo.js', 'w', '$assets/pages/redux_demo.js') f('$out/components/ReduxDemo.js', 'w', '$assets/components/ReduxDemo.js') server_string = f('$assets/server.js', 'r').replace( 'random_string', id_generator()).replace('reactjo', project_name) f('$out/server.js', 'w', server_string) # Pages assets # Vars cfg = get_cfg() user_fields = cfg['current_scaffold']['model']['fields'] user_titles = [field['title'] for field in user_fields] fields_arr = [quote(title) for title in user_titles] fields_arr.append(quote('password')) signup_page = f('$assets/pages/signup.js', 'r').replace( 'const form_fields = []', 'const form_fields = [' + ', '.join(fields_arr) + ']') user_page = f('$assets/pages/user.js', 'r').replace( 'const fields = []', 'const fields = [' + ', '.join(fields_arr) + ']') # User Pages f('$out/pages/login.js', 'w', '$assets/pages/login.js') f('$out/pages/signup.js', 'w', signup_page) f('$out/pages/user.js', 'w', user_page) f('$out/pages/users.js', 'w', '$assets/pages/users.js') f('$out/pages/index.js', 'w', '$assets/pages/index.js') # User Components f('$out/components/users/Delete.js', 'w', '$assets/components/users/Delete.js') f('$out/components/users/Details.js', 'w', '$assets/components/users/Details.js') f('$out/components/users/List.js', 'w', '$assets/components/users/List.js') f('$out/components/users/Login.js', 'w', '$assets/components/users/Login.js') f('$out/components/users/Signup.js', 'w', '$assets/components/users/Signup.js') f('$out/components/users/Update.js', 'w', '$assets/components/users/Update.js') # Services assets f('$out/services/content_create.js', 'w', '$assets/services/content_create.js') f('$out/services/content_update.js', 'w', '$assets/services/content_update.js') f('$out/services/content_delete.js', 'w', '$assets/services/content_delete.js') f('$out/services/permissions.js', 'w', '$assets/services/permissions.js') f('$out/services/get_cookie.js', 'w', '$assets/services/get_cookie.js') f('$out/services/get_headers.js', 'w', '$assets/services/get_headers.js') f('$out/services/get_uri.js', 'w', '$assets/services/get_uri.js') # Vars cfg = get_cfg() user_fields = cfg['current_scaffold']['model']['fields'] user_titles = [field['title'] for field in user_fields] quote_titles = [quote(title) for title in user_titles] set_cfg(cfg) # User Permissions new_permissionset() # Login login_service = f('$assets/services/login_service.js', 'r').replace('reactjo', project_name) f('$out/services/login_service.js', 'w', login_service) # Logout logout_service = f('$assets/services/logout_service.js', 'r').replace('reactjo', project_name) f('$out/services/logout_service.js', 'w', logout_service) # Signup signup_service = f('$assets/services/signup_service.js', 'r').replace( 'let fields = []', 'let fields = [' + ', '.join(quote_titles) + ']') f('$out/services/signup_service.js', 'w', signup_service) # Check current_user current_user_service = f('$assets/services/current_user.js', 'r').replace('reactjo', project_name) f('$out/services/current_user.js', 'w', current_user_service) # Style assets f('$out/styles/index.scss', 'w', '$assets/styles/index.scss') f('$out/styles/base/_base.scss', 'w', '$assets/styles/base/_base.scss') f('$out/styles/base/_functions.scss', 'w', '$assets/styles/base/_functions.scss') f('$out/styles/base/_mixins.scss', 'w', '$assets/styles/base/_mixins.scss') f('$out/styles/base/_variables.scss', 'w', '$assets/styles/base/_variables.scss') f('$out/styles/hacks/_shame.scss', 'w', '$assets/styles/hacks/_shame.scss') f('$out/styles/layout/_body.scss', 'w', '$assets/styles/layout/_body.scss') f('$out/styles/layout/_header.scss', 'w', '$assets/styles/layout/_header.scss') f('$out/styles/layout/_grid.scss', 'w', '$assets/styles/layout/_grid.scss') f('$out/styles/module/_navigations.scss', 'w', '$assets/styles/module/_navigations.scss') f('$out/styles/module/_forms.scss', 'w', '$assets/styles/module/_forms.scss') f('$out/styles/module/_buttons.scss', 'w', '$assets/styles/module/_buttons.scss') f('$out/styles/state/_state.scss', 'w', '$assets/styles/state/_state.scss') wl('Build front end directories and files') # Tests mkdir('$out/__tests__/users') f('$out/__tests__/users/Delete.test.js', 'w', '$assets/tests/users/Delete.js') f('$out/__tests__/users/Details.test.js', 'w', '$assets/tests/users/Details.js') f('$out/__tests__/users/Update.test.js', 'w', '$assets/tests/users/Update.js') print('Installing node dependencies. This will take a while.') os.chdir(f('$out', '$')) if os.name == 'nt': subprocess.run('npm install', shell=True) else: subprocess.run(['npm', 'install']) os.chdir(prev_path) wl('Installed node dependencies')
def scaffold_permission(): cfg = get_cfg() # Get data title = cfg['current_scaffold']['model']['title'] model = 'User' if title == 'UserProfile' else title all_types = [ 'Superuser', 'Staff', 'Authenticated', 'Anonymous', 'Active', 'Anyone', 'Nobody', 'Owner' ] ownerless = all_types[:-1] custom = boolean_input('Customize permissions for ' + model + '?', 'y') auth = cfg['need_users'] == 'True' owner = cfg['current_scaffold']['need_owner'] == 'True' is_user = model == 'User' # Adjust data if not auth: all_types.remove('Authenticated') all_types.remove('Active') if not owner: all_types.remove('Owner') # Build the questions list_answer = 'Anyone' list_options = ownerless list_q = 'Who can view the list of all ' + pluralize(model.lower()) + '?' details_answer = 'Anyone' details_options = all_types details_q = 'Who can view the details of a ' + model.lower() + '?' post_answer = '' if is_user: post_answer = 'Anonymous' else: post_answer = 'Authenticated' if auth else 'Anyone' post_options = ownerless post_q = 'Who can create a ' + model.lower() + '?' update_answer = 'Owner' if owner else 'Staff' update_options = all_types update_q = 'Who can update an existing ' + model.lower() + '?' delete_answer = 'Owner' if owner else 'Staff' delete_options = all_types delete_q = 'Who can delete an existing ' + model.lower() + '?' # Ask questions if necessary if custom: list_answer = options_input(list_q, list_options, list_answer) details_answer = options_input(details_q, details_options, details_answer) post_answer = options_input(post_q, post_options, post_answer) update_answer = options_input(update_q, update_options, update_answer) delete_answer = options_input(delete_q, delete_options, delete_answer) # Update config cfg['current_scaffold']['permissions'] = { 'list': list_answer, 'details': details_answer, 'post': post_answer, 'update': update_answer, 'delete': delete_answer, } set_cfg(cfg) # Build permisionset new_permission = f('$assets/permissions/new.py', 'r').format( Model=model, list_users=list_answer, details_users=details_answer, post_users=post_answer, update_users=update_answer, delete_users=delete_answer, ) f('$api/permissions.py', 'a', new_permission) wl('Created permission')
def scaffold_admin(): cfg = get_cfg() title = cfg['current_scaffold']['model']['title'] new_admin = f('$assets/admin/new.py', 'r').format(title=title) f('$api/admin.py', 'a', new_admin) wl('Added admin entry')
def user_permission(): scaffold_permission() f('$api/permissions.py', 'a', '$assets/permissions/post_own_content.py') f('$api/permissions.py', 'a', '$assets/permissions/update_own_profile.py') wl('Added user permissions')