diff --git a/README.md b/README.md index 3766352..107e70f 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Currently supported App sources: - Any URLs ending with `/fdroid/`, where `` can be anything - most often `repo` - [Steam](https://store.steampowered.com/mobile) - [Telegram App](https://telegram.org) +- [VLC](https://www.videolan.org/vlc/download-android.html) - [Neutron Code](https://neutroncode.com) - "HTML" (Fallback) - Any other URL that returns an HTML page with links to APK files (if multiple, the last file alphabetically is picked) diff --git a/lib/app_sources/vlc.dart b/lib/app_sources/vlc.dart new file mode 100644 index 0000000..e4678d7 --- /dev/null +++ b/lib/app_sources/vlc.dart @@ -0,0 +1,62 @@ +import 'package:html/parser.dart'; +import 'package:http/http.dart'; +import 'package:obtainium/app_sources/html.dart'; +import 'package:obtainium/custom_errors.dart'; +import 'package:obtainium/providers/source_provider.dart'; + +class VLC extends AppSource { + VLC() { + host = 'videolan.org'; + } + + @override + String standardizeURL(String url) { + return 'https://$host'; + } + + @override + Future getLatestAPKDetails( + String standardUrl, + Map additionalSettings, + ) async { + Response res = await get( + Uri.parse('https://www.videolan.org/vlc/download-android.html')); + if (res.statusCode == 200) { + var dwUrlBase = 'get.videolan.org/vlc-android'; + var dwLinks = parse(res.body) + .querySelectorAll('a') + .where((element) => + element.attributes['href']?.contains(dwUrlBase) ?? false) + .toList(); + String? version = dwLinks.isNotEmpty + ? dwLinks.first.attributes['href'] + ?.split('/') + .where((s) => s.isNotEmpty) + .last + : null; + if (version == null) { + throw NoVersionError(); + } + String? targetUrl = 'https://$dwUrlBase/$version/'; + Response res2 = await get(Uri.parse(targetUrl)); + String mirrorDwBase = + 'https://plug-mirror.rcac.purdue.edu/vlc/vlc-android/$version/'; + List apkUrls = []; + if (res2.statusCode == 200) { + apkUrls = parse(res2.body) + .querySelectorAll('a') + .map((e) => e.attributes['href']) + .where((h) => + h != null && h.isNotEmpty && h.toLowerCase().endsWith('.apk')) + .map((e) => mirrorDwBase + e!) + .toList(); + } else { + throw getObtainiumHttpError(res2); + } + + return APKDetails(version, apkUrls, AppNames('VideoLAN', 'VLC')); + } else { + throw getObtainiumHttpError(res); + } + } +} diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index fd4254d..1b19c19 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -20,6 +20,7 @@ import 'package:obtainium/app_sources/signal.dart'; import 'package:obtainium/app_sources/sourceforge.dart'; import 'package:obtainium/app_sources/steammobile.dart'; import 'package:obtainium/app_sources/telegramapp.dart'; +import 'package:obtainium/app_sources/vlc.dart'; import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/mass_app_sources/githubstars.dart'; @@ -348,6 +349,7 @@ class SourceProvider { FDroidRepo(), SteamMobile(), TelegramApp(), + VLC(), NeutronCode(), HTML() // This should ALWAYS be the last option as they are tried in order ];