mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-10-21 02:03:44 +02:00
Header usage bugfix
This commit is contained in:
@@ -27,8 +27,8 @@ class APKCombo extends AppSource {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Map<String, String>?> getRequestHeaders(
|
Future<Map<String, String>?> getRequestHeaders(
|
||||||
{Map<String, dynamic> additionalSettings = const <String, dynamic>{},
|
Map<String, dynamic> additionalSettings,
|
||||||
bool forAPKDownload = false}) async {
|
{bool forAPKDownload = false}) async {
|
||||||
return {
|
return {
|
||||||
"User-Agent": "curl/8.0.1",
|
"User-Agent": "curl/8.0.1",
|
||||||
"Accept": "*/*",
|
"Accept": "*/*",
|
||||||
@@ -37,8 +37,9 @@ class APKCombo extends AppSource {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<MapEntry<String, String>>> getApkUrls(String standardUrl) async {
|
Future<List<MapEntry<String, String>>> getApkUrls(
|
||||||
var res = await sourceRequest('$standardUrl/download/apk');
|
String standardUrl, Map<String, dynamic> additionalSettings) async {
|
||||||
|
var res = await sourceRequest('$standardUrl/download/apk', {});
|
||||||
if (res.statusCode != 200) {
|
if (res.statusCode != 200) {
|
||||||
throw getObtainiumHttpError(res);
|
throw getObtainiumHttpError(res);
|
||||||
}
|
}
|
||||||
@@ -71,9 +72,9 @@ class APKCombo extends AppSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<String> apkUrlPrefetchModifier(
|
Future<String> apkUrlPrefetchModifier(String apkUrl, String standardUrl,
|
||||||
String apkUrl, String standardUrl) async {
|
Map<String, dynamic> additionalSettings) async {
|
||||||
var freshURLs = await getApkUrls(standardUrl);
|
var freshURLs = await getApkUrls(standardUrl, additionalSettings);
|
||||||
var path2Match = Uri.parse(apkUrl).path;
|
var path2Match = Uri.parse(apkUrl).path;
|
||||||
for (var url in freshURLs) {
|
for (var url in freshURLs) {
|
||||||
if (Uri.parse(url.value).path == path2Match) {
|
if (Uri.parse(url.value).path == path2Match) {
|
||||||
@@ -89,7 +90,7 @@ class APKCombo extends AppSource {
|
|||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
String appId = (await tryInferringAppId(standardUrl))!;
|
String appId = (await tryInferringAppId(standardUrl))!;
|
||||||
var preres = await sourceRequest(standardUrl);
|
var preres = await sourceRequest(standardUrl, additionalSettings);
|
||||||
if (preres.statusCode != 200) {
|
if (preres.statusCode != 200) {
|
||||||
throw getObtainiumHttpError(preres);
|
throw getObtainiumHttpError(preres);
|
||||||
}
|
}
|
||||||
@@ -113,7 +114,9 @@ class APKCombo extends AppSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return APKDetails(
|
return APKDetails(
|
||||||
version, await getApkUrls(standardUrl), AppNames(author, appName),
|
version,
|
||||||
|
await getApkUrls(standardUrl, additionalSettings),
|
||||||
|
AppNames(author, appName),
|
||||||
releaseDate: releaseDate);
|
releaseDate: releaseDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -58,7 +58,7 @@ class APKMirror extends AppSource {
|
|||||||
true
|
true
|
||||||
? additionalSettings['filterReleaseTitlesByRegEx']
|
? additionalSettings['filterReleaseTitlesByRegEx']
|
||||||
: null;
|
: null;
|
||||||
Response res = await sourceRequest('$standardUrl/feed');
|
Response res = await sourceRequest('$standardUrl/feed', additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var items = parse(res.body).querySelectorAll('item');
|
var items = parse(res.body).querySelectorAll('item');
|
||||||
dynamic targetRelease;
|
dynamic targetRelease;
|
||||||
|
@@ -55,8 +55,8 @@ class APKPure extends AppSource {
|
|||||||
) async {
|
) async {
|
||||||
String appId = (await tryInferringAppId(standardUrl))!;
|
String appId = (await tryInferringAppId(standardUrl))!;
|
||||||
String host = Uri.parse(standardUrl).host;
|
String host = Uri.parse(standardUrl).host;
|
||||||
var res = await sourceRequest('$standardUrl/download');
|
var res = await sourceRequest('$standardUrl/download', additionalSettings);
|
||||||
var resChangelog = await sourceRequest(standardUrl);
|
var resChangelog = await sourceRequest(standardUrl, additionalSettings);
|
||||||
if (res.statusCode == 200 && resChangelog.statusCode == 200) {
|
if (res.statusCode == 200 && resChangelog.statusCode == 200) {
|
||||||
var html = parse(res.body);
|
var html = parse(res.body);
|
||||||
var htmlChangelog = parse(resChangelog.body);
|
var htmlChangelog = parse(resChangelog.body);
|
||||||
|
@@ -26,11 +26,13 @@ class Aptoide extends AppSource {
|
|||||||
@override
|
@override
|
||||||
Future<String?> tryInferringAppId(String standardUrl,
|
Future<String?> tryInferringAppId(String standardUrl,
|
||||||
{Map<String, dynamic> additionalSettings = const {}}) async {
|
{Map<String, dynamic> additionalSettings = const {}}) async {
|
||||||
return (await getAppDetailsJSON(standardUrl))['package'];
|
return (await getAppDetailsJSON(
|
||||||
|
standardUrl, additionalSettings))['package'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> getAppDetailsJSON(String standardUrl) async {
|
Future<Map<String, dynamic>> getAppDetailsJSON(
|
||||||
var res = await sourceRequest(standardUrl);
|
String standardUrl, Map<String, dynamic> additionalSettings) async {
|
||||||
|
var res = await sourceRequest(standardUrl, additionalSettings);
|
||||||
if (res.statusCode != 200) {
|
if (res.statusCode != 200) {
|
||||||
throw getObtainiumHttpError(res);
|
throw getObtainiumHttpError(res);
|
||||||
}
|
}
|
||||||
@@ -41,8 +43,8 @@ class Aptoide extends AppSource {
|
|||||||
} else {
|
} else {
|
||||||
throw NoReleasesError();
|
throw NoReleasesError();
|
||||||
}
|
}
|
||||||
var res2 =
|
var res2 = await sourceRequest(
|
||||||
await sourceRequest('https://ws2.aptoide.com/api/7/getApp/app_id/$id');
|
'https://ws2.aptoide.com/api/7/getApp/app_id/$id', additionalSettings);
|
||||||
if (res2.statusCode != 200) {
|
if (res2.statusCode != 200) {
|
||||||
throw getObtainiumHttpError(res);
|
throw getObtainiumHttpError(res);
|
||||||
}
|
}
|
||||||
@@ -54,7 +56,7 @@ class Aptoide extends AppSource {
|
|||||||
String standardUrl,
|
String standardUrl,
|
||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
var appDetails = await getAppDetailsJSON(standardUrl);
|
var appDetails = await getAppDetailsJSON(standardUrl, additionalSettings);
|
||||||
String appName = appDetails['name'] ?? tr('app');
|
String appName = appDetails['name'] ?? tr('app');
|
||||||
String author = appDetails['developer']?['name'] ?? name;
|
String author = appDetails['developer']?['name'] ?? name;
|
||||||
String? dateStr = appDetails['updated'];
|
String? dateStr = appDetails['updated'];
|
||||||
|
@@ -67,7 +67,8 @@ class FDroid extends AppSource {
|
|||||||
String? appId = await tryInferringAppId(standardUrl);
|
String? appId = await tryInferringAppId(standardUrl);
|
||||||
String host = Uri.parse(standardUrl).host;
|
String host = Uri.parse(standardUrl).host;
|
||||||
var details = getAPKUrlsFromFDroidPackagesAPIResponse(
|
var details = getAPKUrlsFromFDroidPackagesAPIResponse(
|
||||||
await sourceRequest('https://$host/api/v1/packages/$appId'),
|
await sourceRequest(
|
||||||
|
'https://$host/api/v1/packages/$appId', additionalSettings),
|
||||||
'https://$host/repo/$appId',
|
'https://$host/repo/$appId',
|
||||||
standardUrl,
|
standardUrl,
|
||||||
name,
|
name,
|
||||||
@@ -84,7 +85,8 @@ class FDroid extends AppSource {
|
|||||||
if (!hostChanged) {
|
if (!hostChanged) {
|
||||||
try {
|
try {
|
||||||
var res = await sourceRequest(
|
var res = await sourceRequest(
|
||||||
'https://gitlab.com/fdroid/fdroiddata/-/raw/master/metadata/$appId.yml');
|
'https://gitlab.com/fdroid/fdroiddata/-/raw/master/metadata/$appId.yml',
|
||||||
|
additionalSettings);
|
||||||
var lines = res.body.split('\n');
|
var lines = res.body.split('\n');
|
||||||
var authorLines = lines.where((l) => l.startsWith('AuthorName: '));
|
var authorLines = lines.where((l) => l.startsWith('AuthorName: '));
|
||||||
if (authorLines.isNotEmpty) {
|
if (authorLines.isNotEmpty) {
|
||||||
@@ -94,11 +96,13 @@ class FDroid extends AppSource {
|
|||||||
var changelogUrls = lines.where((l) => l.startsWith('Changelog: '));
|
var changelogUrls = lines.where((l) => l.startsWith('Changelog: '));
|
||||||
if (changelogUrls.isNotEmpty) {
|
if (changelogUrls.isNotEmpty) {
|
||||||
details.changeLog = changelogUrls.first;
|
details.changeLog = changelogUrls.first;
|
||||||
details.changeLog = (await sourceRequest(details.changeLog!
|
details.changeLog = (await sourceRequest(
|
||||||
.split(': ')
|
details.changeLog!
|
||||||
.sublist(1)
|
.split(': ')
|
||||||
.join(': ')
|
.sublist(1)
|
||||||
.replaceFirst('/blob/', '/raw/')))
|
.join(': ')
|
||||||
|
.replaceFirst('/blob/', '/raw/'),
|
||||||
|
additionalSettings))
|
||||||
.body;
|
.body;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -115,7 +119,7 @@ class FDroid extends AppSource {
|
|||||||
Future<Map<String, List<String>>> search(String query,
|
Future<Map<String, List<String>>> search(String query,
|
||||||
{Map<String, dynamic> querySettings = const {}}) async {
|
{Map<String, dynamic> querySettings = const {}}) async {
|
||||||
Response res = await sourceRequest(
|
Response res = await sourceRequest(
|
||||||
'https://search.${hosts[0]}/?q=${Uri.encodeQueryComponent(query)}');
|
'https://search.${hosts[0]}/?q=${Uri.encodeQueryComponent(query)}', {});
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
Map<String, List<String>> urlsWithDescriptions = {};
|
Map<String, List<String>> urlsWithDescriptions = {};
|
||||||
parse(res.body).querySelectorAll('.package-header').forEach((e) {
|
parse(res.body).querySelectorAll('.package-header').forEach((e) {
|
||||||
|
@@ -59,7 +59,7 @@ class FDroidRepo extends AppSource {
|
|||||||
throw NoReleasesError();
|
throw NoReleasesError();
|
||||||
}
|
}
|
||||||
url = removeQueryParamsFromUrl(standardizeUrl(url));
|
url = removeQueryParamsFromUrl(standardizeUrl(url));
|
||||||
var res = await sourceRequest('$url/index.xml');
|
var res = await sourceRequest('$url/index.xml', {});
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var body = parse(res.body);
|
var body = parse(res.body);
|
||||||
Map<String, List<String>> results = {};
|
Map<String, List<String>> results = {};
|
||||||
@@ -117,7 +117,8 @@ class FDroidRepo extends AppSource {
|
|||||||
throw NoReleasesError();
|
throw NoReleasesError();
|
||||||
}
|
}
|
||||||
var res = await sourceRequest(
|
var res = await sourceRequest(
|
||||||
'$standardUrl${standardUrl.endsWith('/index.xml') ? '' : '/index.xml'}');
|
'$standardUrl${standardUrl.endsWith('/index.xml') ? '' : '/index.xml'}',
|
||||||
|
additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var body = parse(res.body);
|
var body = parse(res.body);
|
||||||
var foundApps = body.querySelectorAll('application').where((element) {
|
var foundApps = body.querySelectorAll('application').where((element) {
|
||||||
|
@@ -108,7 +108,8 @@ class GitHub extends AppSource {
|
|||||||
for (var path in possibleBuildGradleLocations) {
|
for (var path in possibleBuildGradleLocations) {
|
||||||
try {
|
try {
|
||||||
var res = await sourceRequest(
|
var res = await sourceRequest(
|
||||||
'${await convertStandardUrlToAPIUrl(standardUrl, additionalSettings)}/contents/$path');
|
'${await convertStandardUrlToAPIUrl(standardUrl, additionalSettings)}/contents/$path',
|
||||||
|
additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
try {
|
try {
|
||||||
var body = jsonDecode(res.body);
|
var body = jsonDecode(res.body);
|
||||||
@@ -160,8 +161,8 @@ class GitHub extends AppSource {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Map<String, String>?> getRequestHeaders(
|
Future<Map<String, String>?> getRequestHeaders(
|
||||||
{Map<String, dynamic> additionalSettings = const <String, dynamic>{},
|
Map<String, dynamic> additionalSettings,
|
||||||
bool forAPKDownload = false}) async {
|
{bool forAPKDownload = false}) async {
|
||||||
var token = await getTokenIfAny(additionalSettings);
|
var token = await getTokenIfAny(additionalSettings);
|
||||||
var headers = <String, String>{};
|
var headers = <String, String>{};
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
@@ -239,7 +240,8 @@ class GitHub extends AppSource {
|
|||||||
if (verifyLatestTag) {
|
if (verifyLatestTag) {
|
||||||
var temp = requestUrl.split('?');
|
var temp = requestUrl.split('?');
|
||||||
Response res = await sourceRequest(
|
Response res = await sourceRequest(
|
||||||
'${temp[0]}/latest${temp.length > 1 ? '?${temp.sublist(1).join('?')}' : ''}');
|
'${temp[0]}/latest${temp.length > 1 ? '?${temp.sublist(1).join('?')}' : ''}',
|
||||||
|
additionalSettings);
|
||||||
if (res.statusCode != 200) {
|
if (res.statusCode != 200) {
|
||||||
if (onHttpErrorCode != null) {
|
if (onHttpErrorCode != null) {
|
||||||
onHttpErrorCode(res);
|
onHttpErrorCode(res);
|
||||||
@@ -248,7 +250,7 @@ class GitHub extends AppSource {
|
|||||||
}
|
}
|
||||||
latestRelease = jsonDecode(res.body);
|
latestRelease = jsonDecode(res.body);
|
||||||
}
|
}
|
||||||
Response res = await sourceRequest(requestUrl);
|
Response res = await sourceRequest(requestUrl, additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var releases = jsonDecode(res.body) as List<dynamic>;
|
var releases = jsonDecode(res.body) as List<dynamic>;
|
||||||
if (latestRelease != null) {
|
if (latestRelease != null) {
|
||||||
@@ -425,7 +427,7 @@ class GitHub extends AppSource {
|
|||||||
String query, String requestUrl, String rootProp,
|
String query, String requestUrl, String rootProp,
|
||||||
{Function(Response)? onHttpErrorCode,
|
{Function(Response)? onHttpErrorCode,
|
||||||
Map<String, dynamic> querySettings = const {}}) async {
|
Map<String, dynamic> querySettings = const {}}) async {
|
||||||
Response res = await sourceRequest(requestUrl);
|
Response res = await sourceRequest(requestUrl, {});
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
int minStarCount = querySettings['minStarCount'] != null
|
int minStarCount = querySettings['minStarCount'] != null
|
||||||
? int.parse(querySettings['minStarCount'])
|
? int.parse(querySettings['minStarCount'])
|
||||||
|
@@ -83,7 +83,7 @@ class GitLab extends AppSource {
|
|||||||
{Map<String, dynamic> querySettings = const {}}) async {
|
{Map<String, dynamic> querySettings = const {}}) async {
|
||||||
var url =
|
var url =
|
||||||
'https://${hosts[0]}/api/v4/projects?search=${Uri.encodeQueryComponent(query)}';
|
'https://${hosts[0]}/api/v4/projects?search=${Uri.encodeQueryComponent(query)}';
|
||||||
var res = await sourceRequest(url);
|
var res = await sourceRequest(url, {});
|
||||||
if (res.statusCode != 200) {
|
if (res.statusCode != 200) {
|
||||||
throw getObtainiumHttpError(res);
|
throw getObtainiumHttpError(res);
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,8 @@ class GitLab extends AppSource {
|
|||||||
if (PAT != null) {
|
if (PAT != null) {
|
||||||
var names = GitHub().getAppNames(standardUrl);
|
var names = GitHub().getAppNames(standardUrl);
|
||||||
Response res = await sourceRequest(
|
Response res = await sourceRequest(
|
||||||
'https://${hosts[0]}/api/v4/projects/${names.author}%2F${names.name}/releases?private_token=$PAT');
|
'https://${hosts[0]}/api/v4/projects/${names.author}%2F${names.name}/releases?private_token=$PAT',
|
||||||
|
additionalSettings);
|
||||||
if (res.statusCode != 200) {
|
if (res.statusCode != 200) {
|
||||||
throw getObtainiumHttpError(res);
|
throw getObtainiumHttpError(res);
|
||||||
}
|
}
|
||||||
@@ -149,7 +150,8 @@ class GitLab extends AppSource {
|
|||||||
releaseDate: releaseDate);
|
releaseDate: releaseDate);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Response res = await sourceRequest('$standardUrl/-/tags?format=atom');
|
Response res = await sourceRequest(
|
||||||
|
'$standardUrl/-/tags?format=atom', additionalSettings);
|
||||||
if (res.statusCode != 200) {
|
if (res.statusCode != 200) {
|
||||||
throw getObtainiumHttpError(res);
|
throw getObtainiumHttpError(res);
|
||||||
}
|
}
|
||||||
|
@@ -179,8 +179,8 @@ class HTML extends AppSource {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Map<String, String>?> getRequestHeaders(
|
Future<Map<String, String>?> getRequestHeaders(
|
||||||
{Map<String, dynamic> additionalSettings = const <String, dynamic>{},
|
Map<String, dynamic> additionalSettings,
|
||||||
bool forAPKDownload = false}) async {
|
{bool forAPKDownload = false}) async {
|
||||||
if (additionalSettings.isNotEmpty) {
|
if (additionalSettings.isNotEmpty) {
|
||||||
if (additionalSettings['requestHeader']?.isNotEmpty != true) {
|
if (additionalSettings['requestHeader']?.isNotEmpty != true) {
|
||||||
additionalSettings['requestHeader'] = [];
|
additionalSettings['requestHeader'] = [];
|
||||||
@@ -278,7 +278,8 @@ class HTML extends AppSource {
|
|||||||
.where((l) => l['customLinkFilterRegex'].isNotEmpty == true)
|
.where((l) => l['customLinkFilterRegex'].isNotEmpty == true)
|
||||||
.toList();
|
.toList();
|
||||||
for (int i = 0; i < (additionalSettings['intermediateLink'].length); i++) {
|
for (int i = 0; i < (additionalSettings['intermediateLink'].length); i++) {
|
||||||
var intLinks = await grabLinksCommon(await sourceRequest(currentUrl),
|
var intLinks = await grabLinksCommon(
|
||||||
|
await sourceRequest(currentUrl, additionalSettings),
|
||||||
additionalSettings['intermediateLink'][i]);
|
additionalSettings['intermediateLink'][i]);
|
||||||
if (intLinks.isEmpty) {
|
if (intLinks.isEmpty) {
|
||||||
throw NoReleasesError();
|
throw NoReleasesError();
|
||||||
@@ -288,7 +289,7 @@ class HTML extends AppSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var uri = Uri.parse(currentUrl);
|
var uri = Uri.parse(currentUrl);
|
||||||
Response res = await sourceRequest(currentUrl);
|
Response res = await sourceRequest(currentUrl, additionalSettings);
|
||||||
var links = await grabLinksCommon(res, additionalSettings);
|
var links = await grabLinksCommon(res, additionalSettings);
|
||||||
|
|
||||||
if ((additionalSettings['apkFilterRegEx'] as String?)?.isNotEmpty == true) {
|
if ((additionalSettings['apkFilterRegEx'] as String?)?.isNotEmpty == true) {
|
||||||
|
@@ -25,8 +25,10 @@ class HuaweiAppGallery extends AppSource {
|
|||||||
getDlUrl(String standardUrl) =>
|
getDlUrl(String standardUrl) =>
|
||||||
'https://${hosts[0].replaceAll('appgallery.', 'appgallery.cloud.')}/appdl/${standardUrl.split('/').last}';
|
'https://${hosts[0].replaceAll('appgallery.', 'appgallery.cloud.')}/appdl/${standardUrl.split('/').last}';
|
||||||
|
|
||||||
requestAppdlRedirect(String dlUrl) async {
|
requestAppdlRedirect(
|
||||||
Response res = await sourceRequest(dlUrl, followRedirects: false);
|
String dlUrl, Map<String, dynamic> additionalSettings) async {
|
||||||
|
Response res =
|
||||||
|
await sourceRequest(dlUrl, additionalSettings, followRedirects: false);
|
||||||
if (res.statusCode == 200 ||
|
if (res.statusCode == 200 ||
|
||||||
res.statusCode == 302 ||
|
res.statusCode == 302 ||
|
||||||
res.statusCode == 304) {
|
res.statusCode == 304) {
|
||||||
@@ -53,7 +55,7 @@ class HuaweiAppGallery extends AppSource {
|
|||||||
Future<String?> tryInferringAppId(String standardUrl,
|
Future<String?> tryInferringAppId(String standardUrl,
|
||||||
{Map<String, dynamic> additionalSettings = const {}}) async {
|
{Map<String, dynamic> additionalSettings = const {}}) async {
|
||||||
String dlUrl = getDlUrl(standardUrl);
|
String dlUrl = getDlUrl(standardUrl);
|
||||||
Response res = await requestAppdlRedirect(dlUrl);
|
Response res = await requestAppdlRedirect(dlUrl, additionalSettings);
|
||||||
return res.headers['location'] != null
|
return res.headers['location'] != null
|
||||||
? appIdFromRedirectDlUrl(res.headers['location']!)
|
? appIdFromRedirectDlUrl(res.headers['location']!)
|
||||||
: null;
|
: null;
|
||||||
@@ -65,7 +67,7 @@ class HuaweiAppGallery extends AppSource {
|
|||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
String dlUrl = getDlUrl(standardUrl);
|
String dlUrl = getDlUrl(standardUrl);
|
||||||
Response res = await requestAppdlRedirect(dlUrl);
|
Response res = await requestAppdlRedirect(dlUrl, additionalSettings);
|
||||||
if (res.headers['location'] == null) {
|
if (res.headers['location'] == null) {
|
||||||
throw NoReleasesError();
|
throw NoReleasesError();
|
||||||
}
|
}
|
||||||
|
@@ -43,7 +43,8 @@ class IzzyOnDroid extends AppSource {
|
|||||||
String? appId = await tryInferringAppId(standardUrl);
|
String? appId = await tryInferringAppId(standardUrl);
|
||||||
return fd.getAPKUrlsFromFDroidPackagesAPIResponse(
|
return fd.getAPKUrlsFromFDroidPackagesAPIResponse(
|
||||||
await sourceRequest(
|
await sourceRequest(
|
||||||
'https://apt.izzysoft.de/fdroid/api/v1/packages/$appId'),
|
'https://apt.izzysoft.de/fdroid/api/v1/packages/$appId',
|
||||||
|
additionalSettings),
|
||||||
'https://android.izzysoft.de/frepo/$appId',
|
'https://android.izzysoft.de/frepo/$appId',
|
||||||
standardUrl,
|
standardUrl,
|
||||||
name,
|
name,
|
||||||
|
@@ -29,8 +29,8 @@ class Jenkins extends AppSource {
|
|||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
standardUrl = trimJobUrl(standardUrl);
|
standardUrl = trimJobUrl(standardUrl);
|
||||||
Response res =
|
Response res = await sourceRequest(
|
||||||
await sourceRequest('$standardUrl/lastSuccessfulBuild/api/json');
|
'$standardUrl/lastSuccessfulBuild/api/json', additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var json = jsonDecode(res.body);
|
var json = jsonDecode(res.body);
|
||||||
var releaseDate = json['timestamp'] == null
|
var releaseDate = json['timestamp'] == null
|
||||||
|
@@ -29,7 +29,8 @@ class Mullvad extends AppSource {
|
|||||||
String standardUrl,
|
String standardUrl,
|
||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
Response res = await sourceRequest('$standardUrl/en/download/android');
|
Response res = await sourceRequest(
|
||||||
|
'$standardUrl/en/download/android', additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var versions = parse(res.body)
|
var versions = parse(res.body)
|
||||||
.querySelectorAll('p')
|
.querySelectorAll('p')
|
||||||
|
@@ -79,7 +79,7 @@ class NeutronCode extends AppSource {
|
|||||||
String standardUrl,
|
String standardUrl,
|
||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
Response res = await sourceRequest(standardUrl);
|
Response res = await sourceRequest(standardUrl, additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var http = parse(res.body);
|
var http = parse(res.body);
|
||||||
var name = http.querySelector('.pd-title')?.innerHtml;
|
var name = http.querySelector('.pd-title')?.innerHtml;
|
||||||
|
@@ -18,8 +18,8 @@ class Signal extends AppSource {
|
|||||||
String standardUrl,
|
String standardUrl,
|
||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
Response res =
|
Response res = await sourceRequest(
|
||||||
await sourceRequest('https://updates.${hosts[0]}/android/latest.json');
|
'https://updates.${hosts[0]}/android/latest.json', additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var json = jsonDecode(res.body);
|
var json = jsonDecode(res.body);
|
||||||
String? apkUrl = json['url'];
|
String? apkUrl = json['url'];
|
||||||
|
@@ -31,7 +31,8 @@ class SourceForge extends AppSource {
|
|||||||
String standardUrl,
|
String standardUrl,
|
||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
Response res = await sourceRequest('$standardUrl/rss?path=/');
|
Response res =
|
||||||
|
await sourceRequest('$standardUrl/rss?path=/', additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var parsedHtml = parse(res.body);
|
var parsedHtml = parse(res.body);
|
||||||
var allDownloadLinks =
|
var allDownloadLinks =
|
||||||
|
@@ -41,7 +41,8 @@ class SourceHut extends AppSource {
|
|||||||
String appName = standardUri.pathSegments.last;
|
String appName = standardUri.pathSegments.last;
|
||||||
bool fallbackToOlderReleases =
|
bool fallbackToOlderReleases =
|
||||||
additionalSettings['fallbackToOlderReleases'] == true;
|
additionalSettings['fallbackToOlderReleases'] == true;
|
||||||
Response res = await sourceRequest('$standardUrl/refs/rss.xml');
|
Response res =
|
||||||
|
await sourceRequest('$standardUrl/refs/rss.xml', additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var parsedHtml = parse(res.body);
|
var parsedHtml = parse(res.body);
|
||||||
List<APKDetails> apkDetailsList = [];
|
List<APKDetails> apkDetailsList = [];
|
||||||
@@ -70,7 +71,7 @@ class SourceHut extends AppSource {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
var res2 = await sourceRequest(releasePage);
|
var res2 = await sourceRequest(releasePage, additionalSettings);
|
||||||
List<MapEntry<String, String>> apkUrls = [];
|
List<MapEntry<String, String>> apkUrls = [];
|
||||||
if (res2.statusCode == 200) {
|
if (res2.statusCode == 200) {
|
||||||
apkUrls = getApkUrlsFromUrls(parse(res2.body)
|
apkUrls = getApkUrlsFromUrls(parse(res2.body)
|
||||||
|
@@ -29,7 +29,8 @@ class SteamMobile extends AppSource {
|
|||||||
String standardUrl,
|
String standardUrl,
|
||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
Response res = await sourceRequest('https://${hosts[0]}/mobile');
|
Response res =
|
||||||
|
await sourceRequest('https://${hosts[0]}/mobile', additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var apkNamePrefix = additionalSettings['app'] as String?;
|
var apkNamePrefix = additionalSettings['app'] as String?;
|
||||||
if (apkNamePrefix == null) {
|
if (apkNamePrefix == null) {
|
||||||
|
@@ -20,7 +20,8 @@ class TelegramApp extends AppSource {
|
|||||||
String standardUrl,
|
String standardUrl,
|
||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
Response res = await sourceRequest('https://t.me/s/TAndroidAPK');
|
Response res =
|
||||||
|
await sourceRequest('https://t.me/s/TAndroidAPK', additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var http = parse(res.body);
|
var http = parse(res.body);
|
||||||
var messages =
|
var messages =
|
||||||
|
@@ -25,11 +25,13 @@ class Uptodown extends AppSource {
|
|||||||
@override
|
@override
|
||||||
Future<String?> tryInferringAppId(String standardUrl,
|
Future<String?> tryInferringAppId(String standardUrl,
|
||||||
{Map<String, dynamic> additionalSettings = const {}}) async {
|
{Map<String, dynamic> additionalSettings = const {}}) async {
|
||||||
return (await getAppDetailsFromPage(standardUrl))['appId'];
|
return (await getAppDetailsFromPage(
|
||||||
|
standardUrl, additionalSettings))['appId'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, String?>> getAppDetailsFromPage(String standardUrl) async {
|
Future<Map<String, String?>> getAppDetailsFromPage(
|
||||||
var res = await sourceRequest(standardUrl);
|
String standardUrl, Map<String, dynamic> additionalSettings) async {
|
||||||
|
var res = await sourceRequest(standardUrl, additionalSettings);
|
||||||
if (res.statusCode != 200) {
|
if (res.statusCode != 200) {
|
||||||
throw getObtainiumHttpError(res);
|
throw getObtainiumHttpError(res);
|
||||||
}
|
}
|
||||||
@@ -57,7 +59,8 @@ class Uptodown extends AppSource {
|
|||||||
String standardUrl,
|
String standardUrl,
|
||||||
Map<String, dynamic> additionalSettings,
|
Map<String, dynamic> additionalSettings,
|
||||||
) async {
|
) async {
|
||||||
var appDetails = await getAppDetailsFromPage(standardUrl);
|
var appDetails =
|
||||||
|
await getAppDetailsFromPage(standardUrl, additionalSettings);
|
||||||
var version = appDetails['version'];
|
var version = appDetails['version'];
|
||||||
var apkUrl = appDetails['apkUrl'];
|
var apkUrl = appDetails['apkUrl'];
|
||||||
var appId = appDetails['appId'];
|
var appId = appDetails['appId'];
|
||||||
@@ -83,9 +86,9 @@ class Uptodown extends AppSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<String> apkUrlPrefetchModifier(
|
Future<String> apkUrlPrefetchModifier(String apkUrl, String standardUrl,
|
||||||
String apkUrl, String standardUrl) async {
|
Map<String, dynamic> additionalSettings) async {
|
||||||
var res = await sourceRequest(apkUrl);
|
var res = await sourceRequest(apkUrl, additionalSettings);
|
||||||
if (res.statusCode != 200) {
|
if (res.statusCode != 200) {
|
||||||
throw getObtainiumHttpError(res);
|
throw getObtainiumHttpError(res);
|
||||||
}
|
}
|
||||||
|
@@ -12,8 +12,8 @@ class VLC extends AppSource {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Map<String, String>?> getRequestHeaders(
|
Future<Map<String, String>?> getRequestHeaders(
|
||||||
{Map<String, dynamic> additionalSettings = const <String, dynamic>{},
|
Map<String, dynamic> additionalSettings,
|
||||||
bool forAPKDownload = false}) async {
|
{bool forAPKDownload = false}) async {
|
||||||
return {
|
return {
|
||||||
"User-Agent":
|
"User-Agent":
|
||||||
"Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36"
|
"Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36"
|
||||||
@@ -25,8 +25,9 @@ class VLC extends AppSource {
|
|||||||
return 'https://${hosts[0]}';
|
return 'https://${hosts[0]}';
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLatestVersion(String standardUrl) async {
|
Future<String?> getLatestVersion(
|
||||||
Response res = await sourceRequest(dwUrlBase);
|
String standardUrl, Map<String, dynamic> additionalSettings) async {
|
||||||
|
Response res = await sourceRequest(dwUrlBase, additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var dwLinks = parse(res.body)
|
var dwLinks = parse(res.body)
|
||||||
.querySelectorAll('a')
|
.querySelectorAll('a')
|
||||||
@@ -78,9 +79,9 @@ class VLC extends AppSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<String> apkUrlPrefetchModifier(
|
Future<String> apkUrlPrefetchModifier(String apkUrl, String standardUrl,
|
||||||
String apkUrl, String standardUrl) async {
|
Map<String, dynamic> additionalSettings) async {
|
||||||
Response res = await sourceRequest(apkUrl);
|
Response res = await sourceRequest(apkUrl, additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
String? apkUrl =
|
String? apkUrl =
|
||||||
parse(res.body).querySelector('#alt_link')?.attributes['href'];
|
parse(res.body).querySelector('#alt_link')?.attributes['href'];
|
||||||
|
@@ -16,9 +16,10 @@ class WhatsApp extends AppSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<String> apkUrlPrefetchModifier(
|
Future<String> apkUrlPrefetchModifier(String apkUrl, String standardUrl,
|
||||||
String apkUrl, String standardUrl) async {
|
Map<String, dynamic> additionalSettings) async {
|
||||||
Response res = await sourceRequest('$standardUrl/android');
|
Response res =
|
||||||
|
await sourceRequest('$standardUrl/android', additionalSettings);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
var targetLinks = parse(res.body)
|
var targetLinks = parse(res.body)
|
||||||
.querySelectorAll('a')
|
.querySelectorAll('a')
|
||||||
@@ -42,8 +43,8 @@ class WhatsApp extends AppSource {
|
|||||||
) async {
|
) async {
|
||||||
// This is a CDN link that is consistent per version
|
// This is a CDN link that is consistent per version
|
||||||
// But it has query params that change constantly
|
// But it has query params that change constantly
|
||||||
Uri apkUri =
|
Uri apkUri = Uri.parse(await apkUrlPrefetchModifier(
|
||||||
Uri.parse(await apkUrlPrefetchModifier(standardUrl, standardUrl));
|
standardUrl, standardUrl, additionalSettings));
|
||||||
var unusableApkUrl = '${apkUri.origin}/${apkUri.path}';
|
var unusableApkUrl = '${apkUri.origin}/${apkUri.path}';
|
||||||
// So we use the param-less URL is a pseudo-version to add the app and check for updates
|
// So we use the param-less URL is a pseudo-version to add the app and check for updates
|
||||||
// See #357 for why we can't scrape the version number directly
|
// See #357 for why we can't scrape the version number directly
|
||||||
|
@@ -18,7 +18,7 @@ class GitHubStars implements MassAppUrlSource {
|
|||||||
Response res = await get(
|
Response res = await get(
|
||||||
Uri.parse(
|
Uri.parse(
|
||||||
'https://api.github.com/users/$username/starred?per_page=100&page=$page'),
|
'https://api.github.com/users/$username/starred?per_page=100&page=$page'),
|
||||||
headers: await GitHub().getRequestHeaders());
|
headers: await GitHub().getRequestHeaders({}));
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
Map<String, List<String>> urlsWithDescriptions = {};
|
Map<String, List<String>> urlsWithDescriptions = {};
|
||||||
for (var e in (jsonDecode(res.body) as List<dynamic>)) {
|
for (var e in (jsonDecode(res.body) as List<dynamic>)) {
|
||||||
|
@@ -326,13 +326,15 @@ class AppsProvider with ChangeNotifier {
|
|||||||
AppSource source = SourceProvider()
|
AppSource source = SourceProvider()
|
||||||
.getSource(app.url, overrideSource: app.overrideSource);
|
.getSource(app.url, overrideSource: app.overrideSource);
|
||||||
String downloadUrl = await source.apkUrlPrefetchModifier(
|
String downloadUrl = await source.apkUrlPrefetchModifier(
|
||||||
app.apkUrls[app.preferredApkIndex].value, app.url);
|
app.apkUrls[app.preferredApkIndex].value,
|
||||||
|
app.url,
|
||||||
|
app.additionalSettings);
|
||||||
var notif = DownloadNotification(app.finalName, 100);
|
var notif = DownloadNotification(app.finalName, 100);
|
||||||
notificationsProvider?.cancel(notif.id);
|
notificationsProvider?.cancel(notif.id);
|
||||||
int? prevProg;
|
int? prevProg;
|
||||||
var fileNameNoExt = '${app.id}-${downloadUrl.hashCode}';
|
var fileNameNoExt = '${app.id}-${downloadUrl.hashCode}';
|
||||||
var headers = await source.getRequestHeaders(
|
var headers = await source.getRequestHeaders(app.additionalSettings,
|
||||||
additionalSettings: app.additionalSettings, forAPKDownload: true);
|
forAPKDownload: true);
|
||||||
var downloadedFile = await downloadFileWithRetry(
|
var downloadedFile = await downloadFileWithRetry(
|
||||||
downloadUrl, fileNameNoExt,
|
downloadUrl, fileNameNoExt,
|
||||||
headers: headers, (double? progress) {
|
headers: headers, (double? progress) {
|
||||||
|
@@ -417,8 +417,8 @@ abstract class AppSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, String>?> getRequestHeaders(
|
Future<Map<String, String>?> getRequestHeaders(
|
||||||
{Map<String, dynamic> additionalSettings = const <String, dynamic>{},
|
Map<String, dynamic> additionalSettings,
|
||||||
bool forAPKDownload = false}) async {
|
{bool forAPKDownload = false}) async {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,12 +426,10 @@ abstract class AppSource {
|
|||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response> sourceRequest(String url,
|
Future<Response> sourceRequest(
|
||||||
{bool followRedirects = true,
|
String url, Map<String, dynamic> additionalSettings,
|
||||||
Map<String, dynamic> additionalSettings =
|
{bool followRedirects = true}) async {
|
||||||
const <String, dynamic>{}}) async {
|
var requestHeaders = await getRequestHeaders(additionalSettings);
|
||||||
var requestHeaders =
|
|
||||||
await getRequestHeaders(additionalSettings: additionalSettings);
|
|
||||||
if (requestHeaders != null || followRedirects == false) {
|
if (requestHeaders != null || followRedirects == false) {
|
||||||
var req = Request('GET', Uri.parse(url));
|
var req = Request('GET', Uri.parse(url));
|
||||||
req.followRedirects = followRedirects;
|
req.followRedirects = followRedirects;
|
||||||
@@ -548,8 +546,8 @@ abstract class AppSource {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> apkUrlPrefetchModifier(
|
Future<String> apkUrlPrefetchModifier(String apkUrl, String standardUrl,
|
||||||
String apkUrl, String standardUrl) async {
|
Map<String, dynamic> additionalSettings) async {
|
||||||
return apkUrl;
|
return apkUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user