Add "refresh before download" + remove WhatsApp (#1943)

This commit is contained in:
Imran Remtulla
2024-12-08 15:58:44 -05:00
parent 22815b8209
commit c012b016f9
28 changed files with 55 additions and 58 deletions

View File

@ -34,7 +34,6 @@ Currently supported App sources:
- Open Source - App-Specific:
- [VLC](https://videolan.org/)
- Other - App-Specific:
- [WhatsApp](https://whatsapp.com)
- [Telegram App](https://telegram.org)
- [Neutron Code](https://neutroncode.com)
- Direct APK Link

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Allow insecure HTTP requests",
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"removeAppQuestion": {
"one": "Želite li ukloniti aplikaciju?",
"other": "Želite li ukloniti aplikacije?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Konfigurace aplikací s využitím crowdsourcingu",
"allowInsecure": "Povolení nezabezpečených požadavků HTTP",
"stayOneVersionBehind": "Zůstaňte o jednu verzi pozadu za nejnovější",
"refreshBeforeDownload": "Obnovení údajů o aplikaci před stažením",
"removeAppQuestion": {
"one": "Odstranit Apku?",
"other": "Odstranit Apky?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Crowdsourcede app-konfigurationer",
"allowInsecure": "Tillad usikre HTTP-anmodninger",
"stayOneVersionBehind": "Forbliv én version bagud den seneste",
"refreshBeforeDownload": "Opdater app-detaljer før download",
"removeAppQuestion": {
"one": "Fjern app?",
"other": "Fjern apps?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Crowdsourced App-Konfigurationen",
"allowInsecure": "Unsichere HTTP-Anfragen zulassen",
"stayOneVersionBehind": "Eine Version hinter der neuesten Version bleiben",
"refreshBeforeDownload": "App-Details vor dem Download aktualisieren",
"removeAppQuestion": {
"one": "App entfernen?",
"other": "Apps entfernen?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Allow insecure HTTP requests",
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"removeAppQuestion": {
"one": "Forigi la aplikaĵon?",
"other": "Forigi la aplikaĵojn?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Allow insecure HTTP requests",
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"removeAppQuestion": {
"one": "Remove App?",
"other": "Remove Apps?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Configuración de aplicaciones por crowdsourcing",
"allowInsecure": "Permitir peticiones HTTP inseguras",
"stayOneVersionBehind": "Mantenerse una versión por detrás de la última",
"refreshBeforeDownload": "Actualiza los datos de la aplicación antes de descargarla",
"removeAppQuestion": {
"one": "¿Eliminar aplicación?",
"other": "¿Eliminar aplicaciones?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "درخواست های HTTP ناامن را مجاز کنید",
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"removeAppQuestion": {
"one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Applis communautaires",
"allowInsecure": "Autoriser les requêtes HTTP non sécurisées",
"stayOneVersionBehind": "Rester à une version de la dernière",
"refreshBeforeDownload": "Actualiser les détails de l'application avant de la télécharger",
"removeAppQuestion": {
"one": "Supprimer l'application?",
"other": "Supprimer les applications?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Nem biztonságos HTTP-kérések engedélyezése",
"stayOneVersionBehind": "Maradjon egy verzióval a legújabb mögött",
"refreshBeforeDownload": "Az alkalmazás adatainak frissítése letöltés előtt",
"removeAppQuestion": {
"one": "Eltávolítja az alkalmazást?",
"other": "Eltávolítja az alkalmazásokat?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Konfigurasi Aplikasi Crowdsourced",
"allowInsecure": "Izinkan permintaan HTTP yang tidak aman",
"stayOneVersionBehind": "Tetap satu versi di belakang versi terbaru",
"refreshBeforeDownload": "Segarkan detail aplikasi sebelum mengunduh",
"removeAppQuestion": {
"one": "Hapus aplikasi?",
"other": "Hapus aplikasi?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Configurazioni di app in crowdsourcing",
"allowInsecure": "Consentire le richieste HTTP non sicure",
"stayOneVersionBehind": "Rimanere una versione indietro rispetto alla più recente",
"refreshBeforeDownload": "Aggiornare i dettagli dell'app prima del download",
"removeAppQuestion": {
"one": "Rimuovere l'app?",
"other": "Rimuovere le app?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "クラウドソーシングによるアプリの設定",
"allowInsecure": "安全でないHTTPリクエストを許可する",
"stayOneVersionBehind": "最新のバージョンから1つ前のものを使用する",
"refreshBeforeDownload": "ダウンロード前にアプリの詳細を更新する",
"removeAppQuestion": {
"one": "アプリを削除しますか?",
"other": "アプリを削除しますか?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "App-configuraties door menigte",
"allowInsecure": "Onveilige HTTP-verzoeken toestaan",
"stayOneVersionBehind": "Blijf een versie achter op de nieuwste",
"refreshBeforeDownload": "Vernieuw app details voor download",
"removeAppQuestion": {
"one": "App verwijderen?",
"other": "Apps verwijderen?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Baza konfiguracji",
"allowInsecure": "Zezwalaj na niezabezpieczone żądania HTTP",
"stayOneVersionBehind": "Pozostań jedną wersję w tyle za najnowszą",
"refreshBeforeDownload": "Odśwież szczegóły aplikacji przed pobraniem",
"removeAppQuestion": {
"one": "Usunąć aplikację?",
"few": "Usunąć aplikacje?",

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Configurações de aplicações com base em crowdsourcing",
"allowInsecure": "Permitir pedidos HTTP inseguros",
"stayOneVersionBehind": "Manter-se uma versão atrás da mais recente",
"refreshBeforeDownload": "Atualizar os detalhes da aplicação antes da transferência",
"removeAppQuestion": {
"one": "Remover aplicativo?",
"other": "Remover aplicativos?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Конфиги приложений с помощью краудсорсинга",
"allowInsecure": "Разрешить небезопасные HTTP-запросы",
"stayOneVersionBehind": "Не отставайте от последней версии",
"refreshBeforeDownload": "Обновляйте информацию о приложении перед загрузкой",
"removeAppQuestion": {
"one": "Удалить приложение?",
"other": "Удалить приложения?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Appkonfigurationer med hjälp av crowdsourcing",
"allowInsecure": "Tillåt osäkra HTTP-förfrågningar",
"stayOneVersionBehind": "Håll dig en version bakom den senaste",
"refreshBeforeDownload": "Uppdatera appdetaljerna före nedladdning",
"removeAppQuestion": {
"one": "Ta Bort App?",
"other": "Ta Bort Appar?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Kitle Kaynaklı Uygulama Yapılandırmaları",
"allowInsecure": "Güvensiz HTTP isteklerine izin ver",
"stayOneVersionBehind": "En son sürümün bir sürüm gerisinde kalın",
"refreshBeforeDownload": "İndirmeden önce uygulama ayrıntılarını yenileyin",
"removeAppQuestion": {
"one": "Uygulamayı Kaldır?",
"other": "Uygulamaları Kaldır?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Налаштування краудсорсингових додатків",
"allowInsecure": "Дозволити незахищені HTTP-запити",
"stayOneVersionBehind": "Залишайтеся на одну версію актуальнішою",
"refreshBeforeDownload": "Оновіть інформацію про програму перед завантаженням",
"removeAppQuestion": {
"one": "Видалити застосунок?",
"other": "Видалити застосунки?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Allow insecure HTTP requests",
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"removeAppQuestion": {
"one": "Gỡ ứng dụng?",
"other": "Gỡ ứng dụng?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "Crowdsourced App Configs",
"allowInsecure": "Allow insecure HTTP requests",
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"removeAppQuestion": {
"one": "移除應用程式?",
"other": "移除應用程式?"

View File

@ -317,6 +317,7 @@
"crowdsourcedConfigsShort": "众包应用程序配置",
"allowInsecure": "允许不安全的 HTTP 请求",
"stayOneVersionBehind": "比最新版本晚一个版本",
"refreshBeforeDownload": "下载前刷新应用程序详细信息",
"removeAppQuestion": {
"one": "是否删除应用?",
"other": "是否删除应用?"

View File

@ -7,6 +7,9 @@ import 'package:obtainium/providers/apps_provider.dart';
import 'package:obtainium/providers/source_provider.dart';
String ensureAbsoluteUrl(String ambiguousUrl, Uri referenceAbsoluteUrl) {
if (ambiguousUrl.startsWith('//')) {
ambiguousUrl = '${referenceAbsoluteUrl.scheme}:$ambiguousUrl';
}
try {
Uri.parse(ambiguousUrl).origin;
return ambiguousUrl;

View File

@ -1,55 +0,0 @@
import 'package:html/parser.dart';
import 'package:http/http.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart';
class WhatsApp extends AppSource {
WhatsApp() {
hosts = ['whatsapp.com'];
versionDetectionDisallowed = true;
}
@override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
return 'https://${hosts[0]}';
}
@override
Future<String> apkUrlPrefetchModifier(String apkUrl, String standardUrl,
Map<String, dynamic> additionalSettings) async {
Response res =
await sourceRequest('$standardUrl/android', additionalSettings);
if (res.statusCode == 200) {
var targetLinks = parse(res.body)
.querySelectorAll('a')
.map((e) => e.attributes['href'] ?? '')
.where((e) => e.isNotEmpty)
.where((e) => e.contains('WhatsApp.apk'))
.toList();
if (targetLinks.isEmpty) {
throw NoAPKError();
}
return targetLinks[0];
} else {
throw getObtainiumHttpError(res);
}
}
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl,
Map<String, dynamic> additionalSettings,
) async {
// This is a CDN link that is consistent per version
// But it has query params that change constantly
Uri apkUri = Uri.parse(await apkUrlPrefetchModifier(
standardUrl, standardUrl, additionalSettings));
var unusableApkUrl = '${apkUri.origin}/${apkUri.path}';
// So we use the param-less URL is a pseudo-version to add the app and check for updates
// See #357 for why we can't scrape the version number directly
// But we re-fetch the URL again with its latest query params at the actual download time
String version = unusableApkUrl.hashCode.toString();
return APKDetails(version, getApkUrlsFromUrls([unusableApkUrl]),
AppNames('Meta', 'WhatsApp'));
}
}

View File

@ -888,6 +888,11 @@ class AppsProvider with ChangeNotifier {
}
MapEntry<String, String>? apkUrl;
var trackOnly = apps[id]!.app.additionalSettings['trackOnly'] == true;
var refreshBeforeDownload =
apps[id]!.app.additionalSettings['refreshBeforeDownload'] == true;
if (refreshBeforeDownload) {
await checkUpdate(apps[id]!.app.id);
}
if (!trackOnly) {
// ignore: use_build_context_synchronously
apkUrl = await confirmAppFileUrl(apps[id]!.app, context, false);
@ -1074,6 +1079,11 @@ class AppsProvider with ChangeNotifier {
throw ObtainiumError(tr('appNotFound'));
}
MapEntry<String, String>? fileUrl;
var refreshBeforeDownload =
apps[id]!.app.additionalSettings['refreshBeforeDownload'] == true;
if (refreshBeforeDownload) {
await checkUpdate(apps[id]!.app.id);
}
if (apps[id]!.app.apkUrls.isNotEmpty ||
apps[id]!.app.otherAssetUrls.isNotEmpty) {
// ignore: use_build_context_synchronously

View File

@ -29,7 +29,6 @@ import 'package:obtainium/app_sources/telegramapp.dart';
import 'package:obtainium/app_sources/tencent.dart';
import 'package:obtainium/app_sources/uptodown.dart';
import 'package:obtainium/app_sources/vlc.dart';
import 'package:obtainium/app_sources/whatsapp.dart';
import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/mass_app_sources/githubstars.dart';
@ -214,6 +213,21 @@ appJSONCompatibilityModifiers(Map<String, dynamic> json) {
'\\d+.\\d+.\\d+';
additionalSettings = replacementAdditionalSettings;
}
// WhatsApp from before it was removed should be converted to HTML (#1943)
if (json['url'] == 'https://whatsapp.com' &&
json['id'] == 'com.whatsapp' &&
json['author'] == 'Meta' &&
json['name'] == 'WhatsApp' &&
json['overrideSource'] == null &&
additionalSettings['trackOnly'] == false &&
additionalSettings['versionExtractionRegEx'] == '' &&
json['lastUpdateCheck'] != null) {
json['url'] = 'https://whatsapp.com/android';
var replacementAdditionalSettings = getDefaultValuesFromFormItems(
HTML().combinedAppSpecificSettingFormItems);
replacementAdditionalSettings['refreshBeforeDownload'] = true;
additionalSettings = replacementAdditionalSettings;
}
}
json['additionalSettings'] = jsonEncode(additionalSettings);
// F-Droid no longer needs cloudflare exception since override can be used - migrate apps appropriately
@ -586,6 +600,10 @@ abstract class AppSource {
label: tr('skipUpdateNotifications'))
],
[GeneratedFormTextField('about', label: tr('about'), required: false)],
[
GeneratedFormSwitch('refreshBeforeDownload',
label: tr('refreshBeforeDownload'))
]
];
// Previous 2 variables combined into one at runtime for convenient usage
@ -809,7 +827,6 @@ class SourceProvider {
Jenkins(),
APKMirror(),
VLC(),
WhatsApp(),
TelegramApp(),
NeutronCode(),
DirectAPKLink(),