import 'package:html/parser.dart'; import 'package:http/http.dart'; import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/providers/source_provider.dart'; class WhatsApp extends AppSource { WhatsApp() { host = 'whatsapp.com'; } @override String sourceSpecificStandardizeURL(String url) { return 'https://$host'; } @override Future apkUrlPrefetchModifier( String apkUrl, String standardUrl) async { Response res = await sourceRequest('https://www.whatsapp.com/android'); if (res.statusCode == 200) { var targetLinks = parse(res.body) .querySelectorAll('a') .map((e) => e.attributes['href'] ?? '') .where((e) => e.isNotEmpty) .where((e) => e.contains('content.whatsapp.net') && e.contains('WhatsApp.apk')) .toList(); if (targetLinks.isEmpty) { throw NoAPKError(); } return targetLinks[0]; } else { throw getObtainiumHttpError(res); } } @override Future getLatestAPKDetails( String standardUrl, Map additionalSettings, ) async { Response res = await sourceRequest('https://www.whatsapp.com/android'); if (res.statusCode == 200) { var targetElements = parse(res.body) .querySelectorAll('p') .where((element) => element.innerHtml.contains('Version ')) .toList(); if (targetElements.isEmpty) { throw NoVersionError(); } var vLines = targetElements[0] .innerHtml .split('\n') .where((element) => element.contains('Version ')) .toList(); if (vLines.isEmpty) { throw NoVersionError(); } var versionMatch = RegExp('[0-9]+(\\.[0-9]+)+').firstMatch(vLines[0]); if (versionMatch == null) { throw NoVersionError(); } String version = vLines[0].substring(versionMatch.start, versionMatch.end); return APKDetails( version, getApkUrlsFromUrls([ 'https://www.whatsapp.com/android?v=$version&=thisIsaPlaceholder&a=realURLPrefetchedAtDownloadTime' ]), AppNames('Meta', 'WhatsApp')); } else { throw getObtainiumHttpError(res); } } }