Get most of the config file generator up and running

This commit is contained in:
Raoul Snyman 2021-06-15 00:21:50 -07:00
parent 2e853e4c5c
commit 51cf5e5e50
No known key found for this signature in database
GPG Key ID: 423F9B322D9BEF2C
5 changed files with 64 additions and 66 deletions

View File

@ -29,7 +29,7 @@ from flask_mail import Mail
from flask_themes2 import Themes, packaged_themes_loader, theme_paths_loader, load_themes_from from flask_themes2 import Themes, packaged_themes_loader, theme_paths_loader, load_themes_from
from flask_user import UserManager from flask_user import UserManager
from scribeengine.admin import admin # from scribeengine.admin import admin
from scribeengine.config import read_config_from_file from scribeengine.config import read_config_from_file
from scribeengine.db import db from scribeengine.db import db
from scribeengine.models import User from scribeengine.models import User

View File

@ -63,3 +63,7 @@ def read_config_from_file(filename):
# Save this into our flask config dictionary # Save this into our flask config dictionary
flask_config[key] = value flask_config[key] = value
return flask_config return flask_config
if __name__ == '__main__':
run_cmd()

View File

@ -0,0 +1,3 @@
from scribeengine.config.cmd import run_cmd
run_cmd()

View File

@ -25,9 +25,10 @@ The :mod:`~scribeengine.config` module contains helper classes for config handli
from argparse import ArgumentParser from argparse import ArgumentParser
from configparser import ConfigParser from configparser import ConfigParser
from random import SystemRandom from random import SystemRandom
from string import ascii_letters, digits, punctuation from string import ascii_letters, digits # , punctuation
ALLOWED_CHARS = ascii_letters + digits + punctuation # ALLOWED_CHARS = ascii_letters + digits + punctuation
ALLOWED_CHARS = ascii_letters + digits
def _generate_secret(length=32): def _generate_secret(length=32):
@ -65,7 +66,7 @@ def write_config_file(config, filename):
if not parser.has_section(section): if not parser.has_section(section):
parser.add_section(section) parser.add_section(section)
for option, value in options.items(): for option, value in options.items():
parser.set(section, option, value) parser.set(section, option, str(value))
with open(filename, "w") as config_file: with open(filename, "w") as config_file:
parser.write(config_file) parser.write(config_file)
@ -86,7 +87,7 @@ def prompt(question, options=None, default=None, type_=str):
return answer return answer
def build_db_url(db_type=None, db_name=None, db_user=None, db_password=None, db_host=None, db_port=None): def build_db_url(args):
""" """
Build an SQLAlchemy connection string using the values given, using defaults for omitted values Build an SQLAlchemy connection string using the values given, using defaults for omitted values
@ -96,37 +97,34 @@ def build_db_url(db_type=None, db_name=None, db_user=None, db_password=None, db_
:param db_password: The password used to authenticate the user :param db_password: The password used to authenticate the user
:param db_host: The hostname or IP address of the database server :param db_host: The hostname or IP address of the database server
:param db_port: The port of the database server :param db_port: The port of the database server
;
:return: An SQLAlchemy connection string :return: An SQLAlchemy connection string
""" """
if not db_type: if not args.get('db_type'):
db_type = 'sqlite' args['db_type'] = 'sqlite'
if not db_name: if not args.get('db_name'):
if db_type == 'sqlite': if args['db_type'] == 'sqlite':
return 'sqlite:///scribeengine.sqlite' args['db_name'] = 'scribeengine.sqlite'
db_name = 'scribeengine' args['db_name'] = 'scribeengine'
if not db_user: if not args.get('db_user'):
db_user = 'scribeegine' args['db_user'] = 'scribeegine'
if not db_password: if not args.get('db_password'):
db_password = _generate_secret(40) args['db_password'] = _generate_secret(40)
if not db_host: if not args.get('db_host'):
db_host = 'localhost' args['db_host'] = 'localhost'
if not db_port: if not args.get('db_port'):
if db_type == 'mysql': if args['db_type'] == 'mysql':
db_port = 3306 args['db_port'] = 3306
elif db_type == 'postgres': elif args['db_type'] == 'postgres':
db_port = 5432 args['db_port'] = 5432
else: else:
db_port = 0 args['db_port'] = 0
return '{db_type}://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}'.format(db_type=db_type, if args['db_type'] == 'sqlite':
db_user=db_user, return '{db_type}:///{db_name}'.format(**args)
db_password=db_password, return '{db_type}://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}'.format(**args)
db_host=db_host,
db_port=db_port,
db_name=db_name)
def ask_db_questions(db_type=None, db_name=None, db_user=None, db_password=None, db_host=None, db_port=None): def ask_db_questions(args):
""" """
Ask questions about the database in order to build a SQLAlchemy connection string Ask questions about the database in order to build a SQLAlchemy connection string
@ -139,44 +137,37 @@ def ask_db_questions(db_type=None, db_name=None, db_user=None, db_password=None,
:return: An SQLAlchemy connection string :return: An SQLAlchemy connection string
""" """
if not db_type: if not args.get('db_type'):
db_type = prompt('Database type', ['sqlite', 'mysql', 'postgres'], 'sqlite').lower() args['db_type'] = prompt('Database type', ['sqlite', 'mysql', 'postgres'], 'sqlite').lower()
if not db_name: if not args.get('db_name'):
if db_type == 'sqlite': if args.get('db_type') == 'sqlite':
db_name = prompt('Database filename', default='scribeengine.sqlite') args['db_name'] = prompt('Database filename', default='scribeengine.sqlite')
return '{db_type}:///{db_name}'.format(db_type=db_type, db_name=db_name) args['db_name'] = prompt('Database name', default='scribeengine')
db_name = prompt('Database name', default='scribeengine') if not args.get('db_user'):
if not db_user: args['db_user'] = prompt('Database user', default='scribeengine')
db_user = prompt('Database user', default='scribeengine') if not args.get('db_password'):
if not db_password: args['db_password'] = prompt('Database password', default=_generate_secret(40))
db_password = prompt('Database password', default=_generate_secret(40)) if not args.get('db_host'):
if not db_host: args['db_host'] = prompt('Database host', default='localhost')
db_host = prompt('Database host', default='localhost') if not args.get('db_port'):
if not db_port: if args.get('db_type') in ['mysql', 'mariadb']:
if db_type in ['mysql', 'mariadb']: args['db_port'] = prompt('Database port', default=3306, type_=int)
db_port = prompt('Database port', default=3306, type_=int) elif args.get('db_type') == 'postgres':
elif db_type == 'postgres': args['db_port'] = prompt('Database port', default=5432, type_=int)
db_port = prompt('Database port', default=5432, type_=int)
else: else:
db_port = prompt('Database port', default=0, type_=int) args['db_port'] = prompt('Database port', default=0, type_=int)
return '{db_type}://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}'.format(db_type=db_type, return args
db_user=db_user,
db_password=db_password,
db_host=db_host,
db_port=db_port,
db_name=db_name)
def run_cmd(): def run_cmd():
""" """
Ask the user a set of questions, and then write them to a config file. Ask the user a set of questions, and then write them to a config file.
""" """
args = parse_args() args = vars(parse_args())
if args.non_interactive: if not args.pop('non_interactive', False):
db_url = build_db_url(args.db_type, args.db_name, args.db_user, args.db_password, args.db_host, args.db_port) ask_db_questions(args)
else: config_file = args.pop('config') or 'config.ini'
db_url = ask_db_questions(args.db_type, args.db_name, args.db_user, args.db_password, args.db_host, db_url = build_db_url(args)
args.db_port)
config = { config = {
'flask': { 'flask': {
'secret_key': _generate_secret() 'secret_key': _generate_secret()
@ -189,8 +180,8 @@ def run_cmd():
}, },
'paths': { 'paths': {
'theme_path', 'theme_path': '',
'uploads_path' 'uploads_path': ''
} }
} }
write_config_file(config, args.config or 'config.ini') write_config_file(config, config_file)

View File

@ -24,7 +24,7 @@ The :mod:`~scribeengine.helpers` module contains some theme helper methods
""" """
from flask import current_app from flask import current_app
from flask_themes2 import get_theme, render_theme_template, template_exists as ft2_template_exists from flask_themes2 import get_theme, render_theme_template, template_exists as ft2_template_exists
from jinja2.loaders import TemplateNotFound, contextfunction from jinja2 import TemplateNotFound, contextfunction
from scribeengine.models import Menu, Site, Variable from scribeengine.models import Menu, Site, Variable