Add Tencent App Store (#1848)

This commit is contained in:
Imran Remtulla
2024-09-27 18:28:37 -04:00
parent 1fcb923469
commit 5d72af5b20
3 changed files with 90 additions and 3 deletions

View File

@ -26,6 +26,7 @@ Currently supported App sources:
- [Aptoide](https://aptoide.com/)
- [Uptodown](https://uptodown.com/)
- [Huawei AppGallery](https://appgallery.huawei.com/)
- [Tencent App Store](https://sj.qq.com/)
- Jenkins Jobs
- [APKMirror](https://apkmirror.com/) (Track-Only)
- Open Source - App-Specific:

View File

@ -0,0 +1,78 @@
import 'dart:convert';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart';
class Tencent extends AppSource {
Tencent() {
name = 'Tencent App Store';
hosts = ['sj.qq.com'];
naiveStandardVersionDetection = true;
showReleaseDateAsVersionToggle = true;
}
@override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
RegExp standardUrlRegEx = RegExp(
'^https?://${getSourceRegex(hosts)}/appdetail/[^/]+',
caseSensitive: false);
var match = standardUrlRegEx.firstMatch(url);
if (match == null) {
throw InvalidURLError(name);
}
return match.group(0)!;
}
@override
Future<String?> tryInferringAppId(String standardUrl,
{Map<String, dynamic> additionalSettings = const {}}) async {
return Uri.parse(standardUrl).pathSegments.last;
}
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl,
Map<String, dynamic> additionalSettings,
) async {
String appId = (await tryInferringAppId(standardUrl))!;
String baseHost = Uri.parse(standardUrl)
.host
.split('.')
.reversed
.toList()
.sublist(0, 2)
.reversed
.join('.');
var res = await sourceRequest(
'https://upage.html5.$baseHost/wechat-apkinfo', additionalSettings,
followRedirects: false, postBody: {"packagename": appId});
if (res.statusCode == 200) {
var json = jsonDecode(res.body);
if (json['app_detail_records'][appId] == null) {
throw NoReleasesError();
}
var version =
json['app_detail_records'][appId]['apk_all_data']['version_name'];
var apkUrl = json['app_detail_records'][appId]['apk_all_data']['url'];
if (apkUrl == null) {
throw NoAPKError();
}
var appName = json['app_detail_records'][appId]['app_info']['name'];
var author = json['app_detail_records'][appId]['app_info']['author'];
var releaseDate =
json['app_detail_records'][appId]['app_info']['update_time'];
return APKDetails(
version,
[MapEntry(Uri.parse(apkUrl).queryParameters['fsname']!, apkUrl)],
AppNames(author, appName),
releaseDate: releaseDate != null
? DateTime.fromMillisecondsSinceEpoch(releaseDate * 1000)
: null);
} else {
throw getObtainiumHttpError(res);
}
}
}

View File

@ -28,6 +28,7 @@ import 'package:obtainium/app_sources/sourceforge.dart';
import 'package:obtainium/app_sources/sourcehut.dart';
import 'package:obtainium/app_sources/steammobile.dart';
import 'package:obtainium/app_sources/telegramapp.dart';
import 'package:obtainium/app_sources/tencent.dart';
import 'package:obtainium/app_sources/uptodown.dart';
import 'package:obtainium/app_sources/vlc.dart';
import 'package:obtainium/app_sources/whatsapp.dart';
@ -465,19 +466,25 @@ abstract class AppSource {
Future<Response> sourceRequest(
String url, Map<String, dynamic> additionalSettings,
{bool followRedirects = true}) async {
{bool followRedirects = true, Object? postBody}) async {
var requestHeaders = await getRequestHeaders(additionalSettings);
if (requestHeaders != null || followRedirects == false) {
var req = Request('GET', Uri.parse(url));
var req = Request(postBody == null ? 'GET' : 'POST', Uri.parse(url));
req.followRedirects = followRedirects;
if (requestHeaders != null) {
req.headers.addAll(requestHeaders);
}
if (postBody != null) {
req.headers[HttpHeaders.contentTypeHeader] = 'application/json';
req.body = jsonEncode(postBody);
}
return Response.fromStream(await IOClient(
createHttpClient(additionalSettings['allowInsecure'] == true))
.send(req));
} else {
return get(Uri.parse(url));
return postBody == null
? get(Uri.parse(url))
: post(Uri.parse(url), body: jsonEncode(postBody));
}
}
@ -782,6 +789,7 @@ class SourceProvider {
Aptoide(),
Uptodown(),
HuaweiAppGallery(),
Tencent(),
Jenkins(),
APKMirror(),
Signal(),