diff --git a/app.py b/app.py index c02042a97bb..6e25f24e248 100644 --- a/app.py +++ b/app.py @@ -2648,10 +2648,20 @@ def split_at(n, xs): if __name__ == '__main__': + is_offline = getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS') + + if is_offline: + # We are running in a standalone build made using pyinstaller. + # cd to the directory that has the data files, disable debug mode, and + # use port 80 (unless overridden) + os.chdir(sys._MEIPASS) + config['port'] = int(os.environ.get('PORT', 80)) + # Start the server on a developer machine. Flask is initialized in DEBUG mode, so it # hot-reloads files. We also flip our own internal "debug mode" flag to True, so our # own file loading routines also hot-reload. - utils.set_debug_mode(not os.getenv('NO_DEBUG_MODE')) + no_debug_mode_requested = os.getenv('NO_DEBUG_MODE') + utils.set_debug_mode(not no_debug_mode_requested) # Set some default environment variables for development mode env_defaults = dict( @@ -2662,12 +2672,9 @@ def split_at(n, xs): if key not in os.environ: os.environ[key] = value - if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): - # We are running via PyInstaller. Cd to the directory that has the data files. - os.chdir(sys._MEIPASS) - - # For local debugging, fetch all static files on every request - app.config['SEND_FILE_MAX_AGE_DEFAULT'] = None + if not is_offline: + # For local debugging, fetch all static files on every request + app.config['SEND_FILE_MAX_AGE_DEFAULT'] = None # If we are running in a Python debugger, don't use flasks reload mode. It creates # subprocesses which make debugging harder. @@ -2682,9 +2689,12 @@ def split_at(n, xs): start_snapshot = tracemalloc.take_snapshot() on_server_start() - logger.debug('app starting in debug mode') + debug = not (is_in_debugger or profile_memory or is_offline) + if debug: + logger.debug('app starting in debug mode') + # Threaded option enables multiple instances for multiple user access support - app.run(threaded=True, debug=not is_in_debugger and not profile_memory, + app.run(threaded=True, debug=debug, port=config['port'], host="0.0.0.0") # See `Procfile` for how the server is started on Heroku. diff --git a/dodo.py b/dodo.py index 244ca05b4f9..fac49c560fd 100644 --- a/dodo.py +++ b/dodo.py @@ -386,7 +386,7 @@ def task__offline(): 'cp data-for-testing.json dist/offlinehedy/_internal/dev_database.json', # There are some research papers in the distribution that take up a lot # of space. - 'rm -rf dist/offlinehedy/_internal/content/research', + 'rm -rf dist/offlinehedy/_internal/content/research/*', ], ) diff --git a/hedy_content.py b/hedy_content.py index 8e5085c345d..e8be890688e 100644 --- a/hedy_content.py +++ b/hedy_content.py @@ -1,5 +1,6 @@ import logging import os +from os import path import static_babel_content @@ -392,9 +393,11 @@ ] } +content_dir = path.join(path.dirname(__file__), 'content') +translations_dir = path.join(path.dirname(__file__), 'translations') RESEARCH = {} -for paper in sorted(os.listdir('content/research'), +for paper in sorted(os.listdir(f'{content_dir}/research'), key=lambda x: int(x.split("_")[-1][:-4]), reverse=True): # An_approach_to_describing_the_semantics_of_Hedy_2022.pdf -> 2022, An @@ -403,16 +406,18 @@ name = name[-4:] + ". " + name[:-5] RESEARCH[name] = paper + + # load all available languages in dict # list_translations of babel does about the same, but without territories. languages = {} -if not os.path.isdir('translations'): +if not os.path.isdir(translations_dir): # should not be possible, but if it's moved someday, EN would still be working. ALL_LANGUAGES['en'] = 'English' ALL_KEYWORD_LANGUAGES['en'] = 'EN' -for folder in os.listdir('translations'): - locale_dir = os.path.join('translations', folder, 'LC_MESSAGES') +for folder in os.listdir(translations_dir): + locale_dir = os.path.join(translations_dir, folder, 'LC_MESSAGES') if not os.path.isdir(locale_dir): continue if filter(lambda x: x.endswith('.mo'), os.listdir(locale_dir)): diff --git a/utils.py b/utils.py index d77ed3e81a0..b21c88a9a0f 100644 --- a/utils.py +++ b/utils.py @@ -6,6 +6,7 @@ import time import functools import os +from os import path import re import string import random @@ -23,21 +24,23 @@ IS_WINDOWS = os.name == 'nt' +prefixes_dir = path.join(path.dirname(__file__), 'prefixes') + # Define code that will be used if some turtle command is present -with open('prefixes/turtle.py', encoding='utf-8') as f: +with open(f'{prefixes_dir}/turtle.py', encoding='utf-8') as f: TURTLE_PREFIX_CODE = f.read() # Preamble that will be used for non-Turtle programs # numerals list generated from: https://replit.com/@mevrHermans/multilangnumerals -with open('prefixes/normal.py', encoding='utf-8') as f: +with open(f'{prefixes_dir}/normal.py', encoding='utf-8') as f: NORMAL_PREFIX_CODE = f.read() # Define code that will be used if a pressed command is used -with open('prefixes/pygame.py', encoding='utf-8') as f: +with open(f'{prefixes_dir}/pygame.py', encoding='utf-8') as f: PYGAME_PREFIX_CODE = f.read() # Define code that will be used if music code is used -with open('prefixes/music.py', encoding='utf-8') as f: +with open(f'{prefixes_dir}/music.py', encoding='utf-8') as f: MUSIC_PREFIX_CODE = f.read()