mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-10-29 20:43:28 +01:00 
			
		
		
		
	Compare commits
	
		
			16 Commits
		
	
	
		
			v0.14.6-be
			...
			v0.14.10-b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8ba0a0a776 | ||
|  | 73ed0cea88 | ||
|  | 58a378d212 | ||
|  | 553307ba70 | ||
|  | 78f73a9049 | ||
|  | abc69e7a0e | ||
|  | 503914dbce | ||
|  | 69680f8680 | ||
|  | 1a616aacb7 | ||
|  | 52d19f267e | ||
|  | 75a8dc9ee4 | ||
|  | 8c63920ef6 | ||
|  | dda5619cdc | ||
|  | 9cc25fd931 | ||
|  | f5a9eb4295 | ||
|  | ebe256e482 | 
							
								
								
									
										32
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| --- | ||||
| name: Bug report | ||||
| about: Something isn't working right. | ||||
| title: '' | ||||
| labels: bug, To Check | ||||
| assignees: '' | ||||
|  | ||||
| --- | ||||
|  | ||||
| **Prerequisites** | ||||
| Please ensure your request is not part of an existing issue. | ||||
|  | ||||
| **Describe the bug** | ||||
| A clear and concise description of what the bug is. | ||||
|  | ||||
| **To Reproduce** | ||||
| Steps to reproduce the behavior: | ||||
| 1. Go to '...' | ||||
| 2. Tap on '....' | ||||
| 3. Scroll down to '....' | ||||
| 4. See error | ||||
|  | ||||
| **Screenshots and Logs** | ||||
| If applicable, add screenshots, logs, and any other artifacts (like some/all files under `/Android/data/dev.imranr.obtainium/`) that you think may help troubleshoot the issue. | ||||
|  | ||||
| **Please complete the following information:** | ||||
|  - Device: [e.g. Pixel 7] | ||||
|  - OS: [e.g. GrapheneOS] | ||||
|  - Obtainium Version [e.g. 0.14.6-beta] | ||||
|  | ||||
| **Additional context** | ||||
| Add any other context about the problem here. | ||||
							
								
								
									
										29
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| --- | ||||
| name: Feature request | ||||
| about: Suggest a new Source, setting, or other feature. | ||||
| title: '' | ||||
| labels: enhancement, To Check | ||||
| assignees: '' | ||||
|  | ||||
| --- | ||||
|  | ||||
| **Prerequisites** | ||||
| Please ensure your request is not part of an existing issue. | ||||
|  | ||||
| **Describe the feature** | ||||
| A clear and concise description of what you want to happen. | ||||
|  | ||||
| For new Sources, it's preferable (not required) if you suggest how the following details can be extracted from the Source in a reliable way (like an API or through web scraping): | ||||
| - The App version (or any release-specific identifier - a "pseudo-version") for the latest release | ||||
| - One or more APK URL(s) for the latest release | ||||
| - Above details for previous releases (optional) | ||||
|  | ||||
| Note that the Web scraper cannot deal with JavaScript-enabled content. | ||||
|  | ||||
| **Describe alternatives you've considered (if applicable)** | ||||
| A clear and concise description of any alternative solutions or features you've considered. | ||||
|  | ||||
| Note that app-specific Sources are less likely to be added. In those cases, see if the HTML Source will work for you (if not, see if a generally-applicable enhancement to the HTML Source would work, and suggest that instead). | ||||
|  | ||||
| **Additional context** | ||||
| Add any other context or screenshots about the feature request here. | ||||
| @@ -16,6 +16,7 @@ Currently supported App sources: | ||||
| - [Signal](https://signal.org/) | ||||
| - [SourceForge](https://sourceforge.net/) | ||||
| - [SourceHut](https://git.sr.ht/) | ||||
| - [Aptoide](https://aptoide.com/) | ||||
| - [APKMirror](https://apkmirror.com/) (Track-Only) | ||||
| - [APKPure](https://apkpure.com/) | ||||
| - [Huawei AppGallery](https://appgallery.huawei.com/) | ||||
|   | ||||
| @@ -252,6 +252,7 @@ | ||||
|     "intermediateLinkNotFound": "Link intermediário não encontrado", | ||||
|     "exemptFromBackgroundUpdates": "Isento de atualizações em segundo plano (se ativadas)", | ||||
|     "bgUpdatesOnWiFiOnly": "Desative atualizações em segundo plano quando não estiver em WiFi", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "Remover App?", | ||||
|         "other": "Remover Apps?" | ||||
|   | ||||
| @@ -249,6 +249,7 @@ | ||||
|    "verifyLatestTag": "Verify the 'latest' tag", | ||||
|    "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", | ||||
|    "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", | ||||
|    "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|    "removeAppQuestion": { | ||||
|       "one": "Želite li ukloniti aplikaciju?", | ||||
|       "other": "Želite li ukloniti aplikacije?" | ||||
|   | ||||
| @@ -249,6 +249,7 @@ | ||||
|     "verifyLatestTag": "Überprüfe das 'latest' Tag", | ||||
|     "exemptFromBackgroundUpdates": "Ausschluss von Hintergrundaktualisierungen (falls aktiviert)", | ||||
|     "bgUpdatesOnWiFiOnly": "Hintergrundaktualisierungen deaktivieren, wenn kein WLAN vorhanden ist", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "App entfernen?", | ||||
|         "other": "Apps entfernen?" | ||||
|   | ||||
| @@ -252,6 +252,7 @@ | ||||
|     "intermediateLinkNotFound": "Intermediate link not found", | ||||
|     "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", | ||||
|     "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "Remove App?", | ||||
|         "other": "Remove Apps?" | ||||
|   | ||||
| @@ -249,6 +249,7 @@ | ||||
|     "verifyLatestTag": "Verify the 'latest' tag", | ||||
|     "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", | ||||
|     "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "¿Eliminar Aplicación?", | ||||
|         "other": "¿Eliminar Aplicaciones?" | ||||
|   | ||||
| @@ -249,6 +249,7 @@ | ||||
|     "verifyLatestTag": "Verify the 'latest' tag", | ||||
|     "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", | ||||
|     "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "برنامه حذف شود؟", | ||||
|         "other": "برنامه ها حذف شوند؟" | ||||
|   | ||||
| @@ -249,6 +249,7 @@ | ||||
|     "verifyLatestTag": "Verify the 'latest' tag", | ||||
|     "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", | ||||
|     "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "Supprimer l'application ?", | ||||
|         "other": "Supprimer les applications ?" | ||||
|   | ||||
| @@ -87,7 +87,7 @@ | ||||
|     "author": "Szerző", | ||||
|     "upToDateApps": "Naprakész appok", | ||||
|     "nonInstalledApps": "Nem telepített appok", | ||||
|     "importExport": "Importálás/Exportálás", | ||||
|     "importExport": "Import/Export", | ||||
|     "settings": "Beállítások", | ||||
|     "exportedTo": "Exportálva ide {}", | ||||
|     "obtainiumExport": "Obtainium Adat Exportálás", | ||||
| @@ -137,7 +137,7 @@ | ||||
|     "share": "Megosztás", | ||||
|     "appNotFound": "App nem található", | ||||
|     "obtainiumExportHyphenatedLowercase": "obtainium-export", | ||||
|     "pickAnAPK": "Válasszon egy APK-ot", | ||||
|     "pickAnAPK": "Válasszon egy APK-t", | ||||
|     "appHasMoreThanOnePackage": "A(z) {} egynél több csomaggal rendelkezik:", | ||||
|     "deviceSupportsXArch": "Eszköze támogatja a {} CPU architektúrát.", | ||||
|     "deviceSupportsFollowingArchs": "Az eszköze a következő CPU architektúrákat támogatja:", | ||||
| @@ -204,7 +204,7 @@ | ||||
|     "copiedToClipboard": "Másolva a vágólapra", | ||||
|     "storagePermissionDenied": "Tárhely engedély megtagadva", | ||||
|     "selectedCategorizeWarning": "Ez felváltja a kiválasztott alkalmazások meglévő kategória-beállításait.", | ||||
|     "filterAPKsByRegEx": "Az APK-ok szűrése reguláris kifejezéssel", | ||||
|     "filterAPKsByRegEx": "Az APK-k szűrése reguláris kifejezéssel", | ||||
|     "removeFromObtainium": "Eltávolítás az Obtainiumból", | ||||
|     "uninstallFromDevice": "Eltávolítás a készülékről", | ||||
|     "onlyWorksWithNonVersionDetectApps": "Csak azoknál az alkalmazásoknál működik, amelyeknél a verzióérzékelés le van tiltva.", | ||||
| @@ -239,15 +239,16 @@ | ||||
|     "gitlabSourceNote": "Előfordulhat, hogy a GitLab APK kibontása nem működik API-kulcs nélkül.", | ||||
|     "sortByFileNamesNotLinks": "Fájlnevek szerinti elrendezés teljes linkek helyett", | ||||
|     "filterReleaseNotesByRegEx": "Kiadási megjegyzések szűrése reguláris kifejezéssel", | ||||
|     "customLinkFilterRegex": "Custom APK Link Filter by Regular Expression (Default '.apk$')", | ||||
|     "appsPossiblyUpdated": "App Updates Attempted", | ||||
|     "appsPossiblyUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were potentially applied in the background", | ||||
|     "xWasPossiblyUpdatedToY": "{} may have been updated to {}.", | ||||
|     "backgroundUpdateReqsExplanation": "Background updates may not be possible for all apps.", | ||||
|     "backgroundUpdateLimitsExplanation": "The success of a background install can only be determined when Obtainium is opened.", | ||||
|     "verifyLatestTag": "Verify the 'latest' tag", | ||||
|     "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", | ||||
|     "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", | ||||
|     "customLinkFilterRegex": "Egyéni APK hivatkozásszűrő reguláris kifejezéssel (Alapérték '.apk$')", | ||||
|     "appsPossiblyUpdated": "App frissítési kísérlet", | ||||
|     "appsPossiblyUpdatedNotifDescription": "Értesíti a felhasználót, hogy egy vagy több alkalmazás frissítése lehetséges a háttérben", | ||||
|     "xWasPossiblyUpdatedToY": "{} frissítve lehet erre {}.", | ||||
|     "backgroundUpdateReqsExplanation": "Előfordulhat, hogy nem minden appnál lehetséges a háttérbeli frissítés.", | ||||
|     "backgroundUpdateLimitsExplanation": "A háttérben történő telepítés sikeressége csak az Obtainium megnyitásakor állapítható meg.", | ||||
|     "verifyLatestTag": "Ellenőrizze a „legújabb” címkét", | ||||
|     "exemptFromBackgroundUpdates": "Mentes a háttérben történő frissítések alól (ha engedélyezett)", | ||||
|     "bgUpdatesOnWiFiOnly": "Tiltsa le a háttérben frissítéseket, ha nincs Wi-Fi-n", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "Eltávolítja az alkalmazást?", | ||||
|         "other": "Eltávolítja az alkalmazást?" | ||||
| @@ -297,7 +298,7 @@ | ||||
|         "other": "{} és {} további alkalmazás frissítve." | ||||
|     }, | ||||
|     "xAndNMoreUpdatesPossiblyInstalled": { | ||||
|         "one": "{} and 1 more app may have been updated.", | ||||
|         "other": "{} and {} more apps may have been updated." | ||||
|         "one": "{} és 1 további alkalmazás is frissült.", | ||||
|         "other": "{} és {} további alkalmazás is frissült." | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -249,6 +249,7 @@ | ||||
|     "verifyLatestTag": "Verify the 'latest' tag", | ||||
|     "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", | ||||
|     "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "Rimuovere l'app?", | ||||
|         "other": "Rimuovere le app?" | ||||
|   | ||||
| @@ -250,6 +250,7 @@ | ||||
|     "verifyLatestTag": "'latest'タグを確認する", | ||||
|     "exemptFromBackgroundUpdates": "バックグラウンドアップデートを行わない (有効な場合)", | ||||
|     "bgUpdatesOnWiFiOnly": "WiFiを使用していない場合,バックグラウンドアップデートを無効にする", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "アプリを削除しますか?", | ||||
|         "other": "アプリを削除しますか?" | ||||
|   | ||||
| @@ -255,6 +255,7 @@ | ||||
|     "verifyLatestTag": "Zweryfikuj najnowszy tag", | ||||
|     "exemptFromBackgroundUpdates": "Wyklucz z uaktualnień w tle (jeśli są włączone)", | ||||
|     "bgUpdatesOnWiFiOnly": "Wyłącz aktualizacje w tle, gdy nie ma połączenia z Wi-Fi", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "Usunąć aplikację?", | ||||
|         "few": "Usunąć aplikacje?", | ||||
|   | ||||
| @@ -249,6 +249,7 @@ | ||||
|     "verifyLatestTag": "Verify the 'latest' tag", | ||||
|     "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", | ||||
|     "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "Удалить приложение?", | ||||
|         "other": "Удалить приложения?" | ||||
|   | ||||
| @@ -250,6 +250,7 @@ | ||||
|     "verifyLatestTag": "验证“Latest”标签", | ||||
|     "exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)", | ||||
|     "bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi", | ||||
|     "autoSelectHighestVersionCode": "Auto-select highest versionCode APK", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "是否删除应用?", | ||||
|         "other": "是否删除应用?" | ||||
|   | ||||
							
								
								
									
										108
									
								
								lib/app_sources/aptoide.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								lib/app_sources/aptoide.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| import 'dart:convert'; | ||||
|  | ||||
| import 'package:easy_localization/easy_localization.dart'; | ||||
| import 'package:html/parser.dart'; | ||||
| import 'package:http/http.dart'; | ||||
| import 'package:obtainium/custom_errors.dart'; | ||||
| import 'package:obtainium/providers/source_provider.dart'; | ||||
|  | ||||
| class Aptoide extends AppSource { | ||||
|   Aptoide() { | ||||
|     host = 'aptoide.com'; | ||||
|     name = tr('Aptoide'); | ||||
|     allowSubDomains = true; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String sourceSpecificStandardizeURL(String url) { | ||||
|     RegExp standardUrlRegEx = RegExp('^https?://([^\\.]+\\.){2,}$host'); | ||||
|     RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase()); | ||||
|     if (match == null) { | ||||
|       throw InvalidURLError(name); | ||||
|     } | ||||
|     return url.substring(0, match.end); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Future<String?> tryInferringAppId(String standardUrl, | ||||
|       {Map<String, dynamic> additionalSettings = const {}}) async { | ||||
|     return (await getAppDetailsJSON(standardUrl))['package']; | ||||
|   } | ||||
|  | ||||
|   Future<Map<String, dynamic>> getAppDetailsJSON(String standardUrl) async { | ||||
|     var res = await sourceRequest(standardUrl); | ||||
|     if (res.statusCode != 200) { | ||||
|       throw getObtainiumHttpError(res); | ||||
|     } | ||||
|     var idMatch = RegExp('"app":{"id":[0-9]+').firstMatch(res.body); | ||||
|     String? id; | ||||
|     if (idMatch != null) { | ||||
|       id = res.body.substring(idMatch.start + 12, idMatch.end); | ||||
|     } else { | ||||
|       throw NoReleasesError(); | ||||
|     } | ||||
|     var res2 = | ||||
|         await sourceRequest('https://ws2.aptoide.com/api/7/getApp/app_id/$id'); | ||||
|     if (res2.statusCode != 200) { | ||||
|       throw getObtainiumHttpError(res); | ||||
|     } | ||||
|     return jsonDecode(res2.body)?['nodes']?['meta']?['data']; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Future<APKDetails> getLatestAPKDetails( | ||||
|     String standardUrl, | ||||
|     Map<String, dynamic> additionalSettings, | ||||
|   ) async { | ||||
|     var appDetails = await getAppDetailsJSON(standardUrl); | ||||
|     String appName = appDetails['name'] ?? tr('app'); | ||||
|     String author = appDetails['developer']?['name'] ?? name; | ||||
|     String? dateStr = appDetails['updated']; | ||||
|     String? version = appDetails['file']?['vername']; | ||||
|     String? apkUrl = appDetails['file']?['path']; | ||||
|     if (version == null) { | ||||
|       throw NoVersionError(); | ||||
|     } | ||||
|     if (apkUrl == null) { | ||||
|       throw NoAPKError(); | ||||
|     } | ||||
|     DateTime? relDate; | ||||
|     if (dateStr != null) { | ||||
|       relDate = DateTime.parse(dateStr); | ||||
|     } | ||||
|  | ||||
|     return APKDetails( | ||||
|         version, getApkUrlsFromUrls([apkUrl]), AppNames(author, appName), | ||||
|         releaseDate: relDate); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Future<Map<String, List<String>>> search(String query, | ||||
|       {Map<String, dynamic> querySettings = const {}}) async { | ||||
|     Response res = await sourceRequest( | ||||
|         'https://search.$host/?q=${Uri.encodeQueryComponent(query)}'); | ||||
|     if (res.statusCode == 200) { | ||||
|       Map<String, List<String>> urlsWithDescriptions = {}; | ||||
|       parse(res.body).querySelectorAll('.package-header').forEach((e) { | ||||
|         String? url = e.attributes['href']; | ||||
|         if (url != null) { | ||||
|           try { | ||||
|             standardizeUrl(url); | ||||
|           } catch (e) { | ||||
|             url = null; | ||||
|           } | ||||
|         } | ||||
|         if (url != null) { | ||||
|           urlsWithDescriptions[url] = [ | ||||
|             e.querySelector('.package-name')?.text.trim() ?? '', | ||||
|             e.querySelector('.package-summary')?.text.trim() ?? | ||||
|                 tr('noDescription') | ||||
|           ]; | ||||
|         } | ||||
|       }); | ||||
|       return urlsWithDescriptions; | ||||
|     } else { | ||||
|       throw getObtainiumHttpError(res); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -3,6 +3,7 @@ import 'dart:convert'; | ||||
| import 'package:easy_localization/easy_localization.dart'; | ||||
| import 'package:html/parser.dart'; | ||||
| import 'package:http/http.dart'; | ||||
| import 'package:obtainium/components/generated_form.dart'; | ||||
| import 'package:obtainium/custom_errors.dart'; | ||||
| import 'package:obtainium/providers/source_provider.dart'; | ||||
|  | ||||
| @@ -11,6 +12,12 @@ class FDroid extends AppSource { | ||||
|     host = 'f-droid.org'; | ||||
|     name = tr('fdroid'); | ||||
|     canSearch = true; | ||||
|     additionalSourceAppSpecificSettingFormItems = [ | ||||
|       [ | ||||
|         GeneratedFormSwitch('autoSelectHighestVersionCode', | ||||
|             label: tr('autoSelectHighestVersionCode')) | ||||
|       ] | ||||
|     ]; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
| @@ -37,7 +44,8 @@ class FDroid extends AppSource { | ||||
|   } | ||||
|  | ||||
|   APKDetails getAPKUrlsFromFDroidPackagesAPIResponse( | ||||
|       Response res, String apkUrlPrefix, String standardUrl) { | ||||
|       Response res, String apkUrlPrefix, String standardUrl, | ||||
|       {bool autoSelectHighestVersionCode = false}) { | ||||
|     if (res.statusCode == 200) { | ||||
|       List<dynamic> releases = jsonDecode(res.body)['packages'] ?? []; | ||||
|       if (releases.isEmpty) { | ||||
| @@ -47,8 +55,12 @@ class FDroid extends AppSource { | ||||
|       if (latestVersion == null) { | ||||
|         throw NoVersionError(); | ||||
|       } | ||||
|       List<String> apkUrls = releases | ||||
|           .where((element) => element['versionName'] == latestVersion) | ||||
|       Iterable<dynamic> latestReleases = | ||||
|           releases.where((element) => element['versionName'] == latestVersion); | ||||
|       if (latestReleases.length > 1 && autoSelectHighestVersionCode) { | ||||
|         latestReleases = [latestReleases.first]; | ||||
|       } | ||||
|       List<String> apkUrls = latestReleases | ||||
|           .map((e) => '${apkUrlPrefix}_${e['versionCode']}.apk') | ||||
|           .toList(); | ||||
|       return APKDetails(latestVersion, getApkUrlsFromUrls(apkUrls), | ||||
| @@ -68,7 +80,9 @@ class FDroid extends AppSource { | ||||
|     return getAPKUrlsFromFDroidPackagesAPIResponse( | ||||
|         await sourceRequest('https://$host/api/v1/packages/$appId'), | ||||
|         'https://$host/repo/$appId', | ||||
|         standardUrl); | ||||
|         standardUrl, | ||||
|         autoSelectHighestVersionCode: | ||||
|             additionalSettings['autoSelectHighestVersionCode'] == true); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   | ||||
| @@ -18,7 +18,7 @@ String ensureAbsoluteUrl(String ambiguousUrl, Uri referenceAbsoluteUrl) { | ||||
|       .toList(); | ||||
|   if (ambiguousUrl.startsWith('/') || currPathSegments.isEmpty) { | ||||
|     return '${referenceAbsoluteUrl.origin}/$ambiguousUrl'; | ||||
|   } else if (ambiguousUrl.split('/').length == 1) { | ||||
|   } else if (ambiguousUrl.split('/').where((e) => e.isNotEmpty).length == 1) { | ||||
|     return '${referenceAbsoluteUrl.origin}/${currPathSegments.join('/')}/$ambiguousUrl'; | ||||
|   } else { | ||||
|     return '${referenceAbsoluteUrl.origin}/${currPathSegments.sublist(0, currPathSegments.length - 1).join('/')}/$ambiguousUrl'; | ||||
|   | ||||
| @@ -3,8 +3,13 @@ import 'package:obtainium/custom_errors.dart'; | ||||
| import 'package:obtainium/providers/source_provider.dart'; | ||||
|  | ||||
| class IzzyOnDroid extends AppSource { | ||||
|   late FDroid fd; | ||||
|  | ||||
|   IzzyOnDroid() { | ||||
|     host = 'android.izzysoft.de'; | ||||
|     fd = FDroid(); | ||||
|     additionalSourceAppSpecificSettingFormItems = | ||||
|         fd.additionalSourceAppSpecificSettingFormItems; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
| @@ -20,7 +25,7 @@ class IzzyOnDroid extends AppSource { | ||||
|   @override | ||||
|   Future<String?> tryInferringAppId(String standardUrl, | ||||
|       {Map<String, dynamic> additionalSettings = const {}}) async { | ||||
|     return FDroid().tryInferringAppId(standardUrl); | ||||
|     return fd.tryInferringAppId(standardUrl); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
| @@ -29,10 +34,12 @@ class IzzyOnDroid extends AppSource { | ||||
|     Map<String, dynamic> additionalSettings, | ||||
|   ) async { | ||||
|     String? appId = await tryInferringAppId(standardUrl); | ||||
|     return FDroid().getAPKUrlsFromFDroidPackagesAPIResponse( | ||||
|     return fd.getAPKUrlsFromFDroidPackagesAPIResponse( | ||||
|         await sourceRequest( | ||||
|             'https://apt.izzysoft.de/fdroid/api/v1/packages/$appId'), | ||||
|         'https://android.izzysoft.de/frepo/$appId', | ||||
|         standardUrl); | ||||
|         standardUrl, | ||||
|         autoSelectHighestVersionCode: | ||||
|             additionalSettings['autoSelectHighestVersionCode'] == true); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -19,7 +19,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart'; | ||||
| // ignore: implementation_imports | ||||
| import 'package:easy_localization/src/localization.dart'; | ||||
|  | ||||
| const String currentVersion = '0.14.6'; | ||||
| const String currentVersion = '0.14.10'; | ||||
| const String currentReleaseTag = | ||||
|     'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES | ||||
|  | ||||
|   | ||||
| @@ -9,6 +9,7 @@ import 'package:html/dom.dart'; | ||||
| import 'package:http/http.dart'; | ||||
| 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/fdroid.dart'; | ||||
| import 'package:obtainium/app_sources/fdroidrepo.dart'; | ||||
| @@ -325,6 +326,7 @@ abstract class AppSource { | ||||
|   bool enforceTrackOnly = false; | ||||
|   bool changeLogIfAnyIsMarkDown = true; | ||||
|   bool appIdInferIsOptional = false; | ||||
|   bool allowSubDomains = false; | ||||
|  | ||||
|   AppSource() { | ||||
|     name = runtimeType.toString(); | ||||
| @@ -522,13 +524,14 @@ class SourceProvider { | ||||
|         Jenkins(), | ||||
|         SourceForge(), | ||||
|         SourceHut(), | ||||
|         Aptoide(), | ||||
|         APKMirror(), | ||||
|         APKPure(), | ||||
|         HuaweiAppGallery(), | ||||
|         // APKCombo(), // Can't get past their scraping blocking yet (get 403 Forbidden) | ||||
|         Mullvad(), | ||||
|         Signal(), | ||||
|         VLC(), // As of 2023-08-26 this site randomly messes up the 'latest' version (one minute it's 3.5.4, next minute back to 3.5.3) | ||||
|         VLC(), | ||||
|         // WhatsApp(), // As of 2023-03-20 this is unusable as the version on the webpage is months out of date | ||||
|         TelegramApp(), | ||||
|         SteamMobile(), | ||||
| @@ -554,7 +557,9 @@ class SourceProvider { | ||||
|     } | ||||
|     AppSource? source; | ||||
|     for (var s in sources.where((element) => element.host != null)) { | ||||
|       if (RegExp('://${s.host}(/|\\z)?').hasMatch(url)) { | ||||
|       if (RegExp( | ||||
|               '://${s.allowSubDomains ? '([^\\.]+\\.)*' : ''}${s.host}(/|\\z)?') | ||||
|           .hasMatch(url)) { | ||||
|         source = s; | ||||
|         break; | ||||
|       } | ||||
|   | ||||
							
								
								
									
										24
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								pubspec.lock
									
									
									
									
									
								
							| @@ -46,10 +46,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: archive | ||||
|       sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a" | ||||
|       sha256: "49b1fad315e57ab0bbc15bcbb874e83116a1d78f77ebd500a4af6c9407d6b28e" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.3.7" | ||||
|     version: "3.3.8" | ||||
|   args: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -206,10 +206,10 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: easy_localization | ||||
|       sha256: "30ebf25448ffe169e0bd9bc4b5da94faa8398967a2ad2ca09f438be8b6953645" | ||||
|       sha256: de63e3b422adfc97f256cbb3f8cf12739b6a4993d390f3cadb3f51837afaefe5 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.0.2" | ||||
|     version: "3.0.3" | ||||
|   easy_logger: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -783,18 +783,18 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: url_launcher | ||||
|       sha256: "38d8e783681bc342e92dc9799cbe4421d08c4d210a67ee9d61d0f7310491a465" | ||||
|       sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "6.1.13" | ||||
|     version: "6.1.14" | ||||
|   url_launcher_android: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: url_launcher_android | ||||
|       sha256: ef7e34951ffa963fb7a65928deeb38d40fb3c5975baf93c1d631341ff7f2650a | ||||
|       sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "6.0.39" | ||||
|     version: "6.1.0" | ||||
|   url_launcher_ios: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -823,10 +823,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: url_launcher_platform_interface | ||||
|       sha256: "4d0dae953f80dc06fa24c58d0f8381302139c22c2dad301417787ad96f5f73bd" | ||||
|       sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.4" | ||||
|     version: "2.1.5" | ||||
|   url_launcher_web: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -879,10 +879,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: webview_flutter_android | ||||
|       sha256: "8545719bbf06f5c4b850f0d5f86da1fe837b1953c56b9af579a26be73627c98d" | ||||
|       sha256: "0d8f5ac96a155e672129bf94c7abf625de01241d44d269dbaff083f1b4deb1aa" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.9.4" | ||||
|     version: "3.9.5" | ||||
|   webview_flutter_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|   | ||||
| @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev | ||||
| # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html | ||||
| # In Windows, build-name is used as the major, minor, and patch parts | ||||
| # of the product and file versions while build-number is used as the build suffix. | ||||
| version: 0.14.6+198 # When changing this, update the tag in main() accordingly | ||||
| version: 0.14.10+202 # When changing this, update the tag in main() accordingly | ||||
|  | ||||
| environment: | ||||
|   sdk: '>=2.18.2 <3.0.0' | ||||
|   | ||||
		Reference in New Issue
	
	Block a user