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/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/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!'
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."
}