Merge branch '0.103.1-fixes' into 'master'

0.103.1 fixes

Closes #943 and #1012

See merge request !513
This commit is contained in:
Peter Serwylo 2017-05-11 22:40:30 +00:00
commit bf8aedd79c
18 changed files with 171 additions and 137 deletions

View File

@ -12,7 +12,9 @@ before_script:
test: test:
script: script:
- ./app/tools/check-string-format.py - ./tools/check-format-strings.py
- ./tools/remove-unused-and-blank-translations.py
- git diff | grep diff && false # there should be no changes
- ./gradlew assemble -PdisablePreDex - ./gradlew assemble -PdisablePreDex
# always report on lint errors to the build log # always report on lint errors to the build log
- sed -i -e 's,textReport .*,textReport true,' app/build.gradle - sed -i -e 's,textReport .*,textReport true,' app/build.gradle

View File

@ -245,13 +245,7 @@ android {
xmlReport false xmlReport false
textReport false textReport false
// Our translations are crowd-sourced lintConfig file("lint.xml")
disable 'MissingTranslation'
// to make CI fail on errors until this is fixed https://github.com/rtyley/spongycastle/issues/7
warning 'InvalidPackage', 'ImpliedQuantity'
error 'AppCompatMethod', 'NestedScrolling', 'StringFormatCount', 'UnsafeProtectedBroadcastReceiver'
} }
packagingOptions { packagingOptions {

36
app/lint.xml Normal file
View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<!-- Our translations are crowd-sourced -->
<issue id="MissingTranslation" severity="ignore"/>
<!-- to make CI fail on errors until this is fixed
https://github.com/rtyley/spongycastle/issues/7 -->
<issue id="InvalidPackage" severity="warning"/>
<issue id="ImpliedQuantity" severity="warning"/>
<!-- These are important to us, so promote from warning to error -->
<issue id="AppCompatMethod" severity="error"/>
<issue id="NestedScrolling" severity="error"/>
<issue id="StringFormatCount" severity="error"/>
<issue id="UnsafeProtectedBroadcastReceiver" severity="error"/>
<!-- Change the severity of hardcoded strings to "error" -->
<issue id="HardcodedText" severity="error"/>
<!-- both the correct and deprecated locales need to be present for
them to be recognized on all devices -->
<issue id="LocaleFolder" severity="error">
<ignore path="src/main/res/values-he"/>
<ignore path="src/main/res/values-id"/>
</issue>
<issue id="SetWorldReadable" severity="error">
<ignore path="src/main/java/org/fdroid/fdroid/installer/ApkFileProvider.java"/>
</issue>
<!-- these should be fixed, but it'll be a chunk of work -->
<issue id="SetTextI18n" severity="error">
<ignore path="src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java"/>
<ignore path="src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java"/>
</issue>
</lint>

View File

@ -44,11 +44,22 @@ public class AppUpdateStatusService extends IntentService {
@Override @Override
protected void onHandleIntent(@Nullable Intent intent) { protected void onHandleIntent(@Nullable Intent intent) {
Utils.debugLog(TAG, "Scanning apk cache to see if we need to prompt the user to install any apks."); Utils.debugLog(TAG, "Scanning apk cache to see if we need to prompt the user to install any apks.");
List<Apk> apksReadyToInstall = new ArrayList<>();
File cacheDir = ApkCache.getApkCacheDir(this); File cacheDir = ApkCache.getApkCacheDir(this);
for (String repoDirName : cacheDir.list()) { if (cacheDir == null) {
return;
}
String[] cacheDirList = cacheDir.list();
if (cacheDirList == null) {
return;
}
List<Apk> apksReadyToInstall = new ArrayList<>();
for (String repoDirName : cacheDirList) {
File repoDir = new File(cacheDir, repoDirName); File repoDir = new File(cacheDir, repoDirName);
for (String apkFileName : repoDir.list()) { String[] apks = repoDir.list();
if (apks == null) {
continue;
}
for (String apkFileName : apks) {
Apk apk = processDownloadedApk(new File(repoDir, apkFileName)); Apk apk = processDownloadedApk(new File(repoDir, apkFileName));
if (apk != null) { if (apk != null) {
Log.i(TAG, "Found downloaded apk " + apk.packageName + ". Notifying user that it should be installed."); Log.i(TAG, "Found downloaded apk " + apk.packageName + ". Notifying user that it should be installed.");

View File

@ -73,6 +73,9 @@ public final class Languages {
} }
} }
// remove the current system language from the menu
tmpMap.remove(currentLocale.getLanguage());
/* SYSTEM_DEFAULT is a fake one for displaying in a chooser menu. */ /* SYSTEM_DEFAULT is a fake one for displaying in a chooser menu. */
tmpMap.put(USE_SYSTEM_DEFAULT, activity.getString(resId)); tmpMap.put(USE_SYSTEM_DEFAULT, activity.getString(resId));
nameMap = Collections.unmodifiableMap(tmpMap); nameMap = Collections.unmodifiableMap(tmpMap);
@ -116,13 +119,21 @@ public final class Languages {
} }
@TargetApi(17) @TargetApi(17)
/**
* Handles setting the language if it is different than the current language,
* or different than the current system-wide locale. The preference is cleared
* if the language matches the system-wide locale or "System Default" is chosen.
*/
public static void setLanguage(final ContextWrapper contextWrapper, String language, boolean refresh) { public static void setLanguage(final ContextWrapper contextWrapper, String language, boolean refresh) {
if (Build.VERSION.SDK_INT >= 24) { if (Build.VERSION.SDK_INT >= 24) {
Utils.debugLog(TAG, "Languages.setLanguage() ignored on >= android-24"); Utils.debugLog(TAG, "Languages.setLanguage() ignored on >= android-24");
Preferences.get().clearLanguage(); Preferences.get().clearLanguage();
return; return;
} }
if (locale != null && TextUtils.equals(locale.getLanguage(), language) && (!refresh)) { if (TextUtils.equals(language, DEFAULT_LOCALE.getLanguage())) {
Preferences.get().clearLanguage();
locale = DEFAULT_LOCALE;
} else if (locale != null && TextUtils.equals(locale.getLanguage(), language) && (!refresh)) {
return; // already configured return; // already configured
} else if (language == null || language.equals(USE_SYSTEM_DEFAULT)) { } else if (language == null || language.equals(USE_SYSTEM_DEFAULT)) {
Preferences.get().clearLanguage(); Preferences.get().clearLanguage();

View File

@ -27,7 +27,6 @@ import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.NfcHelper; import org.fdroid.fdroid.NfcHelper;
import org.fdroid.fdroid.NfcNotEnabledActivity; import org.fdroid.fdroid.NfcNotEnabledActivity;
@ -39,6 +38,8 @@ import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.data.RepoProvider;
import org.fdroid.fdroid.data.Schema.RepoTable; import org.fdroid.fdroid.data.Schema.RepoTable;
import java.util.Locale;
public class RepoDetailsActivity extends ActionBarActivity { public class RepoDetailsActivity extends ActionBarActivity {
private static final String TAG = "RepoDetailsActivity"; private static final String TAG = "RepoDetailsActivity";
@ -323,7 +324,7 @@ public class RepoDetailsActivity extends ActionBarActivity {
name.setText(repo.name); name.setText(repo.name);
int appCount = RepoProvider.Helper.countAppsForRepo(this, repoId); int appCount = RepoProvider.Helper.countAppsForRepo(this, repoId);
numApps.setText(Integer.toString(appCount)); numApps.setText(String.format(Locale.getDefault(), "%d", appCount));
setupDescription(repoView, repo); setupDescription(repoView, repo);
setupRepoFingerprint(repoView, repo); setupRepoFingerprint(repoView, repo);

View File

@ -49,7 +49,7 @@ public class AppNotification extends AppUpdateData {
} }
public void bindApp(AppNotification app) { public void bindApp(AppNotification app) {
((TextView) itemView).setText("Notification for app"); ((TextView) itemView).setText("");
} }
} }

View File

@ -47,7 +47,7 @@ public class DonationPrompt extends AppUpdateData {
} }
public void bindApp(DonationPrompt app) { public void bindApp(DonationPrompt app) {
((TextView) itemView).setText("Donation prompt for app"); ((TextView) itemView).setText("");
} }
} }

View File

@ -466,7 +466,6 @@
<item quantity="one">Убачыць %d праграму</item> <item quantity="one">Убачыць %d праграму</item>
<item quantity="few">Убачыць усе %d праграмы</item> <item quantity="few">Убачыць усе %d праграмы</item>
<item quantity="many">Убачыць усе %d праграм</item> <item quantity="many">Убачыць усе %d праграм</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="app_recommended_version_installed">Версія %1$s (рэкамендуецца)</string> <string name="app_recommended_version_installed">Версія %1$s (рэкамендуецца)</string>
@ -486,7 +485,6 @@
<item quantity="one">Паказаць %1$s праграму ў катэгорыі %2$s</item> <item quantity="one">Паказаць %1$s праграму ў катэгорыі %2$s</item>
<item quantity="few">Паказаць %1$s праграмы ў катэгорыі %2$s</item> <item quantity="few">Паказаць %1$s праграмы ў катэгорыі %2$s</item>
<item quantity="many">Паказаць %1$s праграм ў катэгорыі %2$s</item> <item quantity="many">Паказаць %1$s праграм ў катэгорыі %2$s</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="app__install_downloaded_update">Абнавіць</string> <string name="app__install_downloaded_update">Абнавіць</string>
@ -497,7 +495,6 @@
<item quantity="one">Выпушчана %1$d дзень таму</item> <item quantity="one">Выпушчана %1$d дзень таму</item>
<item quantity="few">Выпушчана %1$d дня таму</item> <item quantity="few">Выпушчана %1$d дня таму</item>
<item quantity="many">Выпушчана %1$d дзён таму</item> <item quantity="many">Выпушчана %1$d дзён таму</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="updates__tts__download_app">Спампаваць</string> <string name="updates__tts__download_app">Спампаваць</string>
@ -510,7 +507,6 @@
<item quantity="one">Спампаваць абнаўленне для %1$d праграмы.</item> <item quantity="one">Спампаваць абнаўленне для %1$d праграмы.</item>
<item quantity="few">Спампаваць абнаўленні для %1$d праграм.</item> <item quantity="few">Спампаваць абнаўленні для %1$d праграм.</item>
<item quantity="many">Спампаваць абнаўленні для %1$d праграм.</item> <item quantity="many">Спампаваць абнаўленні для %1$d праграм.</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="details_new_in_version">Навае ў версіі %s</string> <string name="details_new_in_version">Навае ў версіі %s</string>
@ -520,7 +516,6 @@
<item quantity="one">Абноўлена %1$s дзень таму</item> <item quantity="one">Абноўлена %1$s дзень таму</item>
<item quantity="few">Абноўлена %1$s дні таму</item> <item quantity="few">Абноўлена %1$s дні таму</item>
<item quantity="many">Абноўлена %1$s дзён таму</item> <item quantity="many">Абноўлена %1$s дзён таму</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="antifeatureswarning">Гэтая праграма мае функцыі, што могуць вам не спадабацца.</string> <string name="antifeatureswarning">Гэтая праграма мае функцыі, што могуць вам не спадабацца.</string>
<string name="app_list__name__successfully_installed">%1$s паспяхова ўсталявана</string> <string name="app_list__name__successfully_installed">%1$s паспяхова ўсталявана</string>

View File

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name">ಎಫ್-ಡ್ರಾಯ್ಡ್</string> <resources><string name="app_name">ಎಫ್-ಡ್ರಾಯ್ಡ್</string>
<string name="version">ಆವೃತ್ತಿ</string> <string name="version">ಆವೃತ್ತಿ</string>
<string name="notification_action_install">ಅನುಸ್ಥಾಪಿಸು</string> <string name="notification_action_install">ಅನುಸ್ಥಾಪಿಸು</string>
@ -31,10 +31,10 @@
<string name="nearby_splash__find_people_button">ನನ್ನ ಹತ್ತಿರವಿರುವ ಜನರನ್ನು ಹುಡುಕು</string> <string name="nearby_splash__find_people_button">ನನ್ನ ಹತ್ತಿರವಿರುವ ಜನರನ್ನು ಹುಡುಕು</string>
<string name="system_install_installing">ಅನುಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ…</string> <string name="system_install_installing">ಅನುಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ…</string>
<string name="system_install_button_install">ಅನುಸ್ಥಾಪಿಸು</string> <string name="system_install_button_install">ಅನುಸ್ಥಾಪಿಸು</string>
<string tools:ignore="UnusedResources" name="category_Time">ಸಮಯ</string> <string name="category_Time">ಸಮಯ</string>
<string tools:ignore="UnusedResources" name="category_Security">ಸುರಕ್ಷತೆ</string> <string name="category_Security">ಸುರಕ್ಷತೆ</string>
<string tools:ignore="UnusedResources" name="category_Sports_Health">ಕ್ರೀಡೆ &amp; ಆರೋಗ್ಯ</string> <string name="category_Sports_Health">ಕ್ರೀಡೆ &amp; ಆರೋಗ್ಯ</string>
<string tools:ignore="UnusedResources" name="category_Games">ಆಟಗಳು</string> <string name="category_Games">ಆಟಗಳು</string>
<string name="wifi">ವೈ-ಫೈ</string> <string name="wifi">ವೈ-ಫೈ</string>
<string name="pref_language">ಭಾಷೆ</string> <string name="pref_language">ಭಾಷೆ</string>
<string name="repo_name">ಹೆಸರು</string> <string name="repo_name">ಹೆಸರು</string>

View File

@ -449,7 +449,6 @@
<item quantity="one">Zobacz %d aplikację</item> <item quantity="one">Zobacz %d aplikację</item>
<item quantity="few">Zobacz wszystkie %d aplikacje</item> <item quantity="few">Zobacz wszystkie %d aplikacje</item>
<item quantity="many">Zobacz wszystkich %d aplikacji</item> <item quantity="many">Zobacz wszystkich %d aplikacji</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="app_recommended_version_installed">Wersja %1$s (zalecana)</string> <string name="app_recommended_version_installed">Wersja %1$s (zalecana)</string>
@ -470,7 +469,6 @@
<item quantity="one">Pokaż %1$d aplikację w kategorii %2$s</item> <item quantity="one">Pokaż %1$d aplikację w kategorii %2$s</item>
<item quantity="few">Pokaż wszystkie %1$s aplikacje w kategorii %2$s</item> <item quantity="few">Pokaż wszystkie %1$s aplikacje w kategorii %2$s</item>
<item quantity="many">Pokaż wszystkich %1$s aplikacji w kategorii %2$s</item> <item quantity="many">Pokaż wszystkich %1$s aplikacji w kategorii %2$s</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="app__install_downloaded_update">Aktualizuj</string> <string name="app__install_downloaded_update">Aktualizuj</string>
@ -481,7 +479,6 @@
<item quantity="one">Wydano %1$d dzień temu</item> <item quantity="one">Wydano %1$d dzień temu</item>
<item quantity="few">Wydano %1$d dni temu</item> <item quantity="few">Wydano %1$d dni temu</item>
<item quantity="many">Wydano %1$d dni temu</item> <item quantity="many">Wydano %1$d dni temu</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="updates__tts__download_app">Pobierz</string> <string name="updates__tts__download_app">Pobierz</string>
@ -494,7 +491,6 @@
<item quantity="one">Pobierz aktualizację dla %1$d aplikacji.</item> <item quantity="one">Pobierz aktualizację dla %1$d aplikacji.</item>
<item quantity="few">Pobierz aktualizacje dla %1$d aplikacji.</item> <item quantity="few">Pobierz aktualizacje dla %1$d aplikacji.</item>
<item quantity="many">Pobierz aktualizacje dla %1$d aplikacji.</item> <item quantity="many">Pobierz aktualizacje dla %1$d aplikacji.</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="details_new_in_version">Nowe w wersji %s</string> <string name="details_new_in_version">Nowe w wersji %s</string>
@ -506,7 +502,6 @@
<item quantity="one">Uaktualniono %1$s dzień temu</item> <item quantity="one">Uaktualniono %1$s dzień temu</item>
<item quantity="few">Uaktualniono %1$s dni temu</item> <item quantity="few">Uaktualniono %1$s dni temu</item>
<item quantity="many">Uaktualniono %1$s dni temu</item> <item quantity="many">Uaktualniono %1$s dni temu</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="app_list__name__successfully_installed">%1$s pomyślnie zainstalowano</string> <string name="app_list__name__successfully_installed">%1$s pomyślnie zainstalowano</string>
<string name="nearby_splash__download_apps_from_people_nearby">Brak internetu? Pobierz aplikacje od ludzi w <string name="nearby_splash__download_apps_from_people_nearby">Brak internetu? Pobierz aplikacje od ludzi w

View File

@ -454,7 +454,6 @@
<item quantity="one">Опубликовано %1$d день назад</item> <item quantity="one">Опубликовано %1$d день назад</item>
<item quantity="few">Опубликовано %1$d дня назад</item> <item quantity="few">Опубликовано %1$d дня назад</item>
<item quantity="many">Опубликовано %1$d дней назад</item> <item quantity="many">Опубликовано %1$d дней назад</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="categories__empty_state__no_categories">Нет категорий для показа</string> <string name="categories__empty_state__no_categories">Нет категорий для показа</string>
@ -463,7 +462,6 @@
<item quantity="one">Посмотреть %d приложение</item> <item quantity="one">Посмотреть %d приложение</item>
<item quantity="few">Посмотреть %d приложения</item> <item quantity="few">Посмотреть %d приложения</item>
<item quantity="many">Посмотреть %d приложений</item> <item quantity="many">Посмотреть %d приложений</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="nearby_splash__download_apps_from_people_nearby">Нет интернета? Скачивайте приложения у людей рядом с вами!</string> <string name="nearby_splash__download_apps_from_people_nearby">Нет интернета? Скачивайте приложения у людей рядом с вами!</string>
@ -483,7 +481,6 @@
<item quantity="one">Обновлено %1$s день назад</item> <item quantity="one">Обновлено %1$s день назад</item>
<item quantity="few">Обновлено %1$s дня назад</item> <item quantity="few">Обновлено %1$s дня назад</item>
<item quantity="many">Обновлено %1$s дней назад</item> <item quantity="many">Обновлено %1$s дней назад</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="app_details_donate_prompt">%1$s создано %2$s. Купи им чашечку кофе!</string> <string name="app_details_donate_prompt">%1$s создано %2$s. Купи им чашечку кофе!</string>
@ -494,7 +491,6 @@
<item quantity="one">Скачать обновления для %1$d приложения.</item> <item quantity="one">Скачать обновления для %1$d приложения.</item>
<item quantity="few">Скачать обновления для %1$d приложений.</item> <item quantity="few">Скачать обновления для %1$d приложений.</item>
<item quantity="many">Скачать обновления для %1$d приложений.</item> <item quantity="many">Скачать обновления для %1$d приложений.</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="app_list__name__downloaded_and_ready_to_update">Обновить %1$s</string> <string name="app_list__name__downloaded_and_ready_to_update">Обновить %1$s</string>
@ -521,7 +517,6 @@
<item quantity="one">Посмотреть %1$d приложение в категории %2$s</item> <item quantity="one">Посмотреть %1$d приложение в категории %2$s</item>
<item quantity="few">Посмотреть %1$d приложения в категории %2$s</item> <item quantity="few">Посмотреть %1$d приложения в категории %2$s</item>
<item quantity="many">Посмотреть %1$d приложений в категории %2$s</item> <item quantity="many">Посмотреть %1$d приложений в категории %2$s</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="latest__empty_state__no_recent_apps">Нет недавних приложений</string> <string name="latest__empty_state__no_recent_apps">Нет недавних приложений</string>

View File

@ -508,7 +508,6 @@
<item quantity="one">Завантажити оновлення для %1$d додатку.</item> <item quantity="one">Завантажити оновлення для %1$d додатку.</item>
<item quantity="few">Завантажити оновлення для %1$d додатка.</item> <item quantity="few">Завантажити оновлення для %1$d додатка.</item>
<item quantity="many">Завантажити оновлення для %1$d додатків.</item> <item quantity="many">Завантажити оновлення для %1$d додатків.</item>
<item quantity="other"/>
</plurals> </plurals>
<string name="details_new_in_version">Нове у версії %s</string> <string name="details_new_in_version">Нове у версії %s</string>

View File

@ -1,39 +0,0 @@
#!/usr/bin/env python3
# Remove extra translations
import glob
import os
import re
from xml.etree import ElementTree
strings = set()
for e in ElementTree.parse(os.path.join('src', 'main', 'res', 'values', 'strings.xml')).getroot().findall('.//string'):
name = e.attrib['name']
strings.add(name)
for d in glob.glob(os.path.join('src', 'main', 'res', 'values-*')):
str_path = os.path.join(d, 'strings.xml')
if os.path.exists(str_path):
header = ''
with open(str_path, 'r') as f:
header = f.readline()
tree = ElementTree.parse(str_path)
root = tree.getroot()
elems = root.findall('.//string')
for e in elems:
name = e.attrib['name']
if name not in strings:
root.remove(e)
if not e.text:
root.remove(e)
result = re.sub(r' />', r'/>', ElementTree.tostring(root, encoding='utf-8').decode('utf-8'))
with open(str_path, 'w+') as f:
f.write(header)
f.write(result)
f.write('\n')

View File

@ -13,11 +13,11 @@ formatRe = re.compile(r'(%%|%[^%](\$.)?)')
validFormatRe = re.compile(r'^(%%|%[sd]|%[0-9]\$[sd])$') validFormatRe = re.compile(r'^(%%|%[sd]|%[0-9]\$[sd])$')
oddQuotingRe = re.compile(r'^"\s*(.+?)\s*"$') oddQuotingRe = re.compile(r'^"\s*(.+?)\s*"$')
projectdir = os.path.join(os.path.dirname(__file__), '..') resdir = os.path.join(os.path.dirname(__file__), '..', 'app', 'src', 'main', 'res')
count = 0 count = 0
for d in sorted(glob.glob(os.path.join(projectdir, 'src', 'main', 'res', 'values-*'))): for d in sorted(glob.glob(os.path.join(resdir, 'values-*'))):
str_path = os.path.join(d, 'strings.xml') str_path = os.path.join(d, 'strings.xml')
if not os.path.exists(str_path): if not os.path.exists(str_path):

View File

@ -1,39 +0,0 @@
#!/bin/sh
# This script pulls translations from weblate.
#
# It squashes all the changes into a single commit. This removes authorship
# from the changes, which is given to the Translatebot, so to keep the names
# they are grabbed from git log and added to the commit message.
#
# Note that this will apply changes and commit them! Make sure to not have
# uncommited changes when running this script.
REMOTE="weblate"
REMOTE_URL="git://git.weblate.org/f-droid.git"
REMOTE_BRANCH="master"
AUTHOR="F-Droid Translatebot <team@f-droid.org>"
if ! git ls-remote --exit-code $REMOTE >/dev/null 2>/dev/null; then
echo "Remote doesn't exist! Try the following:"
echo " git remote add $REMOTE $REMOTE_URL"
echo " git fetch $REMOTE"
exit 1
fi
ref="${REMOTE}/${REMOTE_BRANCH}"
diff="HEAD...$ref -- */values-*/strings.xml"
authors=$(git log --format="%s %an" $diff | \
sed 's/.* using Weblate (\(.*\)) \(.*\)/\2||\1/' | sort -f -u | column -s '||' -t)
git diff $diff | git apply
git add */values-*/strings.xml
git commit --author "$AUTHOR" -m "Pull translation updates from Weblate
Translators:
$authors"

View File

@ -0,0 +1,55 @@
#!/usr/bin/env python3
# This script removes strings from the translated files that are not useful:
# * translations for strings that are no longer used
# * empty translated strings, English is better than no text at all
import glob
import os
import re
from xml.etree import ElementTree
resdir = os.path.join(os.path.dirname(__file__), '..', 'app', 'src', 'main', 'res')
sourcepath = os.path.join(resdir, 'values', 'strings.xml')
strings = set()
for e in ElementTree.parse(sourcepath).getroot().findall('.//string'):
name = e.attrib['name']
strings.add(name)
for d in sorted(glob.glob(os.path.join(resdir, 'values-*'))):
str_path = os.path.join(d, 'strings.xml')
if not os.path.exists(str_path):
continue
header = ''
with open(str_path, 'r') as f:
header = f.readline()
# handling XML namespaces in Python is painful, just remove them, they
# should not be in the translation files anyway
with open(str_path, 'rb') as fp:
contents = fp.read()
contents = contents.replace(b' tools:ignore="UnusedResources"', b'') \
.replace(b' xmlns:tools="http://schemas.android.com/tools"', b'')
root = ElementTree.fromstring(contents)
for e in root.findall('.//string'):
name = e.attrib['name']
if name not in strings:
root.remove(e)
if not e.text:
root.remove(e)
for e in root.findall('.//plurals'):
for item in e.findall('item'):
if not item.text:
e.remove(item)
result = re.sub(r' />', r'/>', ElementTree.tostring(root, encoding='utf-8').decode('utf-8'))
with open(str_path, 'w+') as f:
f.write(header)
f.write(result)
f.write('\n')

View File

@ -1,9 +1,15 @@
#!/usr/bin/python3 #!/usr/bin/python3
#
# WARNING! THIS DELETES TRANSLATIONS!
#
# The incomplete translations should be kept by rebasing the weblate
# remote on top of this commit, once its complete.
import csv import csv
import git import git
import os import os
import requests import requests
import sys
projectbasedir = os.path.dirname(os.path.dirname(__file__)) projectbasedir = os.path.dirname(os.path.dirname(__file__))
@ -11,7 +17,7 @@ print(projectbasedir)
repo = git.Repo(projectbasedir) repo = git.Repo(projectbasedir)
msg = 'removing all translations less than 75% complete\n\n' msg = 'removing all translations less than 70% complete\n\n'
url = 'https://hosted.weblate.org/exports/stats/f-droid/f-droid/?format=csv' url = 'https://hosted.weblate.org/exports/stats/f-droid/f-droid/?format=csv'
r = requests.get(url) r = requests.get(url)
@ -19,7 +25,7 @@ stats = csv.reader(r.iter_lines(decode_unicode=True), delimiter=',')
next(stats) # skip CSV header next(stats) # skip CSV header
for row in stats: for row in stats:
if len(row) > 4: if len(row) > 4:
if float(row[4]) > 75.0: if float(row[4]) > 70.0:
continue continue
locale = row[1] locale = row[1]
if '_' in locale: if '_' in locale:
@ -33,10 +39,22 @@ for row in stats:
percent = str(int(float(row[4]))) + '%' percent = str(int(float(row[4]))) + '%'
print('Removing incomplete file: (' + percent + ')\t', print('Removing incomplete file: (' + percent + ')\t',
translation_file) translation_file)
os.remove(os.path.join(projectbasedir, translation_file)) delfile = os.path.join(projectbasedir, translation_file)
if os.path.exists(delfile):
os.remove(delfile)
repo.index.remove([translation_file, ]) repo.index.remove([translation_file, ])
if len(percent) == 2: if len(percent) == 2:
msg += ' ' msg += ' '
msg += percent + ' ' + row[1] + ' ' + row[0] + '\n' msg += percent + ' ' + row[1] + ' ' + row[0] + '\n'
found = False
for remote in repo.remotes:
if remote.name == 'weblate':
remote.fetch()
found = True
if not found:
print('ERROR: there must be a weblate remote to preserve incomplete translations!')
sys.exit(1)
repo.index.commit(msg) repo.index.commit(msg)