Minimum star count for GitHub/Codeberg search (#688)

This commit is contained in:
Imran Remtulla
2023-07-23 02:04:40 -04:00
parent 5cee527d6f
commit 41f102c0ce
18 changed files with 63 additions and 22 deletions

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Provjerite ima li novosti pri otvaranju stranice s detaljima aplikacije", "checkUpdateOnDetailPage": "Provjerite ima li novosti pri otvaranju stranice s detaljima aplikacije",
"disablePageTransitions": "Ugasite animaciju prijelaza stranice", "disablePageTransitions": "Ugasite animaciju prijelaza stranice",
"reversePageTransitions": "Reverzne animacije prijelaza stranice", "reversePageTransitions": "Reverzne animacije prijelaza stranice",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Želite li ukloniti aplikaciju?", "one": "Želite li ukloniti aplikaciju?",
"other": "Želite li ukloniti aplikacije?" "other": "Želite li ukloniti aplikacije?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "App entfernen?", "one": "App entfernen?",
"other": "Apps entfernen?" "other": "Apps entfernen?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Remove App?", "one": "Remove App?",
"other": "Remove Apps?" "other": "Remove Apps?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "¿Eliminar Aplicación?", "one": "¿Eliminar Aplicación?",
"other": "¿Eliminar Aplicaciones?" "other": "¿Eliminar Aplicaciones?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "برنامه حذف شود؟", "one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟" "other": "برنامه ها حذف شوند؟"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Supprimer l'application ?", "one": "Supprimer l'application ?",
"other": "Supprimer les applications ?" "other": "Supprimer les applications ?"

View File

@@ -238,6 +238,7 @@
"checkUpdateOnDetailPage": "Frissítések keresése az app részleteit tartalmazó oldal megnyitásakor", "checkUpdateOnDetailPage": "Frissítések keresése az app részleteit tartalmazó oldal megnyitásakor",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Eltávolítja az alkalmazást?", "one": "Eltávolítja az alkalmazást?",
"other": "Eltávolítja az alkalmazást?" "other": "Eltávolítja az alkalmazást?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Rimuovere l'app?", "one": "Rimuovere l'app?",
"other": "Rimuovere le app?" "other": "Rimuovere le app?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "アプリの詳細ページを開く際にアップデートを確認する", "checkUpdateOnDetailPage": "アプリの詳細ページを開く際にアップデートを確認する",
"disablePageTransitions": "ページ遷移アニメーションを無効化する", "disablePageTransitions": "ページ遷移アニメーションを無効化する",
"reversePageTransitions": "ページ遷移アニメーションを反転する", "reversePageTransitions": "ページ遷移アニメーションを反転する",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "アプリを削除しますか?", "one": "アプリを削除しますか?",
"other": "アプリを削除しますか?" "other": "アプリを削除しますか?"

View File

@@ -243,6 +243,7 @@
"checkUpdateOnDetailPage": "Sprawdzaj aktualizacje podczas otwierania strony szczegółów aplikacji", "checkUpdateOnDetailPage": "Sprawdzaj aktualizacje podczas otwierania strony szczegółów aplikacji",
"disablePageTransitions": "Wyłącz animacje przejścia między stronami", "disablePageTransitions": "Wyłącz animacje przejścia między stronami",
"reversePageTransitions": "Odwróć animacje przejścia pomiędzy stronami", "reversePageTransitions": "Odwróć animacje przejścia pomiędzy stronami",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Usunąć aplikację?", "one": "Usunąć aplikację?",
"other": "Usunąć aplikacje?" "other": "Usunąć aplikacje?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Проверять наличие обновлений при открытии страницы представления приложения", "checkUpdateOnDetailPage": "Проверять наличие обновлений при открытии страницы представления приложения",
"disablePageTransitions": "Отключить анимацию перехода между страницами", "disablePageTransitions": "Отключить анимацию перехода между страницами",
"reversePageTransitions": "Реверс анимации перехода между страницами", "reversePageTransitions": "Реверс анимации перехода между страницами",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Удалить приложение?", "one": "Удалить приложение?",
"other": "Удалить приложения?" "other": "Удалить приложения?"

View File

@@ -239,6 +239,7 @@
"checkUpdateOnDetailPage": "Check for updates on opening an App detail page", "checkUpdateOnDetailPage": "Check for updates on opening an App detail page",
"disablePageTransitions": "Disable page transition animations", "disablePageTransitions": "Disable page transition animations",
"reversePageTransitions": "Reverse page transition animations", "reversePageTransitions": "Reverse page transition animations",
"minStarCount": "Minimum Star Count",
"removeAppQuestion": { "removeAppQuestion": {
"one": "是否删除应用?", "one": "是否删除应用?",
"other": "是否删除应用?" "other": "是否删除应用?"

View File

@@ -5,6 +5,7 @@ import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/source_provider.dart'; import 'package:obtainium/providers/source_provider.dart';
class Codeberg extends AppSource { class Codeberg extends AppSource {
GitHub gh = GitHub();
Codeberg() { Codeberg() {
host = 'codeberg.org'; host = 'codeberg.org';
@@ -32,10 +33,9 @@ class Codeberg extends AppSource {
]; ];
canSearch = true; canSearch = true;
searchQuerySettingFormItems = gh.searchQuerySettingFormItems;
} }
var gh = GitHub();
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+'); RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+');
@@ -68,10 +68,12 @@ class Codeberg extends AppSource {
} }
@override @override
Future<Map<String, List<String>>> search(String query) async { Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) async {
return gh.searchCommon( return gh.searchCommon(
query, query,
'https://$host/api/v1/repos/search?q=${Uri.encodeQueryComponent(query)}&limit=100', 'https://$host/api/v1/repos/search?q=${Uri.encodeQueryComponent(query)}&limit=100',
'data'); 'data',
querySettings: querySettings);
} }
} }

