Re-added APKMirror as a Track-Only source

This commit is contained in:
Imran Remtulla
2022-11-25 18:55:17 -05:00
parent b04d2fad5c
commit 25953399ac
3 changed files with 87 additions and 35 deletions

View File

@@ -0,0 +1,55 @@
import 'package:html/parser.dart';
import 'package:http/http.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart';
class APKMirror extends AppSource {
APKMirror() {
host = 'apkmirror.com';
enforceTrackOnly = true;
}
@override
String standardizeURL(String url) {
RegExp standardUrlRegEx = RegExp('^https?://$host/apk/[^/]+/[^/]+');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) {
throw InvalidURLError(runtimeType.toString());
}
return url.substring(0, match.end);
}
@override
String? changeLogPageFromStandardUrl(String standardUrl) =>
'$standardUrl/#whatsnew';
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl, List<String> additionalData) async {
Response res = await get(Uri.parse('$standardUrl/feed'));
if (res.statusCode == 200) {
String? titleString = parse(res.body)
.querySelector('item')
?.querySelector('title')
?.innerHtml;
String? version = titleString
?.substring(0,
RegExp(' build ( |[0-9])+').firstMatch(titleString)?.start ?? 0)
.split(' ')
.last;
if (version == null) {
throw NoVersionError();
}
return APKDetails(version, []);
} else {
throw NoReleasesError();
}
}
@override
AppNames getAppNames(String standardUrl) {
String temp = standardUrl.substring(standardUrl.indexOf('://') + 3);
List<String> names = temp.substring(temp.indexOf('/') + 1).split('/');
return AppNames(names[1], names[2]);
}
}

View File

@@ -143,7 +143,7 @@ class _AddAppPageState extends State<AddAppPage> {
(BuildContext ctx) {
return GeneratedFormModal(
title:
'App is Track-Only',
'${pickedSource!.enforceTrackOnly ? 'Source' : 'App'} is Track-Only',
items: const [],
defaultValues: const [],
message:
@@ -222,7 +222,11 @@ class _AddAppPageState extends State<AddAppPage> {
(pickedSource!.additionalSourceAppSpecificDefaults
.isNotEmpty ||
pickedSource!
.additionalAppSpecificSourceAgnosticDefaults
.additionalAppSpecificSourceAgnosticFormItems
.where((e) => pickedSource!.enforceTrackOnly
? e.key != 'trackOnlyFormItemKey'
: true)
.map((e) => [e])
.isNotEmpty))
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
@@ -257,33 +261,27 @@ class _AddAppPageState extends State<AddAppPage> {
},
defaultValues: pickedSource!
.additionalSourceAppSpecificDefaults),
if (pickedSource!
.additionalSourceAppSpecificFormItems
.isNotEmpty)
const SizedBox(
height: 8,
),
if (pickedSource!
.additionalAppSpecificSourceAgnosticFormItems
.isNotEmpty)
GeneratedForm(
items: pickedSource!
.additionalAppSpecificSourceAgnosticFormItems
.map((e) => [e])
.toList(),
onValueChanges: (values, valid, isBuilding) {
if (isBuilding) {
GeneratedForm(
items: pickedSource!
.additionalAppSpecificSourceAgnosticFormItems
.where((e) => pickedSource!.enforceTrackOnly
? e.key != 'trackOnlyFormItemKey'
: true)
.map((e) => [e])
.toList(),
onValueChanges: (values, valid, isBuilding) {
if (isBuilding) {
otherAdditionalData = values;
otherAdditionalDataIsValid = valid;
} else {
setState(() {
otherAdditionalData = values;
otherAdditionalDataIsValid = valid;
} else {
setState(() {
otherAdditionalData = values;
otherAdditionalDataIsValid = valid;
});
}
},
defaultValues: pickedSource!
.additionalAppSpecificSourceAgnosticDefaults),
});
}
},
defaultValues: pickedSource!
.additionalAppSpecificSourceAgnosticDefaults),
if (pickedSource!
.additionalAppSpecificSourceAgnosticDefaults
.isNotEmpty)
@@ -304,16 +302,15 @@ class _AddAppPageState extends State<AddAppPage> {
const SizedBox(
height: 8,
),
...sourceProvider
.getSourceHosts()
...sourceProvider.sources
.map((e) => GestureDetector(
onTap: () {
launchUrlString('https://$e',
launchUrlString('https://${e.host}',
mode:
LaunchMode.externalApplication);
},
child: Text(
e,
'${e.runtimeType.toString()}${e.enforceTrackOnly ? ' (Track-Only)' : ''}',
style: const TextStyle(
decoration:
TextDecoration.underline,

View File

@@ -5,6 +5,7 @@ import 'dart:convert';
import 'package:html/dom.dart';
import 'package:http/http.dart';
import 'package:obtainium/app_sources/apkmirror.dart';
import 'package:obtainium/app_sources/fdroid.dart';
import 'package:obtainium/app_sources/github.dart';
import 'package:obtainium/app_sources/gitlab.dart';
@@ -209,7 +210,8 @@ class SourceProvider {
IzzyOnDroid(),
Mullvad(),
Signal(),
SourceForge()
SourceForge(),
APKMirror()
];
// Add more mass url source classes here so they are available via the service
@@ -254,7 +256,7 @@ class SourceProvider {
return false;
}
}
return getSourceHosts().contains(parts.last);
return sources.map((e) => e.host).contains(parts.last);
}
Future<App> getApp(AppSource source, String url, List<String> additionalData,
@@ -306,6 +308,4 @@ class SourceProvider {
}
return [apps, errors];
}
List<String> getSourceHosts() => sources.map((e) => e.host).toList();
}