Third party GitLab search (#1108)

This commit is contained in:
Imran Remtulla
2023-11-24 18:58:10 -05:00
parent 93036c4e67
commit 756763fcbe
3 changed files with 47 additions and 15 deletions

View File

@@ -54,17 +54,25 @@ class FDroidRepo extends AppSource {
@override @override
Future<Map<String, List<String>>> search(String query, Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) async { {Map<String, dynamic> querySettings = const {}}) async {
query = removeQueryParamsFromUrl(standardizeUrl(query)); String? url = querySettings['url'];
var res = await sourceRequest('$query/index.xml'); if (url == null) {
throw NoReleasesError();
}
url = removeQueryParamsFromUrl(standardizeUrl(url));
var res = await sourceRequest('$url/index.xml');
if (res.statusCode == 200) { if (res.statusCode == 200) {
var body = parse(res.body); var body = parse(res.body);
Map<String, List<String>> results = {}; Map<String, List<String>> results = {};
body.querySelectorAll('application').toList().forEach((app) { body.querySelectorAll('application').toList().forEach((app) {
String appId = app.attributes['id']!; String appId = app.attributes['id']!;
results['$query?appId=$appId'] = [ String appName = app.querySelector('name')?.innerHtml ?? appId;
app.querySelector('name')?.innerHtml ?? appId, String appDesc = app.querySelector('desc')?.innerHtml ?? '';
app.querySelector('desc')?.innerHtml ?? '' if (query.isEmpty ||
]; appId.contains(query) ||
appName.contains(query) ||
appDesc.contains(query)) {
results['$url?appId=$appId'] = [appName, appDesc];
}
}); });
return results; return results;
} else { } else {

View File

@@ -48,6 +48,12 @@ class GitLab extends AppSource {
label: tr('fallbackToOlderReleases'), defaultValue: true) label: tr('fallbackToOlderReleases'), defaultValue: true)
] ]
]; ];
searchQuerySettingFormItems = [
GeneratedFormTextField('PAT',
label: tr('gitlabPATLabel').split('(')[0],
password: true,
required: false)
];
} }
@override @override
@@ -80,12 +86,18 @@ class GitLab extends AppSource {
@override @override
Future<Map<String, List<String>>> search(String query, Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) async { {Map<String, dynamic> querySettings = const {}}) async {
String? PAT = await getPATIfAny({}); String? PAT;
if (PAT == null) { if (!hostChanged) {
throw CredsNeededError(name); PAT = await getPATIfAny({});
if (PAT == null) {
throw CredsNeededError(name);
}
}
if ((querySettings['PAT'] as String?)?.isNotEmpty == true) {
PAT = querySettings['PAT'];
} }
var url = var url =
'https://$host/api/v4/search?private_token=$PAT&scope=projects&search=${Uri.encodeQueryComponent(query)}'; 'https://$host/api/v4/search?${PAT?.isNotEmpty == true ? 'private_token=$PAT&' : ''}scope=projects&search=${Uri.encodeQueryComponent(query)}';
var res = await sourceRequest(url); var res = await sourceRequest(url);
if (res.statusCode != 200) { if (res.statusCode != 200) {
throw getObtainiumHttpError(res); throw getObtainiumHttpError(res);
@@ -174,7 +186,6 @@ class GitLab extends AppSource {
...getLinksFromParsedHTML(entryContent, ...getLinksFromParsedHTML(entryContent,
RegExp('/[^/]+\\.apk\$', caseSensitive: false), '') RegExp('/[^/]+\\.apk\$', caseSensitive: false), '')
.where((element) => Uri.parse(element).host != '') .where((element) => Uri.parse(element).host != '')
]; ];
var entryId = entry.querySelector('id')?.innerHtml; var entryId = entry.querySelector('id')?.innerHtml;
var version = var version =

View File

@@ -4,6 +4,7 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:obtainium/app_sources/fdroidrepo.dart';
import 'package:obtainium/components/custom_app_bar.dart'; import 'package:obtainium/components/custom_app_bar.dart';
import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/components/generated_form_modal.dart'; import 'package:obtainium/components/generated_form_modal.dart';
@@ -189,17 +190,29 @@ class _ImportExportPageState extends State<ImportExportPage> {
items: [ items: [
[ [
GeneratedFormTextField('searchQuery', GeneratedFormTextField('searchQuery',
label: tr('searchQuery')) label: tr('searchQuery'),
required: source.name != FDroidRepo().name)
],
...source.searchQuerySettingFormItems.map((e) => [e]),
[
GeneratedFormTextField('url',
label: source.host != null
? tr('overrideSource')
: plural('url', 1).substring(2),
defaultValue: source.host ?? '',
required: true)
], ],
...source.searchQuerySettingFormItems.map((e) => [e])
], ],
); );
}); });
if (values != null && if (values != null) {
(values['searchQuery'] as String?)?.isNotEmpty == true) {
setState(() { setState(() {
importInProgress = true; importInProgress = true;
}); });
if (values['url'] != source.host) {
source = sourceProvider.getSource(values['url'],
overrideSource: source.runtimeType.toString());
}
var urlsWithDescriptions = await source var urlsWithDescriptions = await source
.search(values['searchQuery'] as String, querySettings: values); .search(values['searchQuery'] as String, querySettings: values);
if (urlsWithDescriptions.isNotEmpty) { if (urlsWithDescriptions.isNotEmpty) {