diff --git a/.gitignore b/.gitignore index 061f5d5f2ee..a66d1024b6d 100644 --- a/.gitignore +++ b/.gitignore @@ -158,3 +158,5 @@ batchhedy/output_* #generated grammars grammars-Total/*.lark *.tsbuildinfo +!/coursedata/adventures-transformed/ +!/coursedata/level-defaults-transformed/ diff --git a/coursedata/yaml_transformer.py b/coursedata/yaml_transformer.py new file mode 100644 index 00000000000..4541461b50b --- /dev/null +++ b/coursedata/yaml_transformer.py @@ -0,0 +1,58 @@ +import os +import copy +import utils + +def transform_level_defaults(transformations): + input_path = '../coursedata/level-defaults' + output_path = '../coursedata/level-defaults-transformed/' + yaml_filesnames = [f for f in os.listdir(input_path) if + os.path.isfile(os.path.join(input_path, f)) and f.endswith('.yaml')] + for yaml_filesname_without_path in yaml_filesnames: + + yaml_filesname_with_path = os.path.join(input_path, yaml_filesname_without_path) + + yaml_dict = utils.load_yaml_rt(yaml_filesname_with_path) + transformed_dict = copy.deepcopy(yaml_dict) + for level in yaml_dict: + for old_level, new_level in transformations: + if level == old_level: + transformed_dict[new_level] = transformed_dict[old_level] + del transformed_dict[old_level] + + with open(output_path + yaml_filesname_without_path, 'w') as f: + f.write(utils.dump_yaml_rt(transformed_dict)) + +def transform_adventures(transformations): + input_path = '../coursedata/adventures' + output_path = '../coursedata/adventures-transformed/' + yaml_filesnames = [f for f in os.listdir(input_path) if + os.path.isfile(os.path.join(input_path, f)) and f.endswith('.yaml')] + + for yaml_filesname_without_path in yaml_filesnames: + yaml_filesname_with_path = os.path.join(input_path, yaml_filesname_without_path) + + yaml_dict = utils.load_yaml_rt(yaml_filesname_with_path) + transformed_dict = copy.deepcopy(yaml_dict) + + for akey, adventure in yaml_dict['adventures'].items(): + for level in adventure['levels']: + for old_level, new_level in transformations: + if level == old_level: + transformed_dict['adventures'][akey]['levels'][new_level] = transformed_dict['adventures'][akey]['levels'][old_level] + del transformed_dict['adventures'][akey]['levels'][old_level] + + with open(output_path + yaml_filesname_without_path, 'w') as f: + f.write(utils.dump_yaml_rt(transformed_dict)) + +def transform_levels_in_all_YAMLs(transformations): + # Set the current directory to the root Hedy folder + os.chdir(os.path.join(os.getcwd(), __file__.replace(os.path.basename(__file__), ''))) + # transform_level_defaults(transformations) + transform_adventures(transformations) + + + + + +tranformations = [(5, 17)] +transform_levels_in_all_YAMLs(tranformations) \ No newline at end of file diff --git a/utils.py b/utils.py index 605cf30a560..0b245b2e1ba 100644 --- a/utils.py +++ b/utils.py @@ -10,8 +10,8 @@ from ruamel import yaml from website import querylog import commonmark -commonmark_parser = commonmark.Parser () -commonmark_renderer = commonmark.HtmlRenderer () +commonmark_parser = commonmark.Parser() +commonmark_renderer = commonmark.HtmlRenderer() from bs4 import BeautifulSoup from flask_helpers import render_template @@ -40,11 +40,11 @@ def wrapper(*args, **kwargs): -def timems (): - return int (round (time.time () * 1000)) +def timems(): + return int(round(time.time() * 1000)) -def times (): - return int (round (time.time ())) +def times(): + return int(round(time.time())) @@ -79,7 +79,7 @@ def dump_yaml_rt(data): return yaml.round_trip_dump(data, indent=4, width=999) def slash_join(*args): - ret = [] + ret =[] for arg in args: if not arg: continue @@ -89,10 +89,10 @@ def slash_join(*args): return ''.join(ret) def is_testing_request(request): - return bool ('X-Testing' in request.headers and request.headers ['X-Testing']) + return bool('X-Testing' in request.headers and request.headers['X-Testing']) -def extract_bcrypt_rounds (hash): - return int (re.match ('\$2b\$\d+', hash) [0].replace ('$2b$', '')) +def extract_bcrypt_rounds(hash): + return int(re.match(r'\$2b\$\d+', hash)[0].replace('$2b$', '')) def isoformat(timestamp): """Turn a timestamp into an ISO formatted string.""" @@ -132,10 +132,10 @@ def version(): the_date = datetime.date.fromisoformat(vrz[:10]) if vrz else datetime.date.today() commit = os.getenv('HEROKU_SLUG_COMMIT', '????')[0:6] - return the_date.strftime('%b %d') + f' ({commit})' + return the_date.strftime('%b %d') + f'({commit})' def valid_email(s): - return bool (re.match ('^(([a-zA-Z0-9_+\.\-]+)@([\da-zA-Z\.\-]+)\.([a-zA-Z\.]{2,6})\s*)$', s)) + return bool(re.match(r'^(([a-zA-Z0-9_+\.\-]+)@([\da-zA-Z\.\-]+)\.([a-zA-Z\.]{2,6})\s*)$', s)) @contextlib.contextmanager @@ -150,7 +150,7 @@ def atomic_write_file(filename, mode='wb'): THIS WON'T WORK ON WINDOWS -- atomic file renames don't overwrite on Windows. We could potentially do something else to make it work - (just swallow the exception, someone else already wrote the file?) + (just swallow the exception, someone else already wrote the file?) but for now we just don't support it. """ if IS_WINDOWS: @@ -166,25 +166,27 @@ def atomic_write_file(filename, mode='wb'): # It operates by converting the date to a string, removing its last 3 digits, converting it back to an int # and then invoking the `isoformat` date function on it def mstoisostring(date): - return datetime.datetime.fromtimestamp (int (str (date) [:-3])).isoformat () + return datetime.datetime.fromtimestamp(int(str(date)[:-3])).isoformat() # https://stackoverflow.com/a/2257449 def random_id_generator(size=6, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits): - return ''.join (random.choice (chars) for _ in range (size)) + return ''.join(random.choice(chars) for _ in range(size)) # This function takes a markdown string and returns a list with each of the HTML elements obtained # by rendering the markdown into HTML. -def markdown_to_html_tags (markdown): - _html = commonmark_renderer.render(commonmark_parser.parse (markdown)) +def markdown_to_html_tags(markdown): + _html = commonmark_renderer.render(commonmark_parser.parse(markdown)) soup = BeautifulSoup(_html, 'html.parser') - return soup.find_all () + return soup.find_all() -def page_404 (translations, menu, lang, username, *page_error): +def page_404(translations, menu, lang, username, *page_error): if page_error: - page_error = page_error [0] + page_error = page_error[0] return render_template("404.html", menu=menu, username=username, auth=translations.get_translations(lang, 'Auth'), ui=translations.get_translations(lang, 'ui'), page_error=page_error or ''), 404 -def page_500 (translations, menu, lang, username, *page_error): +def page_500(translations, menu, lang, username, *page_error): if page_error: - page_error = page_error [0] + page_error = page_error[0] return render_template("500.html", menu=menu, username=username, auth=translations.get_translations(lang, 'Auth'), ui=translations.get_translations(lang, 'ui'), page_error=page_error or ''), 500 + +