Merge pull request #1941 from ImranR98/dev

Fix PathAccessException on secondary profiles (#1754), Log installs (#1924), APKPure URL parsing bugfix (#1926), Remove Signal source (HTML is enough) (#1928), F-Droid URL parsing bugfix (#1933), HTML link extraction bugfix (#1937)
This commit is contained in:
Imran
2024-11-01 14:24:33 -04:00
committed by GitHub
32 changed files with 38 additions and 158 deletions

View File

@@ -30,7 +30,6 @@ Currently supported App sources:
- Jenkins Jobs
- [APKMirror](https://apkmirror.com/) (Track-Only)
- Open Source - App-Specific:
- [Signal](https://signal.org/)
- [VLC](https://videolan.org/)
- Other - App-Specific:
- [WhatsApp](https://whatsapp.com)

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Nije pronađena aplikacija s tim ID-om ili imenom",
"reposHaveMultipleApps": "Repo-i mogu sadržavati više aplikacija",
"fdroidThirdPartyRepo": "F-Droid Repo treće strane",
"steamMobile": "Steam Mobile",
"steamChat": "Razgovor na Steamu (chat)",
"install": "Instaliraj",
"markInstalled": "Označi kao instalirano",
"update": "Nadogradi",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Žádná aplikace s tímto ID nebo názvem nebyla nalezena",
"reposHaveMultipleApps": "Repozitáře mohou obsahovat více aplikací",
"fdroidThirdPartyRepo": "F-Droid repozitář třetí strany",
"steamMobile": "Steam Mobile",
"steamChat": "Steam Chat",
"install": "Nainstalujte",
"markInstalled": "Označit jako nainstalovaný",
"update": "Aktualizovat",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Ingen app med det ID eller navn blev fundet",
"reposHaveMultipleApps": "Repos kan indeholde flere apps",
"fdroidThirdPartyRepo": "F-Droid Tredjeparts-repo",
"steamMobile": "Steam Mobil",
"steamChat": "Steam Chat",
"install": "Installer",
"markInstalled": "Markér som installeret",
"update": "Opdater",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Es wurde keine App mit dieser ID oder diesem Namen gefunden",
"reposHaveMultipleApps": "Repos können mehrere Apps enthalten",
"fdroidThirdPartyRepo": "F-Droid-Drittanbieter-Repo",
"steamMobile": "Steam Mobile",
"steamChat": "Steam-Chat",
"install": "Installieren",
"markInstalled": "Als installiert markieren",
"update": "Aktualisieren",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Neniu apo estas trovita kun tiu identigilo aŭ nomo",
"reposHaveMultipleApps": "Deponejoj povas enhavi plurajn apojn",
"fdroidThirdPartyRepo": "Tria deponejo de F-Droid",
"steamMobile": "Telefona Steam",
"steamChat": "Steam Babilejo",
"install": "Instali",
"markInstalled": "Marki kiel instalita",
"update": "Ĝisdatigi",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "No App was found with that ID or Name",
"reposHaveMultipleApps": "Repos may contain multiple Apps",
"fdroidThirdPartyRepo": "F-Droid Third-Party Repo",
"steamMobile": "Steam Mobile",
"steamChat": "Steam Chat",
"install": "Install",
"markInstalled": "Mark Installed",
"update": "Update",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "No se han encontrado aplicaciones con ese ID o nombre",
"reposHaveMultipleApps": "Los repositorios pueden contener varias aplicaciones",
"fdroidThirdPartyRepo": "Repositorio de terceros F-Droid",
"steamMobile": "Steam para móviles",
"steamChat": "Chat de Steam",
"install": "Instalar",
"markInstalled": "Marcar como instalada",
"update": "Actualizar",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "هیچ برنامه ای با آن شناسه یا نام یافت نشد",
"reposHaveMultipleApps": "مخازن ممکن است شامل چندین برنامه باشد",
"fdroidThirdPartyRepo": "مخازن شخص ثالث F-Droid",
"steamMobile": "استیم موبایل",
"steamChat": "چت استیم",
"install": "نصب",
"markInstalled": "علامت گذاری به عنوان نصب شده",
"update": "به روز رسانی",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Aucune application n'a été trouvée avec cet identifiant ou ce nom",
"reposHaveMultipleApps": "Les dépôts peuvent contenir plusieurs applications",
"fdroidThirdPartyRepo": "Dépôt tiers F-Droid",
"steamMobile": "Application mobile Steam",
"steamChat": "Steam Chat",
"install": "Installer",
"markInstalled": "Marquer comme étant installé",
"update": "Mettre à jour",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Nem található alkalmazás ezzel az azonosítóval vagy névvel",
"reposHaveMultipleApps": "A tárolók több alkalmazást is tartalmazhatnak",
"fdroidThirdPartyRepo": "F-Droid harmadik féltől származó tároló",
"steamMobile": "Steam Mobil",
"steamChat": "Steam Chat",
"install": "Telepítés",
"markInstalled": "Telepítettnek jelölés",
"update": "Frissítés",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Tidak ada aplikasi yang ditemukan dengan ID atau nama tersebut",
"reposHaveMultipleApps": "Repositori dapat berisi beberapa aplikasi",
"fdroidThirdPartyRepo": "Repositori pihak ketiga F-Droid",
"steamMobile": "Steam Mobile",
"steamChat": "Obrolan Steam",
"install": "Pasang",
"markInstalled": "Tandai terpasang",
"update": "perbarui",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Non è stata trovata alcuna app con quell'ID o nome",
"reposHaveMultipleApps": "I repository possono contenere più app",
"fdroidThirdPartyRepo": "Repository F-Droid di terze parti",
"steamMobile": "Mobile a vapore",
"steamChat": "Chat di vapore",
"install": "Installa",
"markInstalled": "Contrassegna come installata",
"update": "Aggiorna",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "そのIDや名前を持つアプリは見つかりませんでした",
"reposHaveMultipleApps": "リポジトリには複数のアプリが含まれることがあります",
"fdroidThirdPartyRepo": "F-Droid サードパーティリポジトリ",
"steamMobile": "Steamモバイル",
"steamChat": "Steamチャット",
"install": "インストール",
"markInstalled": "インストール済みとしてマークする",
"update": "アップデート",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Er is geen app gevonden met dat ID of die naam",
"reposHaveMultipleApps": "Repositories kunnen meerdere apps bevatten",
"fdroidThirdPartyRepo": "F-Droid Repository voor derden",
"steamMobile": "Steam Mobile",
"steamChat": "Steam Chat",
"install": "Installeren",
"markInstalled": "Als geïnstalleerd markeren",
"update": "Bijwerken",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Nie znaleziono aplikacji o tym identyfikatorze lub nazwie",
"reposHaveMultipleApps": "Repozytoria mogą zawierać wiele aplikacji",
"fdroidThirdPartyRepo": "Zewnętrzne repo F-Droid",
"steamMobile": "Mobilny Steam",
"steamChat": "Steam Chat",
"install": "Instaluj",
"markInstalled": "Oznacz jako zainstalowane",
"update": "Zaktualizuj",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Nenhum aplicativo foi encontrado com esse ID ou nome",
"reposHaveMultipleApps": "Repositórios podem conter múltiplos aplicativos",
"fdroidThirdPartyRepo": "Repositórios de terceiros F-Droid",
"steamMobile": "Steam para celular",
"steamChat": "Chat do Steam",
"install": "Instalar",
"markInstalled": "Marcar instalado",
"update": "Atualizar",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Приложение с таким ID или названием не было найдено",
"reposHaveMultipleApps": "В хранилище несколько приложений",
"fdroidThirdPartyRepo": "Сторонние репозитории F-Droid",
"steamMobile": "Приложение Steam",
"steamChat": "Steam Chat",
"install": "Установить",
"markInstalled": "Пометить как установленное",
"update": "Обновить",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Ingen App funnen med det namnet eller ID",
"reposHaveMultipleApps": "Förråd kan innehålla flera ApparR",
"fdroidThirdPartyRepo": "F-Droid Tredjeparts Förråd",
"steamMobile": "Steam Mobile",
"steamChat": "Steam Chat",
"install": "Installera",
"markInstalled": "Märk Installerad",
"update": "Uppdatera",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Bu kimlik veya ada sahip bir uygulama bulunamadı",
"reposHaveMultipleApps": "Depolar birden fazla uygulama içerebilir",
"fdroidThirdPartyRepo": "F-Droid Üçüncü Parti Depo",
"steamMobile": "Steam Mobil",
"steamChat": "Steam Sohbet",
"install": "Yükle",
"markInstalled": "Yüklendi olarak İşaretle",
"update": "Güncelle",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Застосунок з таким ідентифікатором або назвою не знайдено",
"reposHaveMultipleApps": "Сховища можуть містити кілька застосунків",
"fdroidThirdPartyRepo": "F-Droid Стороннє сховище",
"steamMobile": "Мобільний Steam",
"steamChat": "Чат Steam",
"install": "Встановити",
"markInstalled": "Позначити як встановлене",
"update": "Оновити",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "Không tìm thấy ứng dụng nào có ID hoặc tên đó",
"reposHaveMultipleApps": "Kho có thể chứa nhiều Ứng dụng",
"fdroidThirdPartyRepo": "Kho lưu trữ bên thứ ba F-Droid",
"steamMobile": "Điện thoại di động hơi nước",
"steamChat": "Trò chuyện hơi nước",
"install": "Cài đặt",
"markInstalled": "Đánh dấu là đã cài đặt",
"update": "Cập nhật",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "找不到具有該 ID 或名稱的應用程式",
"reposHaveMultipleApps": "倉庫可能包含多個應用程式",
"fdroidThirdPartyRepo": "F-Droid 第三方倉庫",
"steamMobile": "Steam 行動版",
"steamChat": "Steam 聊天",
"install": "安裝",
"markInstalled": "標記為已安裝",
"update": "更新",

View File

@@ -179,8 +179,6 @@
"appWithIdOrNameNotFound": "未找到符合此 ID 或名称的应用",
"reposHaveMultipleApps": "存储库中可能包含多个应用",
"fdroidThirdPartyRepo": "F-Droid 第三方存储库",
"steamMobile": "Steam Mobile",
"steamChat": "Steam Chat",
"install": "安装",
"markInstalled": "标记为已安装",
"update": "更新",

View File

@@ -164,9 +164,15 @@ class APKPure extends AppSource {
String host = Uri.parse(standardUrl).host;
var res0 = await sourceRequest('$standardUrl/versions', additionalSettings);
var decodedStandardUrl = standardUrl;
try {
decodedStandardUrl = Uri.decodeFull(decodedStandardUrl);
} catch (e) {
//
}
var versionLinks = await grabLinksCommon(res0, {
'skipSort': true,
'customLinkFilterRegex': '${Uri.decodeFull(standardUrl)}/download/[^/]+\$'
'customLinkFilterRegex': '$decodedStandardUrl/download/[^/]+\$'
});
var supportedArchs = (await DeviceInfoPlugin().androidInfo).supportedAbis;

View File

@@ -45,7 +45,7 @@ class FDroid extends AppSource {
RegExpMatch? match = standardUrlRegExB.firstMatch(url);
if (match != null) {
url =
'https://${Uri.parse(match.group(0)!).host}/packages/${Uri.parse(url).pathSegments.last}';
'https://${Uri.parse(match.group(0)!).host}/packages/${Uri.parse(url).pathSegments.where((s) => s.trim().isNotEmpty).last}';
}
RegExp standardUrlRegExA = RegExp(
'^https?://(www\\.)?${getSourceRegex(hosts)}/+packages/+[^/]+',

View File

@@ -18,7 +18,7 @@ String ensureAbsoluteUrl(String ambiguousUrl, Uri referenceAbsoluteUrl) {
.where((element) => element.trim().isNotEmpty)
.toList();
String absoluteUrl;
if (ambiguousUrl.startsWith('/') || currPathSegments.isEmpty) {
if (ambiguousUrl.startsWith('/')) {
absoluteUrl = '${referenceAbsoluteUrl.origin}$ambiguousUrl';
} else if (currPathSegments.isEmpty) {
absoluteUrl = '${referenceAbsoluteUrl.origin}/$ambiguousUrl';

View File

@@ -1,37 +0,0 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart';
class Signal extends AppSource {
Signal() {
hosts = ['signal.org'];
}
@override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
return 'https://${hosts[0]}';
}
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl,
Map<String, dynamic> additionalSettings,
) async {
Response res = await sourceRequest(
'https://updates.${hosts[0]}/android/latest.json', additionalSettings);
if (res.statusCode == 200) {
var json = jsonDecode(res.body);
String? apkUrl = json['url'];
List<String> apkUrls = apkUrl == null ? [] : [apkUrl];
String? version = json['versionName'];
if (version == null) {
throw NoVersionError();
}
return APKDetails(
version, getApkUrlsFromUrls(apkUrls), AppNames(name, 'Signal'));
} else {
throw getObtainiumHttpError(res);
}
}
}

View File

@@ -1,63 +0,0 @@
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';
class SteamMobile extends AppSource {
SteamMobile() {
hosts = ['store.steampowered.com'];
name = 'Steam';
additionalSourceAppSpecificSettingFormItems = [
[
GeneratedFormDropdown('app', apks.entries.toList(),
label: tr('app'), defaultValue: apks.entries.toList()[0].key)
]
];
}
final apks = {'steam': tr('steamMobile'), 'steam-chat-app': tr('steamChat')};
@override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
return 'https://${hosts[0]}';
}
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl,
Map<String, dynamic> additionalSettings,
) async {
Response res =
await sourceRequest('https://${hosts[0]}/mobile', additionalSettings);
if (res.statusCode == 200) {
var apkNamePrefix = additionalSettings['app'] as String?;
if (apkNamePrefix == null) {
throw NoReleasesError();
}
String apkInURLRegexPattern =
'/$apkNamePrefix-([0-9]+\\.)*[0-9]+\\.apk\$';
var links = parse(res.body)
.querySelectorAll('a')
.map((e) => e.attributes['href'] ?? '')
.where((e) => RegExp('https://.*$apkInURLRegexPattern').hasMatch(e))
.toList();
if (links.isEmpty) {
throw NoReleasesError();
}
var versionMatch = RegExp(apkInURLRegexPattern).firstMatch(links[0]);
if (versionMatch == null) {
throw NoVersionError();
}
var version = links[0].substring(
versionMatch.start + apkNamePrefix.length + 2, versionMatch.end - 4);
var apkUrls = [links[0]];
return APKDetails(version, getApkUrlsFromUrls(apkUrls),
AppNames(name, apks[apkNamePrefix]!));
} else {
throw getObtainiumHttpError(res);
}
}
}

View File

@@ -700,6 +700,8 @@ class AppsProvider with ChangeNotifier {
}
}
PackageInfo? appInfo = await getInstalledInfo(apps[file.appId]!.app.id);
logs.add(
'Installing "${newInfo.packageName}" version "${newInfo.versionName}" versionCode "${newInfo.versionCode}"${appInfo != null ? ' (from existing version "${appInfo.versionName}" versionCode "${appInfo.versionCode}")' : ''}');
if (appInfo != null &&
newInfo.versionCode! < appInfo.versionCode! &&
!(await canDowngradeApps())) {
@@ -743,6 +745,10 @@ class AppsProvider with ChangeNotifier {
return installed;
}
Future<String> getStorageRootPath() async {
return '/${(await getExternalStorageDirectory())!.uri.pathSegments.sublist(0, 3).join('/')}';
}
Future<void> moveObbFile(File file, String appId) async {
if (!file.path.toLowerCase().endsWith('.obb')) return;
@@ -751,7 +757,7 @@ class AppsProvider with ChangeNotifier {
await Permission.storage.request();
}
String obbDirPath = "/storage/emulated/0/Android/obb/$appId";
String obbDirPath = "${await getStorageRootPath()}/Android/obb/$appId";
Directory(obbDirPath).createSync(recursive: true);
String obbFileName = file.path.split("/").last;
@@ -1045,10 +1051,11 @@ class AppsProvider with ChangeNotifier {
Future<void> downloadFn(MapEntry<String, String> fileUrl, App app) async {
try {
var exportDir = await settingsProvider.getExportDir();
String downloadPath = '/storage/emulated/0/Download';
String downloadPath = '${await getStorageRootPath()}/Download';
bool downloadsAccessible = false;
try {
downloadsAccessible = Directory(downloadPath).existsSync();
Directory(downloadPath).listSync();
downloadsAccessible = true;
} catch (e) {
//
}

View File

@@ -23,10 +23,8 @@ import 'package:obtainium/app_sources/izzyondroid.dart';
import 'package:obtainium/app_sources/html.dart';
import 'package:obtainium/app_sources/jenkins.dart';
import 'package:obtainium/app_sources/neutroncode.dart';
import 'package:obtainium/app_sources/signal.dart';
import 'package:obtainium/app_sources/sourceforge.dart';
import 'package:obtainium/app_sources/sourcehut.dart';
import 'package:obtainium/app_sources/steammobile.dart';
import 'package:obtainium/app_sources/telegramapp.dart';
import 'package:obtainium/app_sources/tencent.dart';
import 'package:obtainium/app_sources/uptodown.dart';
@@ -183,7 +181,7 @@ appJSONCompatibilityModifiers(Map<String, dynamic> json) {
}).toList();
}
// Steam source apps should be converted to HTML (#1244)
var legacySteamSourceApps = SteamMobile().apks.keys;
var legacySteamSourceApps = ['steam', 'steam-chat-app'];
if (legacySteamSourceApps.contains(additionalSettings['app'] ?? '')) {
json['url'] = '${json['url']}/mobile';
var replacementAdditionalSettings = getDefaultValuesFromFormItems(
@@ -200,6 +198,23 @@ appJSONCompatibilityModifiers(Map<String, dynamic> json) {
replacementAdditionalSettings['matchGroupToUse'] = '\$1';
additionalSettings = replacementAdditionalSettings;
}
// Signal apps from before it was removed should be converted to HTML (#1928)
if (json['url'] == 'https://signal.org' &&
json['id'] == 'org.thoughtcrime.securesms' &&
json['author'] == 'Signal' &&
json['name'] == 'Signal' &&
json['overrideSource'] == null &&
additionalSettings['trackOnly'] == false &&
additionalSettings['versionExtractionRegEx'] == '' &&
json['lastUpdateCheck'] != null &&
json['lastUpdateCheck'] <= 1730484400402000) {
json['url'] = 'https://updates.signal.org/android/latest.json';
var replacementAdditionalSettings = getDefaultValuesFromFormItems(
HTML().combinedAppSpecificSettingFormItems);
replacementAdditionalSettings['versionExtractionRegEx'] =
'\\d+.\\d+.\\d+';
additionalSettings = replacementAdditionalSettings;
}
}
json['additionalSettings'] = jsonEncode(additionalSettings);
// F-Droid no longer needs cloudflare exception since override can be used - migrate apps appropriately
@@ -794,7 +809,6 @@ class SourceProvider {
Tencent(),
Jenkins(),
APKMirror(),
Signal(),
VLC(),
WhatsApp(),
TelegramApp(),

View File

@@ -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.28+2285
version: 1.1.29+2286
environment:
sdk: '>=3.0.0 <4.0.0'