mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-10-31 05:23:28 +01:00 
			
		
		
		
	Compare commits
	
		
			4 Commits
		
	
	
		
			v0.7.3-bet
			...
			v0.7.4-bet
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | a4bc278e4c | ||
|  | b04986622b | ||
|  | 2059e4fd44 | ||
|  | 618a1523cf | 
| @@ -1,3 +1,5 @@ | ||||
| import 'dart:convert'; | ||||
|  | ||||
| import 'package:html/parser.dart'; | ||||
| import 'package:http/http.dart'; | ||||
| import 'package:obtainium/custom_errors.dart'; | ||||
| @@ -28,41 +30,24 @@ class FDroid extends AppSource { | ||||
|   String? changeLogPageFromStandardUrl(String standardUrl) => null; | ||||
|  | ||||
|   @override | ||||
|   Future<String> apkUrlPrefetchModifier(String apkUrl) async => apkUrl; | ||||
|   String? tryInferringAppId(String standardUrl) { | ||||
|     return Uri.parse(standardUrl).pathSegments.last; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Future<APKDetails> getLatestAPKDetails( | ||||
|       String standardUrl, List<String> additionalData) async { | ||||
|     Response res = await get(Uri.parse(standardUrl)); | ||||
|   APKDetails getAPKUrlsFromFDroidPackagesAPIResponse( | ||||
|       Response res, String apkUrlPrefix) { | ||||
|     if (res.statusCode == 200) { | ||||
|       var releases = parse(res.body).querySelectorAll('.package-version'); | ||||
|       List<dynamic> releases = jsonDecode(res.body)['packages'] ?? []; | ||||
|       if (releases.isEmpty) { | ||||
|         throw NoReleasesError(); | ||||
|       } | ||||
|       String? latestVersion = releases[0] | ||||
|           .querySelector('.package-version-header b') | ||||
|           ?.innerHtml | ||||
|           .split(' ') | ||||
|           .sublist(1) | ||||
|           .join(' '); | ||||
|       String? latestVersion = releases[0]['versionName']; | ||||
|       if (latestVersion == null) { | ||||
|         throw NoVersionError(); | ||||
|       } | ||||
|       List<String> apkUrls = releases | ||||
|           .where((element) => | ||||
|               element | ||||
|                   .querySelector('.package-version-header b') | ||||
|                   ?.innerHtml | ||||
|                   .split(' ') | ||||
|                   .sublist(1) | ||||
|                   .join(' ') == | ||||
|               latestVersion) | ||||
|           .map((e) => | ||||
|               e | ||||
|                   .querySelector('.package-version-download a') | ||||
|                   ?.attributes['href'] ?? | ||||
|               '') | ||||
|           .where((element) => element.isNotEmpty) | ||||
|           .where((element) => element['versionName'] == latestVersion) | ||||
|           .map((e) => '${apkUrlPrefix}_${e['versionCode']}.apk') | ||||
|           .toList(); | ||||
|       if (apkUrls.isEmpty) { | ||||
|         throw NoAPKError(); | ||||
| @@ -73,6 +58,15 @@ class FDroid extends AppSource { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Future<APKDetails> getLatestAPKDetails( | ||||
|       String standardUrl, List<String> additionalData) async { | ||||
|     String? appId = tryInferringAppId(standardUrl); | ||||
|     return getAPKUrlsFromFDroidPackagesAPIResponse( | ||||
|         await get(Uri.parse('https://f-droid.org/api/v1/packages/$appId')), | ||||
|         'https://f-droid.org/repo/$appId'); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   AppNames getAppNames(String standardUrl) { | ||||
|     return AppNames('F-Droid', Uri.parse(standardUrl).pathSegments.last); | ||||
|   | ||||
| @@ -105,9 +105,6 @@ class GitHub extends AppSource { | ||||
|   String? changeLogPageFromStandardUrl(String standardUrl) => | ||||
|       '$standardUrl/releases'; | ||||
|  | ||||
|   @override | ||||
|   Future<String> apkUrlPrefetchModifier(String apkUrl) async => apkUrl; | ||||
|  | ||||
|   @override | ||||
|   Future<APKDetails> getLatestAPKDetails( | ||||
|       String standardUrl, List<String> additionalData) async { | ||||
|   | ||||
| @@ -23,9 +23,6 @@ class GitLab extends AppSource { | ||||
|   String? changeLogPageFromStandardUrl(String standardUrl) => | ||||
|       '$standardUrl/-/releases'; | ||||
|  | ||||
|   @override | ||||
|   Future<String> apkUrlPrefetchModifier(String apkUrl) async => apkUrl; | ||||
|  | ||||
|   @override | ||||
|   Future<APKDetails> getLatestAPKDetails( | ||||
|       String standardUrl, List<String> additionalData) async { | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import 'package:html/parser.dart'; | ||||
| import 'package:http/http.dart'; | ||||
| import 'package:obtainium/app_sources/fdroid.dart'; | ||||
| import 'package:obtainium/custom_errors.dart'; | ||||
| import 'package:obtainium/providers/source_provider.dart'; | ||||
|  | ||||
| @@ -22,41 +23,18 @@ class IzzyOnDroid extends AppSource { | ||||
|   String? changeLogPageFromStandardUrl(String standardUrl) => null; | ||||
|  | ||||
|   @override | ||||
|   Future<String> apkUrlPrefetchModifier(String apkUrl) async => apkUrl; | ||||
|   String? tryInferringAppId(String standardUrl) { | ||||
|     return FDroid().tryInferringAppId(standardUrl); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Future<APKDetails> getLatestAPKDetails( | ||||
|       String standardUrl, List<String> additionalData) async { | ||||
|     Response res = await get(Uri.parse(standardUrl)); | ||||
|     if (res.statusCode == 200) { | ||||
|       var parsedHtml = parse(res.body); | ||||
|       var multipleVersionApkUrls = parsedHtml | ||||
|           .querySelectorAll('a') | ||||
|           .where((element) => | ||||
|               element.attributes['href']?.toLowerCase().endsWith('.apk') ?? | ||||
|               false) | ||||
|           .map((e) => 'https://$host${e.attributes['href'] ?? ''}') | ||||
|           .toList(); | ||||
|       if (multipleVersionApkUrls.isEmpty) { | ||||
|         throw NoAPKError(); | ||||
|       } | ||||
|       var version = parsedHtml | ||||
|           .querySelector('#keydata') | ||||
|           ?.querySelectorAll('b') | ||||
|           .where( | ||||
|               (element) => element.innerHtml.toLowerCase().contains('version')) | ||||
|           .toList()[0] | ||||
|           .parentNode | ||||
|           ?.parentNode | ||||
|           ?.children[1] | ||||
|           .innerHtml; | ||||
|       if (version == null) { | ||||
|         throw NoVersionError(); | ||||
|       } | ||||
|       return APKDetails(version, [multipleVersionApkUrls[0]]); | ||||
|     } else { | ||||
|       throw NoReleasesError(); | ||||
|     } | ||||
|     String? appId = tryInferringAppId(standardUrl); | ||||
|     return FDroid().getAPKUrlsFromFDroidPackagesAPIResponse( | ||||
|         await get( | ||||
|             Uri.parse('https://apt.izzysoft.de/fdroid/api/v1/packages/$appId')), | ||||
|         'https://android.izzysoft.de/frepo/$appId'); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   | ||||
| @@ -22,9 +22,6 @@ class Mullvad extends AppSource { | ||||
|   String? changeLogPageFromStandardUrl(String standardUrl) => | ||||
|       'https://github.com/mullvad/mullvadvpn-app/blob/master/CHANGELOG.md'; | ||||
|  | ||||
|   @override | ||||
|   Future<String> apkUrlPrefetchModifier(String apkUrl) async => apkUrl; | ||||
|  | ||||
|   @override | ||||
|   Future<APKDetails> getLatestAPKDetails( | ||||
|       String standardUrl, List<String> additionalData) async { | ||||
|   | ||||
| @@ -16,9 +16,6 @@ class Signal extends AppSource { | ||||
|   @override | ||||
|   String? changeLogPageFromStandardUrl(String standardUrl) => null; | ||||
|  | ||||
|   @override | ||||
|   Future<String> apkUrlPrefetchModifier(String apkUrl) async => apkUrl; | ||||
|  | ||||
|   @override | ||||
|   Future<APKDetails> getLatestAPKDetails( | ||||
|       String standardUrl, List<String> additionalData) async { | ||||
|   | ||||
| @@ -21,9 +21,6 @@ class SourceForge extends AppSource { | ||||
|   @override | ||||
|   String? changeLogPageFromStandardUrl(String standardUrl) => null; | ||||
|  | ||||
|   @override | ||||
|   Future<String> apkUrlPrefetchModifier(String apkUrl) async => apkUrl; | ||||
|  | ||||
|   @override | ||||
|   Future<APKDetails> getLatestAPKDetails( | ||||
|       String standardUrl, List<String> additionalData) async { | ||||
|   | ||||
| @@ -16,7 +16,7 @@ import 'package:dynamic_color/dynamic_color.dart'; | ||||
| import 'package:device_info_plus/device_info_plus.dart'; | ||||
| import 'package:android_alarm_manager_plus/android_alarm_manager_plus.dart'; | ||||
|  | ||||
| const String currentVersion = '0.7.3'; | ||||
| const String currentVersion = '0.7.4'; | ||||
| const String currentReleaseTag = | ||||
|     'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES | ||||
|  | ||||
|   | ||||
| @@ -115,18 +115,23 @@ class _AddAppPageState extends State<AddAppPage> { | ||||
|                                                     additionalData); | ||||
|                                             await settingsProvider | ||||
|                                                 .getInstallPermission(); | ||||
|                                             // ignore: use_build_context_synchronously | ||||
|                                             var apkUrl = await appsProvider | ||||
|                                                 .confirmApkUrl(app, context); | ||||
|                                             if (apkUrl == null) { | ||||
|                                               throw ObtainiumError('Cancelled'); | ||||
|                                             // Only download the APK here if you need to for the package ID | ||||
|                                             if (sourceProvider | ||||
|                                                 .isTempId(app.id)) { | ||||
|                                               // ignore: use_build_context_synchronously | ||||
|                                               var apkUrl = await appsProvider | ||||
|                                                   .confirmApkUrl(app, context); | ||||
|                                               if (apkUrl == null) { | ||||
|                                                 throw ObtainiumError( | ||||
|                                                     'Cancelled'); | ||||
|                                               } | ||||
|                                               app.preferredApkIndex = | ||||
|                                                   app.apkUrls.indexOf(apkUrl); | ||||
|                                               var downloadedApk = | ||||
|                                                   await appsProvider | ||||
|                                                       .downloadApp(app); | ||||
|                                               app.id = downloadedApk.appId; | ||||
|                                             } | ||||
|                                             app.preferredApkIndex = | ||||
|                                                 app.apkUrls.indexOf(apkUrl); | ||||
|                                             var downloadedApk = | ||||
|                                                 await appsProvider | ||||
|                                                     .downloadApp(app); | ||||
|                                             app.id = downloadedApk.appId; | ||||
|                                             if (appsProvider.apps | ||||
|                                                 .containsKey(app.id)) { | ||||
|                                               throw ObtainiumError( | ||||
|   | ||||
| @@ -155,14 +155,18 @@ class AppSource { | ||||
|     throw NotImplementedError(); | ||||
|   } | ||||
|  | ||||
|   Future<String> apkUrlPrefetchModifier(String apkUrl) { | ||||
|     throw NotImplementedError(); | ||||
|   Future<String> apkUrlPrefetchModifier(String apkUrl) async { | ||||
|     return apkUrl; | ||||
|   } | ||||
|  | ||||
|   bool canSearch = false; | ||||
|   Future<Map<String, String>> search(String query) { | ||||
|     throw NotImplementedError(); | ||||
|   } | ||||
|  | ||||
|   String? tryInferringAppId(String standardUrl) { | ||||
|     return null; | ||||
|   } | ||||
| } | ||||
|  | ||||
| ObtainiumError getObtainiumHttpError(Response res) { | ||||
| @@ -240,7 +244,9 @@ class SourceProvider { | ||||
|     APKDetails apk = | ||||
|         await source.getLatestAPKDetails(standardUrl, additionalData); | ||||
|     return App( | ||||
|         id ?? generateTempID(names, source), | ||||
|         id ?? | ||||
|             source.tryInferringAppId(standardUrl) ?? | ||||
|             generateTempID(names, source), | ||||
|         standardUrl, | ||||
|         names.author[0].toUpperCase() + names.author.substring(1), | ||||
|         name.trim().isNotEmpty | ||||
|   | ||||
| @@ -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.7.3+59 # When changing this, update the tag in main() accordingly | ||||
| version: 0.7.4+60 # When changing this, update the tag in main() accordingly | ||||
|  | ||||
| environment: | ||||
|   sdk: '>=2.18.2 <3.0.0' | ||||
|   | ||||
		Reference in New Issue
	
	Block a user