Skip to content

Commit

Permalink
FIXED GITHUB ISSUE
Browse files Browse the repository at this point in the history
  • Loading branch information
Imran Remtulla committed Sep 14, 2022
1 parent 52b9766 commit 294327b
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 43 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Currently supported App sources:
## Limitations
- App installs are assumed to have succeeded; failures and cancelled installs cannot be detected.
- Auto (unattended) updates are unsupported due to a lack of any capable Flutter plugin.
- For some sources, data is gathered using Web scraping and can easily break due to changes in website design. In such cases, more reliable methods are either unavailable (e.g. Mullvad), insufficient (e.g. GitHub RSS) or subject to rate limits (e.g. GitHub API).
- For some sources, data is gathered using Web scraping and can easily break due to changes in website design. In such cases, more reliable methods may be unavailable.

## Screenshots

Expand Down
2 changes: 1 addition & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import 'package:dynamic_color/dynamic_color.dart';
import 'package:device_info_plus/device_info_plus.dart';

const String currentReleaseTag =
'v0.1.8-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES
'v0.1.9-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES

@pragma('vm:entry-point')
void bgTaskCallback() {
Expand Down
95 changes: 55 additions & 40 deletions lib/providers/source_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ escapeRegEx(String s) {
});
}

const String couldNotFindReleases = 'Unable to fetch release info';
const String couldNotFindLatestVersion =
'Could not determine latest release version';
const String notValidURL = 'Not a valid URL';
const String noAPKFound = 'No APK found';

List<String> getLinksFromParsedHTML(
Document dom, RegExp hrefPattern, String prependToLinks) =>
dom
Expand Down Expand Up @@ -98,44 +104,53 @@ class GitHub implements AppSource {
RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) {
throw 'Not a valid URL';
throw notValidURL;
}
return url.substring(0, match.end);
}

@override
Future<APKDetails> getLatestAPKDetails(String standardUrl) async {
Response res = await get(Uri.parse('$standardUrl/releases/latest'));
Response res = await get(Uri.parse(
'https://api.$host/repos${standardUrl.substring('https://$host'.length)}/releases'));
if (res.statusCode == 200) {
var standardUri = Uri.parse(standardUrl);
var parsedHtml = parse(res.body);
var apkUrlList = getLinksFromParsedHTML(
parsedHtml,
RegExp(
'^${escapeRegEx(standardUri.path)}/releases/download/[^/]+/[^/]+\\.apk\$',
caseSensitive: false),
standardUri.origin);
if (apkUrlList.isEmpty) {
throw 'No APK found';
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) {
throw couldNotFindReleases;
}
String getTag(String url) {
List<String> parts = url.split('/');
return parts[parts.length - 2];
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) {
throw noAPKFound;
}

String latestTag = getTag(apkUrlList[0]);
String? version = parsedHtml
.querySelector('.octicon-tag')
?.nextElementSibling
?.innerHtml
.trim();
String? version = latestRelease['tag_name'];
if (version == null) {
throw 'Could not determine latest release version';
throw couldNotFindLatestVersion;
}
return APKDetails(version,
apkUrlList.where((element) => getTag(element) == latestTag).toList());
return APKDetails(version, apkUrlList);
} else {
throw 'Unable to fetch release info';
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';
}

throw couldNotFindReleases;
}
}

Expand All @@ -156,7 +171,7 @@ class GitLab implements AppSource {
RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) {
throw 'Not a valid URL';
throw notValidURL;
}
return url.substring(0, match.end);
}
Expand Down Expand Up @@ -184,18 +199,18 @@ class GitLab implements AppSource {
.toList()
];
if (apkUrlList.isEmpty) {
throw 'No APK found';
throw noAPKFound;
}

var entryId = entry?.querySelector('id')?.innerHtml;
var version =
entryId == null ? null : Uri.parse(entryId).pathSegments.last;
if (version == null) {
throw 'Could not determine latest release version';
throw couldNotFindLatestVersion;
}
return APKDetails(version, apkUrlList);
} else {
throw 'Unable to fetch release info';
throw couldNotFindReleases;
}
}

Expand Down Expand Up @@ -223,15 +238,15 @@ class Signal implements AppSource {
var json = jsonDecode(res.body);
String? apkUrl = json['url'];
if (apkUrl == null) {
throw 'No APK found';
throw noAPKFound;
}
String? version = json['versionName'];
if (version == null) {
throw 'Could not determine latest release version';
throw couldNotFindLatestVersion;
}
return APKDetails(version, [apkUrl]);
} else {
throw 'Unable to fetch release info';
throw couldNotFindReleases;
}
}

Expand All @@ -248,7 +263,7 @@ class FDroid implements AppSource {
RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/packages/[^/]+');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) {
throw 'Not a valid URL';
throw notValidURL;
}
return url.substring(0, match.end);
}
Expand All @@ -263,19 +278,19 @@ class FDroid implements AppSource {
?.querySelector('.package-version-download a')
?.attributes['href'];
if (apkUrl == null) {
throw 'No APK found';
throw noAPKFound;
}
var version = latestReleaseDiv
?.querySelector('.package-version-header b')
?.innerHtml
.split(' ')
.last;
if (version == null) {
throw 'Could not determine latest release version';
throw couldNotFindLatestVersion;
}
return APKDetails(version, [apkUrl]);
} else {
throw 'Unable to fetch release info';
throw couldNotFindReleases;
}
}

Expand All @@ -295,7 +310,7 @@ class Mullvad implements AppSource {
RegExp standardUrlRegEx = RegExp('^https?://$host');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) {
throw 'Not a valid URL';
throw notValidURL;
}
return url.substring(0, match.end);
}
Expand All @@ -311,12 +326,12 @@ class Mullvad implements AppSource {
?.split('/')
.last;
if (version == null) {
throw 'Could not determine the latest release version';
throw couldNotFindLatestVersion;
}
return APKDetails(
version, ['https://mullvad.net/download/app/apk/latest']);
} else {
throw 'Unable to fetch release info';
throw couldNotFindReleases;
}
}

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 0.1.8+9 # When changing this, update the tag in main() accordingly
version: 0.1.9+10 # When changing this, update the tag in main() accordingly

environment:
sdk: '>=2.19.0-79.0.dev <3.0.0'
Expand Down

0 comments on commit 294327b

Please sign in to comment.