From c12fdcf810980799583ab09ee0746ee9a1f291c5 Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Wed, 27 Sep 2023 09:31:00 -0400 Subject: [PATCH 1/4] refactor: Move translations to the openedx Transifex project --- .tx/config | 6 + Makefile | 21 +- requirements/base.in | 3 +- requirements/base.txt | 2 + requirements/dev.txt | 2 + requirements/translations.in | 2 + requirements/translations.txt | 8 + scripts/translate.py | 14 +- scripts/utils.py | 143 ++++++----- .../apps/superset/conf/locale/en/locale.yaml | 241 ++++++++++++++++++ .../apps/superset/localization/locale.yaml | 88 ++++++- 11 files changed, 436 insertions(+), 94 deletions(-) create mode 100644 .tx/config create mode 100644 requirements/translations.in create mode 100644 requirements/translations.txt create mode 100644 tutoraspects/templates/aspects/apps/superset/conf/locale/en/locale.yaml diff --git a/.tx/config b/.tx/config new file mode 100644 index 000000000..7d41c9227 --- /dev/null +++ b/.tx/config @@ -0,0 +1,6 @@ +[main] +host = https://www.transifex.com + +[o:open-edx:p:edx-platform:r:tutor-contrib-aspects] +source_lang = en +type = KEYVALUEJSON diff --git a/Makefile b/Makefile index 9bac70c43..0983b2078 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ upgrade: $(COMMON_CONSTRAINTS_TXT) pip install -r requirements/pip-tools.txt $(UPGRADE) -o requirements/base.txt requirements/base.in $(UPGRADE) -o requirements/dev.txt requirements/dev.in + $(UPGRADE) -o requirements/translations.txt requirements/translations.in requirements: ## Install packages from base requirement files pip install -r requirements/pip.txt @@ -42,6 +43,10 @@ dev-requirements: ## Install packages from developer requirement files pip uninstall --yes $(PROJECT) pip install -e . +translation-requirements: ## Install packages from translation requirements + pip install -r requirements/pip.txt + pip install -r requirements/translations.txt + build-pythonpackage: ## Build Python packages ready to upload to pypi python setup.py sdist bdist_wheel @@ -78,17 +83,15 @@ release-push: git push origin $(TAG) ###### Additional commands -push_translations: - TUTOR_ROOT=$(TUTOR_ROOT) tutor config save - python scripts/translate.py $(TUTOR_ROOT) push +pull_translations: translation-requirements + rm -rf tutoraspects/templates/aspects/apps/superset/conf/locale/*; + atlas pull $(OPENEDX_ATLAS_ARGS) translations/tutor-contrib-aspects/tutoraspects/templates/aspects/apps/superset/conf/locale/:tutoraspects/templates/aspects/apps/superset/conf/locale/ -compile_translations: - TUTOR_ROOT=$(TUTOR_ROOT) tutor config save - python scripts/translate.py $(TUTOR_ROOT) compile + @echo "Translations have been pulled via Atlas." + python scripts/translate.py . compile -list_translations: - TUTOR_ROOT=$(TUTOR_ROOT) tutor config save - python scripts/translate.py $(TUTOR_ROOT) list +extract_translations: translation-requirements + python scripts/translate.py . extract version: ## Print the current tutor version @python -c 'import io, os; about = {}; exec(io.open(os.path.join("$(PACKAGE)", "__about__.py"), "rt", encoding="utf-8").read(), about); print(about["__version__"])' diff --git a/requirements/base.in b/requirements/base.in index a303579ac..40579b28b 100644 --- a/requirements/base.in +++ b/requirements/base.in @@ -1,4 +1,5 @@ click -tutor>=15 bcrypt +openedx-atlas transifex-python +tutor>=15 diff --git a/requirements/base.txt b/requirements/base.txt index 5d54d5288..b55f0d8c5 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -43,6 +43,8 @@ oauthlib==3.2.2 # via # kubernetes # requests-oauthlib +openedx-atlas==0.5.0 + # via -r requirements/base.in parsimonious==0.10.0 # via pyseeyou pyasn1==0.5.0 diff --git a/requirements/dev.txt b/requirements/dev.txt index e1c9cf2f3..34ccce5db 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -106,6 +106,8 @@ oauthlib==3.2.2 # -r requirements/base.txt # kubernetes # requests-oauthlib +openedx-atlas==0.5.0 + # via -r requirements/base.txt packaging==23.2 # via # black diff --git a/requirements/translations.in b/requirements/translations.in new file mode 100644 index 000000000..6952e02e0 --- /dev/null +++ b/requirements/translations.in @@ -0,0 +1,2 @@ +# Requirements needed to run in openedx-translations to manage localization +click diff --git a/requirements/translations.txt b/requirements/translations.txt new file mode 100644 index 000000000..3a8facebc --- /dev/null +++ b/requirements/translations.txt @@ -0,0 +1,8 @@ +# +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: +# +# make upgrade +# +click==8.1.7 + # via -r requirements/translations.in diff --git a/scripts/translate.py b/scripts/translate.py index 3092785aa..951e34218 100644 --- a/scripts/translate.py +++ b/scripts/translate.py @@ -2,15 +2,7 @@ import sys import click -from transifex.native import init -from utils import (LANGUAGES, compile_translations, get_text_for_translations, - push_translations) - -init( - os.getenv("TRANSIFEX_TOKEN"), - LANGUAGES, - os.getenv("TRANSIFEX_SECRET"), -) +from utils import compile_translations, extract_translations, get_text_for_translations @click.command() @@ -18,8 +10,8 @@ @click.argument("action") def command(root, action): """Interface for the translations.""" - if action == "push": - push_translations(root) + if action == "extract": + extract_translations(root) elif action == "compile": compile_translations(root) elif action == "list": diff --git a/scripts/utils.py b/scripts/utils.py index cbd8999f7..0ad860484 100644 --- a/scripts/utils.py +++ b/scripts/utils.py @@ -1,50 +1,46 @@ +import os import yaml -from transifex.native import tx -from transifex.native.parsing import SourceString ASSET_FOLDER_MAPPING = { "dashboard_title": "dashboards", "slice_name": "charts", - "database_name": "databases", - "table_name": "datasets", } -LANGUAGES = [ - "es", - "it", - "fr", - "zh", - "ja", - "de", - "pt", - "ru", - "ko", - "sk", - "sl", - "nl", -] - def get_text_for_translations(root_path): - assets_file = ( - root_path + "/env/plugins/aspects/apps/superset/pythonpath/assets.yaml" + assets_path = ( + os.path.join(root_path, "tutoraspects/templates/openedx-assets/assets/") ) + print(f"Assets path: {assets_path}") + strings = [] - file = yaml.load(open(assets_file, "r"), Loader=yaml.FullLoader) + for root, dirs, files in os.walk(assets_path): + for file in files: + if not file.endswith(".yaml"): + continue + path = os.path.join(root, file) + print(f"Reading {path}") + with open(path, 'r') as asset_file: + asset_str = asset_file.read().replace("{{", "'") + asset_str = asset_str.replace("}}", "'") - for asset in file: - strings.extend(mark_text_for_translation(asset)) + asset = yaml.safe_load(asset_str) + strings.extend(mark_text_for_translation(asset)) return strings def mark_text_for_translation(asset): - """For every asset extract the text and mark it for translation""" + """ + For every asset extract the text and mark it for translation + """ def extract_text(asset, type): - """Extract text from an asset""" + """ + Extract text from an asset + """ strings = [] if type == "dashboards": strings.append(asset["dashboard_title"]) @@ -73,64 +69,81 @@ def extract_text(asset, type): if asset["params"].get("y_axis_label"): strings.append(asset["params"]["y_axis_label"]) - elif type == "databases": - # WARNING: Databases are not translated - pass - elif type == "datasets": - # WARNING: Datasets are not translated - pass return strings for key, value in ASSET_FOLDER_MAPPING.items(): if key in asset: strings = extract_text(asset, value) print( - f"Extracting text from {value} {asset.get('uuid')}", - strings, + f"Extracted {len(strings)} strings from {value} {asset.get('uuid')}" ) return strings + # If we get here it's a type of asset that we don't translate, return nothing. + return [] -def compile_translations(root_path): - print("Fetching translations...") - tx.fetch_translations() - translation_file = ( - "tutoraspects/templates/aspects/apps/superset/localization/locale.yaml" +def compile_translations(root_path): + """ + Combine translated files into the single file we use for translation. + + This should be called after we pull translations using Atlas, see the + pull_translations make target. + """ + translations_path = ( + os.path.join( + root_path, + "tutoraspects/templates/aspects/apps/superset/conf/locale" + ) ) - file = open(translation_file, "w") - STRINGS = get_text_for_translations(root_path) - - translations = {} + all_translations = {} + for root, dirs, files in os.walk(translations_path): + for file in files: + if not file.endswith(".yaml"): + continue + + lang = root.split(os.sep)[-1] + path = os.path.join(root, file) + with open(path, 'r') as asset_file: + loc_str = asset_file.read() + all_translations[lang] = yaml.safe_load(loc_str)[lang] + + out_path = ( + os.path.join( + root_path, + "tutoraspects/templates/aspects/apps/superset/localization/locale.yaml" + ) + ) - print("Compiling translations...") + print(f"Writing all translations out to {out_path}") + with open(out_path, 'w') as outfile: + outfile.write("---\n") + yaml.safe_dump(all_translations, outfile) + outfile.write("\n{{ patch('superset-extra-asset-translations')}}\n") - for language in LANGUAGES: - print("Processing language", language) - translations[language] = {} - for string in STRINGS: - if not translations[language].get(string): - translation = tx.get_translation(string, language, None) - translations[language][string] = translation if translation else "" - file.write("---\n") - file.write(yaml.dump(translations)) - file.write("\n{{ patch('superset-extra-asset-translations')}}\n") +def extract_translations(root_path): + """ + This gathers all translatable text from the Superset assets. + An English locale file is created, which openedx-translations will send to + Transifex for translation. + """ + translation_file = ( + "tutoraspects/templates/aspects/apps/superset/conf/locale/en/locale.yaml" + ) -def push_translations(root_path): - print("Publishing translation strings...") + print("Gathering text for translations...") + STRINGS = set(get_text_for_translations(root_path)) + translations = {'en': {}} - STRINGS = get_text_for_translations(root_path) + for string in STRINGS: + translations['en'][string] = string - source_strings = [] - for text in STRINGS: - source_string = SourceString( - text, - ) - source_strings.append(source_string) + print(f"Writing English strings to {translation_file}") + with open(translation_file, "w") as file: + file.write(yaml.dump(translations)) - response_code, response_content = tx.push_source_strings(source_strings, purge=True) - print(response_code, response_content) + print("Done compiling translations.") diff --git a/tutoraspects/templates/aspects/apps/superset/conf/locale/en/locale.yaml b/tutoraspects/templates/aspects/apps/superset/conf/locale/en/locale.yaml new file mode 100644 index 000000000..14bfba3bf --- /dev/null +++ b/tutoraspects/templates/aspects/apps/superset/conf/locale/en/locale.yaml @@ -0,0 +1,241 @@ +en: + ? "# Instance information Aspects: ' ASPECTS_VERSION '\n{% if RUN_VECTOR %} - **Vector\ + \ Version**: ' DOCKER_IMAGE_VECTOR ' \n {% endif %} {% if RUN_CLICKHOUSE %} -\ + \ **Clickhouse Version**: ' DOCKER_IMAGE_CLICKHOUSE ' \n {% endif %} {% if RUN_RALPH\ + \ %} - **Ralph Version**: ' DOCKER_IMAGE_RALPH ' \n {% endif %} {% if RUN_SUPERSET\ + \ %} - **Superset Version**: ' DOCKER_IMAGE_SUPERSET ' \n {% endif %} \n\n## Dependencies:\ + \ {% for requirement in OPENEDX_EXTRA_PIP_REQUIREMENTS %} {% if 'openedx-event-sink-clickhouse'\ + \ in requirement %} - **Clickhouse Event Sink Version**: ' requirement.split('==')[1]\ + \ ' \n {% elif 'event-routing-backends' in requirement %} - **Event Routing Backends\ + \ Version**: ' requirement.split('==')[1] ' \n {% endif %} {% endfor %} " + : "# Instance information Aspects: ' ASPECTS_VERSION '\n{% if RUN_VECTOR %} - **Vector\ + \ Version**: ' DOCKER_IMAGE_VECTOR ' \n {% endif %} {% if RUN_CLICKHOUSE %} -\ + \ **Clickhouse Version**: ' DOCKER_IMAGE_CLICKHOUSE ' \n {% endif %} {% if RUN_RALPH\ + \ %} - **Ralph Version**: ' DOCKER_IMAGE_RALPH ' \n {% endif %} {% if RUN_SUPERSET\ + \ %} - **Superset Version**: ' DOCKER_IMAGE_SUPERSET ' \n {% endif %} \n\n## Dependencies:\ + \ {% for requirement in OPENEDX_EXTRA_PIP_REQUIREMENTS %} {% if 'openedx-event-sink-clickhouse'\ + \ in requirement %} - **Clickhouse Event Sink Version**: ' requirement.split('==')[1]\ + \ ' \n {% elif 'event-routing-backends' in requirement %} - **Event Routing Backends\ + \ Version**: ' requirement.split('==')[1] ' \n {% endif %} {% endfor %} " + ? '### Course Enrollment + + + + These charts can help you understand how many students are enrolled in your course + by showing how enrollments have changed over time and which enrollment modes students + are choosing. More details about each chart can be found by clicking the "3 dot" + menu at the top right of the chart and selecting "Show chart description". + + + You can filter these results by choosing selecting various options from the filters + on the left.' + : '### Course Enrollment + + + + These charts can help you understand how many students are enrolled in your course + by showing how enrollments have changed over time and which enrollment modes students + are choosing. More details about each chart can be found by clicking the "3 dot" + menu at the top right of the chart and selecting "Show chart description". + + + You can filter these results by choosing selecting various options from the filters + on the left.' + ? '### Problem Engagement + + + These charts can help you learn which problems your students have engaged with + or skipped, and the relative difficulty of problems across your course. More details + about each chart can be found by clicking the "3 dot" menu at the top right of + the chart and selecting "Show chart description". + + + **Select a course from the filters on the left to populate these charts.**' + : '### Problem Engagement + + + These charts can help you learn which problems your students have engaged with + or skipped, and the relative difficulty of problems across your course. More details + about each chart can be found by clicking the "3 dot" menu at the top right of + the chart and selecting "Show chart description". + + + **Select a course from the filters on the left to populate these charts.**' + ? '### Problem Performance + + + These charts help show the difficulty of your problems by showing you which answers + your students choose and which require many tries or hints to complete successfully. + + + **Select a problem from the filters on the left to populate the charts.**' + : '### Problem Performance + + + These charts help show the difficulty of your problems by showing you which answers + your students choose and which require many tries or hints to complete successfully. + + + **Select a problem from the filters on the left to populate the charts.**' + ? '### Video Engagement + + + These charts can help understand which videos are watched, and rewatched, most + often. It can also show how many users use the closed captions and transcript + features on your videos, and how often. + + + **Select a course from the filters on the left to populate these charts.**' + : '### Video Engagement + + + These charts can help understand which videos are watched, and rewatched, most + often. It can also show how many users use the closed captions and transcript + features on your videos, and how often. + + + **Select a course from the filters on the left to populate these charts.**' + ? '### Video Performance + + + This section allows you to see which parts of a particular video are most watched + or skipped. + + + **Select a video from the filters on the left to populate these charts.**' + : '### Video Performance + + + This section allows you to see which parts of a particular video are most watched + or skipped. + + + **Select a video from the filters on the left to populate these charts.**' + ? A count of the number of enrollments and un-enrollments per day. Learners can + enroll and unenroll multiple times, in this chart each individual enrollment and + unenrollment will be counted. + : A count of the number of enrollments and un-enrollments per day. Learners can + enroll and unenroll multiple times, in this chart each individual enrollment and + unenrollment will be counted. + Active Users Per Organization: Active Users Per Organization + Actor IDs over time: Actor IDs over time + Answers Chosen: Answers Chosen + ClickHouse: ClickHouse + Course Enrollment: Course Enrollment + Course Enrollments Over Time: Course Enrollments Over Time + Course Grade (out of 100%): Course Grade (out of 100%) + Course Grade Distribution: Course Grade Distribution + Courses: Courses + Courses Per Organization: Courses Per Organization + Currently Enrolled Learners Per Day: Currently Enrolled Learners Per Day + Distinct forum users: Distinct forum users + Distribution Of Attempts: Distribution Of Attempts + Distribution Of Hints Per Correct Answer: Distribution Of Hints Per Correct Answer + Distribution Of Problem Grades: Distribution Of Problem Grades + Distribution Of Responses: Distribution Of Responses + Enrollment Events Per Day: Enrollment Events Per Day + Enrollments: Enrollments + Enrollments By Enrollment Mode: Enrollments By Enrollment Mode + Enrollments By Type: Enrollments By Type + Event type: Event type + Events per course: Events per course + Forum Interaction: Forum Interaction + Hints / Answer Displayed Before Correct Answer Chosen: Hints / Answer Displayed + Before Correct Answer Chosen + Instance Health: Instance Health + Instructor Dashboard: Instructor Dashboard + Last Received Event: Last Received Event + Last course syncronized: Last course syncronized + Most Active Courses Per Day: Most Active Courses Per Day + Number Of Attempts To Find Correct Answer: Number Of Attempts To Find Correct Answer + Number Of Students: Number Of Students + Number Of Viewers / Views: Number Of Viewers / Views + Number of Users / Uses: Number of Users / Uses + Number of Views / Viewers: Number of Views / Viewers + Number of users: Number of users + Operator Dashboard: Operator Dashboard + Organizations: Organizations + Percentage Grade: Percentage Grade + Posts per user: Posts per user + Problem Engagement: Problem Engagement + Problem Performance: Problem Performance + Question Title: Question Title + Responses: Responses + Responses Per Problem: Responses Per Problem + Seconds Of Video: Seconds Of Video + Slowest ClickHouse Queries: Slowest ClickHouse Queries + Students: Students + ? The cumulative total of unique enrolled learners based on their enrollment state + at the end of each day. If a learner was enrolled previously, but has left the + course since, they are not counted as of the date they left. If they re-enroll + in the course they will be counted again. + : The cumulative total of unique enrolled learners based on their enrollment state + at the end of each day. If a learner was enrolled previously, but has left the + course since, they are not counted as of the date they left. If they re-enroll + in the course they will be counted again. + ? The current count of active enrollments by their most recent enrollment type, + so if a learner upgraded from Audit to Verified they will only be counted once + as Verified. Learners who have un-enrolled in the course are not counted. + : The current count of active enrollments by their most recent enrollment type, + so if a learner upgraded from Audit to Verified they will only be counted once + as Verified. Learners who have un-enrolled in the course are not counted. + The distribution of grades for a course, out of 100%. Grades are grouped in ranges of 10%.: The + distribution of grades for a course, out of 100%. Grades are grouped in ranges + of 10%. + ? The number of students who have responded to a question, and whether they have + ever answered correctly. Students can answer some questions multiple times, but + this chart counts each student only once per question. + : The number of students who have responded to a question, and whether they have + ever answered correctly. Students can answer some questions multiple times, but + this chart counts each student only once per question. + ? This chart displays counts of the number of times hints (including displaying + the answer itself) were displayed for each learner who eventually answered the + problem correctly. If the problem had no hint or answer display configured this + chart will group everyone into "0". + : This chart displays counts of the number of times hints (including displaying + the answer itself) were displayed for each learner who eventually answered the + problem correctly. If the problem had no hint or answer display configured this + chart will group everyone into "0". + ? This chart helps understand how many learners are using the video's transcripts + or closed captions. If the video has not transcripts or captions the chart will + be empty. + : This chart helps understand how many learners are using the video's transcripts + or closed captions. If the video has not transcripts or captions the chart will + be empty. + ? This chart shows how many unique learners have watched each video, and how many + repeat views each has gotten. If a video has never been played it will not appear + in this chart. + : This chart shows how many unique learners have watched each video, and how many + repeat views each has gotten. If a video has never been played it will not appear + in this chart. + ? This chart shows how often an answer or combination of answers (for multi-select) + is selected by learners. Some problems allow learners to submit a response more + than once, this chart will include all of the responses in that case. + : This chart shows how often an answer or combination of answers (for multi-select) + is selected by learners. Some problems allow learners to submit a response more + than once, this chart will include all of the responses in that case. + ? This chart shows the number of attempts that students needed to make before getting + the problem's answer correct. This only counts students who eventually answered + correctly. + : This chart shows the number of attempts that students needed to make before getting + the problem's answer correct. This only counts students who eventually answered + correctly. + ? 'This chart shows the number of students who scored within a certain percentage + of points for this problem. For problems that are pass/fail it will only show + the lowest and highest percentage ranges. ' + : 'This chart shows the number of students who scored within a certain percentage + of points for this problem. For problems that are pass/fail it will only show + the lowest and highest percentage ranges. ' + ? This chart shows which parts of a video are most watched, and which are most re-watched. + Each segment represents 5 seconds of the video. + : This chart shows which parts of a video are most watched, and which are most re-watched. + Each segment represents 5 seconds of the video. + Total Organizations: Total Organizations + Transcripts / Captions Per Video: Transcripts / Captions Per Video + Unique actors: Unique actors + Video Engagement: Video Engagement + Video Performance: Video Performance + Video Title: Video Title + Watched Video Segments: Watched Video Segments + Watches Per Video: Watches Per Video + xAPI Events Over Time: xAPI Events Over Time diff --git a/tutoraspects/templates/aspects/apps/superset/localization/locale.yaml b/tutoraspects/templates/aspects/apps/superset/localization/locale.yaml index 853c83559..8fa77986d 100644 --- a/tutoraspects/templates/aspects/apps/superset/localization/locale.yaml +++ b/tutoraspects/templates/aspects/apps/superset/localization/locale.yaml @@ -1,5 +1,11 @@ --- de: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment @@ -152,6 +158,12 @@ de: Watches Per Video: '' xAPI Events Over Time: '' es: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment @@ -209,7 +221,7 @@ es: unenrollment will be counted. : '' Active Users Per Organization: '' - Actor IDs over time: IDs de actores a lo largo del tiempo + Actor IDs over time: '' Answers Chosen: '' Coming Soon: '' Course Enrollment: '' @@ -217,7 +229,7 @@ es: Course Grade Distribution: '' Course Registrations Over Time: '' Course Success: '' - Courses: Cursos + Courses: '' Courses Per Organization: '' Currently Enrolled Learners Per Day: '' Distribution Of Attempts: '' @@ -228,13 +240,13 @@ es: Enrollments: '' Enrollments By Enrollment Mode: '' Enrollments By Type: '' - Event type: Tipo de evento - Events per course: Eventos por curso + Event type: '' + Events per course: '' Hints / Answer Displayed Before Correct Answer Chosen: '' Instance Health: '' Instructor Dashboard: '' Last Received Event: '' - Last course syncronized: "\xDAltimo curso sincronizado" + Last course syncronized: '' Learner Engagement: '' Most Active Courses Per Day: '' Number Of Attempts To Find Correct Answer: '' @@ -242,8 +254,8 @@ es: Number Of Viewers / Views: '' Number of Users / Uses: '' Number of Views / Viewers: '' - Operator Dashboard: Panel de Operador - Organizations: Organizaciones + Operator Dashboard: '' + Organizations: '' Percentage Grade: '' Problem Engagement: '' Problem Performance: '' @@ -296,7 +308,7 @@ es: : '' Total Organizations: '' Transcripts / Captions Per Video: '' - Unique actors: "Actores \xFAnicos" + Unique actors: '' Video Engagement: '' Video Performance: '' Video Title: '' @@ -304,6 +316,12 @@ es: Watches Per Video: '' xAPI Events Over Time: '' fr: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment @@ -456,6 +474,12 @@ fr: Watches Per Video: '' xAPI Events Over Time: '' it: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment @@ -608,6 +632,12 @@ it: Watches Per Video: '' xAPI Events Over Time: '' ja: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment @@ -760,6 +790,12 @@ ja: Watches Per Video: '' xAPI Events Over Time: '' ko: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment @@ -912,6 +948,12 @@ ko: Watches Per Video: '' xAPI Events Over Time: '' nl: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment @@ -1064,6 +1106,12 @@ nl: Watches Per Video: '' xAPI Events Over Time: '' pt: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment @@ -1216,6 +1264,12 @@ pt: Watches Per Video: '' xAPI Events Over Time: '' ru: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment @@ -1368,6 +1422,12 @@ ru: Watches Per Video: '' xAPI Events Over Time: '' sk: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment @@ -1520,6 +1580,12 @@ sk: Watches Per Video: '' xAPI Events Over Time: '' sl: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment @@ -1672,6 +1738,12 @@ sl: Watches Per Video: '' xAPI Events Over Time: '' zh: + ? "# Instance information Aspects: 0.49.0\n\n- **Vector Version**: timberio/vector:0.30.0-alpine\ + \ \n\n\n- **Clickhouse Version**: clickhouse/clickhouse-server:23.8 \n\n\n- **Ralph\ + \ Version**: fundocker/ralph:3.9.0 \n\n\n- **Superset Version**: edunext/aspects-superset:0.49.0\ + \ \n\n\n\n## Dependencies:\n\n- **Clickhouse Event Sink Version**: 0.2.2 \n\n\n\ + \n- **Event Routing Backends Version**: 6.2.0 \n\n\n" + : '' ? '### Course Enrollment From 6249248ae1ce84483d5b2230eb543f486b30ced9 Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Thu, 12 Oct 2023 14:14:46 -0400 Subject: [PATCH 2/4] fix: Remove Jinja from localized files The double curly braces breaks YAML, and we don't want to be translating the rendered files as currently happens. We'll need to update this functionality to pull what data it can at runtime. --- .../apps/superset/conf/locale/en/locale.yaml | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/tutoraspects/templates/aspects/apps/superset/conf/locale/en/locale.yaml b/tutoraspects/templates/aspects/apps/superset/conf/locale/en/locale.yaml index 14bfba3bf..e0743b8fe 100644 --- a/tutoraspects/templates/aspects/apps/superset/conf/locale/en/locale.yaml +++ b/tutoraspects/templates/aspects/apps/superset/conf/locale/en/locale.yaml @@ -1,22 +1,6 @@ en: - ? "# Instance information Aspects: ' ASPECTS_VERSION '\n{% if RUN_VECTOR %} - **Vector\ - \ Version**: ' DOCKER_IMAGE_VECTOR ' \n {% endif %} {% if RUN_CLICKHOUSE %} -\ - \ **Clickhouse Version**: ' DOCKER_IMAGE_CLICKHOUSE ' \n {% endif %} {% if RUN_RALPH\ - \ %} - **Ralph Version**: ' DOCKER_IMAGE_RALPH ' \n {% endif %} {% if RUN_SUPERSET\ - \ %} - **Superset Version**: ' DOCKER_IMAGE_SUPERSET ' \n {% endif %} \n\n## Dependencies:\ - \ {% for requirement in OPENEDX_EXTRA_PIP_REQUIREMENTS %} {% if 'openedx-event-sink-clickhouse'\ - \ in requirement %} - **Clickhouse Event Sink Version**: ' requirement.split('==')[1]\ - \ ' \n {% elif 'event-routing-backends' in requirement %} - **Event Routing Backends\ - \ Version**: ' requirement.split('==')[1] ' \n {% endif %} {% endfor %} " - : "# Instance information Aspects: ' ASPECTS_VERSION '\n{% if RUN_VECTOR %} - **Vector\ - \ Version**: ' DOCKER_IMAGE_VECTOR ' \n {% endif %} {% if RUN_CLICKHOUSE %} -\ - \ **Clickhouse Version**: ' DOCKER_IMAGE_CLICKHOUSE ' \n {% endif %} {% if RUN_RALPH\ - \ %} - **Ralph Version**: ' DOCKER_IMAGE_RALPH ' \n {% endif %} {% if RUN_SUPERSET\ - \ %} - **Superset Version**: ' DOCKER_IMAGE_SUPERSET ' \n {% endif %} \n\n## Dependencies:\ - \ {% for requirement in OPENEDX_EXTRA_PIP_REQUIREMENTS %} {% if 'openedx-event-sink-clickhouse'\ - \ in requirement %} - **Clickhouse Event Sink Version**: ' requirement.split('==')[1]\ - \ ' \n {% elif 'event-routing-backends' in requirement %} - **Event Routing Backends\ - \ Version**: ' requirement.split('==')[1] ' \n {% endif %} {% endfor %} " + ? "# Instance information Aspects: " + : "# Instance information Aspects: " ? '### Course Enrollment From f2216b105697b3ee5860d45fffe0a2d65f5176fc Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Fri, 13 Oct 2023 10:58:49 -0400 Subject: [PATCH 3/4] refactor: Change where transifex input generates Per feedback in https://github.com/openedx/openedx-translations/pull/1834 this is really just a temp file, so we should treat it as one. Also adding a README to the locale dir to deter people from editing those files. --- .gitignore | 1 + .tx/config | 6 ------ scripts/utils.py | 7 ++++--- .../templates/aspects/apps/superset/conf/README.md | 7 +++++++ 4 files changed, 12 insertions(+), 9 deletions(-) delete mode 100644 .tx/config create mode 100644 tutoraspects/templates/aspects/apps/superset/conf/README.md diff --git a/.gitignore b/.gitignore index 50cd6869f..dabb1d8c4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ __pycache__ /.idea/ venv/ env/ +transifex_input.yaml diff --git a/.tx/config b/.tx/config deleted file mode 100644 index 7d41c9227..000000000 --- a/.tx/config +++ /dev/null @@ -1,6 +0,0 @@ -[main] -host = https://www.transifex.com - -[o:open-edx:p:edx-platform:r:tutor-contrib-aspects] -source_lang = en -type = KEYVALUEJSON diff --git a/scripts/utils.py b/scripts/utils.py index 0ad860484..256984c89 100644 --- a/scripts/utils.py +++ b/scripts/utils.py @@ -131,9 +131,10 @@ def extract_translations(root_path): An English locale file is created, which openedx-translations will send to Transifex for translation. """ - translation_file = ( - "tutoraspects/templates/aspects/apps/superset/conf/locale/en/locale.yaml" - ) + # The expectation is that this will end up at the site root, which should + # be cwd for make targets. This is a temporary file used only in the Github + # action in openedx-translations. + translation_file = "transifex_input.yaml" print("Gathering text for translations...") STRINGS = set(get_text_for_translations(root_path)) diff --git a/tutoraspects/templates/aspects/apps/superset/conf/README.md b/tutoraspects/templates/aspects/apps/superset/conf/README.md new file mode 100644 index 000000000..182ab3da5 --- /dev/null +++ b/tutoraspects/templates/aspects/apps/superset/conf/README.md @@ -0,0 +1,7 @@ +# Locale Files + +These files are managed via the OEP-58 process and should not be manually edited as they will be overwritten. The process is: + +1. A Github action on `openedx-translations` will pull this repo and run `make extract-translations` on this repo's Makefile. This pulls all translatable strings from the Superset assets. These are then uploaded to Transifex for translation. +2. As translations are updated in Transifex they will be pushed to the correct language's files in `openedx-translations`. +3. A Github action on this repo will run `make pull-translations` periodically. This will run the Atlas tool to synchronize the translation files in this directory with what is stored in `openedx-translations`. Then it will run a command to compile all of the separate translated files into one `locale.yaml` that is used to create the localized dashboard and chart strings during the Tutor init command. It will then automatically merge those changed files. From 3d8eb9f3970cd23623dd7ae79395d4d21da2d16c Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Fri, 13 Oct 2023 13:02:48 -0400 Subject: [PATCH 4/4] build: Add free disk space to dev and local tests Now we're running out of space on those test runners as well. --- .github/workflows/test-tutor-aspects.yml | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.github/workflows/test-tutor-aspects.yml b/.github/workflows/test-tutor-aspects.yml index 699a8bb32..913129584 100644 --- a/.github/workflows/test-tutor-aspects.yml +++ b/.github/workflows/test-tutor-aspects.yml @@ -33,6 +33,20 @@ jobs: run: tutor config save - name: Setup Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@d5af243ce7bacb67384aa6c5b1fc5f169e30903e + with: + # this might remove tools that are actually needed, + # if set to "true" but frees about 6 GB + tool-cache: false + + # all of these default to true, but feel free to set to + # "false" if necessary for your workflow + android: true + dotnet: true + haskell: true + large-packages: false + swap-storage: true - name: Tutor build openedx run: tutor images build openedx aspects aspects-superset - name: Tutor start @@ -71,6 +85,20 @@ jobs: run: tutor config save - name: Setup Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@d5af243ce7bacb67384aa6c5b1fc5f169e30903e + with: + # this might remove tools that are actually needed, + # if set to "true" but frees about 6 GB + tool-cache: false + + # all of these default to true, but feel free to set to + # "false" if necessary for your workflow + android: true + dotnet: true + haskell: true + large-packages: false + swap-storage: true - name: Tutor build openedx run: tutor images build openedx-dev aspects aspects-superset - name: Tutor start