def test_set_cfg(): cfg = get_cfg() cfg['foo'] = 'bar' set_cfg(cfg) another_cfg = get_cfg() assert ('foo' in another_cfg) teardown_config()
def mkdir(path, name=None): path = parse_shortcuts(path) # Create directory if not os.path.exists(path): os.mkdir(path) # Create path entry in config cfg = get_cfg() if not name in cfg['paths'].keys() and name is not None: cfg['paths'][name] = path set_cfg(cfg)
def new(): backend_name = string_input('Name the Django backend app:', 'backend') need_users = True # Kept for legacy cfg = get_cfg() cfg['need_users'] = str(need_users) cfg['backend_name'] = backend_name set_cfg(cfg) try: build_structure() except Exception as e: print(e)
def setup_config(): src = file_read(config_asset_path) target = config_destination_path if not os.path.isdir(reactjorc_path): os.mkdir(reactjorc_path) file_write(target, src) cfg = get_cfg() super_root = os.getcwd() project_name = 'www' cfg['paths']['super_root'] = super_root cfg['paths']['project_root'] = os.path.join(super_root, project_name) set_cfg(cfg)
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 worklist(string, prev_path=None): # Solves issues with finding config.json after changing dirs if prev_path: next_path = os.getcwd() os.chdir(prev_path) cfg = get_cfg() # Create worklist if necessary. Should never be necessary. if not 'worklist' in cfg: cfg['worklist'] = [] # Add worklist entry cfg['worklist'].append(string) set_cfg(cfg) if prev_path: os.chdir(next_path)
def scaffold_config(): cfg = get_cfg() cfg['current_scaffold'] = {} model = { "title": 'UserProfile', "fields": [ { "title": "name", "type": "CharField", "options": [ "max_length = 255", "unique = True" ], "string": "name = models.CharField(max_length=255, unique=True)\n " }, { "title": "email", "type": "EmailField", "options": [ "max_length = 255", "unique = True" ], "string": "email = models.EmailField(max_length=255, unique=True)\n " } ] } cfg['current_scaffold']['model'] = model cfg['current_scaffold']['need_owner'] = 'True' set_cfg(cfg) print(' ') print(' ') print(paint(return_model(), 'green')) print(' ') print(' ') if boolean_input('Add some fields to the user model?'): get_model_field() user_permission() # Push current_scaffold to models cfg = get_cfg() cfg['models'].append(cfg['current_scaffold']['model']) set_cfg(cfg)
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 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 get_model_field(): cfg = get_cfg() field_title = string_input('Name this field') field_type = options_input('Which fieldtype would you like to use? ', types) # Get correct option, regardless of caps field_type = types[lower_types.index(field_type.lower())] field_object = { 'title': field_title, 'type': field_type, 'options': [], } if field_type in ['CharField', 'CommaSeparatedIntegerField', 'EmailField']: ml = str(string_input('max_length', '255')) field_object['options'].append('max_length = ' + ml) # Datefield specific arguments if field_type in ['DateField', 'DateTimeField', 'TimeField']: # auto_now_add and auto_now cannot be used together. auto_now_add = str(boolean_input('Use DateField auto_now_add? ')) if auto_now_add != 'True': auto_now = str(boolean_input('Use DateField auto_now? ')) # Set the option if auto_now_add == 'True': field_object['options'].append('auto_now_add = True') elif auto_now == 'True': field_object['options'].append('auto_now = True') # Decimalfield specific arguments if field_type == 'DecimalField': decimal_places = string_input('decimal_places') max_digits = string_input('max_digits') field_object['options'].append('decimal_places = ' + decimal_places) field_object['options'].append('max_digits = ' + max_digits) # Filefield specific arguments if field_type == 'FileField': upload_to = string_input('upload_to', None) if upload_to != None: field_object['options'].append('upload_to = ' + quote(upload_to)) storage = string_input('storage', None) if storage != None: field_object['options'].append('storage = ' + quote(storage)) max_length = string_input('max_length', None) if max_length != None: field_object['options'].append('max_length = ' + max_length) # FilePathField specific arguments if field_type in ['FilePathField']: path = string_input('path = ') field_object['options'].append('path = ' + quote(path)) match = string_input("match. For example r'$^'", None) if match != None: field_object['options'].append('match = ' + match) max_length = string_input('max_length', None) if max_length != None: field_object['options'].append('max_length = ' + max_length) recursive = str(boolean_input('recursive', 'n')) field_object['options'].append('recursive = ' + recursive) allow_files = str(boolean_input('allow_files', 'y')) field_object['options'].append('allow_files = ' + allow_files) allow_folders = str(boolean_input('allow_folders', 'n')) field_object['options'].append('allow_folders = ' + allow_folders) if field_type == 'ImageField': height_field = string_input('height_field', None) if height_field != None: field_object['options'].append('height_field = ' + height_field) width_field = string_input('width_field', None) if width_field != None: field_object['options'].append('width_field = ' + width_field) if field_type == 'SlugField': max_length = string_input('max_length', '50') field_object['options'].append('max_length = ' + max_length) if field_type == 'URLField': max_length = string_input('max_length', '200') field_object['options'].append('max_length = ' + max_length) foreign = False if field_type in ['ForeignKey', 'OneToOneField', 'ManyToManyField']: models = [model['title'] for model in cfg['models']] models.append('self') other_model = options_input('Choose a foreign model', models) field_object['options'].append(quote(other_model)) if boolean_input('Add a related_name option?', 'n'): related_name = string_input( 'related_name =', cfg['current_scaffold']['model']['title'].lower() ) field_object['options'].append('related_name = ' + quote(related_name)) if field_type in ['ForeignKey', 'OneToOneField']: choices = [ 'CASCADE', 'PROTECT', 'SET_NULL', 'SET_DEFAULT','SET()','DO_NOTHING' ] on_delete = options_input('on_delete ', choices, 'CASCADE') field_object['options'].append('on_delete = models.' + on_delete) # If we missed anything, let the user add it now. def more_options(): if boolean_input( 'Add another option to' + field_object['title'] + '?', 'n'): new_option = string_input("enter it now. (e.g. foo='bar')") field_object['options'].append(new_option) more_options() # Build the string ftitle = field_object['title'] ftype = field_object['type'] foptions = '' for i, o in enumerate(field_object['options']): if i > 0: foptions += f', {o}' else: foptions = o cfg['current_scaffold']['model']['fields'].append({ 'title': ftitle, 'type': ftype, 'options': field_object['options'], 'string': f'{ftitle} = models.{ftype}({foptions})\n ' }) set_cfg(cfg) print('========================') print('Your model so far:') print(' ') print(paint(return_model(), 'green')) print('========================') another_field = boolean_input('Make another field? ') if another_field: get_model_field() # All done making fields. # Add the __str__ method else : user = cfg['current_scaffold']['model']['title'] == 'UserProfile' if not user: current_fields = cfg['current_scaffold']['model']['fields'] titles = [field['title'] for field in current_fields] default_title = titles[0] if cfg['current_scaffold']['need_owner'] == 'True': default_title = titles[1] str_field = options_input( 'Which field should be used for the __str__ method?', titles, default_title ) cfg['current_scaffold']['model']['__str__'] = str_field set_cfg(cfg)