Merge branch 'system-language-names' into 'master'
get language names from system, instead of hard coded list Closes #908 and #858 See merge request !461
This commit is contained in:
commit
78ecba646c
@ -13,7 +13,6 @@ before_script:
|
||||
test:
|
||||
script:
|
||||
- cd app
|
||||
- ./tools/langs-list-check.py
|
||||
- ./tools/check-string-format.py
|
||||
- cd ..
|
||||
- ./gradlew assemble -PdisablePreDex
|
||||
|
23
RELEASE_CHECKLIST.md
Normal file
23
RELEASE_CHECKLIST.md
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
# Release Checklist
|
||||
|
||||
This is the things that need to happen for all releases, alpha or stable:
|
||||
|
||||
* pull translations from Weblate: ./tools/pull-trans.sh
|
||||
|
||||
* rebase Weblate in its web interface, since we squash commits
|
||||
|
||||
* update `versionCode` in _app/build.gradle_
|
||||
|
||||
* make signed tag with version name
|
||||
|
||||
* update _metadata/org.fdroid.fdroid.txt_ in _fdroiddata_
|
||||
|
||||
## Stable releases
|
||||
|
||||
For stable releases, there are a couple more steps to do __before__
|
||||
making the release tag:
|
||||
|
||||
* update CHANGELOG.md
|
||||
|
||||
* run `./tools/trim-incomplete-translations-for-release.py`
|
@ -27,7 +27,6 @@ import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
@ -36,16 +35,15 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.StrictMode;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.nostra13.universalimageloader.cache.disc.impl.LimitedAgeDiskCache;
|
||||
import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||
|
||||
import info.guardianproject.netcipher.NetCipher;
|
||||
import info.guardianproject.netcipher.proxy.OrbotHelper;
|
||||
import org.acra.ACRA;
|
||||
import org.acra.ReportingInteractionMode;
|
||||
import org.acra.annotation.ReportsCrashes;
|
||||
@ -59,17 +57,13 @@ import org.fdroid.fdroid.data.Repo;
|
||||
import org.fdroid.fdroid.installer.InstallHistoryService;
|
||||
import org.fdroid.fdroid.net.ImageLoaderForUIL;
|
||||
import org.fdroid.fdroid.net.WifiStateChangeService;
|
||||
import sun.net.www.protocol.bluetooth.Handler;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.URLStreamHandlerFactory;
|
||||
import java.security.Security;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import info.guardianproject.netcipher.NetCipher;
|
||||
import info.guardianproject.netcipher.proxy.OrbotHelper;
|
||||
import sun.net.www.protocol.bluetooth.Handler;
|
||||
|
||||
@ReportsCrashes(mailTo = "reports@f-droid.org",
|
||||
mode = ReportingInteractionMode.DIALOG,
|
||||
@ -82,8 +76,6 @@ public class FDroidApp extends Application {
|
||||
|
||||
public static final String SYSTEM_DIR_NAME = Environment.getRootDirectory().getAbsolutePath();
|
||||
|
||||
private static Locale locale;
|
||||
|
||||
// for the local repo on this device, all static since there is only one
|
||||
public static volatile int port;
|
||||
public static volatile String ipAddressString;
|
||||
@ -181,25 +173,10 @@ public class FDroidApp extends Application {
|
||||
repo = new Repo();
|
||||
}
|
||||
|
||||
public void updateLanguage() {
|
||||
Context ctx = getBaseContext();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
String lang = prefs.getString(Preferences.PREF_LANGUAGE, "");
|
||||
locale = Utils.getLocaleFromAndroidLangTag(lang);
|
||||
applyLanguage();
|
||||
}
|
||||
|
||||
private void applyLanguage() {
|
||||
Context ctx = getBaseContext();
|
||||
Configuration cfg = new Configuration();
|
||||
cfg.locale = locale == null ? Locale.getDefault() : locale;
|
||||
ctx.getResources().updateConfiguration(cfg, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
applyLanguage();
|
||||
Languages.setLanguage(this, Preferences.get().getLangauge(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -215,7 +192,9 @@ public class FDroidApp extends Application {
|
||||
.penaltyLog()
|
||||
.build());
|
||||
}
|
||||
updateLanguage();
|
||||
Preferences.setup(this);
|
||||
Languages.setup(getClass(), R.string.pref_language_default);
|
||||
Languages.setLanguage(this, Preferences.get().getLangauge(), false);
|
||||
|
||||
ACRA.init(this);
|
||||
if (isAcraProcess()) {
|
||||
@ -224,7 +203,6 @@ public class FDroidApp extends Application {
|
||||
|
||||
PRNGFixes.apply();
|
||||
|
||||
Preferences.setup(this);
|
||||
curTheme = Preferences.get().getTheme();
|
||||
Preferences.get().configureProxy();
|
||||
|
||||
@ -325,13 +303,13 @@ public class FDroidApp extends Application {
|
||||
|
||||
/**
|
||||
* Asks if the current process is "org.fdroid.fdroid:acra".
|
||||
*
|
||||
* <p>
|
||||
* This is helpful for bailing out of the {@link FDroidApp#onCreate} method early, preventing
|
||||
* problems that arise from executing the code twice. This happens due to the `android:process`
|
||||
* statement in AndroidManifest.xml causes another process to be created to run
|
||||
* {@link org.fdroid.fdroid.acra.CrashReportActivity}. This was causing lots of things to be
|
||||
* started/run twice including {@link CleanCacheService} and {@link WifiStateChangeService}.
|
||||
*
|
||||
* <p>
|
||||
* Note that it is not perfect, because some devices seem to not provide a list of running app
|
||||
* processes when asked. In such situations, F-Droid may regress to the behaviour where some
|
||||
* services may run twice and thus cause weirdness or slowness. However that is probably better
|
||||
|
285
app/src/main/java/org/fdroid/fdroid/Languages.java
Normal file
285
app/src/main/java/org/fdroid/fdroid/Languages.java
Normal file
@ -0,0 +1,285 @@
|
||||
package org.fdroid.fdroid;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.res.AssetManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public final class Languages {
|
||||
public static final String TAG = "Languages";
|
||||
|
||||
public static final String USE_SYSTEM_DEFAULT = "";
|
||||
|
||||
private static final Locale DEFAULT_LOCALE;
|
||||
private static final Locale TIBETAN = new Locale("bo");
|
||||
private static final Locale CHINESE_HONG_KONG = new Locale("zh", "HK");
|
||||
private static final String DEFAULT_STRING = "System Default";
|
||||
|
||||
private static Locale locale;
|
||||
private static Languages singleton;
|
||||
private static Class<?> clazz;
|
||||
private static int resId;
|
||||
private static Map<String, String> tmpMap = new TreeMap<>();
|
||||
private static Map<String, String> nameMap;
|
||||
|
||||
static {
|
||||
DEFAULT_LOCALE = Locale.getDefault();
|
||||
}
|
||||
|
||||
private Languages(Activity activity) {
|
||||
AssetManager assets = activity.getAssets();
|
||||
Configuration config = activity.getResources().getConfiguration();
|
||||
// Resources() requires DisplayMetrics, but they are only needed for drawables
|
||||
DisplayMetrics ignored = new DisplayMetrics();
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(ignored);
|
||||
Resources resources;
|
||||
Set<Locale> localeSet = new LinkedHashSet<>();
|
||||
for (Locale locale : LOCALES_TO_TEST) {
|
||||
config.locale = locale;
|
||||
resources = new Resources(assets, ignored, config);
|
||||
if (!TextUtils.equals(DEFAULT_STRING, resources.getString(resId))
|
||||
|| locale.equals(Locale.ENGLISH)) {
|
||||
localeSet.add(locale);
|
||||
}
|
||||
}
|
||||
for (Locale locale : localeSet) {
|
||||
if (locale.equals(TIBETAN)) {
|
||||
// include English name for devices without Tibetan font support
|
||||
tmpMap.put(TIBETAN.getLanguage(), "Tibetan བོད་སྐད།"); // Tibetan
|
||||
} else if (locale.equals(Locale.SIMPLIFIED_CHINESE)) {
|
||||
tmpMap.put(Locale.SIMPLIFIED_CHINESE.toString(), "中文 (中国)"); // Chinese (China)
|
||||
} else if (locale.equals(Locale.TRADITIONAL_CHINESE)) {
|
||||
tmpMap.put(Locale.TRADITIONAL_CHINESE.toString(), "中文 (台灣)"); // Chinese (Taiwan)
|
||||
} else if (locale.equals(CHINESE_HONG_KONG)) {
|
||||
tmpMap.put(CHINESE_HONG_KONG.toString(), "中文 (香港)"); // Chinese (Hong Kong)
|
||||
} else {
|
||||
tmpMap.put(locale.getLanguage(), capitalize(locale.getDisplayLanguage(locale)));
|
||||
}
|
||||
}
|
||||
|
||||
/* SYSTEM_DEFAULT is a fake one for displaying in a chooser menu. */
|
||||
localeSet.add(null);
|
||||
tmpMap.put(USE_SYSTEM_DEFAULT, activity.getString(resId));
|
||||
nameMap = Collections.unmodifiableMap(tmpMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of {@link Languages} to work with, providing the
|
||||
* {@link Activity} that is will be working as part of, as well as the
|
||||
* {@code resId} that has the exact string "Use System Default",
|
||||
* i.e. {@code R.string.use_system_default}.
|
||||
* <p/>
|
||||
* That string resource {@code resId} is also used to find the supported
|
||||
* translations: if an included translation has a translated string that
|
||||
* matches that {@code resId}, then that language will be included as a
|
||||
* supported language.
|
||||
*
|
||||
* @param clazz the {@link Class} of the default {@code Activity},
|
||||
* usually the main {@code Activity} from where the
|
||||
* Settings is launched from.
|
||||
* @param resId the string resource ID to for the string "System Default",
|
||||
* e.g. {@code R.string.pref_language_default}
|
||||
*/
|
||||
public static void setup(Class<?> clazz, int resId) {
|
||||
if (Languages.clazz == null) {
|
||||
Languages.clazz = clazz;
|
||||
Languages.resId = resId;
|
||||
} else {
|
||||
throw new RuntimeException("Languages singleton was already initialized, duplicate call to Languages.setup()!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param activity the {@link Activity} this is working as part of
|
||||
* @return the singleton to work with
|
||||
*/
|
||||
public static Languages get(Activity activity) {
|
||||
if (singleton == null) {
|
||||
singleton = new Languages(activity);
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
|
||||
@TargetApi(17)
|
||||
public static void setLanguage(final ContextWrapper contextWrapper, String language, boolean refresh) {
|
||||
if (locale != null && TextUtils.equals(locale.getLanguage(), language) && (!refresh)) {
|
||||
return; // already configured
|
||||
} else if (language == null || language.equals(USE_SYSTEM_DEFAULT)) {
|
||||
locale = DEFAULT_LOCALE;
|
||||
} else {
|
||||
/* handle locales with the country in it, i.e. zh_CN, zh_TW, etc */
|
||||
String[] localeSplit = language.split("_");
|
||||
if (localeSplit.length > 1) {
|
||||
locale = new Locale(localeSplit[0], localeSplit[1]);
|
||||
} else {
|
||||
locale = new Locale(language);
|
||||
}
|
||||
}
|
||||
|
||||
final Resources resources = contextWrapper.getBaseContext().getResources();
|
||||
Configuration config = resources.getConfiguration();
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
config.setLocale(locale);
|
||||
} else {
|
||||
config.locale = locale;
|
||||
}
|
||||
resources.updateConfiguration(config, resources.getDisplayMetrics());
|
||||
Locale.setDefault(locale);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Force reload the {@link Activity to make language changes take effect.}
|
||||
*
|
||||
* @param activity the {@code Activity} to force reload
|
||||
*/
|
||||
public static void forceChangeLanguage(Activity activity) {
|
||||
Intent intent = activity.getIntent();
|
||||
if (intent == null) { // when launched as LAUNCHER
|
||||
return;
|
||||
}
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
activity.finish();
|
||||
activity.overridePendingTransition(0, 0);
|
||||
activity.startActivity(intent);
|
||||
activity.overridePendingTransition(0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the language based on the locale.
|
||||
*/
|
||||
public String getName(String locale) {
|
||||
String ret = nameMap.get(locale);
|
||||
// if no match, try to return a more general name (i.e. English for en_IN)
|
||||
if (ret == null && locale.contains("_")) {
|
||||
ret = nameMap.get(locale.split("_")[0]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an array of the names of all the supported languages, sorted to
|
||||
* match what is returned by {@link Languages#getSupportedLocales()}.
|
||||
*/
|
||||
public String[] getAllNames() {
|
||||
return nameMap.values().toArray(new String[nameMap.size()]);
|
||||
}
|
||||
|
||||
public int getPosition(Locale locale) {
|
||||
String localeName = locale.getLanguage();
|
||||
int i = 0;
|
||||
for (String key : nameMap.keySet()) {
|
||||
if (TextUtils.equals(key, localeName)) {
|
||||
return i;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return sorted list of supported locales.
|
||||
*/
|
||||
public String[] getSupportedLocales() {
|
||||
Set<String> keys = nameMap.keySet();
|
||||
return keys.toArray(new String[keys.size()]);
|
||||
}
|
||||
|
||||
private String capitalize(final String line) {
|
||||
return Character.toUpperCase(line.charAt(0)) + line.substring(1);
|
||||
}
|
||||
|
||||
private static final Locale[] LOCALES_TO_TEST = {
|
||||
Locale.ENGLISH,
|
||||
Locale.FRENCH,
|
||||
Locale.GERMAN,
|
||||
Locale.ITALIAN,
|
||||
Locale.JAPANESE,
|
||||
Locale.KOREAN,
|
||||
Locale.SIMPLIFIED_CHINESE,
|
||||
Locale.TRADITIONAL_CHINESE,
|
||||
CHINESE_HONG_KONG,
|
||||
TIBETAN,
|
||||
new Locale("af"),
|
||||
new Locale("am"),
|
||||
new Locale("ar"),
|
||||
new Locale("az"),
|
||||
new Locale("be"),
|
||||
new Locale("bg"),
|
||||
new Locale("bn"),
|
||||
new Locale("ca"),
|
||||
new Locale("cs"),
|
||||
new Locale("da"),
|
||||
new Locale("el"),
|
||||
new Locale("es"),
|
||||
new Locale("et"),
|
||||
new Locale("eu"),
|
||||
new Locale("fa"),
|
||||
new Locale("fi"),
|
||||
new Locale("gl"),
|
||||
new Locale("hi"),
|
||||
new Locale("hr"),
|
||||
new Locale("hu"),
|
||||
new Locale("hy"),
|
||||
new Locale("in"),
|
||||
new Locale("hy"),
|
||||
new Locale("in"),
|
||||
new Locale("is"),
|
||||
new Locale("it"),
|
||||
new Locale("iw"),
|
||||
new Locale("ka"),
|
||||
new Locale("kk"),
|
||||
new Locale("km"),
|
||||
new Locale("kn"),
|
||||
new Locale("ky"),
|
||||
new Locale("lo"),
|
||||
new Locale("lt"),
|
||||
new Locale("lv"),
|
||||
new Locale("mk"),
|
||||
new Locale("ml"),
|
||||
new Locale("mn"),
|
||||
new Locale("mr"),
|
||||
new Locale("ms"),
|
||||
new Locale("my"),
|
||||
new Locale("nb"),
|
||||
new Locale("ne"),
|
||||
new Locale("nl"),
|
||||
new Locale("pl"),
|
||||
new Locale("pt"),
|
||||
new Locale("rm"),
|
||||
new Locale("ro"),
|
||||
new Locale("ru"),
|
||||
new Locale("si"),
|
||||
new Locale("sk"),
|
||||
new Locale("sl"),
|
||||
new Locale("sn"),
|
||||
new Locale("sr"),
|
||||
new Locale("sv"),
|
||||
new Locale("sw"),
|
||||
new Locale("ta"),
|
||||
new Locale("te"),
|
||||
new Locale("th"),
|
||||
new Locale("tl"),
|
||||
new Locale("tr"),
|
||||
new Locale("uk"),
|
||||
new Locale("ur"),
|
||||
new Locale("uz"),
|
||||
new Locale("vi"),
|
||||
new Locale("zu"),
|
||||
};
|
||||
|
||||
}
|
@ -229,6 +229,10 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
|
||||
.replaceAll(" ", "-");
|
||||
}
|
||||
|
||||
public String getLangauge() {
|
||||
return preferences.getString(Preferences.PREF_LANGUAGE, "");
|
||||
}
|
||||
|
||||
public String getLocalRepoName() {
|
||||
return preferences.getString(PREF_LOCAL_REPO_NAME, getDefaultLocalRepoName());
|
||||
}
|
||||
|
@ -12,19 +12,18 @@ import android.preference.Preference;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.support.v4.preference.PreferenceFragment;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.geecko.QuickLyric.view.AppCompatListPreference;
|
||||
import info.guardianproject.netcipher.NetCipher;
|
||||
import info.guardianproject.netcipher.proxy.OrbotHelper;
|
||||
import org.fdroid.fdroid.AppDetails2;
|
||||
import org.fdroid.fdroid.CleanCacheService;
|
||||
import org.fdroid.fdroid.FDroidApp;
|
||||
import org.fdroid.fdroid.Languages;
|
||||
import org.fdroid.fdroid.Preferences;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.UpdateService;
|
||||
import org.fdroid.fdroid.installer.InstallHistoryService;
|
||||
import org.fdroid.fdroid.installer.PrivilegedInstaller;
|
||||
|
||||
import info.guardianproject.netcipher.NetCipher;
|
||||
import info.guardianproject.netcipher.proxy.OrbotHelper;
|
||||
|
||||
public class PreferencesFragment extends PreferenceFragment
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
@ -62,6 +61,12 @@ public class PreferencesFragment extends PreferenceFragment
|
||||
enableProxyCheckPref = (CheckBoxPreference) findPreference(Preferences.PREF_ENABLE_PROXY);
|
||||
updateAutoDownloadPref = findPreference(Preferences.PREF_AUTO_DOWNLOAD_INSTALL_UPDATES);
|
||||
updatePrivilegedExtensionPref = findPreference(Preferences.PREF_UNINSTALL_PRIVILEGED_APP);
|
||||
|
||||
AppCompatListPreference languagePref = (AppCompatListPreference) findPreference(Preferences.PREF_LANGUAGE);
|
||||
Languages languages = Languages.get(getActivity());
|
||||
languagePref.setDefaultValue(Languages.USE_SYSTEM_DEFAULT);
|
||||
languagePref.setEntries(languages.getAllNames());
|
||||
languagePref.setEntryValues(languages.getSupportedLocales());
|
||||
}
|
||||
|
||||
private void checkSummary(String key, int resId) {
|
||||
@ -136,8 +141,9 @@ public class PreferencesFragment extends PreferenceFragment
|
||||
case Preferences.PREF_LANGUAGE:
|
||||
entrySummary(key);
|
||||
if (changing) {
|
||||
// TODO: Ask MainActivity to restart itself.
|
||||
((FDroidApp) getActivity().getApplication()).updateLanguage();
|
||||
Activity activity = getActivity();
|
||||
Languages.setLanguage(activity, Preferences.get().getLangauge(), false);
|
||||
Languages.forceChangeLanguage(activity);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -44,126 +44,4 @@
|
||||
<item>night</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="languageValues">
|
||||
<item></item>
|
||||
<item>en</item>
|
||||
<item>af</item>
|
||||
<item>ar</item>
|
||||
<item>ast</item>
|
||||
<item>be</item>
|
||||
<item>bg</item>
|
||||
<item>ca</item>
|
||||
<item>cs</item>
|
||||
<item>da</item>
|
||||
<item>de</item>
|
||||
<item>el</item>
|
||||
<item>eo</item>
|
||||
<item>es</item>
|
||||
<item>et</item>
|
||||
<item>eu</item>
|
||||
<item>fa</item>
|
||||
<item>fi</item>
|
||||
<item>fr</item>
|
||||
<item>gl</item>
|
||||
<item>he</item>
|
||||
<item>hi</item>
|
||||
<item>hr</item>
|
||||
<item>hu</item>
|
||||
<item>hy</item>
|
||||
<item>id</item>
|
||||
<item>is</item>
|
||||
<item>it</item>
|
||||
<item>ja</item>
|
||||
<item>ko</item>
|
||||
<item>lt</item>
|
||||
<item>lv</item>
|
||||
<item>mk</item>
|
||||
<item>my</item>
|
||||
<item>nb</item>
|
||||
<item>nl</item>
|
||||
<item>pl</item>
|
||||
<item>pt-rBR</item>
|
||||
<item>pt-rPT</item>
|
||||
<item>ro</item>
|
||||
<item>ru</item>
|
||||
<item>sc</item>
|
||||
<item>sk</item>
|
||||
<item>sl</item>
|
||||
<item>sn</item>
|
||||
<item>sq</item>
|
||||
<item>sr</item>
|
||||
<item>sv</item>
|
||||
<item>ta</item>
|
||||
<item>th</item>
|
||||
<item>tr</item>
|
||||
<item>ug</item>
|
||||
<item>uk</item>
|
||||
<item>ur</item>
|
||||
<item>vi</item>
|
||||
<item>zh-rCN</item>
|
||||
<item>zh-rHK</item>
|
||||
<item>zh-rTW</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="languageNames">
|
||||
<item>@string/pref_language_default</item>
|
||||
<item>English</item>
|
||||
<item>Afrikaans</item>
|
||||
<item>ﺎﻠﻋﺮﺒﻳﺓ</item>
|
||||
<item>Asturian</item>
|
||||
<item>белорусский</item>
|
||||
<item>Български</item>
|
||||
<item>Català</item>
|
||||
<item>Čeština</item>
|
||||
<item>Dansk</item>
|
||||
<item>Deutsch</item>
|
||||
<item>Ελληνικά</item>
|
||||
<item>Esperanto</item>
|
||||
<item>Español</item>
|
||||
<item>Eesti</item>
|
||||
<item>Euskara</item>
|
||||
<item>ﻑﺍﺮﺳی</item>
|
||||
<item>Suomi</item>
|
||||
<item>Français</item>
|
||||
<item>Galego</item>
|
||||
<item>עברית</item>
|
||||
<item>हिन्दी</item>
|
||||
<item>Hrvatski</item>
|
||||
<item>Magyar</item>
|
||||
<item>հայերեն</item>
|
||||
<item>Bahasa Indonesia</item>
|
||||
<item>Íslenska</item>
|
||||
<item>Italiano</item>
|
||||
<item>日本語</item>
|
||||
<item>한국어</item>
|
||||
<item>Lietuvių</item>
|
||||
<item>Latviešu</item>
|
||||
<item>македонски</item>
|
||||
<item>မြန်မာစာ</item>
|
||||
<item>Norsk bokmål</item>
|
||||
<item>Nederlands</item>
|
||||
<item>Polski</item>
|
||||
<item>Português (Brasil)</item>
|
||||
<item>Português (Portugal)</item>
|
||||
<item>Română</item>
|
||||
<item>Русский</item>
|
||||
<item>Sardinian</item>
|
||||
<item>Slovenčina</item>
|
||||
<item>Slovenščina</item>
|
||||
<item>ChiSona</item>
|
||||
<item>Shqip</item>
|
||||
<item>Српски</item>
|
||||
<item>Svenska</item>
|
||||
<item>தமிழ்</item>
|
||||
<item>ไทย</item>
|
||||
<item>Türkçe</item>
|
||||
<item>ﺉۇﻲﻏۇﺭچە</item>
|
||||
<item>Українська</item>
|
||||
<item>اردو</item>
|
||||
<item>Tiếng Việt</item>
|
||||
<item>中文 (中国)</item>
|
||||
<item>中文 (香港)</item>
|
||||
<item>中文 (台湾)</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
@ -43,10 +43,7 @@
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/display">
|
||||
<com.geecko.QuickLyric.view.AppCompatListPreference android:title="@string/pref_language"
|
||||
android:key="language"
|
||||
android:defaultValue=""
|
||||
android:entries="@array/languageNames"
|
||||
android:entryValues="@array/languageValues" />
|
||||
android:key="language"/>
|
||||
<com.geecko.QuickLyric.view.AppCompatListPreference android:title="@string/theme"
|
||||
android:key="theme"
|
||||
android:defaultValue="light"
|
||||
|
@ -1,63 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# List supported languages missing from the preference array
|
||||
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
from xml.etree import ElementTree
|
||||
|
||||
prefs = set([''])
|
||||
trans = set(['', 'en'])
|
||||
|
||||
donottranslate = os.path.join('src', 'main', 'res', 'values', 'donottranslate.xml')
|
||||
|
||||
for e in ElementTree.parse(donottranslate).getroot().findall('.//string-array'):
|
||||
if e.attrib['name'] != 'languageValues':
|
||||
continue
|
||||
for i in e.findall('.//item'):
|
||||
lang = i.text
|
||||
if not lang:
|
||||
continue
|
||||
prefs.add(lang)
|
||||
|
||||
for d in glob.glob(os.path.join('src', 'main', 'res', 'values-*')):
|
||||
lang = d[len(os.path.join('src', 'main', 'res', 'values-')):]
|
||||
if not lang:
|
||||
continue
|
||||
if re.match('^sw[0-9]+dp|v[0-9]+$', lang):
|
||||
continue
|
||||
if lang == 'ldrtl':
|
||||
continue
|
||||
if os.path.islink(d):
|
||||
continue
|
||||
trans.add(lang)
|
||||
|
||||
print("In the settings array: %s" % ' '.join(sorted(prefs)))
|
||||
print("Actually translated: %s" % ' '.join(sorted(trans)))
|
||||
|
||||
missing = []
|
||||
for lang in trans:
|
||||
if lang not in prefs:
|
||||
missing.append(lang)
|
||||
|
||||
if missing:
|
||||
print("Missing:")
|
||||
for lang in missing:
|
||||
print(" %s" % lang)
|
||||
|
||||
extra = []
|
||||
for lang in prefs:
|
||||
if lang not in trans:
|
||||
extra.append(lang)
|
||||
|
||||
if extra:
|
||||
print("Extra:")
|
||||
for lang in extra:
|
||||
print(" %s" % lang)
|
||||
|
||||
if not missing and not extra:
|
||||
print("All good.")
|
||||
else:
|
||||
sys.exit(1)
|
42
tools/trim-incomplete-translations-for-release.py
Executable file
42
tools/trim-incomplete-translations-for-release.py
Executable file
@ -0,0 +1,42 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import csv
|
||||
import git
|
||||
import os
|
||||
import requests
|
||||
|
||||
|
||||
projectbasedir = os.path.dirname(os.path.dirname(__file__))
|
||||
print(projectbasedir)
|
||||
|
||||
repo = git.Repo(projectbasedir)
|
||||
|
||||
msg = 'removing all translations less than 75% complete\n\n'
|
||||
|
||||
url = 'https://hosted.weblate.org/exports/stats/f-droid/f-droid/?format=csv'
|
||||
r = requests.get(url)
|
||||
stats = csv.reader(r.iter_lines(decode_unicode=True), delimiter=',')
|
||||
next(stats) # skip CSV header
|
||||
for row in stats:
|
||||
if len(row) > 4:
|
||||
if float(row[4]) > 75.0:
|
||||
continue
|
||||
locale = row[1]
|
||||
if '_' in locale:
|
||||
codes = locale.split('_')
|
||||
if codes[1] == 'Hans':
|
||||
codes[1] = 'CN'
|
||||
elif codes[1] == 'Hant':
|
||||
codes[1] = 'TW'
|
||||
locale = codes[0] + '-r' + codes[1]
|
||||
translation_file = 'app/src/main/res/values-' + locale + '/strings.xml'
|
||||
percent = str(int(float(row[4]))) + '%'
|
||||
print('Removing incomplete file: (' + percent + ')\t',
|
||||
translation_file)
|
||||
os.remove(os.path.join(projectbasedir, translation_file))
|
||||
repo.index.remove([translation_file, ])
|
||||
if len(percent) == 2:
|
||||
msg += ' '
|
||||
msg += percent + ' ' + row[1] + ' ' + row[0] + '\n'
|
||||
|
||||
repo.index.commit(msg)
|
Loading…
x
Reference in New Issue
Block a user