コード例 #1
0
ファイル: serve_run.py プロジェクト: Buscedv/Ask
def run_server():
    app: ModuleType = import_app()

    # Starts the server or runs the main function if the app isn't using routes, meaning it's just a script.
    try:
        if not cfg.is_repl and not cfg.is_module_transpile:
            printing.style_print('Running the app...',
                                 styles=['bold'],
                                 end=' ')
            print('(Press Ctrl+C to stop)')

        if not cfg.uses_routes:
            # The app is just a script. Ask is used like a general purpose language.
            app.main()

        # The app uses routes, so it's an API, the app needs to run in a web server.
        elif askfile.get(['server', 'production'],
                         True) is True and cfg.is_dev is False:
            # Run in the production server.
            print('\033[91m\t- ', end='')
            waitress.serve(
                TransLogger(
                    app.app,
                    logger_name='Ask Application',
                    format=' '.join([
                        f'\033[37m\t- {datetime.datetime.now().strftime("[%d/%b/%Y %H:%M:%S]")}\033[0m',
                        '\033[1m%(REQUEST_METHOD)s\033[0m '
                        '"\033[32m%(REMOTE_ADDR)s%(REQUEST_URI)s\033[0m"',
                        '→',
                        '\033[94m%(status)s\033[0m',
                    ])),
                host=askfile.get(['server', 'host'], '127.0.0.1'),
                port=askfile.get(['server', 'port'], '5000'),
                ident='Ask Application',
            )
        else:
            # Run in the development server.
            os.environ['FLASK_APP'] = files.output_file_path()
            if cfg.is_dev:
                os.environ['FLASK_ENV'] = 'development'

            app.app.run()
    except Exception as e:  # Exception is used here to capture all exception types.
        errors.error_while_running(e, cfg.transpilation_result['source_lines'],
                                   cfg.transpilation_result['time_result'])

        if cfg.is_repl:
            # Tries to remove the line the error was on.
            if len(cfg.repl_previous_transpiled.split('\n')) > 2:
                cfg.repl_previous_transpiled = '\n'.join(
                    cfg.repl_previous_transpiled.split('\n')[:-2])
            return

        exit(1)
コード例 #2
0
def main():
    cfg.set_defaults()

    if len(sys.argv) > 1:
        param_file_name, no_valid_flags = parse_sys_args(sys.argv)
        cfg.source_file_name = param_file_name

        # Load the config if it hasn't been set.
        # This will only be false when running in module transpile mode.
        if not cfg.ask_config:
            askfile.load()

        if not param_file_name and True in [
                x in sys.argv for x in ['-d', '--dev', '-xd', '--extra-dev']
        ]:
            repl(True)

        if not cfg.is_module_transpile:
            printing.initial_print()

        if os.path.isfile(f'{os.getcwd()}/{cfg.source_file_name}'):
            transpiler.transpile_from_file()

            if askfile.get(['system', 'server'], True):
                # Starts server
                serve_run.run_server()
            elif not cfg.is_module_transpile:
                printing.style_print('\nAuto start server is turned OFF.',
                                     styles=['bold'])
                print('\t - The transpiled code can be found in:', end=' ')
                printing.style_print(askfile.get(['system', 'output_path'],
                                                 'app.py'),
                                     color='blue',
                                     end='')
                print('.')
        else:
            if no_valid_flags:
                if param_file_name[0] == '-':
                    style_print(f'- Invalid flag "{param_file_name}".',
                                color='yellow')
                    exit(1)

                printing.style_print('- The file could not be found!',
                                     color='red')
                exit(1)

        # Deletes the output file if configured to.
        files.maybe_delete_app()
    else:
        repl(True)
コード例 #3
0
def db_path_with_prefix() -> str:
	prefix = 'sqlite:///'

	if askfile.get(['db', 'custom'], False):
		prefix = ''

	return f'{prefix}{get_db_file_path()}'
コード例 #4
0
def maybe_delete_app(force: bool = False):
	if not askfile.get(['system', 'keep_app'], True) or force:
		try:
			os.remove(output_file_path())

			for module in cfg.imported_ask_modules_to_delete:
				os.remove(f'{get_root_from_file_path(output_file_path())}/{module}.py')
		except FileNotFoundError:
			return
コード例 #5
0
def generic_construct_output_file_path(file_name_or_path):
	prefix = f'{os.getcwd()}/'

	if askfile.get(['db', 'custom'], False):
		prefix = ''

	if '/' in cfg.source_file_name:
		prefix += f'{get_root_from_file_path(cfg.source_file_name)}/'

	if file_name_or_path[0] == '/':
		file_name_or_path = file_name_or_path[1:]

	return prefix + file_name_or_path
コード例 #6
0
ファイル: transpiler.py プロジェクト: Buscedv/Ask
def build_db(file_name: str):
    if not cfg.is_include_transpile:
        printing.style_print('Database:', styles=['bold'])

    if not askfile.get(['db', 'custom'], False) and not os.path.exists(
            files.get_db_file_path()):
        if not cfg.is_include_transpile:
            print('\t- Building database...', end='')
        db_root = files.get_root_from_file_path(files.get_db_file_path())
        if not cfg.is_include_transpile:
            print('\t✅')

        if db_root and db_root != file_name and not os.path.exists(db_root):
            if not cfg.is_include_transpile:
                print('\t- Building Folder Structure...', end='')
            os.makedirs(db_root)
            if not cfg.is_include_transpile:
                print('\t✅')
