diff --git a/assets/translations/bs.json b/assets/translations/bs.json index a83f1dd..6be1a39 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Želite li ukloniti aplikaciju?", "other": "Želite li ukloniti aplikacije?" diff --git a/assets/translations/cs.json b/assets/translations/cs.json index f21663f..f4de726 100644 --- a/assets/translations/cs.json +++ b/assets/translations/cs.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Odstranit Apku?", "other": "Odstranit Apky?" diff --git a/assets/translations/de.json b/assets/translations/de.json index 119ba9c..84d148b 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -294,6 +294,10 @@ "useVersionCodeAsOSVersion": "Verwende die Appversion als erkannte Version vom Betriebssystem", "requestHeader": "Request Header", "useLatestAssetDateAsReleaseDate": "Den letzten Asset-Upload als Veröffentlichungsdatum verwenden", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "App entfernen?", "other": "Apps entfernen?" diff --git a/assets/translations/en.json b/assets/translations/en.json index 5907ccf..f6f3811 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -294,6 +294,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/es.json b/assets/translations/es.json index e01f283..595e7d6 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "¿Eliminar Aplicación?", "other": "¿Eliminar Aplicaciones?" diff --git a/assets/translations/fa.json b/assets/translations/fa.json index fd52064..46ea68b 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "استفاده کد نسخه برنامه به جای نسخه شناسایی شده توسط سیستم عامل استفاده کنید", "requestHeader": "درخواست سطر بالایی", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "برنامه حذف شود؟", "other": "برنامه ها حذف شوند؟" diff --git a/assets/translations/fr.json b/assets/translations/fr.json index ee33cf8..ed255e3 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Supprimer l'application ?", "other": "Supprimer les applications ?" diff --git a/assets/translations/hu.json b/assets/translations/hu.json index c6d8c47..c50e2b9 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Az app versionCode használata a rendszer által észlelt verzióként", "requestHeader": "Kérelem fejléc", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Eltávolítja az alkalmazást?", "other": "Eltávolítja az alkalmazást?" diff --git a/assets/translations/it.json b/assets/translations/it.json index ae5b7a9..e9de63c 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Rimuovere l'app?", "other": "Rimuovere le app?" diff --git a/assets/translations/ja.json b/assets/translations/ja.json index e2b4d38..eb459d6 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -294,6 +294,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "アプリを削除しますか?", "other": "アプリを削除しますか?" diff --git a/assets/translations/nl.json b/assets/translations/nl.json index 4f788d0..e0f4546 100644 --- a/assets/translations/nl.json +++ b/assets/translations/nl.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "App verwijderen?", "other": "Apps verwijderen?" diff --git a/assets/translations/pl.json b/assets/translations/pl.json index 44f2f9d..4fead4e 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Usunąć aplikację?", "few": "Usunąć aplikacje?", diff --git a/assets/translations/pt.json b/assets/translations/pt.json index dc2370f..405aa74 100644 --- a/assets/translations/pt.json +++ b/assets/translations/pt.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Remover aplicativo?", "other": "Remover aplicativos?" diff --git a/assets/translations/ru.json b/assets/translations/ru.json index 2168990..ce680f7 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -294,6 +294,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" diff --git a/assets/translations/sv.json b/assets/translations/sv.json index 157382f..58f8416 100644 --- a/assets/translations/sv.json +++ b/assets/translations/sv.json @@ -278,6 +278,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Ta Bort App?", "other": "Ta Bort Appar?" diff --git a/assets/translations/tr.json b/assets/translations/tr.json index 5ade2f2..cf655df 100644 --- a/assets/translations/tr.json +++ b/assets/translations/tr.json @@ -292,6 +292,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "Uygulamayı Kaldır?", "other": "Uygulamaları Kaldır?" diff --git a/assets/translations/vi.json b/assets/translations/vi.json index eb20091..d3dfea4 100644 --- a/assets/translations/vi.json +++ b/assets/translations/vi.json @@ -290,6 +290,10 @@ "root": "Root", "shizukuBinderNotFound": "Shizuku chưa khởi động", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion":{ "one": "Gỡ ứng dụng?", "other": "Gỡ ứng dụng?" diff --git a/assets/translations/zh.json b/assets/translations/zh.json index d570125..993b130 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -294,6 +294,10 @@ "useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version", "requestHeader": "Request header", "useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date", + "defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method", + "partialAPKHash": "Partial APK Hash", + "APKLinkHash": "APK Link Hash", + "directAPKLink": "Direct APK Link", "removeAppQuestion": { "one": "是否删除应用?", "other": "是否删除应用?" diff --git a/lib/app_sources/directAPKLink.dart b/lib/app_sources/directAPKLink.dart new file mode 100644 index 0000000..def21dd --- /dev/null +++ b/lib/app_sources/directAPKLink.dart @@ -0,0 +1,44 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:obtainium/app_sources/html.dart'; +import 'package:obtainium/providers/source_provider.dart'; + +class DirectAPKLink extends AppSource { + HTML html = HTML(); + + DirectAPKLink() { + neverAutoSelect = true; + name = tr('directAPKLink'); + additionalSourceAppSpecificSettingFormItems = html + .additionalSourceAppSpecificSettingFormItems + .where((element) => element + .where((element) => element.key == 'requestHeader') + .isNotEmpty) + .toList(); + excludeCommonSettingKeys = [ + 'versionExtractionRegEx', + 'matchGroupToUse', + 'versionDetection', + 'useVersionCodeAsOSVersion', + 'apkFilterRegEx', + 'autoApkFilterByArch' + ]; + } + + @override + Future getLatestAPKDetails( + String standardUrl, + Map additionalSettings, + ) async { + var additionalSettingsNew = + getDefaultValuesFromFormItems(html.combinedAppSpecificSettingFormItems); + for (var s in additionalSettings.keys) { + if (additionalSettingsNew.containsKey(s)) { + additionalSettingsNew[s] = additionalSettings[s]; + } + } + additionalSettingsNew['defaultPseudoVersioningMethod'] = 'partialAPKHash'; + additionalSettingsNew['directAPKLink'] = true; + additionalSettings['versionDetection'] = false; + return html.getLatestAPKDetails(standardUrl, additionalSettingsNew); + } +} diff --git a/lib/app_sources/html.dart b/lib/app_sources/html.dart index d13653a..fdb94a0 100644 --- a/lib/app_sources/html.dart +++ b/lib/app_sources/html.dart @@ -108,11 +108,7 @@ class HTML extends AppSource { [ GeneratedFormSwitch('versionExtractWholePage', label: tr('versionExtractWholePage')) - ], - [ - GeneratedFormSwitch('supportFixedAPKURL', - defaultValue: true, label: tr('supportFixedAPKURL')), - ], + ] ]; var commonFormItems = [ [GeneratedFormSwitch('filterByLinkText', label: tr('filterByLinkText'))], @@ -172,6 +168,16 @@ class HTML extends AppSource { 'User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36' } ]) + ], + [ + GeneratedFormDropdown( + 'defaultPseudoVersioningMethod', + [ + MapEntry('partialAPKHash', tr('partialAPKHash')), + MapEntry('APKLinkHash', tr('APKLinkHash')) + ], + label: tr('defaultPseudoVersioningMethod'), + defaultValue: 'partialAPKHash') ] ]; } @@ -286,17 +292,25 @@ class HTML extends AppSource { currentUrl = intLinks.last.key; } } - var uri = Uri.parse(currentUrl); - Response res = await sourceRequest(currentUrl, additionalSettings); - var links = await grabLinksCommon(res, additionalSettings); + List> links = []; + String versionExtractionWholePageString = currentUrl; + if (additionalSettings['directAPKLink'] != true) { + Response res = await sourceRequest(currentUrl, additionalSettings); + versionExtractionWholePageString = + res.body.split('\r\n').join('\n').split('\n').join('\\n'); + links = await grabLinksCommon(res, additionalSettings); - if ((additionalSettings['apkFilterRegEx'] as String?)?.isNotEmpty == true) { - var reg = RegExp(additionalSettings['apkFilterRegEx']); - links = links.where((element) => reg.hasMatch(element.key)).toList(); - } - if (links.isEmpty) { - throw NoReleasesError(); + if ((additionalSettings['apkFilterRegEx'] as String?)?.isNotEmpty == + true) { + var reg = RegExp(additionalSettings['apkFilterRegEx']); + links = links.where((element) => reg.hasMatch(element.key)).toList(); + } + if (links.isEmpty) { + throw NoReleasesError(); + } + } else { + links = [MapEntry(currentUrl, currentUrl)]; } var rel = links.last.key; String? version; @@ -304,11 +318,12 @@ class HTML extends AppSource { additionalSettings['versionExtractionRegEx'] as String?, additionalSettings['matchGroupToUse'] as String?, additionalSettings['versionExtractWholePage'] == true - ? res.body.split('\r\n').join('\n').split('\n').join('\\n') + ? versionExtractionWholePageString : rel); - version ??= additionalSettings['supportFixedAPKURL'] != true - ? rel.hashCode.toString() - : (await checkPartialDownloadHashDynamc(rel)).toString(); + version ??= + additionalSettings['defaultPseudoVersioningMethod'] == 'APKLinkHash' + ? rel.hashCode.toString() + : (await checkPartialDownloadHashDynamc(rel)).toString(); return APKDetails(version, [rel].map((e) => MapEntry(e, e)).toList(), AppNames(uri.host, tr('app'))); } diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index ac6b284..b1a7242 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -11,6 +11,7 @@ import 'package:obtainium/app_sources/apkmirror.dart'; import 'package:obtainium/app_sources/apkpure.dart'; import 'package:obtainium/app_sources/aptoide.dart'; import 'package:obtainium/app_sources/codeberg.dart'; +import 'package:obtainium/app_sources/directAPKLink.dart'; import 'package:obtainium/app_sources/fdroid.dart'; import 'package:obtainium/app_sources/fdroidrepo.dart'; import 'package:obtainium/app_sources/github.dart'; @@ -112,6 +113,12 @@ appJSONCompatibilityModifiers(Map json) { additionalSettings['versionDetection'] = false; additionalSettings['releaseDateAsVersion'] = true; } + // Convert bool style pseudo version method to dropdown style + if (originalAdditionalSettings['supportFixedAPKURL'] == true) { + additionalSettings['defaultPseudoVersioningMethod'] = 'partialAPKHash'; + } else if (originalAdditionalSettings['supportFixedAPKURL'] == false) { + additionalSettings['defaultPseudoVersioningMethod'] = 'APKLinkHash'; + } // Ensure additionalSettings are correctly typed for (var item in formItems) { if (additionalSettings[item.key] != null) { @@ -391,6 +398,7 @@ abstract class AppSource { bool neverAutoSelect = false; bool showReleaseDateAsVersionToggle = false; bool versionDetectionDisallowed = false; + List excludeCommonSettingKeys = []; AppSource() { name = runtimeType.toString(); @@ -536,6 +544,13 @@ abstract class AppSource { ]); } } + additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly = + additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly + .map((e) => e + .where((ee) => !excludeCommonSettingKeys.contains(ee.key)) + .toList()) + .where((e) => e.isNotEmpty) + .toList(); if (versionDetectionDisallowed) { overrideAdditionalAppSpecificSourceAgnosticSettingSwitch( 'versionDetection', @@ -715,6 +730,7 @@ class SourceProvider { WhatsApp(), TelegramApp(), NeutronCode(), + DirectAPKLink(), HTML() // This should ALWAYS be the last option as they are tried in order ];