From 03778fd743a5aaf9fe73d119feb9e103057a8a2d Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Mon, 19 Aug 2024 22:37:57 -0400 Subject: [PATCH] Fix Uptodown - was completely broken (#1796) --- lib/app_sources/uptodown.dart | 30 +++++++++++++++++++++--------- lib/providers/apps_provider.dart | 12 +++++++++--- lib/providers/source_provider.dart | 1 + 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/lib/app_sources/uptodown.dart b/lib/app_sources/uptodown.dart index 00de36c..30c86ce 100644 --- a/lib/app_sources/uptodown.dart +++ b/lib/app_sources/uptodown.dart @@ -10,6 +10,7 @@ class Uptodown extends AppSource { allowSubDomains = true; naiveStandardVersionDetection = true; showReleaseDateAsVersionToggle = true; + urlsAlwaysHaveExtension = true; } @override @@ -39,20 +40,29 @@ class Uptodown extends AppSource { } var html = parse(res.body); String? version = html.querySelector('div.version')?.innerHtml; - String? apkUrl = - '${standardUrl.split('/').reversed.toList().sublist(1).reversed.join('/')}/post-download'; String? name = html.querySelector('#detail-app-name')?.innerHtml.trim(); String? author = html.querySelector('#author-link')?.innerHtml.trim(); var detailElements = html.querySelectorAll('#technical-information td'); String? appId = (detailElements.elementAtOrNull(2))?.innerHtml.trim(); String? dateStr = (detailElements.elementAtOrNull(29))?.innerHtml.trim(); + String? fileId = + html.querySelector('#detail-app-name')?.attributes['data-file-id']; + String? extension = html + .querySelectorAll('td') + .where((e) => e.text.toLowerCase().trim() == 'file type') + .firstOrNull + ?.nextElementSibling + ?.text + .toLowerCase() + .trim(); return Map.fromEntries([ MapEntry('version', version), - MapEntry('apkUrl', apkUrl), MapEntry('appId', appId), MapEntry('name', name), MapEntry('author', author), - MapEntry('dateStr', dateStr) + MapEntry('dateStr', dateStr), + MapEntry('fileId', fileId), + MapEntry('extension', extension) ]); } @@ -64,14 +74,16 @@ class Uptodown extends AppSource { var appDetails = await getAppDetailsFromPage(standardUrl, additionalSettings); var version = appDetails['version']; - var apkUrl = appDetails['apkUrl']; var appId = appDetails['appId']; + var fileId = appDetails['fileId']; + var extension = appDetails['extension']; if (version == null) { throw NoVersionError(); } - if (apkUrl == null) { + if (fileId == null) { throw NoAPKError(); } + var apkUrl = '$standardUrl/$fileId-x'; if (appId == null) { throw NoReleasesError(); } @@ -82,8 +94,8 @@ class Uptodown extends AppSource { if (dateStr != null) { relDate = parseDateTimeMMMddCommayyyy(dateStr); } - return APKDetails( - version, getApkUrlsFromUrls([apkUrl]), AppNames(author, appName), + return APKDetails(version, [MapEntry('$appId.$extension', apkUrl)], + AppNames(author, appName), releaseDate: relDate); } @@ -96,7 +108,7 @@ class Uptodown extends AppSource { } var html = parse(res.body); var finalUrlKey = - html.querySelector('.post-download')?.attributes['data-url']; + html.querySelector('#detail-download-button')?.attributes['data-url']; if (finalUrlKey == null) { throw NoAPKError(); } diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index b01deb0..57cd005 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -225,7 +225,9 @@ Future downloadFile(String url, String fileName, bool fileNameHasExt, ext != 'apk') { ext = 'apk'; } - fileName = fileName.split('/').last; // Ensure the fileName is a file name + fileName = fileNameHasExt + ? fileName + : fileName.split('/').last; // Ensure the fileName is a file name File downloadedFile = File('$destDir/$fileName.$ext'); if (fileNameHasExt) { // If the user says the filename already has an ext, ignore whatever you inferred from above @@ -447,11 +449,15 @@ class AppsProvider with ChangeNotifier { notificationsProvider?.cancel(notif.id); int? prevProg; var fileNameNoExt = '${app.id}-${downloadUrl.hashCode}'; + if (source.urlsAlwaysHaveExtension) { + fileNameNoExt = + '$fileNameNoExt.${app.apkUrls[app.preferredApkIndex].key.split('.').last}'; + } var headers = await source.getRequestHeaders(app.additionalSettings, forAPKDownload: true); var downloadedFile = await downloadFileWithRetry( - downloadUrl, fileNameNoExt, false, headers: headers, - (double? progress) { + downloadUrl, fileNameNoExt, source.urlsAlwaysHaveExtension, + headers: headers, (double? progress) { int? prog = progress?.ceil(); if (apps[app.id] != null) { apps[app.id]!.downloadProgress = progress; diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index e4a23eb..8b1c41e 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -412,6 +412,7 @@ abstract class AppSource { bool showReleaseDateAsVersionToggle = false; bool versionDetectionDisallowed = false; List excludeCommonSettingKeys = []; + bool urlsAlwaysHaveExtension = false; AppSource() { name = runtimeType.toString();