View File

@@ -72,7 +72,8 @@ class FDroid extends AppSource {
} }
@override @override
Future<Map<String, List<String>>> search(String query) async { Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) async {
Response res = await sourceRequest( Response res = await sourceRequest(
'https://search.$host/?q=${Uri.encodeQueryComponent(query)}'); 'https://search.$host/?q=${Uri.encodeQueryComponent(query)}');
if (res.statusCode == 200) { if (res.statusCode == 200) {

View File

@@ -79,6 +79,21 @@ class GitHub extends AppSource {
]; ];
canSearch = true; canSearch = true;
searchQuerySettingFormItems = [
GeneratedFormTextField('minStarCount',
label: tr('minStarCount'),
defaultValue: '0',
additionalValidators: [
(value) {
try {
int.parse(value ?? '0');
} catch (e) {
return tr('invalidInput');
}
return null;
}
])
];
} }
@override @override
@@ -310,20 +325,26 @@ class GitHub extends AppSource {
Future<Map<String, List<String>>> searchCommon( Future<Map<String, List<String>>> searchCommon(
String query, String requestUrl, String rootProp, String query, String requestUrl, String rootProp,
{Function(Response)? onHttpErrorCode}) async { {Function(Response)? onHttpErrorCode,
Map<String, dynamic> querySettings = const {}}) async {
Response res = await sourceRequest(requestUrl); Response res = await sourceRequest(requestUrl);
if (res.statusCode == 200) { if (res.statusCode == 200) {
int minStarCount = querySettings['minStarCount'] != null
? int.parse(querySettings['minStarCount'])
: 0;
Map<String, List<String>> urlsWithDescriptions = {}; Map<String, List<String>> urlsWithDescriptions = {};
for (var e in (jsonDecode(res.body)[rootProp] as List<dynamic>)) { for (var e in (jsonDecode(res.body)[rootProp] as List<dynamic>)) {
urlsWithDescriptions.addAll({ if ((e['stargazers_count'] ?? e['stars_count'] ?? 0) >= minStarCount) {
e['html_url'] as String: [ urlsWithDescriptions.addAll({
e['full_name'] as String, e['html_url'] as String: [
((e['archived'] == true ? '[ARCHIVED] ' : '') + e['full_name'] as String,
(e['description'] != null ((e['archived'] == true ? '[ARCHIVED] ' : '') +
? e['description'] as String (e['description'] != null
: tr('noDescription'))) ? e['description'] as String
] : tr('noDescription')))
}); ]
});
}
} }
return urlsWithDescriptions; return urlsWithDescriptions;
} else { } else {
@@ -335,13 +356,14 @@ class GitHub extends AppSource {
} }
@override @override
Future<Map<String, List<String>>> search(String query) async { Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) async {
return searchCommon( return searchCommon(
query, query,
'${await getAPIHost()}/search/repositories?q=${Uri.encodeQueryComponent(query)}&per_page=100', '${await getAPIHost()}/search/repositories?q=${Uri.encodeQueryComponent(query)}&per_page=100',
'items', onHttpErrorCode: (Response res) { 'items', onHttpErrorCode: (Response res) {
rateLimitErrorCheck(res); rateLimitErrorCheck(res);
}); }, querySettings: querySettings);
} }
rateLimitErrorCheck(Response res) { rateLimitErrorCheck(Response res) {

View File

@@ -69,7 +69,8 @@ class GitLab extends AppSource {
} }
@override @override
Future<Map<String, List<String>>> search(String query) async { Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) async {
String? PAT = await getPATIfAny(); String? PAT = await getPATIfAny();
if (PAT == null) { if (PAT == null) {
throw CredsNeededError(name); throw CredsNeededError(name);

View File

@@ -182,7 +182,8 @@ class _ImportExportPageState extends State<ImportExportPage> {
[ [
GeneratedFormTextField('searchQuery', GeneratedFormTextField('searchQuery',
label: tr('searchQuery')) label: tr('searchQuery'))
] ],
...source.searchQuerySettingFormItems.map((e) => [e])
], ],
); );
}); });
@@ -191,8 +192,8 @@ class _ImportExportPageState extends State<ImportExportPage> {
setState(() { setState(() {
importInProgress = true; importInProgress = true;
}); });
var urlsWithDescriptions = var urlsWithDescriptions = await source
await source.search(values['searchQuery'] as String); .search(values['searchQuery'] as String, querySettings: values);
if (urlsWithDescriptions.isNotEmpty) { if (urlsWithDescriptions.isNotEmpty) {
var selectedUrls = var selectedUrls =
// ignore: use_build_context_synchronously // ignore: use_build_context_synchronously

View File

@@ -436,7 +436,9 @@ abstract class AppSource {
} }
bool canSearch = false; bool canSearch = false;
Future<Map<String, List<String>>> search(String query) { List<GeneratedFormItem> searchQuerySettingFormItems = [];
Future<Map<String, List<String>>> search(String query,
{Map<String, dynamic> querySettings = const {}}) {
throw NotImplementedError(); throw NotImplementedError();
} }