mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-08-11 01:20:16 +02:00
Re-added APKMirror as a Track-Only source
This commit is contained in:
55
lib/app_sources/apkmirror.dart
Normal file
55
lib/app_sources/apkmirror.dart
Normal 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]);
|
||||
}
|
||||
}
|
@@ -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,
|
||||
|
@@ -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();
|
||||
}
|
||||
|
Reference in New Issue
Block a user