コード例 #7
0
def generic_transpile_symbol(word: str, words: dict, default: str = None) -> str:
	if askfile.get(['rules', 'underscores'], True):
		words = translator_utils.add_underscores_to_dict_keys(words)

	return defaultdict(lambda: default if default is not None else word, words)[word]
コード例 #8
0
def lex(raw: List[str]) -> List[List[str]]:
    tmp = ''
    is_collector = False
    is_str = False
    might_be_special_str = False
    collector_ends = []
    include_collector_end = False
    is_dict = []

    tokens = []

    for line in raw:
        line = lexer_utils.reformat_line(line)
        for char_index, char in enumerate(line):
            # Ignores comments
            if char == '#':
                break

            if is_str:
                if char not in collector_ends:
                    tmp += char
                if char in collector_ends:
                    tmp += char

                    tokens.append(['STR', tmp])

                    is_str = False
                    collector_ends = []
                    tmp = ''

                continue

            # Detects raw & f-strings.
            if char in ['r', 'f']:
                might_be_special_str = char

            if is_collector:
                if char not in collector_ends:
                    tmp += char
                else:
                    tokens[-1][1] = tmp

                    if include_collector_end:
                        tokens.append([
                            'OP' if char not in ['\n', '\t'] else 'FORMAT',
                            char
                        ])

                    is_collector = False
                    include_collector_end = False
                    tmp = ''

            # Function call.
            elif char == '(':
                if tmp:
                    tokens.append(['FUNC', tmp.replace(' ', '')])
                    tmp = ''

            # Variable assignment.
            elif char == '=':
                if tmp:
                    tokens.append(['WORD', tmp])
                    tokens.append(['OP', char])

                    if tmp not in cfg.variables:
                        cfg.variables.append(tmp)

                    tmp = ''
                else:
                    tokens.append(['OP', char])

            # String.
            elif char in ['"', '\'']:
                is_str = True
                collector_ends = [char]

                tmp = ''
                if might_be_special_str == 'r':
                    tmp = r''
                elif might_be_special_str == 'f':
                    tmp = f''
                tmp += char

                might_be_special_str = ''

            # Dict open.
            elif char == '{':
                is_dict.append(True)
                tokens.append(['OP', char])

            # Dict close.
            elif char == '}':
                tokens, tmp, is_collector, collector_ends, include_collector_end = lexer_utils.word_or_special(
                    tokens, tmp)

                is_dict.pop(0)
                tokens.append(['OP', char])

            # Number (on its own).
            elif char.isdigit() and not tmp:
                if tokens and tokens[-1][0] == 'NUM':
                    tokens[-1][1] += char
                    continue
                tokens.append(['NUM', char])

            # Decorator.
            elif char == '&':
                is_collector = True
                collector_ends = ['\n']
                include_collector_end = True
                tmp = ''
                tokens.append(['DEC', ''])

            # Operator (special character).
            elif char in cfg.operators:
                if char == ':' and is_dict and tmp:
                    tokens.append(['KEY', tmp])
                    tmp = ''

                tokens, tmp, is_collector, collector_ends, include_collector_end = lexer_utils.word_or_special(
                    tokens, tmp)
                tokens.append(['OP', char])

            # Formatting.
            elif char in ['\n', '\t']:
                tokens, tmp, is_collector, collector_ends, include_collector_end = lexer_utils.word_or_special(
                    tokens, tmp)
                tokens.append(['FORMAT', char])

            # Character isn't anything specific, meaning it's e.g. a letter. These get collected for later use.
            elif char not in ['\n', '\t', ' ']:
                tmp += char
            else:
                # There might be a word or keyword in tmp.
                tokens, tmp, is_collector, collector_ends, include_collector_end = lexer_utils.word_or_special(
                    tokens, tmp)

            if len(tokens) > 2 and transpiler_utils.token_check(
                    tokens[-2], 'WORD',
                    transpiler_utils.add_underscores_to_elems(['db'])
                    if askfile.get(['rules', 'underscores'], True) else 'db'):
                # Removes the WORD 'db'/'_db' and the OP '.'.
                tokens.pop(-1)
                tokens.pop(-1)
                is_collector = True
                collector_ends = ['(', ',', ')']
                include_collector_end = True
                tmp = ''
                tokens.append(['DB_ACTION', ''])
                cfg.uses_db = True

    return tokens
コード例 #9
0
def output_file_path() -> str:
	return generic_construct_output_file_path(askfile.get(['system', 'output_path'], 'app.py'))
コード例 #10
0
def get_db_file_path() -> str:
	return generic_construct_output_file_path(askfile.get(['db', 'path'], 'db.db'))
コード例 #11
0
ファイル: test_askfile.py プロジェクト: Buscedv/Ask
 def test_multiple_missing(self):
     cfg.ask_config = {}
     self.assertEqual(
         'missing', askfile.get(['missing_group', 'missing_key'],
                                'missing'))
コード例 #12
0
ファイル: test_askfile.py プロジェクト: Buscedv/Ask
 def test_multiple(self):
     cfg.ask_config = {'group': {'key': 'value'}}
     self.assertEqual('value', askfile.get(['group', 'key'], 'missing'))
コード例 #13
0
ファイル: test_askfile.py プロジェクト: Buscedv/Ask
 def test_single(self):
     cfg.ask_config = {'key': 'value'}
     self.assertEqual('value', askfile.get(['key'], 'missing'))