diff --git a/README.md b/README.md index 9d8e321..1c43ade 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,13 @@ Get Android App Updates Directly From the Source. -Obtainium allows you to install and update Apps directly from their releases pages, and receive notifications when new releases are made available. +Obtainium allows you to install and update apps directly from their releases pages, and receive notifications when new releases are made available. -Motivation: [Side Of Burritos - You should use this instead of F-Droid | How to use app RSS feed](https://youtu.be/FFz57zNR_M0) - -Read the Wiki: [https://github.com/ImranR98/Obtainium/wiki](https://github.com/ImranR98/Obtainium/wiki) +More info: +- [Obtainium/wiki](https://github.com/ImranR98/Obtainium/wiki) +- [AppVerifier](https://github.com/soupslurpr/AppVerifier) - App verification tool (recommended, integrates with Obtainium) +- [apps.obtainium.imranr.dev](https://apps.obtainium.imranr.dev/) - Crowdsourced app configurations +- [Side Of Burritos - You should use this instead of F-Droid | How to use app RSS feed](https://youtu.be/FFz57zNR_M0) - Original motivation for this app Currently supported App sources: - Open Source - General: diff --git a/assets/translations/de.json b/assets/translations/de.json index 58f6873..6af12aa 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -19,7 +19,7 @@ "noDescription": "Keine Beschreibung", "cancel": "Abbrechen", "continue": "Weiter", - "requiredInBrackets": "(Benötigt)", + "requiredInBrackets": "(wird benötigt)", "dropdownNoOptsError": "FEHLER: DROPDOWN MUSS MINDESTENS EINE OPTION HABEN", "colour": "Farbe", "githubStarredRepos": "GitHub Starred Repos", @@ -183,9 +183,9 @@ "disableVersionDetection": "Versionsermittlung deaktivieren", "noVersionDetectionExplanation": "Diese Option sollte nur für Apps verwendet werden, bei denen die Versionserkennung nicht korrekt funktioniert.", "downloadingX": "Lade {} herunter", - "downloadX": "Herunterladen {}", - "downloadedX": "Heruntergeladen {}", - "releaseAsset": "Asset freigeben", + "downloadX": "{} herunterladen", + "downloadedX": "{} heruntergeladen", + "releaseAsset": "release Asset", "downloadNotifDescription": "Benachrichtigt den Nutzer über den Fortschritt beim Herunterladen einer App", "noAPKFound": "Keine APK gefunden", "noVersionDetection": "Keine Versionserkennung", diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 9e60af6..46f7bf3 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -1,7 +1,7 @@ { "invalidURLForSource": "URL d'application {} invalide", - "noReleaseFound": "Impossible de trouver une version appropriée", - "noVersionFound": "Impossible de déterminer la version de la version", + "noReleaseFound": "Impossible de trouver une version adaptée", + "noVersionFound": "Impossible de déterminer la variante de la version", "urlMatchesNoSource": "L'URL ne correspond pas à une source connue", "cantInstallOlderVersion": "Impossible d'installer une ancienne version d'une application", "appIdMismatch": "L'ID de paquet téléchargé ne correspond pas à l'ID de l'application existante", @@ -43,7 +43,7 @@ "additionalOptsFor": "Options supplémentaires pour {}", "supportedSources": "Sources prises en charge ", "trackOnlyInBrackets": "(Suivi uniquement)", - "searchableInBrackets": "(Recherchable)", + "searchableInBrackets": "(Intérrogeable)", "appsString": "Applications", "noApps": "Aucune application", "noAppsForFilter": "Aucune application pour le filtre", @@ -51,7 +51,7 @@ "percentProgress": "Progrès: {}%", "pleaseWait": "Veuillez patienter", "updateAvailable": "Mise à jour disponible", - "notInstalled": "Pas installé", + "notInstalled": "Non installé", "pseudoVersion": "pseudo-version", "selectAll": "Tout sélectionner", "deselectX": "Déselectionner {}", @@ -60,22 +60,22 @@ "removeSelectedApps": "Supprimer les applications sélectionnées", "updateX": "Mise à jour {}", "installX": "Installer {}", - "markXTrackOnlyAsUpdated": "Marquer {}\n(Suivi uniquement)\nas mis à jour", + "markXTrackOnlyAsUpdated": "Marquer {}\n(Suivi uniquement)\n comme mis à jour", "changeX": "Changer {}", "installUpdateApps": "Installer/Mettre à jour les applications", "installUpdateSelectedApps": "Installer/Mettre à jour les applications sélectionnées", - "markXSelectedAppsAsUpdated": "Marquer {} les applications sélectionnées comme mises à jour ?", + "markXSelectedAppsAsUpdated": "Marquer {} les applications sélectionnées comme étant à jour ?", "no": "Non", "yes": "Oui", - "markSelectedAppsUpdated": "Marquer les applications sélectionnées comme mises à jour", + "markSelectedAppsUpdated": "Marquer les applications sélectionnées comme étant à jour", "pinToTop": "Épingler en haut", - "unpinFromTop": "Détacher du haut", - "resetInstallStatusForSelectedAppsQuestion": "Réinitialiser l'état d'installation des applications sélectionnées ?", - "installStatusOfXWillBeResetExplanation": "L'état d'installation de toutes les applications sélectionnées sera réinitialisé.\n\nCela peut aider lorsque la version de l'application affichée dans Obtainium est incorrecte en raison d'échecs de mises à jour ou d'autres problèmes.", - "customLinkMessage": "Ces liens fonctionnent sur les appareils sur lesquels Obtenirium est installé", + "unpinFromTop": "Désépingler du haut", + "resetInstallStatusForSelectedAppsQuestion": "Réinitialiser le statu d'installation des applications sélectionnées ?", + "installStatusOfXWillBeResetExplanation": "Le statu d'installation de toutes les applications sélectionnées sera réinitialisé.\n\nCela peut aider lorsque la version de l'application affichée dans Obtainium est incorrecte en raison d'échecs de mises à jour ou d'autres problèmes.", + "customLinkMessage": "Ces liens fonctionnent sur les appareils sur lesquels Obtainium est installé", "shareAppConfigLinks": "Partager la configuration de l'application sous forme de lien HTML", "shareSelectedAppURLs": "Partager les URL d'application sélectionnées", - "resetInstallStatus": "Réinitialiser le statut d'installation", + "resetInstallStatus": "Réinitialiser le statu d'installation", "more": "Plus", "removeOutdatedFilter": "Supprimer le filtre d'application obsolète", "showOutdatedOnly": "Afficher uniquement les applications obsolètes", @@ -88,12 +88,12 @@ "importExport": "Importer/Exporter", "settings": "Paramètres", "exportedTo": "Exporté vers {}", - "obtainiumExport": "Exportation d'Obtainium", + "obtainiumExport": "Exporter d'Obtainium", "invalidInput": "Entrée invalide", "importedX": "Importé {}", - "obtainiumImport": "Importation d'Obtainium", + "obtainiumImport": "Importer d'Obtainium", "importFromURLList": "Importer à partir de la liste d'URL", - "searchQuery": "Requête de recherche", + "searchQuery": "Requête", "appURLList": "Liste d'URL d'application", "line": "Queue", "searchX": "Rechercher {}", @@ -110,14 +110,14 @@ "dark": "Sombre", "light": "Clair", "followSystem": "Suivre le système", - "useBlackTheme": "Utilisez le thème noir pur et sombre", + "useBlackTheme": "Utilisez le thème noir pur", "appSortBy": "Applications triées par", "authorName": "Auteur/Nom", "nameAuthor": "Nom/Auteur", "asAdded": "Comme ajouté", "appSortOrder": "Ordre de tri des applications", "ascending": "Ascendant", - "descending": "Descendanr", + "descending": "Descendant", "bgUpdateCheckInterval": "Intervalle de vérification des mises à jour en arrière-plan", "neverManualOnly": "Jamais - Manuel uniquement", "appearance": "Apparence", @@ -131,13 +131,13 @@ "close": "Fermer", "share": "Partager", "appNotFound": "Application introuvable", - "obtainiumExportHyphenatedLowercase": "exportation d'obtainium", + "obtainiumExportHyphenatedLowercase": "exportation d'Obtainium", "pickAnAPK": "Choisissez un APK", "appHasMoreThanOnePackage": "{} a plus d'un paquet :", - "deviceSupportsXArch": "Votre appareil prend en charge l'architecture de processeur {}.", + "deviceSupportsXArch": "Votre appareil prend en charge l'architecture CPU {}.", "deviceSupportsFollowingArchs": "Votre appareil prend en charge les architectures CPU suivantes :", "warning": "Avertissement", - "sourceIsXButPackageFromYPrompt": "La source de l'application est '{}' mais le paquet de version provient de '{}'. Continuer?", + "sourceIsXButPackageFromYPrompt": "La source de l'application est '{}' mais la version du paquet provient de '{}'. Continuer?", "updatesAvailable": "Mises à jour disponibles", "updatesAvailableNotifDescription": "Avertit l'utilisateur que des mises à jour sont disponibles pour une ou plusieurs applications suivies par Obtainium", "noNewUpdates": "Aucune nouvelle mise à jour.", @@ -179,7 +179,7 @@ "markInstalled": "Marquer installée", "update": "Mettre à jour", "markUpdated": "Marquer à jour", - "additionalOptions": "Options additionelles", + "additionalOptions": "Options additionnelles", "disableVersionDetection": "Désactiver la détection de version", "noVersionDetectionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement.", "downloadingX": "Téléchargement {}", @@ -188,7 +188,7 @@ "releaseAsset": "Actif libéré", "downloadNotifDescription": "Avertit l'utilisateur de la progression du téléchargement d'une application", "noAPKFound": "Aucun APK trouvé", - "noVersionDetection": "Pas de détection de version", + "noVersionDetection": "Aucune de détection de version", "categorize": "Catégoriser", "categories": "Catégories", "category": "Catégorie", @@ -201,13 +201,13 @@ "language": "Langue", "copiedToClipboard": "Copié dans le presse-papier", "storagePermissionDenied": "Autorisation de stockage refusée", - "selectedCategorizeWarning": "Cela remplacera tous les paramètres de catégorie existants pour les applications sélectionnées.", + "selectedCategorizeWarning": "Cela remplacera toutes les catégorie définies pour les applications sélectionnées.", "filterAPKsByRegEx": "Filtrer les APK par expression régulière", "removeFromObtainium": "Supprimer d'Obtainium", "uninstallFromDevice": "Désinstaller de l'appareil", "onlyWorksWithNonVersionDetectApps": "Fonctionne uniquement pour les applications avec la détection de version désactivée.", "releaseDateAsVersion": "Utiliser la date de sortie comme version", - "releaseDateAsVersionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement, mais une date de sortie est disponible.", + "releaseDateAsVersionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement, mais dont une date de sortie est disponible.", "changes": "Changements", "releaseDate": "Date de sortie", "importFromURLsInFile": "Importer à partir d'URL dans un fichier (comme OPML)", @@ -215,59 +215,59 @@ "versionDetection": "Détection des versions", "standardVersionDetection": "Détection de version standard", "groupByCategory": "Regrouper par catégorie", - "autoApkFilterByArch": "Essayez de filtrer les APK par architecture CPU si possible", + "autoApkFilterByArch": "Si possible, essayez de filtrer les APK par architecture CPU", "overrideSource": "Remplacer la source", - "dontShowAgain": "Ne montre plus ça", - "dontShowTrackOnlyWarnings": "Don't Show the 'Track-Only' Warning", + "dontShowAgain": "Ne plus montrer", + "dontShowTrackOnlyWarnings": "Ne pas afficher l'avertissement 'Track-Only'", "dontShowAPKOriginWarnings": "Ne pas afficher les avertissements sur l'origine de l'APK", "moveNonInstalledAppsToBottom": "Déplacer les applications non installées vers le bas de la vue Applications", "gitlabPATLabel": "Jeton d'accès personnel GitLab", "about": "À propos de", - "requiresCredentialsInSettings": "{}: This needs additional credentials (in Settings)", + "requiresCredentialsInSettings": "{}: Cela nécessite des identifiants supplémentaires (dans Paramètres)", "checkOnStart": "Vérifier les mises à jour au démarrage", "tryInferAppIdFromCode": "Essayez de déduire l'ID de l'application à partir du code source", "removeOnExternalUninstall": "Supprimer automatiquement les applications désinstallées en externe", - "pickHighestVersionCode": "Sélectionner automatiquement le code APK de la version la plus élevée", - "checkUpdateOnDetailPage": "Vérifier les mises à jour lors de l'ouverture d'une page de détails d'application", + "pickHighestVersionCode": "Sélectionner automatiquement le code de version de l'APK la plus élevée", + "checkUpdateOnDetailPage": "Vérifier les mises à jour lors de l'ouverture de la page détaillée d'une application", "disablePageTransitions": "Désactiver les animations de transition de page", - "reversePageTransitions": "Animations de transition de page inversée", + "reversePageTransitions": "Inverser les animations de transition de page", "minStarCount": "Nombre minimum d'étoiles", "addInfoBelow": "Ajoutez ces informations ci-dessous.", "addInfoInSettings": "Ajoutez ces informations dans les paramètres.", - "githubSourceNote": "La limitation du débit GitHub peut être évitée à l'aide d'une clé API.", + "githubSourceNote": "La limite de débit GitHub peut être évitée à l'aide d'une clé API.", "sortByLastLinkSegment": "Trier uniquement sur le dernier segment du lien", "filterReleaseNotesByRegEx": "Filtrer les notes de version par expression régulière", - "customLinkFilterRegex": "Filtre de lien APK personnalisé par expression régulière (par défaut '.apk$')", + "customLinkFilterRegex": "Filtre du lien APK personnalisé par expression régulière (par défaut '.apk$')", "appsPossiblyUpdated": "Tentative de mise à jour de l'application", "appsPossiblyUpdatedNotifDescription": "Avertit l'utilisateur que des mises à jour d'une ou plusieurs applications ont été potentiellement appliquées en arrière-plan", "xWasPossiblyUpdatedToY": "{} a peut-être été mis à jour vers {}.", "enableBackgroundUpdates": "Activer les mises à jour en arrière-plan", "backgroundUpdateReqsExplanation": "Les mises à jour en arrière-plan peuvent ne pas être possibles pour toutes les applications.", - "backgroundUpdateLimitsExplanation": "Le succès d'une installation en arrière-plan ne peut être déterminé qu'à l'ouverture d'Obetium.", - "verifyLatestTag": "Vérifiez la balise 'dernière'", + "backgroundUpdateLimitsExplanation": "Le succès d'une installation en arrière-plan ne peut être déterminé qu'à l'ouverture d'Obtainium.", + "verifyLatestTag": "Vérifiez la balise 'Latest'", "intermediateLinkRegex": " Filtrer un lien \" intermédiaire \" à visiter ", - "filterByLinkText": "Filtrer les liens par texte de lien", + "filterByLinkText": "Filtrer les liens par le texte du lien", "intermediateLinkNotFound": "Lien intermédiaire introuvable", "intermediateLink": "Lien intermédiaire", - "exemptFromBackgroundUpdates": "Exempt des mises à jour en arrière-plan (si activé)", + "exemptFromBackgroundUpdates": "Exempté des mises à jour en arrière-plan (si activé)", "bgUpdatesOnWiFiOnly": "Désactiver les mises à jour en arrière-plan lorsque vous n'êtes pas connecté au WiFi", - "autoSelectHighestVersionCode": "Sélection automatique de la version la plus élevéeCode APK", - "versionExtractionRegEx": "Version Extraction RegEx", - "matchGroupToUse": "Match Group to Use", - "highlightTouchTargets": "Mettez en évidence les cibles tactiles moins évidentes", + "autoSelectHighestVersionCode": "Sélection automatique du code de version de l'APK la plus élevée", + "versionExtractionRegEx": "Expression régulière d'extraction de version", + "matchGroupToUse": "Groupe de correspondance pour l'expression régulière d'extraction de version", + "highlightTouchTargets": "Mettre en évidence les cibles tactiles moins évidentes", "pickExportDir": "Choisir le répertoire d'exportation", - "autoExportOnChanges": "Exportation automatique sur modifications", + "autoExportOnChanges": "Exporter automatiquement après modification", "includeSettings": "Inclure les paramètres", "filterVersionsByRegEx": "Filtrer les versions par expression régulière", - "trySelectingSuggestedVersionCode": "Essayez de sélectionner la version suggéréeCode APK", - "dontSortReleasesList": "Conserver la commande de version de l'API", + "trySelectingSuggestedVersionCode": "Essayez de sélectionner le code de la version APK suggérée", + "dontSortReleasesList": "Conserver l'ordre des version de l'API", "reverseSort": "Tri inversé", "takeFirstLink": "Prendre le premier lien", "skipSort": "Sauter le tri", "debugMenu": "Menu de débogage", "bgTaskStarted": "Tâche en arrière-plan démarrée - vérifier les journaux.", - "runBgCheckNow": "Exécuter la vérification de la mise à jour en arrière-plan maintenant", - "versionExtractWholePage": "Apply Version Extraction Regex to Entire Page", + "runBgCheckNow": "Exécuter maintenant la vérification de la mise à jour en arrière-plan", + "versionExtractWholePage": "Appliquer l'expression régulière d'extraction de version sur l'ensemble de la page", "installing": "Installation", "skipUpdateNotifications": "Ignorer les notifications de mise à jour", "updatesAvailableNotifChannel": "Mises à jour disponibles", @@ -278,19 +278,19 @@ "downloadingXNotifChannel": "Téléchargement {}", "completeAppInstallationNotifChannel": "Installation complète de l'application", "checkingForUpdatesNotifChannel": "Vérification des mises à jour", - "onlyCheckInstalledOrTrackOnlyApps": "Vérifiez uniquement les mises à jour des applications installées et de suivi uniquement", + "onlyCheckInstalledOrTrackOnlyApps": "Vérifiez uniquement les mises à jour des applications installées et 'Track-Only'", "supportFixedAPKURL": "Prise en charge des URL APK fixes", "selectX": "Sélectionner {}", "parallelDownloads": "Autoriser les téléchargements parallèles", "installMethod": "Méthode d'installation", "normal": "Normale", "root": "Racine", - "shizukuBinderNotFound": "Shizuku is not running", - "useSystemFont": "Utiliser la police système", - "systemFontError": "Erreur de chargement de la police système : {}", + "shizukuBinderNotFound": "Service Shizuku compatible non trouvé", + "useSystemFont": "Utiliser la police du système", + "systemFontError": "Erreur de chargement de la police du système : {}", "useVersionCodeAsOSVersion": "Utiliser le code de version de l'application comme version détectée par le système d'exploitation", "requestHeader": "En-tête de demande", - "useLatestAssetDateAsReleaseDate": "Utiliser le dernier téléchargement d'élément comme date de sortie", + "useLatestAssetDateAsReleaseDate": "Utiliser le dernier élément téléversé comme date de sortie", "defaultPseudoVersioningMethod": "Méthode de pseudo-version par défaut", "partialAPKHash": "Hash APK partiel", "APKLinkHash": "Hash de lien APK", @@ -313,12 +313,12 @@ "other": "Trop de demandes (taux limité) - réessayez dans {} minutes" }, "bgUpdateGotErrorRetryInMinutes": { - "one": "La vérification de la mise à jour en arrière-plan a rencontré un {}, planifiera une nouvelle tentative de vérification dans {} minute", - "other": "La vérification de la mise à jour en arrière-plan a rencontré un {}, planifiera une nouvelle tentative de vérification dans {} minutes" + "one": "La vérification de la mise à jour en arrière-plan a rencontré un {}, une nouvelle tentative de vérification sera planifié dans {} minute", + "other": "La vérification de la mise à jour en arrière-plan a rencontré un {}, une nouvelle tentative de vérification sera planifié dans {} minute" }, "bgCheckFoundUpdatesWillNotifyIfNeeded": { - "one": "La vérification des mises à jour en arrière-plan trouvée {} mise à jour - avertira l'utilisateur si nécessaire", - "other": "La vérification des mises à jour en arrière-plan a trouvé {} mises à jour - avertira l'utilisateur si nécessaire" + "one": "La vérification des mises à jour en arrière-plan a trouvée {} mise à jour - l'utilisateur sera notifié si nécessaire", + "other": "La vérification des mises à jour en arrière-plan a trouvé {} mises à jour - l'utilisateur sera notifié si nécessaire" }, "apps": { "one": "{} Application", diff --git a/assets/translations/hu.json b/assets/translations/hu.json index a5dc4bc..0436026 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -185,7 +185,7 @@ "downloadingX": "{} letöltés", "downloadX": "Letöltés {}", "downloadedX": "Letöltés {}", - "releaseAsset": "Release Asset", + "releaseAsset": "Kiadási tartalom", "downloadNotifDescription": "Értesíti a felhasználót az app letöltésének előrehaladásáról", "noAPKFound": "Nem található APK", "noVersionDetection": "Nincs verzió érzékelés", diff --git a/assets/translations/ru.json b/assets/translations/ru.json index 8f79902..e1344e1 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -364,6 +364,6 @@ }, "apk": { "one": "{} APK", - "other": "{} APKs" + "other": "{} APKи" } } diff --git a/fastlane/metadata/android/ru/full_description.txt b/fastlane/metadata/android/ru/full_description.txt new file mode 100644 index 0000000..38a337c --- /dev/null +++ b/fastlane/metadata/android/ru/full_description.txt @@ -0,0 +1,54 @@ +

Obtainium позволяет вам устанавливать и обновлять приложения прямо с их объявлений о выпусках и получать уведомления о новых выпусках.

+

Для деталей читайте Вики

+

+ Поддерживаемые источники приложений: +

+ +

+ Ограничения: +

+

+ Для некоторых источников данные собираются с помощью веб-скрапинга и могут легко сломаться из-за изменений в дизайне веб-сайта. В таких случаях более надежные методы могут быть недоступны. +

diff --git a/fastlane/metadata/android/ru/short_description.txt b/fastlane/metadata/android/ru/short_description.txt new file mode 100644 index 0000000..cb303f6 --- /dev/null +++ b/fastlane/metadata/android/ru/short_description.txt @@ -0,0 +1 @@ +Получайте обновления приложений прямо из источника \ No newline at end of file diff --git a/lib/app_sources/html.dart b/lib/app_sources/html.dart index 51f6143..6ebee0a 100644 --- a/lib/app_sources/html.dart +++ b/lib/app_sources/html.dart @@ -244,16 +244,17 @@ class HTML extends AppSource { true) { var reg = RegExp(additionalSettings['customLinkFilterRegex']); links = allLinks - .where((element) => - reg.hasMatch(filterLinkByText ? element.value : element.key)) + .where((element) => reg.hasMatch( + filterLinkByText ? element.value : Uri.decodeFull(element.key))) .toList(); } else { links = allLinks - .where((element) => - Uri.parse(filterLinkByText ? element.value : element.key) - .path - .toLowerCase() - .endsWith('.apk')) + .where((element) => Uri.parse(filterLinkByText + ? element.value + : Uri.decodeFull(element.key)) + .path + .toLowerCase() + .endsWith('.apk')) .toList(); } if (!skipSort) { @@ -315,7 +316,7 @@ class HTML extends AppSource { additionalSettings['matchGroupToUse'] as String?, additionalSettings['versionExtractWholePage'] == true ? versionExtractionWholePageString - : rel); + : Uri.decodeFull(rel)); version ??= additionalSettings['defaultPseudoVersioningMethod'] == 'APKLinkHash' ? rel.hashCode.toString() diff --git a/lib/components/generated_form.dart b/lib/components/generated_form.dart index c8d059a..23eb928 100644 --- a/lib/components/generated_form.dart +++ b/lib/components/generated_form.dart @@ -245,8 +245,8 @@ class _GeneratedFormState extends State { void someValueChanged({bool isBuilding = false, bool forceInvalid = false}) { Map returnValues = values; var valid = true; - for (int r = 0; r < widget.items.length; r++) { - for (int i = 0; i < widget.items[r].length; i++) { + for (int r = 0; r < formInputs.length; r++) { + for (int i = 0; i < formInputs[r].length; i++) { if (formInputs[r][i] is TextFormField) { valid = valid && validateTextField(formInputs[r][i] as TextFormField); } diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index 7d224ee..a58dfb0 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -235,8 +235,9 @@ Future downloadFile( var fullContentLength = response.contentLength; if (useExisting && downloadedFile.existsSync()) { var length = downloadedFile.lengthSync(); - if (fullContentLength == null) { - // Assume full + if (fullContentLength == null || !rangeFeatureEnabled) { + // If there is no content length reported, assume it the existing file is fully downloaded + // Also if the range feature is not supported, don't trust the content length if any (#1542) client.close(); return downloadedFile; } else { @@ -291,14 +292,11 @@ Future downloadFile( return s; }).pipe(sink); await sink.close(); - bool likelyCorruptFile = (progress ?? 0) > 101; progress = null; if (onProgress != null) { onProgress(progress); } - if (response.statusCode < 200 || - response.statusCode > 299 || - likelyCorruptFile) { + if (response.statusCode < 200 || response.statusCode > 299) { tempDownloadedFile.deleteSync(recursive: true); throw response.reasonPhrase ?? tr('unexpectedError'); } @@ -392,30 +390,26 @@ class AppsProvider with ChangeNotifier { }(); } - Future handleAPKIDChange(App app, PackageInfo? newInfo, + Future handleAPKIDChange(App app, PackageInfo newInfo, File downloadedFile, String downloadUrl) async { // If the APK package ID is different from the App ID, it is either new (using a placeholder ID) or the ID has changed // The former case should be handled (give the App its real ID), the latter is a security issue var isTempIdBool = isTempId(app); - if (newInfo != null) { - if (app.id != newInfo.packageName) { - if (apps[app.id] != null && !isTempIdBool && !app.allowIdChange) { - throw IDChangedError(newInfo.packageName!); - } - var idChangeWasAllowed = app.allowIdChange; - app.allowIdChange = false; - var originalAppId = app.id; - app.id = newInfo.packageName!; - downloadedFile = downloadedFile.renameSync( - '${downloadedFile.parent.path}/${app.id}-${downloadUrl.hashCode}.${downloadedFile.path.split('.').last}'); - if (apps[originalAppId] != null) { - await removeApps([originalAppId]); - await saveApps([app], - onlyIfExists: !isTempIdBool && !idChangeWasAllowed); - } + if (app.id != newInfo.packageName) { + if (apps[app.id] != null && !isTempIdBool && !app.allowIdChange) { + throw IDChangedError(newInfo.packageName!); + } + var idChangeWasAllowed = app.allowIdChange; + app.allowIdChange = false; + var originalAppId = app.id; + app.id = newInfo.packageName!; + downloadedFile = downloadedFile.renameSync( + '${downloadedFile.parent.path}/${app.id}-${downloadUrl.hashCode}.${downloadedFile.path.split('.').last}'); + if (apps[originalAppId] != null) { + await removeApps([originalAppId]); + await saveApps([app], + onlyIfExists: !isTempIdBool && !idChangeWasAllowed); } - } else if (isTempIdBool) { - throw ObtainiumError('Could not get ID from APK'); } return downloadedFile; } @@ -479,6 +473,10 @@ class AppsProvider with ChangeNotifier { newInfo = await pm.getPackageArchiveInfo(archiveFilePath: apks.first.path); } + if (newInfo == null) { + downloadedFile.delete(); + throw ObtainiumError('Could not get ID from APK'); + } downloadedFile = await handleAPKIDChange(app, newInfo, downloadedFile, downloadUrl); // Delete older versions of the file if any diff --git a/pubspec.lock b/pubspec.lock index 96f56cb..da986ac 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -292,10 +292,10 @@ packages: dependency: "direct main" description: name: flutter_archive - sha256: "22e931ef6ef764edc922e425e46f4a4f888e864b976f4ecbe54aea9859abc090" + sha256: "5ca235f304c12bf468979235f400f79846d204169d715939e39197106f5fc970" url: "https://pub.dev" source: hosted - version: "6.0.2" + version: "6.0.3" flutter_fgbg: dependency: "direct main" description: @@ -659,10 +659,10 @@ packages: dependency: transitive description: name: petitparser - sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 url: "https://pub.dev" source: hosted - version: "5.4.0" + version: "6.0.2" platform: dependency: transitive description: @@ -937,10 +937,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d" + sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a" url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.1" url_launcher_windows: dependency: transitive description: @@ -1041,10 +1041,10 @@ packages: dependency: transitive description: name: xml - sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.5.0" yaml: dependency: transitive description: @@ -1054,5 +1054,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.3.3 <4.0.0" + dart: ">=3.3.0 <4.0.0" flutter: ">=3.19.0" diff --git a/pubspec.yaml b/pubspec.yaml index 0f5796c..8c28486 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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: 1.1.2+2259 +version: 1.1.4+2261 environment: sdk: '>=3.0.0 <4.0.0'