From 56f7c3f7c63ae89691da6e94ec86b9bf4e802f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 18 May 2023 13:59:02 +0200 Subject: [PATCH 1/2] MOBILE-4343 lang: Remove php dependancy on langpacks --- gulp/task-override-lang.js | 134 +++++++ gulpfile.js | 6 + package.json | 5 +- scripts/create_langindex.sh | 319 +-------------- scripts/create_langindex_functions.sh | 355 +++++++++++++++++ scripts/lang_functions.php | 541 -------------------------- scripts/lang_functions.sh | 156 +------- scripts/moodle_to_json.php | 68 ---- scripts/update_lang.sh | 29 -- scripts/update_lang_functions.sh | 186 +++++++++ scripts/update_langpacks.sh | 36 ++ 11 files changed, 739 insertions(+), 1096 deletions(-) create mode 100644 gulp/task-override-lang.js create mode 100644 scripts/create_langindex_functions.sh delete mode 100644 scripts/lang_functions.php mode change 100755 => 100644 scripts/lang_functions.sh delete mode 100644 scripts/moodle_to_json.php delete mode 100755 scripts/update_lang.sh create mode 100755 scripts/update_lang_functions.sh create mode 100755 scripts/update_langpacks.sh diff --git a/gulp/task-override-lang.js b/gulp/task-override-lang.js new file mode 100644 index 000000000..cdb5e4aa3 --- /dev/null +++ b/gulp/task-override-lang.js @@ -0,0 +1,134 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const gulp = require('gulp'); +const slash = require('gulp-slash'); +const through = require('through'); +const bufferFrom = require('buffer-from'); +const pathLib = require('path'); +const { readFileSync } = require('fs'); + +/** + * Use the English generated lang file (src/assets/lang/en.json) to override strings in features lang.json files. + */ +class OverrideLangTask { + + /** + * Run the task. + * + * @param done Function to call when done. + */ + run(done) { + const self = this; + + const path = pathLib.join('./src/assets/lang', 'en.json'); + const data = JSON.parse(readFileSync(path)); + + const files = {}; + + for (const key in data) { + let filePath = './src'; + + const exp = key.split('.'); + + + const type = exp.shift(); + let component = 'moodle'; + let plainid = exp.shift(); + + if (exp.length > 0) { + component = plainid; + plainid = exp.join('.'); + } + + const component_slashes = component.replace('_', '/'); + + switch (type) { + case 'core': + if (component == 'moodle') { + filePath = pathLib.join(filePath, 'core/lang.json'); + } else { + filePath = pathLib.join(filePath, `/core/features/${component_slashes}/lang.json`); + } + break; + case 'addon': + filePath = pathLib.join(filePath, `/addons/${component_slashes}/lang.json`); + break; + case 'assets': + filePath = pathLib.join(filePath, `/${type}/${component}.json`); + break; + default: + filePath = pathLib.join(filePath, `/${type}/lang.json`); + break; + } + filePath = pathLib.resolve(filePath); + + if (files[filePath] === undefined) { + files[filePath] = {}; + } + + files[filePath][plainid] = data[key]; + } + + const paths = Object.keys(files); + gulp.src(paths, { allowEmpty: true }) + .pipe(slash()) + .pipe(through(function(destFile) { + const oldContents = self.readFile(destFile); + destFile.contents = self.jsonFile(oldContents, files[destFile.path]); + + this.emit('data', destFile); + })) + .pipe(gulp.dest((data) => data.base, { overwrite: true})) + .on('end', done); + } + + /** + * Reads file. + * + * @param file File treated. + */ + readFile(file) { + if (file.isNull() || file.isStream()) { + return; // ignore + } + + try { + return JSON.parse(file.contents.toString()); + } catch (err) { + console.log('Error parsing JSON: ' + err); + } + } + + /** + * Creates the stringified json. + * + * @param oldContents File old data. + * @param data File data. + * @return Buffer with the treated data. + */ + jsonFile(oldContents, data) { + data = Object.assign(oldContents, data); + + const fileContents = {}; + // Force ordering by string key. + Object.keys(data).sort().forEach((key) => { + fileContents[key] = data[key]; + }); + + return bufferFrom(JSON.stringify(fileContents, null, 4) + "\n"); + } +} + +module.exports = OverrideLangTask; diff --git a/gulpfile.js b/gulpfile.js index 295e4a6df..e7f127210 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -16,6 +16,7 @@ const BuildLangTask = require('./gulp/task-build-lang'); const BuildBehatPluginTask = require('./gulp/task-build-behat-plugin'); const BuildEnvTask = require('./gulp/task-build-env'); const PushTask = require('./gulp/task-push'); +const OverrideLangTask = require('./gulp/task-override-lang'); const Utils = require('./gulp/utils'); const gulp = require('gulp'); @@ -36,6 +37,11 @@ gulp.task('lang', (done) => { new BuildLangTask().run(paths.lang, done); }); +// Use the English generated lang file (src/assets/lang/en.json) to override strings in features lang.json files. +gulp.task('lang-override', (done) => { + new OverrideLangTask().run(done); +}); + // Build an env file depending on the current environment. gulp.task('env', (done) => { new BuildEnvTask().run(done); diff --git a/package.json b/package.json index 2e111a855..2fb4aaa0e 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,10 @@ "ionic:serve:before": "gulp", "ionic:serve": "cross-env-shell ./scripts/serve.sh", "ionic:build:before": "gulp", - "postinstall": "patch-package" + "postinstall": "patch-package", + "lang:update-langpacks": "./scripts/update_langpacks.sh", + "lang:detect-langpacks": "./scripts/update_langpacks.sh detect", + "lang:create-langindex": "./scripts/create_langindex.sh" }, "dependencies": { "@angular/animations": "~10.0.14", diff --git a/scripts/create_langindex.sh b/scripts/create_langindex.sh index 43c2a03c6..67f564796 100755 --- a/scripts/create_langindex.sh +++ b/scripts/create_langindex.sh @@ -3,323 +3,22 @@ # Script to create langindex from available language packs. # ./create_langindex.sh [findbetter] # If findbetter is set it will try to find a better solution for every key. -# Edit lang_functions.sh LANGPACKSFOLDER variable to match your system's # + +DIR="${BASH_SOURCE%/*}" +if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi + +cd $DIR + source "functions.sh" source "lang_functions.sh" - -#Saves or updates a key on langindex_old.json -function save_key { - local key=$1 - local found=$2 - - print_ok "$key=$found" - echo "{\"$key\": \"$found\"}" > langindex_old.json - jq -s '.[0] + .[1]' langindex.json langindex_old.json > langindex_new.json - mv langindex_new.json langindex.json -} - -#Removes a key on langindex_old.json -function remove_key { - local key=$1 - - cat langindex.json | jq 'del(."'$key'")' > langindex_new.json - mv langindex_new.json langindex.json - print_ok "Deleted unused key $key" -} - -#Check if and i exists in php file -function exists_in_file { - local file=$1 - local id=$2 - - file=`echo $file | sed s/^mod_workshop_assessment/workshopform/1` - file=`echo $file | sed s/^mod_assign_/assign/1` - file=`echo $file | sed s/^mod_//1` - - completeFile="$LANGPACKSFOLDER/en/$file.php" - if [ -f "$completeFile" ]; then - foundInFile=`grep "string\[\'$id\'\]" $completeFile` - if [ ! -z "$foundInFile" ]; then - coincidence=1 - found=$file - return - fi - fi - coincidence=0 - found=0 -} - -#Checks if a key exists on the original local_moodlemobileapp.php -function exists_in_mobile { - local file='local_moodlemobileapp' - exists_in_file $file $key -} - -function do_match { - match=${1/\{\{/\{} - match=${match/\}\}/\}} - filematch="" - - coincidence=`grep "$match" $LANGPACKSFOLDER/en/*.php | wc -l` - if [ $coincidence -eq 1 ]; then - filematch=`grep "$match" $LANGPACKSFOLDER/en/*.php | cut -d'/' -f5 | cut -d'.' -f1` - exists_in_file $filematch $plainid - elif [ $coincidence -gt 0 ] && [ "$#" -gt 1 ]; then - print_message "$2" - tput setaf 6 - grep "$match" $LANGPACKSFOLDER/en/*.php - else - coincidence=0 - fi -} - -#Find if the id or the value can be found on files to help providing a solution. -function find_matches { - do_match "string\[\'$plainid\'\] = \'$value\'" "Found EXACT match for $key in the following paths" - if [ $coincidence -gt 0 ]; then - case=1 - save_key $key "TBD" - return - fi - - do_match " = \'$value\'" "Found some string VALUES for $key in the following paths" - if [ $coincidence -gt 0 ]; then - case=2 - save_key $key "TBD" - return - fi - - do_match "string\[\'$plainid\'\]" "Found some string KEYS for $key in the following paths, value $value" - if [ $coincidence -gt 0 ]; then - case=3 - save_key $key "TBD" - return - fi - - print_message "No match found for $key add it to local_moodlemobileapp" - save_key $key "local_moodlemobileapp" -} - -function find_single_matches { - do_match "string\[\'$plainid\'\] = \'$value\'" - if [ ! -z $filematch ] && [ $found != 0 ]; then - case=1 - return - fi - - do_match " = \'$value\'" - if [ ! -z $filematch ] && [ $filematch != 'local_moodlemobileapp' ]; then - case=2 - print_message "Found some string VALUES for $key in the following paths $filematch" - tput setaf 6 - grep "$match" $LANGPACKSFOLDER/en/*.php - return - fi - - do_match "string\[\'$plainid\'\]" - if [ ! -z $filematch ] && [ $found != 0 ]; then - case=3 - return - fi -} - - -#Tries to gues the file where the id will be found. -function guess_file { - local key=$1 - local value=$2 - - local type=`echo $key | cut -d'.' -f1` - local component=`echo $key | cut -d'.' -f2` - local plainid=`echo $key | cut -d'.' -f3-` - - if [ -z "$plainid" ]; then - plainid=$component - component='moodle' - fi - - exists_in_file $component $plainid - - if [ $found == 0 ]; then - tempid=`echo $plainid | sed s/^mod_//1` - if [ $component == 'moodle' ] && [ "$tempid" != "$plainid" ]; then - exists_in_file $plainid pluginname - - if [ $found != 0 ]; then - found=$found/pluginname - fi - fi - fi - - # Not found in file, try in local_moodlemobileapp - if [ $found == 0 ]; then - exists_in_mobile - fi - - # Still not found, if only found in one file, use it. - if [ $found == 0 ]; then - find_single_matches - fi - - # Last fallback. - if [ $found == 0 ]; then - exists_in_file 'moodle' $plainid - fi - - if [ $found == 0 ]; then - find_matches - else - save_key $key $found - fi -} - -function current_translation_exists { - local key=$1 - local current=$2 - local file=$3 - - plainid=`echo $key | cut -d'.' -f3-` - - if [ -z "$plainid" ]; then - plainid=`echo $key | cut -d'.' -f2` - fi - - local currentFile=`echo $current | cut -d'/' -f1` - local currentStr=`echo $current | cut -d'/' -f2-` - if [ $currentFile == $current ]; then - currentStr=$plainid - fi - - exists_in_file $currentFile $currentStr - if [ $found == 0 ]; then - # Translation not found. - exec="jq -r .\"$key\" $file" - value=`$exec` - - print_error "Translation of '$currentStr' not found in '$currentFile'" - - guess_file $key "$value" - fi -} - -#Finds if there's a better file where to get the id from. -function find_better_file { - local key=$1 - local value=$2 - local current=$3 - - local type=`echo $key | cut -d'.' -f1` - local component=`echo $key | cut -d'.' -f2` - local plainid=`echo $key | cut -d'.' -f3-` - - if [ -z "$plainid" ]; then - plainid=$component - component='moodle' - fi - - local currentFile=`echo $current | cut -d'/' -f1` - local currentStr=`echo $current | cut -d'/' -f2-` - if [ $currentFile == $current ]; then - currentStr=$plainid - fi - - exists_in_file $component $plainid - if [ $found != 0 ] && [ $currentStr == $plainid ]; then - if [ $found != $currentFile ]; then - print_ok "Key '$key' found in component, no need to replace old '$current'" - fi - - return - fi - - # Still not found, if only found in one file, use it. - if [ $found == 0 ]; then - find_single_matches - fi - - if [ $found != 0 ] && [ $found != $currentFile ] && [ $case -lt 3 ]; then - print_message "Indexed string '$key' found in '$found' better than '$current'" - return - fi - - if [ $currentFile == 'local_moodlemobileapp' ]; then - exists_in_mobile - else - exists_in_file $currentFile $currentStr - fi - - if [ $found == 0 ]; then - print_error "Indexed string '$key' not found on current place '$current'" - if [ $currentFile != 'local_moodlemobileapp' ]; then - print_error "Execute this on AMOS - CPY [$currentStr,$currentFile],[$key,local_moodlemobileapp]" - save_key $key "local_moodlemobileapp" - fi - fi -} - -# Parses the file. -function parse_file { - findbetter=$2 - keys=`jq -r 'keys[]' $1` - for key in $keys; do - # Check if already parsed. - exec="jq -r .\"$key\" langindex.json" - found=`$exec` - - if [ -z "$found" ] || [ "$found" == 'null' ]; then - exec="jq -r .\"$key\" $1" - value=`$exec` - guess_file $key "$value" - else - if [ "$found" == 'donottranslate' ]; then - # Do nothing since is not translatable. - continue - elif [ ! -z "$findbetter" ]; then - exec="jq -r .\"$key\" $1" - value=`$exec` - find_better_file "$key" "$value" "$found" - elif [ "$found" != 'local_moodlemobileapp' ]; then - current_translation_exists "$key" "$found" "$1" - fi - fi - done - - # Do some cleanup - langkeys=`jq -r 'keys[]' langindex.json` - findkeys="${keys[@]}" - for key in $langkeys; do - # Check if already used. - array_contains "$key" "$findkeys" - - if [ -z "$found" ] || [ "$found" == 'null' ]; then - remove_key $key - fi - done -} - -# Checks if an array contains an string. -function array_contains { - local hayjack=$2 - local needle=$1 - found='' - for i in $hayjack; do - if [ "$i" == "$needle" ] ; then - found=$i - return - fi - done -} - +source "create_langindex_functions.sh" print_title 'Generating language from code...' npx gulp lang -print_title 'Getting languages' - -get_language en +get_english print_title 'Processing file' #Create langindex.json if not exists. @@ -328,7 +27,7 @@ if [ ! -f 'langindex.json' ]; then fi findbetter=$1 -parse_file '../src/assets/lang/en.json' $findbetter +parse_file $findbetter echo diff --git a/scripts/create_langindex_functions.sh b/scripts/create_langindex_functions.sh new file mode 100644 index 000000000..6627f1ce5 --- /dev/null +++ b/scripts/create_langindex_functions.sh @@ -0,0 +1,355 @@ +#!/bin/bash +# +# Functions used to create langidex. +# + +SERVER_URL='https://download.moodle.org/' + +# Downloads a file and if it's a zip file, unzip it. +function download_file { + local url=$1 + local filename=$(basename ${url}) + + pushd $LANGPACKS_PATH > /dev/null + + curl -s $url --output $filename > /dev/null + size=$(du -k "$filename" | cut -f 1) + if [ ! -n $filename ] || [ $size -le 1 ]; then + echo "Wrong or corrupt file $filename" + rm $filename + + popd > /dev/null + return + fi + + if [[ $filename == *.zip ]]; then + local lang="${filename%.*}" + # Delete previous downloaded folder + rm -R $lang > /dev/null 2>&1> /dev/null + + # Unzip + unzip -o -u $lang.zip > /dev/null + + # Delete the zip + rm $filename + fi + + popd > /dev/null +} + +function get_english { + if [ ! -d $LANGPACKS_PATH ]; then + mkdir $LANGPACKS_PATH + fi + + get_app_version + + echo "Getting English language..." + download_file "$SERVER_URL/download.php/direct/langpack/$LANGVERSION/en.zip" +} + +#Saves or updates a key on langindex_old.json +function save_key { + local key=$1 + local found=$2 + + print_ok "$key=$found" + echo "{\"$key\": \"$found\"}" > langindex_old.json + jq -s '.[0] + .[1]' langindex.json langindex_old.json > langindex_new.json + mv langindex_new.json langindex.json +} + +#Removes a key on langindex_old.json +function remove_key { + local key=$1 + + cat langindex.json | jq 'del(."'$key'")' > langindex_new.json + mv langindex_new.json langindex.json + print_ok "Deleted unused key $key" +} + +#Check if a lang id exists in php file +function exists_in_file { + local file=$1 + local id=$2 + + file=`echo $file | sed s/^mod_workshop_assessment/workshopform/1` + file=`echo $file | sed s/^mod_assign_/assign/1` + file=`echo $file | sed s/^mod_//1` + + completeFile="$LANGPACKS_PATH/en/$file.php" + if [ -f "$completeFile" ]; then + foundInFile=`grep "string\[\'$id\'\]" $completeFile` + if [ ! -z "$foundInFile" ]; then + coincidence=1 + found=$file + return + fi + fi + coincidence=0 + found=0 +} + +#Checks if a key exists on the original local_moodlemobileapp.php +function exists_in_mobile { + local file='local_moodlemobileapp' + exists_in_file $file $key +} + +function do_match { + match=${1/\{\{/\{} + match=${match/\}\}/\}} + filematch="" + + coincidence=`grep "$match" $LANGPACKS_PATH/en/*.php | wc -l` + if [ $coincidence -eq 1 ]; then + filematch=`grep "$match" $LANGPACKS_PATH/en/*.php | cut -d'/' -f5 | cut -d'.' -f1` + exists_in_file $filematch $plainid + elif [ $coincidence -gt 0 ] && [ "$#" -gt 1 ]; then + print_message "$2" + tput setaf 6 + grep "$match" $LANGPACKS_PATH/en/*.php + else + coincidence=0 + fi +} + +#Find if the id or the value can be found on files to help providing a solution. +function find_matches { + do_match "string\[\'$plainid\'\] = \'$value\'" "Found EXACT match for $key in the following paths" + if [ $coincidence -gt 0 ]; then + case=1 + save_key $key "TBD" + return + fi + + do_match " = \'$value\'" "Found some string VALUES for $key in the following paths" + if [ $coincidence -gt 0 ]; then + case=2 + save_key $key "TBD" + return + fi + + do_match "string\[\'$plainid\'\]" "Found some string KEYS for $key in the following paths, value $value" + if [ $coincidence -gt 0 ]; then + case=3 + save_key $key "TBD" + return + fi + + print_message "No match found for $key add it to local_moodlemobileapp" + save_key $key "local_moodlemobileapp" +} + +function find_single_matches { + do_match "string\[\'$plainid\'\] = \'$value\'" + if [ ! -z $filematch ] && [ $found != 0 ]; then + case=1 + return + fi + + do_match " = \'$value\'" + if [ ! -z $filematch ] && [ $filematch != 'local_moodlemobileapp' ]; then + case=2 + print_message "Found some string VALUES for $key in the following paths $filematch" + tput setaf 6 + grep "$match" $LANGPACKS_PATH/en/*.php + return + fi + + do_match "string\[\'$plainid\'\]" + if [ ! -z $filematch ] && [ $found != 0 ]; then + case=3 + return + fi +} + + +#Tries to gues the file where the id will be found. +function guess_file { + local key=$1 + local value=$2 + + local type=`echo $key | cut -d'.' -f1` + local component=`echo $key | cut -d'.' -f2` + local plainid=`echo $key | cut -d'.' -f3-` + + if [ -z "$plainid" ]; then + plainid=$component + component='moodle' + fi + + exists_in_file $component $plainid + + if [ $found == 0 ]; then + tempid=`echo $plainid | sed s/^mod_//1` + if [ $component == 'moodle' ] && [ "$tempid" != "$plainid" ]; then + exists_in_file $plainid pluginname + + if [ $found != 0 ]; then + found=$found/pluginname + fi + fi + fi + + # Not found in file, try in local_moodlemobileapp + if [ $found == 0 ]; then + exists_in_mobile + fi + + # Still not found, if only found in one file, use it. + if [ $found == 0 ]; then + find_single_matches + fi + + # Last fallback. + if [ $found == 0 ]; then + exists_in_file 'moodle' $plainid + fi + + if [ $found == 0 ]; then + find_matches + else + save_key $key $found + fi +} + +function current_translation_exists { + local key=$1 + local current=$2 + local file=$3 + + plainid=`echo $key | cut -d'.' -f3-` + + if [ -z "$plainid" ]; then + plainid=`echo $key | cut -d'.' -f2` + fi + + local currentFile=`echo $current | cut -d'/' -f1` + local currentStr=`echo $current | cut -d'/' -f2-` + if [ $currentFile == $current ]; then + currentStr=$plainid + fi + + exists_in_file $currentFile $currentStr + if [ $found == 0 ]; then + # Translation not found. + exec="jq -r .\"$key\" $file" + value=`$exec` + + print_error "Translation of '$currentStr' not found in '$currentFile'" + + guess_file $key "$value" + fi +} + +#Finds if there's a better file where to get the id from. +function find_better_file { + local key=$1 + local value=$2 + local current=$3 + + local type=`echo $key | cut -d'.' -f1` + local component=`echo $key | cut -d'.' -f2` + local plainid=`echo $key | cut -d'.' -f3-` + + if [ -z "$plainid" ]; then + plainid=$component + component='moodle' + fi + + local currentFile=`echo $current | cut -d'/' -f1` + local currentStr=`echo $current | cut -d'/' -f2-` + if [ $currentFile == $current ]; then + currentStr=$plainid + fi + + exists_in_file $component $plainid + if [ $found != 0 ] && [ $currentStr == $plainid ]; then + if [ $found != $currentFile ]; then + print_ok "Key '$key' found in component, no need to replace old '$current'" + fi + + return + fi + + # Still not found, if only found in one file, use it. + if [ $found == 0 ]; then + find_single_matches + fi + + if [ $found != 0 ] && [ $found != $currentFile ] && [ $case -lt 3 ]; then + print_message "Indexed string '$key' found in '$found' better than '$current'" + return + fi + + if [ $currentFile == 'local_moodlemobileapp' ]; then + exists_in_mobile + else + exists_in_file $currentFile $currentStr + fi + + if [ $found == 0 ]; then + print_error "Indexed string '$key' not found on current place '$current'" + if [ $currentFile != 'local_moodlemobileapp' ]; then + print_error "Execute this on AMOS + CPY [$currentStr,$currentFile],[$key,local_moodlemobileapp]" + save_key $key "local_moodlemobileapp" + fi + fi +} + +# Parses the file. +function parse_file { + file="$LANG_PATH/en.json" + findbetter=$1 + + keys=`jq -r 'keys[]' $file` + for key in $keys; do + # Check if already parsed. + exec="jq -r .\"$key\" langindex.json" + found=`$exec` + + if [ -z "$found" ] || [ "$found" == 'null' ]; then + exec="jq -r .\"$key\" $1" + value=`$exec` + guess_file $key "$value" + else + if [ "$found" == 'donottranslate' ]; then + # Do nothing since is not translatable. + continue + elif [ ! -z "$findbetter" ]; then + exec="jq -r .\"$key\" $1" + value=`$exec` + find_better_file "$key" "$value" "$found" + elif [ "$found" != 'local_moodlemobileapp' ]; then + current_translation_exists "$key" "$found" "$1" + fi + fi + done + + # Do some cleanup + langkeys=`jq -r 'keys[]' langindex.json` + findkeys="${keys[@]}" + for key in $langkeys; do + # Check if already used. + array_contains "$key" "$findkeys" + + if [ -z "$found" ] || [ "$found" == 'null' ]; then + remove_key $key + fi + done +} + +# Checks if an array contains an string. +function array_contains { + local hayjack=$2 + local needle=$1 + found='' + for i in $hayjack; do + if [ "$i" == "$needle" ] ; then + found=$i + return + fi + done +} diff --git a/scripts/lang_functions.php b/scripts/lang_functions.php deleted file mode 100644 index 18c7252d5..000000000 --- a/scripts/lang_functions.php +++ /dev/null @@ -1,541 +0,0 @@ -. - -/** - * Helper functions converting moodle strings to json. - */ - -function detect_languages($languages) { - echo "\n\n\n"; - - $all_languages = glob(LANGPACKSFOLDER.'/*' , GLOB_ONLYDIR); - function get_lang_from_dir($dir) { - return str_replace('_', '-', explode('/', $dir)[3]); - } - function get_lang_not_wp($langname) { - return (substr($langname, -3) !== '-wp'); - } - $all_languages = array_map('get_lang_from_dir', $all_languages); - $all_languages = array_filter($all_languages, 'get_lang_not_wp'); - - $detect_lang = array_diff($all_languages, $languages); - $new_langs = []; - foreach ($detect_lang as $lang) { - $new = detect_lang($lang); - if ($new) { - $new_langs[$lang] = $lang; - } - } - - return $new_langs; -} - -function build_languages($languages, $added_langs = []) { - // Process the languages. - foreach ($languages as $lang) { - if (build_lang($lang)) { - $added_langs[$lang] = $lang; - } - } - - return $added_langs; -} - -/** - * Loads lang index keys. - */ -function load_langindex() { - global $STATS; - global $LANGINDEX; - - $local = 0; - $total = 0; - // Process the index file, just once. - $langindexjson = load_json('langindex.json'); - - $LANGINDEX = []; - foreach ($langindexjson as $appkey => $value) { - if ($value == APPMODULENAME) { - $file = $value; - $lmskey = $appkey; - $local++; - } else { - $exp = explode('/', $value, 2); - $file = $exp[0]; - if (count($exp) == 2) { - $lmskey = $exp[1]; - } else { - $exp = explode('.', $appkey, 3); - - if (count($exp) == 3) { - $lmskey = $exp[2]; - } else { - $lmskey = $exp[1]; - } - } - } - - if (!isset($LANGINDEX[$file])) { - $LANGINDEX[$file] = []; - } - - $LANGINDEX[$file][$appkey] = $lmskey; - $total++; - } - - $STATS = new StdClass(); - $STATS->local = $local; - $STATS->total = $total; - - echo "Total strings to translate $total ($local local)\n"; -} - -/** - * Add lang names to config file. - * - * @param $langs Array of language codes to add. - * @param $config Loaded config file. - */ -function add_langs_to_config($langs, $config) { - $changed = false; - $config_langs = get_object_vars($config['languages']); - foreach ($langs as $lang) { - if (!isset($config_langs[$lang])) { - $langfoldername = get_langfolder($lang); - - $lmsstring = get_translation_strings($langfoldername, 'langconfig'); - $config['languages']->$lang = $lmsstring['thislanguage']; - $changed = true; - } - } - - if ($changed) { - // Sort languages by key. - $config['languages'] = json_decode( json_encode( $config['languages'] ), true ); - ksort($config['languages']); - $config['languages'] = json_decode( json_encode( $config['languages'] ), false ); - save_json(CONFIG, $config); - } -} - -/** - * Save json data. - * - * @param $path Path of the file to load. - * @param $content Content string to save. - */ -function save_json($path, $content) { - file_put_contents($path, str_replace('\/', '/', json_encode($content, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT))."\n"); -} - -/** - * Load json data. - * - * @param $path Path of the file to load. - * @return Associative array obtained from json. - */ -function load_json($path) { - $file = file_get_contents($path); - return (array) json_decode($file); -} - -/** - * Get's lang folder from lang code. - * - * @param $lang Lang code. - * @return Folder path. - */ -function get_langfolder($lang) { - $folder = LANGPACKSFOLDER.'/'.str_replace('-', '_', $lang); - if (!is_dir($folder) || !is_file($folder.'/langconfig.php')) { - return false; - } - - return $folder; -} - -/** - * Import translation file from langpack and returns it. - * - * @param $langfoldername Lang folder path. - * @param $file File name (excluding extension). - * @param $override_folder If needed, the folder of the file to override strings. - * @return String array. - */ -function get_translation_strings($langfoldername, $file, $override_folder = false) { - $lmsstring = import_translation_strings($langfoldername, $file); - if ($override_folder) { - $override = import_translation_strings($override_folder, $file); - $lmsstring = array_merge($lmsstring, $override); - } - - return $lmsstring; -} - -/** - * Import translation file from langpack and returns it. - * - * @param $langfoldername Lang folder path. - * @param $file File name (excluding extension). - * @return String array. - */ -function import_translation_strings($langfoldername, $file) { - - $path = $langfoldername.'/'.$file.'.php'; - // Apply translations. - if (!file_exists($path)) { - return []; - } - - $string = []; - - include($path); - - return $string; -} - -/** - * Build translations files from langpack. - * - * @param lang Language code. - * @return Wether it succeeded. - */ -function build_lang($lang) { - global $STATS; - global $LANGINDEX; - - $langfoldername = get_langfolder($lang); - if (!$langfoldername) { - echo "Cannot translate $lang, folder not found"; - - return false; - } - - if (OVERRIDE_LANG_SUFIX) { - $override_langfolder = get_langfolder($lang.OVERRIDE_LANG_SUFIX); - } else { - $override_langfolder = false; - } - - $total = $STATS->total; - $local = 0; - - $langparts = explode('-', $lang, 2); - $parentname = $langparts[0] ? $langparts[0] : ""; - $parent = ""; - - echo "Processing $lang"; - // Check parent language exists. - if ($parentname != $lang && get_langfolder($parentname)) { - echo " ($parentname)"; - $parent = $parentname; - } - - $langFile = false; - if (file_exists(ASSETSPATH.$lang.'.json')) { - // Load lang files just once. - $langFile = load_json(ASSETSPATH.$lang.'.json'); - } - - $translations = []; - // Add the translation to the array. - foreach ($LANGINDEX as $file => $keys) { - $lmsstring = get_translation_strings($langfoldername, $file, $override_langfolder); - foreach ($keys as $appkey => $lmskey) { - // Apply translations. - if (empty($lmsstring)) { - if ($file == 'donottranslate') { - // Restore it form the json. - if ($langFile && is_array($langFile) && isset($langFile[$appkey])) { - $translations[$appkey] = $langFile[$appkey]; - } else { - // If not present, do not count it in the total. - $total--; - } - - continue; - } - - if (TOTRANSLATE) { - echo "\n\t\tTo translate $lmskey on $file"; - } - continue; - } - - if (!isset($lmsstring[$lmskey]) || ($lang == 'en' && $file == APPMODULENAME)) { - // Not yet translated. Do not override. - if ($langFile && is_array($langFile) && isset($langFile[$appkey])) { - $translations[$appkey] = $langFile[$appkey]; - - if ($file == APPMODULENAME) { - $local++; - } - } - if (TOTRANSLATE && !isset($lmsstring[$lmskey])) { - echo "\n\t\tTo translate $lmskey on $file"; - } - continue; - } - - $text = $lmsstring[$lmskey]; - - if ($file != APPMODULENAME) { - $text = str_replace('$a->@', '$a.', $text); - $text = str_replace('$a->', '$a.', $text); - $text = str_replace('{$a', '{{$a', $text); - $text = str_replace('}', '}}', $text); - $text = preg_replace('/@@.+?@@(
)?\\s*/', '', $text); - // Prevent double. - $text = str_replace(['{{{', '}}}'], ['{{', '}}'], $text); - } else { - // @TODO: Remove that line when core.cannotconnect and core.login.invalidmoodleversion are completelly changed to use $a - if (($appkey == 'core.cannotconnect' || $appkey == 'core.login.invalidmoodleversion') && strpos($text, '2.4')) { - $text = str_replace('2.4', '{{$a}}', $text); - } - $local++; - } - - $translations[$appkey] = html_entity_decode($text); - } - } - - if (!empty($parent)) { - $translations['core.parentlanguage'] = $parent; - } else if (isset($translations['core.parentlanguage'])) { - unset($translations['core.parentlanguage']); - } - - // Sort and save. - ksort($translations); - save_json(ASSETSPATH.$lang.'.json', $translations); - - $success = count($translations); - $percentage = floor($success/$total * 100); - $bar = progressbar($percentage); - if (strlen($lang) <= 2 && !$parent) { - echo "\t"; - } - echo "\t\t$success of $total -> $percentage% $bar ($local local)\n"; - - if ($lang == 'en') { - generate_local_module_file($LANGINDEX[APPMODULENAME], $translations); - override_component_lang_files($translations); - } - - return true; -} - -/** - * Generates an ASCII progress bar. - * - * @param $percentage Done part. - * @param $length Length of the text. - * @return Text generated. - */ -function progressbar($percentage, $length = 10) { - $done = floor($percentage / $length); - return "\t".str_repeat('=', $done) . str_repeat('-', $length - $done); -} - -/** - * Check translations on langpack and detects if the language should be added. - * - * @param lang Language code. - * @return If the file should be added to the app. - */ -function detect_lang($lang) { - global $STATS; - global $LANGINDEX; - - $langfoldername = get_langfolder($lang); - if (!$langfoldername) { - echo "Cannot translate $lang, folder not found"; - - return false; - } - - $total = $STATS->total; - $success = 0; - $local = 0; - - $lmsstring = get_translation_strings($langfoldername, 'langconfig'); - $parent = isset($lmsstring['parentlanguage']) ? $lmsstring['parentlanguage'] : ""; - if (!isset($lmsstring['thislanguage'])) { - echo "Cannot translate $lang, translated name not found"; - return false; - } - - $title = $lang; - if ($parent != "" && $parent != $lang) { - $title .= " ($parent)"; - } - $langname = $lmsstring['thislanguage']; - $title .= " ".$langname." -D"; - - $lmsstring = get_translation_strings($langfoldername, APPMODULENAME); - if (!empty($lmsstring)) { - // Add the translation to the array. - foreach ($LANGINDEX as $file => $keys) { - $lmsstring = get_translation_strings($langfoldername, $file); - - // Apply translations. - if (empty($lmsstring)) { - // Do not count non translatable in the totals. - if ($file == 'donottranslate') { - $total -= count($keys); - } - continue; - } - - foreach ($keys as $lmskey) { - if (!isset($lmsstring[$lmskey])) { - continue; - } - - if ($file == APPMODULENAME) { - $local++; - } - - $success++; - } - } - } - - echo "Checking ".$title.str_repeat("\t", 7 - floor(mb_strlen($title, 'UTF-8')/8)); - - if ($local == 0) { - echo "\tNo Mobile App strings found\n"; - } else { - $percentage = floor($success/$total * 100); - $bar = progressbar($percentage); - - echo "\t$success of $total -> $percentage% $bar ($local local)"; - if (($percentage > 75 && $local > 50) || ($percentage > 50 && $local > 75)) { - echo " \t DETECTED\n"; - return true; - } - echo "\n"; - } - - return false; -} - -/** - * Save a key - value pair into a json file. - * - * @param key Key of the json object. - * @param value Value of the json object. - * @param filePath Path of the json file. - */ -function save_key($key, $value, $filePath) { - $file = load_json($filePath); - $value = html_entity_decode($value); - if (!isset($file[$key]) || $file[$key] != $value) { - $file[$key] = $value; - ksort($file); - save_json($filePath, $file); - } -} - -/** - * Take newer ENGLISH translations from the langpacks and applies it to the app lang.json files. - * - * @param [array] $translations English translations. - */ -function override_component_lang_files($translations) { - echo "Override component lang files.\n"; - foreach ($translations as $key => $value) { - $path = '../src/'; - $exp = explode('.', $key, 3); - - $type = $exp[0]; - if (count($exp) == 3) { - $component = $exp[1]; - $plainid = $exp[2]; - } else { - $component = 'moodle'; - $plainid = $exp[1]; - } - switch($type) { - case 'core': - if ($component == 'moodle') { - $path .= 'core/lang.json'; - } else { - $path .= 'core/features/'.str_replace('_', '/', $component).'/lang.json'; - } - break; - case 'addon': - $path .= 'addons/'.str_replace('_', '/', $component).'/lang.json'; - break; - case 'assets': - $path .= $type.'/'.$component.'.json'; - break; - default: - $path .= $type.'/lang.json'; - break; - - } - - if (is_file($path)) { - save_key($plainid, $value, $path); - } else { - echo "Cannot override: $path not found.\n"; - } - } -} - -/** - * Generates local module file to update languages in AMOS. - * - * @param [array] $appindex Translation appindex. - * @param [array] $translations English translations. - */ -function generate_local_module_file($appindex, $translations) { - echo 'Generate '.APPMODULENAME."\n"; - - $lmsstring = ""; - foreach ($appindex as $appkey => $lmskey) { - if (isset($translations[$appkey])) { - $lmsstring .= '$string[\''.$appkey.'\'] = \''.str_replace("'", "\'", $translations[$appkey]).'\';'."\n"; - } - } - - if (empty($lmsstring)) { - echo "ERROR, translations not found, you probably didn't run gulp lang!\n"; - - return; - } - - $filepath = '../../moodle-'.APPMODULENAME.'/lang/en/'.APPMODULENAME.'.php'; - $filecontents = file_get_contents($filepath); - - $startcomment = "/* AUTO START */\n"; - $endcomment = '/* AUTO END */'; - - $start = strpos($filecontents, $startcomment); - $start = $start === false ? 0 : $start + strlen($startcomment); - - $end = strpos($filecontents, $endcomment, $start); - $end = $end === false ? strlen($filecontents) : $end; - - $filecontents = substr_replace($filecontents, $lmsstring, $start, $end - $start); - - if (substr($filecontents, -2) != "\n\n") { - $filecontents .= "\n"; - } - - file_put_contents($filepath, $filecontents); -} diff --git a/scripts/lang_functions.sh b/scripts/lang_functions.sh old mode 100755 new mode 100644 index f3ab9392b..1cf030d0e --- a/scripts/lang_functions.sh +++ b/scripts/lang_functions.sh @@ -1,49 +1,15 @@ #!/bin/bash # -# Functions to fetch languages. +# Common functions to fetch languages. # -LANGPACKSFOLDER='../../moodle-langpacks' # Langpacks will be downloaded here. -BUCKET='moodle-lang-prod' -MOODLEORG_URL='https://download.moodle.org/download.php/direct/langpack' -DEFAULT_LASTVERSION='4.2' # Update it every version. +LANG_PATH='../src/assets/lang' +SUFFIX='' # Determines suffix of the langpacks to be merged. Ie, using wp will include en.json and en_wp.json + # (and the later will override the earlier). +LANGPACKS_PATH='/tmp/moodleapp-lang' -# Checks if AWS is available and configured. -function check_aws { - if [ ! -z $AWS_SERVICE ]; then - return - fi - - export AWS_SERVICE=1 - - aws --version &> /dev/null - if [ $? -ne 0 ]; then - export AWS_SERVICE=0 - echo 'AWS not installed. Check https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html for more info.' - return - fi - - # In order to login to AWS, use credentials file or AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY vars. - if [ ! -f ~/.aws/credentials ] && ([ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]); then - export AWS_SERVICE=0 - echo 'AWS Cannot authenticate. Use aws configure or set the proper env vars.' - return - fi -} - -function list_aws_files { - local folder="$1" - check_aws - - if [ $AWS_SERVICE -eq 1 ]; then - export AWS_FOLDERS=`aws s3 ls s3://$BUCKET/$1` - else - export AWS_FOLDERS=[] - fi -} - -# Get last version of Moodle to fetch latest languages. -function get_lang_version { +# Get the version of the Moodle App to fetch latest languages. +function get_app_version { if [ ! -z "${LANGVERSION}" ]; then return fi @@ -55,110 +21,6 @@ function get_lang_version { return fi - list_aws_files '' - LANGVERSION='' - for folder in $AWS_FOLDERS; do - if [ $folder != 'PRE' ]; then - LANGVERSION=${folder/\//} - fi - done - - if [ ! -z "${LANGVERSION}" ]; then - echo "Using last version $LANGVERSION detected" - return - fi - - LANGVERSION=$DEFAULT_LASTVERSION - echo "Using default version $LANGVERSION" -} - -# Create langfolder -function create_langfolder { - if [ ! -d $LANGPACKSFOLDER ]; then - mkdir $LANGPACKSFOLDER - fi -} - -# Get language list from the installed ones (will not discover new translations). -function get_language_folders { - list_aws_files "$LANGVERSION/" - - langs="" - for file in $AWS_FOLDERS; do - if [[ "$file" == *.zip ]]; then - file=${file/\.zip/} - langs+="$file " - fi - done - - if [ -z "${langs}" ]; then - # Get language list from the installed ones (will not discover new translations). - echo "Fallback language list will only get current installation languages" - langs=`jq -r '.languages | keys[]' ../moodle.config.json` - fi -} - -# Entry function to get a language file. -function get_language { - lang=$1 - lang=${lang/-/_} - - get_lang_version - - create_langfolder - - echo "Getting $lang language" - - pushd $LANGPACKSFOLDER > /dev/null - - curl -s $MOODLEORG_URL/$LANGVERSION/$lang.zip --output $lang.zip > /dev/null - size=$(du -k "$lang.zip" | cut -f 1) - if [ ! -n $lang.zip ] || [ $size -le 1 ]; then - echo "Wrong language name or corrupt file for $lang" - rm $lang.zip - - popd > /dev/null - return - fi - - rm -R $lang > /dev/null 2>&1> /dev/null - unzip -o -u $lang.zip > /dev/null - - # This is the AWS version to get the language but right now it's slower. - # aws s3 cp s3://$BUCKET/$LANGVERSION/$lang.zip . > /dev/null - - rm $lang.zip - popd > /dev/null -} - -# Entry function to get all language files. -function get_languages { - suffix=$1 - if [ -z $suffix ]; then - suffix='' - fi - - get_lang_version - - if [ -d $LANGPACKSFOLDER ]; then - lastupdate=`date -r $LANGPACKSFOLDER +%s` - currenttime=`date +%s` - ellapsedtime=$((currenttime - lastupdate)) - if [ $ellapsedtime -lt 3600 ]; then - echo 'Recently updated, skip update languages' - return - fi - else - create_langfolder - fi - - get_language_folders - - for lang in $langs; do - get_language "$lang" - - if [ ! -z $suffix ]; then - get_language "$lang$suffix" - fi - done + echo "Cannot decide version" + exit 1 } diff --git a/scripts/moodle_to_json.php b/scripts/moodle_to_json.php deleted file mode 100644 index 166ba1c87..000000000 --- a/scripts/moodle_to_json.php +++ /dev/null @@ -1,68 +0,0 @@ -. - -/** - * Script for converting moodle strings to json. - */ - -// Check we are in CLI. -if (isset($_SERVER['REMOTE_ADDR'])) { - exit(1); -} -define('MOODLE_INTERNAL', 1); -define('LANGPACKSFOLDER', '../../moodle-langpacks'); -define('APPMODULENAME','local_moodlemobileapp'); -define('ASSETSPATH', '../src/assets/lang/'); -define('CONFIG', '../moodle.config.json'); -define('OVERRIDE_LANG_SUFIX', false); - -global $strings; -require_once('lang_functions.php'); - -$config = file_get_contents(CONFIG); -$config = (array) json_decode($config); -$config_langs = array_keys(get_object_vars($config['languages'])); - -// Set languages to do. If script is called using a language it will be used as unique. -if (isset($argv[1]) && !empty($argv[1])) { - $forcedetect = false; - define('TOTRANSLATE', true); - $languages = explode(',', $argv[1]); -} else { - $forcedetect = true; - define('TOTRANSLATE', false); - $languages = $config_langs; -} - -if (!file_exists(ASSETSPATH)) { - mkdir(ASSETSPATH); -} - - -load_langindex(); - -$added_langs = build_languages($languages); - -if ($forcedetect) { - $new_langs = detect_languages($languages); - - if (!empty($new_langs)) { - echo "\n\n\nThe following languages are going to be added\n\n\n"; - $added_langs = build_languages($new_langs, $added_langs); - } -} - -add_langs_to_config($added_langs, $config); diff --git a/scripts/update_lang.sh b/scripts/update_lang.sh deleted file mode 100755 index d603e232e..000000000 --- a/scripts/update_lang.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# -# Script to update language packs on assets and detect new translated languages. -# ./update_lang.sh [language] -# If language is set it will only update the selected language. -# Edit lang_functions.sh LANGPACKSFOLDER variable to match your system's -# -source "functions.sh" -source "lang_functions.sh" - -forceLang=$1 - -print_title 'Generating language from code...' -npx gulp lang - -print_title 'Getting local mobile langs' -git clone --depth 1 https://github.com/moodlehq/moodle-local_moodlemobileapp.git ../../moodle-local_moodlemobileapp - -if [ -z $forceLang ]; then - get_languages - php -f moodle_to_json.php -else - get_language "$forceLang" - php -f moodle_to_json.php "$forceLang" -fi - -cp langindex.json ../../moodle-local_moodlemobileapp - -print_ok 'All done!' diff --git a/scripts/update_lang_functions.sh b/scripts/update_lang_functions.sh new file mode 100755 index 000000000..ef8b31069 --- /dev/null +++ b/scripts/update_lang_functions.sh @@ -0,0 +1,186 @@ +#!/bin/bash +# +# Functions to update langpacks. +# + +APPMODULENAME='local_moodlemobileapp' + +TOTAL_STRINGS=0 +LANGINDEX_STRINGS=0 + +function progressbar { + let _progress=(${1}*100/100*100)/100 + let _done=(${_progress}*4)/10 + let _left=40-$_done + _fill=$(printf "%${_done}s") + _empty=$(printf "%${_left}s") + bar=`printf "[${_fill// /#}${_empty// /-}] ${_progress}%%"` +} + +# Copy language file +function copy_lang { + lang=$1 + + index_keys=`jq -r 'to_entries[] | "\"\(.key)\","' langindex.json` + index_keys=`echo $index_keys | sed 's/,*$//'` + + hyphenlang=${lang/_/-} + langfilepath=$LANG_PATH/$hyphenlang.json + cp $LANGPACKS_PATH/$lang.json $langfilepath + + # Merge SUFFIX file if exists. + if [ ! -z "$SUFFIX" ] && [ -f "$LANGPACKS_PATH/${lang}_${SUFFIX}.json" ]; then + suffixfilepath="$LANGPACKS_PATH/${lang}_${SUFFIX}.json" + jq --indent 4 -s --sort-keys ".[0] + .[1]" $langfilepath $suffixfilepath > /tmp/moodle-langtmp.json + mv /tmp/moodle-langtmp.json $langfilepath + fi + + + # Remove strings non exiting on langindex. + query="with_entries(select([.key] | inside([$index_keys])))" + jq --indent 2 -r "$query" $langfilepath > /tmp/moodle-langtmp.json + mv /tmp/moodle-langtmp.json $langfilepath + + name=`jq -r .\"$lang\".name $LANGPACKS_PATH/languages.json` + local=`jq -r .\"$lang\".local $LANGPACKS_PATH/languages.json` + translated=`jq -r '. | length' $langfilepath` + percentage=`echo "($translated * 100) /$LANGINDEX_STRINGS" | bc` + progressbar $percentage + echo -e "Generated $hyphenlang\t $translated of $LANGINDEX_STRINGS\t $bar ($local local)" + + + # Add or update language name to config. + newlang="{\"$hyphenlang\": \"$name\"}" + languages=`jq -s --sort-keys ".[0].languages + $newlang" ../moodle.config.json` + jq --indent 4 -s ".[0].languages = $languages | .[0]" ../moodle.config.json > /tmp/moodle-langtmp.json + mv /tmp/moodle-langtmp.json ../moodle.config.json +} + +function detect_lang { + lang=$1 + + name=`jq -r .\"$lang\".name $LANGPACKS_PATH/languages.json` + if [ -z "$name" ] || [ "$name" == 'null' ]; then + continue + fi + + hyphenlang=${lang/_/-} + if [ -f $LANG_PATH/$hyphenlang.json ]; then + # Already exists + continue + fi + + local=`jq -r .\"$lang\".local $LANGPACKS_PATH/languages.json` + translated=`jq -r .\"$lang\".translated $LANGPACKS_PATH/languages.json` + percentage=`echo "($translated * 100) /$TOTAL_STRINGS" | bc` + progressbar $percentage + echo -e "Checking $lang\t $translated of $TOTAL_STRINGS \t $bar ($local local)"; + + if [[ ( $percentage -gt 75 && $local -gt 50 ) || ( $percentage -gt 50 && $local -gt 75 ) ]] ; then + name=`jq -r .\"$lang\".name $LANGPACKS_PATH/languages.json` + echo "*** NEW LANGUAGE DETECTED $lang - $name ***" + + copy_lang $lang + fi +} + +function load_langpacks { + get_app_version + + print_title 'Getting local mobile langs' + if [ -d $LANGPACKS_PATH ]; then + pushd $LANGPACKS_PATH + + git checkout "langpack_$LANGVERSION" + git pull + + if [ $? -ne 0 ]; then + echo "Cannot update language repository" + exit 1 + fi + + popd + else + git clone --depth 1 --single-branch --branch "langpack_$LANGVERSION" https://github.com/moodlehq/moodle-local_moodlemobileapp.git $LANGPACKS_PATH + if [ $? -ne 0 ]; then + echo "Cannot clone language repository" + exit 1 + fi + fi + + local_strings=`jq -r '.languages.local' $LANGPACKS_PATH/languages.json` + TOTAL_STRINGS=`jq -r '.languages.total' $LANGPACKS_PATH/languages.json` + LANGINDEX_STRINGS=`jq -r '. | length' langindex.json` + + print_message "Total strings to translate $TOTAL_STRINGS ($local_strings local)"; +} + +# Entry function to get all language files. +function get_languages { + print_title 'Copying existing languages' + # Existing languages, copy and clean the files. + langs=`jq -r '.languages | keys[]' ../moodle.config.json` + for lang in $langs; do + lang=${lang//-/_} + copy_lang $lang + done +} + +# Entry function to detect new languages. +function detect_languages { + # Do not detect new langs when suffix is set. + if [ ! -z $SUFFIX ]; then + return + fi + + print_title "Detect new languages" + langs=`jq -r 'keys[]' $LANGPACKS_PATH/languages.json` + for lang in $langs; do + if [[ $lang = *_wp ]]; then + # Skip Workplace. + continue + fi + + detect_lang $lang + done +} + +# Entry function to generate translation module file. +function generate_local_module_file { + if [ ! -d "../../moodle-$APPMODULENAME" ]; then + print_error "Module $APPMODULENAME directory does not exists, skipping..." + return + fi + + print_title "Generating $APPMODULENAME..." + + module_translations='' + + keys=`jq -r 'map_values(select(contains("local_moodlemobileapp"))) | keys[]' langindex.json` + for key in $keys; do + # Check if already parsed. + translation=`jq -r .\"$key\" $LANG_PATH/en.json` + if [ -z "$translation" ]; then + echo "Key $key not translated!" + continue + fi + translation="${translation//\'/\\\'}" + module_translations="$module_translations\$string['$key'] = '$translation';\n"; + done + + if [ -z "$module_translations" ]; then + print_error "ERROR, translations not found, you probably didn't run gulp lang!"; + return + fi + + echo -e $module_translations > /tmp/translations.php + + filepath="../../moodle-$APPMODULENAME/lang/en/$APPMODULENAME.php"; + + BEGIN_GEN=$(cat $filepath | grep -n '\/\* AUTO START \*\/' | sed 's/\(.*\):.*/\1/g') + END_GEN=$(cat $filepath | grep -n '\/\* AUTO END \*\/' | sed 's/\(.*\):.*/\1/g') + cat <(head -n $BEGIN_GEN $filepath) /tmp/translations.php <(tail -n +$END_GEN $filepath) > /tmp/translations_temp.php + mv /tmp/translations_temp.php $filepath + + cp langindex.json ../../moodle-$APPMODULENAME +} diff --git a/scripts/update_langpacks.sh b/scripts/update_langpacks.sh new file mode 100755 index 000000000..911226d5e --- /dev/null +++ b/scripts/update_langpacks.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# +# Script to update language packs on assets and detect new translated languages. +# ./update_langpacks.sh [detect] +# +# When detect is present, it will check other languages not included in moodle.config.json to be included in the build. +# It will alo generate the local module files and override the current lang.json on the src folder. +# + +DIR="${BASH_SOURCE%/*}" +if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi + +cd $DIR + +source "functions.sh" +source "lang_functions.sh" +source "update_lang_functions.sh" + +load_langpacks + +get_languages + +if [[ -z $1 ]]; then + print_ok 'All done!' + exit 0 +fi + +# Detect new languages and copy langindex to the translations folder. + +detect_languages + +generate_local_module_file + +gulp lang-override + +print_ok 'All done!' From b947fadc72ca3b434456c15b00ec060a8b731148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 15 Jun 2023 13:00:59 +0200 Subject: [PATCH 2/2] MOBILE-4343 lang: Updated langpacks --- moodle.config.json | 14 +- src/addons/block/activityresults/lang.json | 2 +- src/addons/block/badges/lang.json | 2 +- src/addons/block/blogmenu/lang.json | 2 +- src/addons/block/blogrecent/lang.json | 2 +- src/addons/block/blogtags/lang.json | 2 +- src/addons/block/calendarmonth/lang.json | 2 +- src/addons/block/calendarupcoming/lang.json | 2 +- src/addons/block/comments/lang.json | 2 +- src/addons/block/completionstatus/lang.json | 2 +- src/addons/block/glossaryrandom/lang.json | 2 +- src/addons/block/learningplans/lang.json | 2 +- src/addons/block/newsitems/lang.json | 2 +- src/addons/block/onlineusers/lang.json | 2 +- src/addons/block/privatefiles/lang.json | 2 +- src/addons/block/recentactivity/lang.json | 2 +- src/addons/block/rssclient/lang.json | 2 +- src/addons/block/selfcompletion/lang.json | 2 +- src/addons/block/tags/lang.json | 2 +- src/addons/blog/lang.json | 2 +- src/addons/competency/lang.json | 2 +- src/addons/coursecompletion/lang.json | 2 +- src/addons/mod/choice/lang.json | 2 +- src/addons/mod/folder/lang.json | 2 +- src/addons/mod/imscp/lang.json | 2 +- src/addons/mod/lesson/lang.json | 2 +- src/addons/mod/lti/lang.json | 2 +- src/addons/mod/page/lang.json | 2 +- src/addons/mod/survey/lang.json | 2 +- src/addons/mod/url/lang.json | 2 +- src/addons/privatefiles/lang.json | 2 +- src/assets/countries.json | 2 +- src/assets/mimetypes.json | 138 ++++++++++---------- src/core/features/comments/lang.json | 2 +- src/core/features/contentlinks/lang.json | 2 +- src/core/features/course/lang.json | 4 +- src/core/features/fileuploader/lang.json | 2 +- src/core/features/h5p/lang.json | 16 +-- src/core/features/question/lang.json | 2 +- src/core/features/reportbuilder/lang.json | 6 +- src/core/features/settings/lang.json | 6 +- src/core/features/sharedfiles/lang.json | 2 +- src/core/features/tag/lang.json | 4 +- 43 files changed, 130 insertions(+), 130 deletions(-) diff --git a/moodle.config.json b/moodle.config.json index 48d7ba498..2163e7027 100644 --- a/moodle.config.json +++ b/moodle.config.json @@ -10,18 +10,18 @@ "default_lang": "en", "languages": { "af": "Afrikaans", - "ar": "عربي", + "ar": "العربية", "az": "Azərbaycanca", "bg": "Български", "ca": "Català", "cs": "Čeština", "da": "Dansk", "de": "Deutsch", - "de-du": "Deutsch - Du", + "de-du": "Deutsch (du)", "el": "Ελληνικά", "en": "English", - "en-us": "English - United States", - "es": "Español", + "en-us": "English (United States)", + "es": "Español - Internacional", "es-mx": "Español - México", "eu": "Euskara", "fa": "فارسی", @@ -31,10 +31,10 @@ "he": "עברית", "hi": "हिंदी", "hr": "Hrvatski", - "hsb": "Hornjoserbsski", + "hsb": "Hornjoserbsce", "hu": "magyar", "hy": "Հայերեն", - "id": "Indonesian", + "id": "Bahasa Indonesia", "it": "Italiano", "ja": "日本語", "km": "ខ្មែរ", @@ -46,7 +46,7 @@ "mn": "Монгол", "mr": "मराठी", "nl": "Nederlands", - "no": "Norsk - bokmål", + "no": "Norsk", "pl": "Polski", "pt": "Português - Portugal", "pt-br": "Português - Brasil", diff --git a/src/addons/block/activityresults/lang.json b/src/addons/block/activityresults/lang.json index 4dd6abbb7..470ab1255 100644 --- a/src/addons/block/activityresults/lang.json +++ b/src/addons/block/activityresults/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Activity results" -} \ No newline at end of file +} diff --git a/src/addons/block/badges/lang.json b/src/addons/block/badges/lang.json index dd957321f..847d438bd 100644 --- a/src/addons/block/badges/lang.json +++ b/src/addons/block/badges/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Latest badges" -} \ No newline at end of file +} diff --git a/src/addons/block/blogmenu/lang.json b/src/addons/block/blogmenu/lang.json index 23541f7a0..be4ee9cc1 100644 --- a/src/addons/block/blogmenu/lang.json +++ b/src/addons/block/blogmenu/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Blog menu" -} \ No newline at end of file +} diff --git a/src/addons/block/blogrecent/lang.json b/src/addons/block/blogrecent/lang.json index a92c0cce5..4d022b3e2 100644 --- a/src/addons/block/blogrecent/lang.json +++ b/src/addons/block/blogrecent/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Recent blog entries" -} \ No newline at end of file +} diff --git a/src/addons/block/blogtags/lang.json b/src/addons/block/blogtags/lang.json index 683c3aa90..cc4488bcc 100644 --- a/src/addons/block/blogtags/lang.json +++ b/src/addons/block/blogtags/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Blog tags" -} \ No newline at end of file +} diff --git a/src/addons/block/calendarmonth/lang.json b/src/addons/block/calendarmonth/lang.json index 86a476c29..d0e208beb 100644 --- a/src/addons/block/calendarmonth/lang.json +++ b/src/addons/block/calendarmonth/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Calendar" -} \ No newline at end of file +} diff --git a/src/addons/block/calendarupcoming/lang.json b/src/addons/block/calendarupcoming/lang.json index 4d73d8f67..33f4bbffa 100644 --- a/src/addons/block/calendarupcoming/lang.json +++ b/src/addons/block/calendarupcoming/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Upcoming events" -} \ No newline at end of file +} diff --git a/src/addons/block/comments/lang.json b/src/addons/block/comments/lang.json index adcbcabae..6b5d42e46 100644 --- a/src/addons/block/comments/lang.json +++ b/src/addons/block/comments/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Comments" -} \ No newline at end of file +} diff --git a/src/addons/block/completionstatus/lang.json b/src/addons/block/completionstatus/lang.json index fe57356da..b531539b7 100644 --- a/src/addons/block/completionstatus/lang.json +++ b/src/addons/block/completionstatus/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Course completion status" -} \ No newline at end of file +} diff --git a/src/addons/block/glossaryrandom/lang.json b/src/addons/block/glossaryrandom/lang.json index 1ae4de38c..975e8cbbf 100644 --- a/src/addons/block/glossaryrandom/lang.json +++ b/src/addons/block/glossaryrandom/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Random glossary entry" -} \ No newline at end of file +} diff --git a/src/addons/block/learningplans/lang.json b/src/addons/block/learningplans/lang.json index 0a7f81e22..a047676aa 100644 --- a/src/addons/block/learningplans/lang.json +++ b/src/addons/block/learningplans/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Learning plans" -} \ No newline at end of file +} diff --git a/src/addons/block/newsitems/lang.json b/src/addons/block/newsitems/lang.json index 83b981297..2e719fbd7 100644 --- a/src/addons/block/newsitems/lang.json +++ b/src/addons/block/newsitems/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Latest announcements" -} \ No newline at end of file +} diff --git a/src/addons/block/onlineusers/lang.json b/src/addons/block/onlineusers/lang.json index 4bc6cd412..524bc8460 100644 --- a/src/addons/block/onlineusers/lang.json +++ b/src/addons/block/onlineusers/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Online users" -} \ No newline at end of file +} diff --git a/src/addons/block/privatefiles/lang.json b/src/addons/block/privatefiles/lang.json index bba9d4bc0..9a71bd905 100644 --- a/src/addons/block/privatefiles/lang.json +++ b/src/addons/block/privatefiles/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Private files" -} \ No newline at end of file +} diff --git a/src/addons/block/recentactivity/lang.json b/src/addons/block/recentactivity/lang.json index 29f7996e2..173afd573 100644 --- a/src/addons/block/recentactivity/lang.json +++ b/src/addons/block/recentactivity/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Recent activity" -} \ No newline at end of file +} diff --git a/src/addons/block/rssclient/lang.json b/src/addons/block/rssclient/lang.json index 18282971b..25574eafe 100644 --- a/src/addons/block/rssclient/lang.json +++ b/src/addons/block/rssclient/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Remote RSS feeds" -} \ No newline at end of file +} diff --git a/src/addons/block/selfcompletion/lang.json b/src/addons/block/selfcompletion/lang.json index 32521695a..8d171b35a 100644 --- a/src/addons/block/selfcompletion/lang.json +++ b/src/addons/block/selfcompletion/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Self completion" -} \ No newline at end of file +} diff --git a/src/addons/block/tags/lang.json b/src/addons/block/tags/lang.json index a4080dd78..7771c78e4 100644 --- a/src/addons/block/tags/lang.json +++ b/src/addons/block/tags/lang.json @@ -1,3 +1,3 @@ { "pluginname": "Tags" -} \ No newline at end of file +} diff --git a/src/addons/blog/lang.json b/src/addons/blog/lang.json index 6e183232f..c4b04081d 100644 --- a/src/addons/blog/lang.json +++ b/src/addons/blog/lang.json @@ -9,4 +9,4 @@ "publishtoworld": "Anyone in the world", "showonlyyourentries": "Show only your entries", "siteblogheading": "Site blog" -} \ No newline at end of file +} diff --git a/src/addons/competency/lang.json b/src/addons/competency/lang.json index e09256cb0..37dec65d3 100644 --- a/src/addons/competency/lang.json +++ b/src/addons/competency/lang.json @@ -47,4 +47,4 @@ "userplans": "Learning plans", "xcompetenciesproficientoutofy": "{{$a.x}} out of {{$a.y}} competencies are proficient", "xcompetenciesproficientoutofyincourse": "You are proficient in {{$a.x}} out of {{$a.y}} competencies in this course." -} \ No newline at end of file +} diff --git a/src/addons/coursecompletion/lang.json b/src/addons/coursecompletion/lang.json index 81ef0272e..4acee2760 100644 --- a/src/addons/coursecompletion/lang.json +++ b/src/addons/coursecompletion/lang.json @@ -20,4 +20,4 @@ "requirement": "Requirement", "status": "Status", "viewcoursereport": "View course report" -} \ No newline at end of file +} diff --git a/src/addons/mod/choice/lang.json b/src/addons/mod/choice/lang.json index 7adee8f2e..7b60c3b6d 100644 --- a/src/addons/mod/choice/lang.json +++ b/src/addons/mod/choice/lang.json @@ -25,4 +25,4 @@ "savemychoice": "Save my choice", "userchoosethisoption": "Users who chose this option", "yourselection": "Your selection" -} \ No newline at end of file +} diff --git a/src/addons/mod/folder/lang.json b/src/addons/mod/folder/lang.json index 40bcdb36a..cee1b560a 100644 --- a/src/addons/mod/folder/lang.json +++ b/src/addons/mod/folder/lang.json @@ -1,4 +1,4 @@ { "emptyfilelist": "There are no files to show.", "modulenameplural": "Folders" -} \ No newline at end of file +} diff --git a/src/addons/mod/imscp/lang.json b/src/addons/mod/imscp/lang.json index 441eea598..9204b4ef8 100644 --- a/src/addons/mod/imscp/lang.json +++ b/src/addons/mod/imscp/lang.json @@ -3,4 +3,4 @@ "modulenameplural": "IMS content packages", "showmoduledescription": "Show description", "toc": "TOC" -} \ No newline at end of file +} diff --git a/src/addons/mod/lesson/lang.json b/src/addons/mod/lesson/lang.json index 3c310fca4..8a5178451 100644 --- a/src/addons/mod/lesson/lang.json +++ b/src/addons/mod/lesson/lang.json @@ -83,4 +83,4 @@ "youranswer": "Your answer", "yourcurrentgradeisoutof": "Your current grade is {{$a.grade}} out of {{$a.total}}", "youshouldview": "You should answer at least: {{$a}}" -} \ No newline at end of file +} diff --git a/src/addons/mod/lti/lang.json b/src/addons/mod/lti/lang.json index 7a70ea4e7..eaa294329 100644 --- a/src/addons/mod/lti/lang.json +++ b/src/addons/mod/lti/lang.json @@ -3,4 +3,4 @@ "errorinvalidlaunchurl": "The launch URL is not valid.", "launchactivity": "Launch the activity", "modulenameplural": "External tools" -} \ No newline at end of file +} diff --git a/src/addons/mod/page/lang.json b/src/addons/mod/page/lang.json index 34bd9817d..c6920f9f3 100644 --- a/src/addons/mod/page/lang.json +++ b/src/addons/mod/page/lang.json @@ -1,4 +1,4 @@ { "errorwhileloadingthepage": "Error while loading the page content.", "modulenameplural": "Pages" -} \ No newline at end of file +} diff --git a/src/addons/mod/survey/lang.json b/src/addons/mod/survey/lang.json index 9ccaff870..dd0cef354 100644 --- a/src/addons/mod/survey/lang.json +++ b/src/addons/mod/survey/lang.json @@ -7,4 +7,4 @@ "responses": "Responses", "results": "Results", "surveycompletednograph": "You have completed this survey." -} \ No newline at end of file +} diff --git a/src/addons/mod/url/lang.json b/src/addons/mod/url/lang.json index 18eff8be5..379f3833b 100644 --- a/src/addons/mod/url/lang.json +++ b/src/addons/mod/url/lang.json @@ -2,4 +2,4 @@ "accessurl": "Access the URL", "modulenameplural": "URLs", "pointingtourl": "URL that the resource points to." -} \ No newline at end of file +} diff --git a/src/addons/privatefiles/lang.json b/src/addons/privatefiles/lang.json index b923f6141..585d7684d 100644 --- a/src/addons/privatefiles/lang.json +++ b/src/addons/privatefiles/lang.json @@ -5,4 +5,4 @@ "files": "Files", "privatefiles": "Private files", "sitefiles": "Site files" -} \ No newline at end of file +} diff --git a/src/assets/countries.json b/src/assets/countries.json index 777763e84..39bdf09e7 100644 --- a/src/assets/countries.json +++ b/src/assets/countries.json @@ -248,4 +248,4 @@ "ZA": "South Africa", "ZM": "Zambia", "ZW": "Zimbabwe" -} \ No newline at end of file +} diff --git a/src/assets/mimetypes.json b/src/assets/mimetypes.json index a1b422dc5..4c5192c63 100644 --- a/src/assets/mimetypes.json +++ b/src/assets/mimetypes.json @@ -1,71 +1,71 @@ { - "application/dash_xml": "Dynamic Adaptive Streaming over HTTP (MPEG-DASH)", - "application/epub_zip": "EPUB ebook", - "application/json": "{{$a.MIMETYPE2}} text", - "application/msword": "Word document", - "application/pdf": "PDF document", - "application/vnd.google-apps.audio": "Google Drive audio", - "application/vnd.google-apps.document": "Google Docs", - "application/vnd.google-apps.drawing": "Google Drawing", - "application/vnd.google-apps.file": "Google Drive file", - "application/vnd.google-apps.folder": "Google Drive folder", - "application/vnd.google-apps.form": "Google Forms", - "application/vnd.google-apps.fusiontable": "Google Fusion Tables", - "application/vnd.google-apps.presentation": "Google Slides", - "application/vnd.google-apps.script": "Google Apps Scripts", - "application/vnd.google-apps.site": "Google Sites", - "application/vnd.google-apps.spreadsheet": "Google Sheets", - "application/vnd.google-apps.video": "Google Drive video", - "application/vnd.moodle.backup": "Moodle backup", - "application/vnd.ms-excel": "Excel spreadsheet", - "application/vnd.ms-excel.sheet.macroEnabled.12": "Excel 2007 macro-enabled workbook", - "application/vnd.ms-powerpoint": "Powerpoint presentation", - "application/vnd.oasis.opendocument.spreadsheet": "OpenDocument Spreadsheet", - "application/vnd.oasis.opendocument.spreadsheet-template": "OpenDocument Spreadsheet template", - "application/vnd.oasis.opendocument.text": "OpenDocument Text document", - "application/vnd.oasis.opendocument.text-template": "OpenDocument Text template", - "application/vnd.oasis.opendocument.text-web": "OpenDocument Web page template", - "application/vnd.openxmlformats-officedocument.presentationml.presentation": "Powerpoint 2007 presentation", - "application/vnd.openxmlformats-officedocument.presentationml.slideshow": "Powerpoint 2007 slideshow", - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "Excel 2007 spreadsheet", - "application/vnd.openxmlformats-officedocument.spreadsheetml.template": "Excel 2007 template", - "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "Word 2007 document", - "application/x-iwork-keynote-sffkey": "iWork Keynote presentation", - "application/x-iwork-numbers-sffnumbers": "iWork Numbers spreadsheet", - "application/x-iwork-pages-sffpages": "iWork Pages document", - "application/x-javascript": "JavaScript source", - "application/x-mpegURL": "HTTP Live Streaming (HLS)", - "application/x-mspublisher": "Publisher document", - "application/x-shockwave-flash": "Flash animation", - "application/xhtml_xml": "XHTML document", - "archive": "Archive ({{$a.EXT}})", - "audio": "Audio file ({{$a.EXT}})", - "default": "{{$a.mimetype}}", - "document/unknown": "File", - "group:archive": "Archive files", - "group:audio": "Audio files", - "group:document": "Document files", - "group:html_audio": "Audio files natively supported by browsers", - "group:html_track": "HTML track files", - "group:html_video": "Video files natively supported by browsers", - "group:image": "Image files", - "group:media_source": "Streaming media", - "group:optimised_image": "Image files to be optimised, such as badges", - "group:presentation": "Presentation files", - "group:sourcecode": "Source code", - "group:spreadsheet": "Spreadsheet files", - "group:video": "Video files", - "group:web_audio": "Audio files used on the web", - "group:web_file": "Web files", - "group:web_image": "Image files used on the web", - "group:web_video": "Video files used on the web", - "image": "Image ({{$a.MIMETYPE2}})", - "image/vnd.microsoft.icon": "Windows icon", - "text/css": "Cascading Style-Sheet", - "text/csv": "Comma-separated values", - "text/html": "HTML document", - "text/plain": "Text file", - "text/rtf": "RTF document", - "text/vtt": "Web Video Text Track", - "video": "Video file ({{$a.EXT}})" + "application/dash_xml": "Dynamic Adaptive Streaming over HTTP (MPEG-DASH)", + "application/epub_zip": "EPUB ebook", + "application/json": "{{$a.MIMETYPE2}} text", + "application/msword": "Word document", + "application/pdf": "PDF document", + "application/vnd.google-apps.audio": "Google Drive audio", + "application/vnd.google-apps.document": "Google Docs", + "application/vnd.google-apps.drawing": "Google Drawing", + "application/vnd.google-apps.file": "Google Drive file", + "application/vnd.google-apps.folder": "Google Drive folder", + "application/vnd.google-apps.form": "Google Forms", + "application/vnd.google-apps.fusiontable": "Google Fusion Tables", + "application/vnd.google-apps.presentation": "Google Slides", + "application/vnd.google-apps.script": "Google Apps Scripts", + "application/vnd.google-apps.site": "Google Sites", + "application/vnd.google-apps.spreadsheet": "Google Sheets", + "application/vnd.google-apps.video": "Google Drive video", + "application/vnd.moodle.backup": "Moodle backup", + "application/vnd.ms-excel": "Excel spreadsheet", + "application/vnd.ms-excel.sheet.macroEnabled.12": "Excel 2007 macro-enabled workbook", + "application/vnd.ms-powerpoint": "Powerpoint presentation", + "application/vnd.oasis.opendocument.spreadsheet": "OpenDocument Spreadsheet", + "application/vnd.oasis.opendocument.spreadsheet-template": "OpenDocument Spreadsheet template", + "application/vnd.oasis.opendocument.text": "OpenDocument Text document", + "application/vnd.oasis.opendocument.text-template": "OpenDocument Text template", + "application/vnd.oasis.opendocument.text-web": "OpenDocument Web page template", + "application/vnd.openxmlformats-officedocument.presentationml.presentation": "Powerpoint 2007 presentation", + "application/vnd.openxmlformats-officedocument.presentationml.slideshow": "Powerpoint 2007 slideshow", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "Excel 2007 spreadsheet", + "application/vnd.openxmlformats-officedocument.spreadsheetml.template": "Excel 2007 template", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "Word 2007 document", + "application/x-iwork-keynote-sffkey": "iWork Keynote presentation", + "application/x-iwork-numbers-sffnumbers": "iWork Numbers spreadsheet", + "application/x-iwork-pages-sffpages": "iWork Pages document", + "application/x-javascript": "JavaScript source", + "application/x-mpegURL": "HTTP Live Streaming (HLS)", + "application/x-mspublisher": "Publisher document", + "application/x-shockwave-flash": "Flash animation", + "application/xhtml_xml": "XHTML document", + "archive": "Archive ({{$a.EXT}})", + "audio": "Audio file ({{$a.EXT}})", + "default": "{{$a.mimetype}}", + "document/unknown": "File", + "group:archive": "Archive files", + "group:audio": "Audio files", + "group:document": "Document files", + "group:html_audio": "Audio files natively supported by browsers", + "group:html_track": "HTML track files", + "group:html_video": "Video files natively supported by browsers", + "group:image": "Image files", + "group:media_source": "Streaming media", + "group:optimised_image": "Image files to be optimised, such as badges", + "group:presentation": "Presentation files", + "group:sourcecode": "Source code", + "group:spreadsheet": "Spreadsheet files", + "group:video": "Video files", + "group:web_audio": "Audio files used on the web", + "group:web_file": "Web files", + "group:web_image": "Image files used on the web", + "group:web_video": "Video files used on the web", + "image": "Image ({{$a.MIMETYPE2}})", + "image/vnd.microsoft.icon": "Windows icon", + "text/css": "Cascading Style-Sheet", + "text/csv": "Comma-separated values", + "text/html": "HTML document", + "text/plain": "Text file", + "text/rtf": "RTF document", + "text/vtt": "Web Video Text Track", + "video": "Video file ({{$a.EXT}})" } diff --git a/src/core/features/comments/lang.json b/src/core/features/comments/lang.json index c48dcce17..1ff89ef1f 100644 --- a/src/core/features/comments/lang.json +++ b/src/core/features/comments/lang.json @@ -9,4 +9,4 @@ "nocomments": "No comments", "savecomment": "Save comment", "warningcommentsnotsent": "Couldn't sync comments. {{error}}" -} \ No newline at end of file +} diff --git a/src/core/features/contentlinks/lang.json b/src/core/features/contentlinks/lang.json index 460c6acac..e3795794d 100644 --- a/src/core/features/contentlinks/lang.json +++ b/src/core/features/contentlinks/lang.json @@ -5,4 +5,4 @@ "errornoactions": "Couldn't find an action to perform with this link.", "errornosites": "Couldn't find any site to handle this link.", "errorredirectothersite": "The redirect URL cannot point to a different site." -} \ No newline at end of file +} diff --git a/src/core/features/course/lang.json b/src/core/features/course/lang.json index 33b03e34d..d1501f66e 100644 --- a/src/core/features/course/lang.json +++ b/src/core/features/course/lang.json @@ -3,7 +3,7 @@ "activitynotyetviewableremoteaddon": "Your organisation installed a plugin that is not yet supported.", "allsections": "All sections", "aria:sectionprogress": "Section progress:", - "availablespace": " You currently have about {{available}} free space.", + "availablespace": "You currently have about {{available}} free space.", "cannotdeletewhiledownloading": "Files cannot be deleted while the activity is being downloaded. Please wait for the download to finish.", "completion_automatic:done": "Done:", "completion_automatic:failed": "Failed:", @@ -20,7 +20,7 @@ "confirmdownload": "You are about to download {{size}}.{{availableSpace}} Are you sure you want to continue?", "confirmdownloadunknownsize": "It was not possible to calculate the size of the download.{{availableSpace}} Are you sure you want to continue?", "confirmdownloadzerosize": "You are about to start downloading.{{availableSpace}} Are you sure you want to continue?", - "confirmlimiteddownload": "You are not currently connected to Wi-Fi. ", + "confirmlimiteddownload": "You are not currently connected to Wi-Fi.", "confirmpartialdownloadsize": "You are about to download at least {{size}}.{{availableSpace}} Are you sure you want to continue?", "couldnotloadsectioncontent": "Could not load the section content. Please try again later.", "couldnotloadsections": "Could not load the sections. Please try again later.", diff --git a/src/core/features/fileuploader/lang.json b/src/core/features/fileuploader/lang.json index 588b497ee..cc0b876cc 100644 --- a/src/core/features/fileuploader/lang.json +++ b/src/core/features/fileuploader/lang.json @@ -15,8 +15,8 @@ "errorreadingfile": "Error reading file.", "errorwhileuploading": "An error occurred during the file upload.", "file": "File", - "fileuploaded": "The file was successfully uploaded.", "filesofthesetypes": "Accepted file types:", + "fileuploaded": "The file was successfully uploaded.", "invalidfiletype": "{{$a}} filetype cannot be accepted.", "maxbytesfile": "The file {{$a.file}} is too large. The maximum size you can upload is {{$a.size}}.", "microphonepermissiondenied": "Permission to access the microphone has been denied.", diff --git a/src/core/features/h5p/lang.json b/src/core/features/h5p/lang.json index 60276c04d..40d96721a 100644 --- a/src/core/features/h5p/lang.json +++ b/src/core/features/h5p/lang.json @@ -1,8 +1,8 @@ { "a11yTitle:label": "Assistive Technologies label", - "add": "Add", "acceptTerms": "I accept the terms of use", "accountDetailsLinkText": "here", + "add": "Add", "additionallicenseinfo": "Any additional information about the licence", "address": "Address", "age": "Typical age", @@ -15,11 +15,11 @@ "authorrole": "Author's role", "back": "Back", "by": "by", - "cancellabel": "Cancel", "cancelPublishConfirmationDialogCancelButtonText": "No", "cancelPublishConfirmationDialogConfirmButtonText": "Yes", "cancelPublishConfirmationDialogDescription": "Are you sure you want to cancel the sharing process?", "cancelPublishConfirmationDialogTitle": "Cancel sharing", + "cancellabel": "Cancel", "ccattribution": "Attribution (CC BY)", "ccattributionnc": "Attribution-NonCommercial (CC BY-NC)", "ccattributionncnd": "Attribution-NonCommercial-NoDerivs (CC BY-NC-ND)", @@ -40,8 +40,8 @@ "connectionReestablished": "Connection reestablished.", "contactPerson": "Contact person", "contentCopied": "Content is copied to the clipboard", - "contentchanged": "This content has changed since you last used it.", "contentLicenseTitle": "Content license info", + "contentchanged": "This content has changed since you last used it.", "contenttype": "Content type", "copyright": "Rights of use", "copyrightinfo": "Copyright information", @@ -56,10 +56,10 @@ "discipline:dropdownButton": "Dropdown button", "discipline:in": "in", "discipline:searchPlaceholder": "Type to search for disciplines", - "disciplines": "Disciplines", - "disciplineLabel": "Disciplines", "disciplineDescription": "You can select multiple disciplines", + "disciplineLabel": "Disciplines", "disciplineLimitReachedMessage": "You can select up to :numDisciplines disciplines", + "disciplines": "Disciplines", "download": "Download", "downloadtitle": "Download this content as a H5P file.", "editInfoTitle": "Edit info for :title", @@ -78,9 +78,9 @@ "icon": "Icon", "iconDescription": "640x480px. If not selected content will use category icon", "invalidAge": "Invalid input format for Typical age. Possible input formats separated by commas: \"1, 34-45, -50, -59-\".", + "keywordExists": "Keyword already exists!", "keywords": "Keywords", "keywordsDescription": "You can add multiple keywords separated by commas. Press \"Enter\" or \"Add\" to confirm keywords", - "keywordExists": "Keyword already exists!", "keywordsExits": "Keywords already exists!", "keywordsPlaceholder": "Add keywords", "language": "Language", @@ -100,10 +100,10 @@ "licenseV1": "Version 1", "licenseV2": "Version 2", "licenseV3": "Version 3", + "licenseVersionDescription": "Select a license version", "licensee": "Licensee", "licenseextras": "Licence extras", "licenseversion": "Licence version", - "licenseVersionDescription": "Select a license version", "logoUploadText": "Organization logo or avatar", "longDescription": "Long description", "longDescriptionPlaceholder": "Long description of your content", @@ -147,9 +147,9 @@ "screenshots": "Screenshots", "screenshotsDescription": "Add up to five screenshots of your content", "share": "Share", - "shared": "Shared", "shareFailed": "Share failed.", "shareTryAgain": "Something went wrong, please try to share again.", + "shared": "Shared", "sharingNote": "All content details can be edited after sharing", "shortDescription": "Short description", "shortDescriptionPlaceholder": "Short description of your content", diff --git a/src/core/features/question/lang.json b/src/core/features/question/lang.json index ee7018835..897bd5d8c 100644 --- a/src/core/features/question/lang.json +++ b/src/core/features/question/lang.json @@ -19,4 +19,4 @@ "questionmessage": "Question {{$a}}: {{$b}}", "questionno": "Question {{$a}}", "requiresgrading": "Requires grading" -} \ No newline at end of file +} diff --git a/src/core/features/reportbuilder/lang.json b/src/core/features/reportbuilder/lang.json index 08f70940e..cf6891c6e 100644 --- a/src/core/features/reportbuilder/lang.json +++ b/src/core/features/reportbuilder/lang.json @@ -1,9 +1,9 @@ { + "filtersapplied": "There may be filters applied to this view. To edit filters or change the sorting order, open this report on your browser.", + "hidecolumns": "Hide columns", "modifiedby": "Modified by", "reports": "Reports", - "filtersapplied": "There may be filters applied to this view. To edit filters or change the sorting order, open this report on your browser.", "reportsource": "Report source", - "timecreated": "Time created", "showcolumns": "Show columns", - "hidecolumns": "Hide columns" + "timecreated": "Time created" } diff --git a/src/core/features/settings/lang.json b/src/core/features/settings/lang.json index db8630f5f..6a1f92534 100644 --- a/src/core/features/settings/lang.json +++ b/src/core/features/settings/lang.json @@ -8,14 +8,14 @@ "cannotsyncwithoutwifi": "Your device is not connected to Wi-Fi. Connect to a Wi-Fi network or turn off Data Saver in the app settings.", "changelanguage": "Change to {{$a}}", "changelanguagealert": "Changing the language will restart the app.", + "colorscheme": "Color Scheme", "colorscheme-dark": "Dark", "colorscheme-light": "Light", - "colorscheme-system-notice": "System default mode will depend on your device support.", "colorscheme-system": "System default", - "colorscheme": "Color Scheme", + "colorscheme-system-notice": "System default mode will depend on your device support.", "compilationinfo": "Compilation info", - "connectwifitosync": "Connect to a Wi-Fi network or turn off Data saver to synchronise sites.", "connecttosync": "Your device is offline. Connect to the internet to synchronise sites.", + "connectwifitosync": "Connect to a Wi-Fi network or turn off Data saver to synchronise sites.", "copyinfo": "Copy device info on the clipboard", "cordovadevicemodel": "Cordova device model", "cordovadeviceosversion": "Cordova device OS version", diff --git a/src/core/features/sharedfiles/lang.json b/src/core/features/sharedfiles/lang.json index c7ba93a40..23d22e89a 100644 --- a/src/core/features/sharedfiles/lang.json +++ b/src/core/features/sharedfiles/lang.json @@ -8,4 +8,4 @@ "replace": "Replace", "sharedfiles": "Shared files", "successstorefile": "File successfully stored. Select the file to upload to your private files or use in an activity." -} \ No newline at end of file +} diff --git a/src/core/features/tag/lang.json b/src/core/features/tag/lang.json index bf320e3f6..e5b47fd49 100644 --- a/src/core/features/tag/lang.json +++ b/src/core/features/tag/lang.json @@ -3,16 +3,16 @@ "errorareanotsupported": "This tag area is not supported by the app.", "inalltagcoll": "Everywhere", "itemstaggedwith": "{{$a.tagarea}} tagged with \"{{$a.tag}}\"", - "notagsfound": "No tags matching \"{{$a}}\" found", "noresultsfor": "No results for \"{{$a}}\"", + "notagsfound": "No tags matching \"{{$a}}\" found", "searchtags": "Search tags", "showingfirsttags": "Showing {{$a}} most popular tags", "tag": "Tag", - "tagareabadgedescription": "There are {{count}} items.", "tagarea_course": "Courses", "tagarea_course_modules": "Activities and resources", "tagarea_post": "Blog posts", "tagarea_user": "User interests", + "tagareabadgedescription": "There are {{count}} items.", "tags": "Tags", "warningareasnotsupported": "Some of the tag areas are not displayed because they are not supported by the app." }