diff --git a/lib/app_sources/fdroidrepo.dart b/lib/app_sources/fdroidrepo.dart index 43b656f..41e92df 100644 --- a/lib/app_sources/fdroidrepo.dart +++ b/lib/app_sources/fdroidrepo.dart @@ -1,5 +1,6 @@ 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'; @@ -45,7 +46,7 @@ class FDroidRepo extends AppSource { String sourceSpecificStandardizeURL(String url) { var standardUri = Uri.parse(url); var pathSegments = standardUri.pathSegments; - if (pathSegments.last == 'index.xml') { + if (pathSegments.isNotEmpty && pathSegments.last == 'index.xml') { pathSegments.removeLast(); standardUri = standardUri.replace(path: pathSegments.join('/')); } @@ -60,7 +61,7 @@ class FDroidRepo extends AppSource { throw NoReleasesError(); } url = removeQueryParamsFromUrl(standardizeUrl(url)); - var res = await sourceRequest('$url/index.xml', {}); + var res = await sourceRequestWithURLVariants(url, {}); if (res.statusCode == 200) { var body = parse(res.body); Map> results = {}; @@ -72,7 +73,11 @@ class FDroidRepo extends AppSource { appId.contains(query) || appName.contains(query) || appDesc.contains(query)) { - results['$url?appId=$appId'] = [appName, appDesc]; + results[ + '${res.request!.url.toString().split('/').reversed.toList().sublist(1).reversed.join('/')}?appId=$appId'] = [ + appName, + appDesc + ]; } }); return results; @@ -102,6 +107,26 @@ class FDroidRepo extends AppSource { return app; } + Future sourceRequestWithURLVariants( + String url, + Map additionalSettings, + ) async { + var res = await sourceRequest( + '$url${url.endsWith('/index.xml') ? '' : '/index.xml'}', + additionalSettings); + if (res.statusCode != 200) { + var base = url.endsWith('/index.xml') + ? url.split('/').reversed.toList().sublist(1).reversed.join('/') + : url; + res = await sourceRequest('$base/repo/index.xml', additionalSettings); + if (res.statusCode != 200) { + res = await sourceRequest( + '$base/fdroid/repo/index.xml', additionalSettings); + } + } + return res; + } + @override Future getLatestAPKDetails( String standardUrl, @@ -117,25 +142,8 @@ class FDroidRepo extends AppSource { if (appIdOrName == null) { throw NoReleasesError(); } - var res = await sourceRequest( - '$standardUrl${standardUrl.endsWith('/index.xml') ? '' : '/index.xml'}', - additionalSettings); - if (res.statusCode != 200) { - var base = standardUrl.endsWith('/index.xml') - ? standardUrl - .split('/') - .reversed - .toList() - .sublist(1) - .reversed - .join('/') - : standardUrl; - res = await sourceRequest('$base/repo/index.xml', additionalSettings); - if (res.statusCode != 200) { - res = await sourceRequest( - '$base/fdroid/repo/index.xml', additionalSettings); - } - } + var res = + await sourceRequestWithURLVariants(standardUrl, additionalSettings); if (res.statusCode == 200) { var body = parse(res.body); var foundApps = body.querySelectorAll('application').where((element) { diff --git a/lib/pages/add_app.dart b/lib/pages/add_app.dart index e73829e..bb8bf27 100644 --- a/lib/pages/add_app.dart +++ b/lib/pages/add_app.dart @@ -163,7 +163,7 @@ class AddAppPageState extends State { app = await sourceProvider.getApp( pickedSource!, userInput.trim(), additionalSettings, trackOnlyOverride: trackOnly, - overrideSource: pickedSourceOverride, + sourceIsOverriden: pickedSourceOverride != null, inferAppIdIfOptional: inferAppIdIfOptional); // Only download the APK here if you need to for the package ID if (isTempId(app) && app.additionalSettings['trackOnly'] != true) { diff --git a/lib/pages/import_export.dart b/lib/pages/import_export.dart index 18a61dd..7e73d0a 100644 --- a/lib/pages/import_export.dart +++ b/lib/pages/import_export.dart @@ -213,7 +213,7 @@ class _ImportExportPageState extends State { setState(() { importInProgress = true; }); - if (values['url'] != source.hosts[0]) { + if (source.hosts.isEmpty || values['url'] != source.hosts[0]) { source = sourceProvider.getSource(values['url'], overrideSource: source.runtimeType.toString()); } diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index 486c101..d2c34bf 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -819,7 +819,7 @@ class SourceProvider { AppSource source, String url, Map additionalSettings, {App? currentApp, bool trackOnlyOverride = false, - String? overrideSource, + bool sourceIsOverriden = false, bool inferAppIdIfOptional = false}) async { if (trackOnlyOverride || source.enforceTrackOnly) { additionalSettings['trackOnly'] = true; @@ -887,7 +887,9 @@ class SourceProvider { categories: currentApp?.categories ?? const [], releaseDate: apk.releaseDate, changeLog: apk.changeLog, - overrideSource: overrideSource ?? currentApp?.overrideSource, + overrideSource: sourceIsOverriden + ? source.runtimeType.toString() + : currentApp?.overrideSource, allowIdChange: currentApp?.allowIdChange ?? trackOnly || (source.appIdInferIsOptional && @@ -911,6 +913,7 @@ class SourceProvider { apps.add(await getApp( source, url, + sourceIsOverriden: sourceOverride != null, getDefaultValuesFromFormItems( source.combinedAppSpecificSettingFormItems))); } catch (e) {