mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-07-15 06:06:44 +02:00
Adds Source-specific options + other changes (#26)
* Started work on dynamic forms * dynamic form progress (switch doesn't work) * dynamic forms work * Gen. form improvements, source specific data (untested) * Gen form bugfix * Removed redundant generated modal code * Added custom validators to gen. forms * Progress on source options (incomplete), gen form bugfixes * Tweaks, more * More * Progress * Changed a default * Additional options done!
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:obtainium/components/generated_form.dart';
|
||||
import 'package:obtainium/providers/source_provider.dart';
|
||||
|
||||
class GitHub implements AppSource {
|
||||
@ -11,47 +12,68 @@ class GitHub implements AppSource {
|
||||
RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+');
|
||||
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
|
||||
if (match == null) {
|
||||
throw notValidURL;
|
||||
throw notValidURL(runtimeType.toString());
|
||||
}
|
||||
return url.substring(0, match.end);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<APKDetails> getLatestAPKDetails(String standardUrl) async {
|
||||
Future<APKDetails> getLatestAPKDetails(
|
||||
String standardUrl, List<String> additionalData) async {
|
||||
var includePrereleases =
|
||||
additionalData.isNotEmpty && additionalData[0] == "true";
|
||||
var fallbackToOlderReleases =
|
||||
additionalData.length >= 2 && additionalData[1] == "true";
|
||||
var regexFilter = additionalData.length >= 3 && additionalData[2].isNotEmpty
|
||||
? additionalData[2]
|
||||
: null;
|
||||
Response res = await get(Uri.parse(
|
||||
'https://api.$host/repos${standardUrl.substring('https://$host'.length)}/releases'));
|
||||
if (res.statusCode == 200) {
|
||||
var releases = jsonDecode(res.body) as List<dynamic>;
|
||||
// Right now, the latest non-prerelease version is picked
|
||||
// If none exists, the latest prerelease version is picked
|
||||
// In the future, the user could be given a choice
|
||||
var nonPrereleaseReleases =
|
||||
releases.where((element) => element['prerelease'] != true).toList();
|
||||
var latestRelease = nonPrereleaseReleases.isNotEmpty
|
||||
? nonPrereleaseReleases[0]
|
||||
: releases.isNotEmpty
|
||||
? releases[0]
|
||||
: null;
|
||||
if (latestRelease == null) {
|
||||
|
||||
List<String> getReleaseAPKUrls(dynamic release) =>
|
||||
(release['assets'] as List<dynamic>?)
|
||||
?.map((e) {
|
||||
return e['browser_download_url'] != null
|
||||
? e['browser_download_url'] as String
|
||||
: '';
|
||||
})
|
||||
.where((element) => element.toLowerCase().endsWith('.apk'))
|
||||
.toList() ??
|
||||
[];
|
||||
|
||||
dynamic targetRelease;
|
||||
|
||||
for (int i = 0; i < releases.length; i++) {
|
||||
if (!fallbackToOlderReleases && i > 0) break;
|
||||
if (!includePrereleases && releases[i]['prerelease'] == true) {
|
||||
continue;
|
||||
}
|
||||
if (regexFilter != null &&
|
||||
!RegExp(regexFilter)
|
||||
.hasMatch((releases[i]['name'] as String).trim())) {
|
||||
continue;
|
||||
}
|
||||
var apkUrls = getReleaseAPKUrls(releases[i]);
|
||||
if (apkUrls.isEmpty) {
|
||||
continue;
|
||||
}
|
||||
targetRelease = releases[i];
|
||||
targetRelease['apkUrls'] = apkUrls;
|
||||
break;
|
||||
}
|
||||
if (targetRelease == null) {
|
||||
throw couldNotFindReleases;
|
||||
}
|
||||
List<dynamic>? assets = latestRelease['assets'];
|
||||
List<String>? apkUrlList = assets
|
||||
?.map((e) {
|
||||
return e['browser_download_url'] != null
|
||||
? e['browser_download_url'] as String
|
||||
: '';
|
||||
})
|
||||
.where((element) => element.toLowerCase().endsWith('.apk'))
|
||||
.toList();
|
||||
if (apkUrlList == null || apkUrlList.isEmpty) {
|
||||
if ((targetRelease['apkUrls'] as List<String>).isEmpty) {
|
||||
throw noAPKFound;
|
||||
}
|
||||
String? version = latestRelease['tag_name'];
|
||||
String? version = targetRelease['tag_name'];
|
||||
if (version == null) {
|
||||
throw couldNotFindLatestVersion;
|
||||
}
|
||||
return APKDetails(version, apkUrlList);
|
||||
return APKDetails(version, targetRelease['apkUrls']);
|
||||
} else {
|
||||
if (res.headers['x-ratelimit-remaining'] == '0') {
|
||||
throw 'Rate limit reached - try again in ${(int.parse(res.headers['x-ratelimit-reset'] ?? '1800000000') / 60000000).toString()} minutes';
|
||||
@ -67,4 +89,34 @@ class GitHub implements AppSource {
|
||||
List<String> names = temp.substring(temp.indexOf('/') + 1).split('/');
|
||||
return AppNames(names[0], names[1]);
|
||||
}
|
||||
|
||||
@override
|
||||
List<List<GeneratedFormItem>> additionalDataFormItems = [
|
||||
[GeneratedFormItem(label: "Include prereleases", type: FormItemType.bool)],
|
||||
[
|
||||
GeneratedFormItem(
|
||||
label: "Fallback to older releases", type: FormItemType.bool)
|
||||
],
|
||||
[
|
||||
GeneratedFormItem(
|
||||
label: "Filter Release Titles by Regular Expression",
|
||||
type: FormItemType.string,
|
||||
required: false,
|
||||
additionalValidators: [
|
||||
(value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
RegExp(value);
|
||||
} catch (e) {
|
||||
return "Invalid regular expression";
|
||||
}
|
||||
}
|
||||
])
|
||||
]
|
||||
];
|
||||
|
||||
@override
|
||||
List<String> additionalDataDefaults = ["true", "true", ""];
|
||||
}
|
||||
|
Reference in New Issue
Block a user