Newer
Older
* Copyright (C) 2019 Guillaume Benoit <guillaume@manjaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a get of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Pamac {
public class Database: Object {
class AURUpdates {
public List<AURPackage> updates;
public List<AURPackage> outofdate;
public AURUpdates (owned List<AURPackage> updates, owned List<AURPackage> outofdate) {
this.updates = (owned) updates;
this.outofdate = (owned) outofdate;
}
}
AlpmConfig alpm_config;
Alpm.Handle? alpm_handle;
Alpm.Handle? files_handle;
MainLoop loop;
AUR aur;
As.Store app_store;
string locale;
public Config config { get; construct set; }
public Database (Config config) {
Object (config: config);
}
construct {
// init appstream
app_store = new As.Store ();
app_store.set_add_flags (As.StoreAddFlags.USE_UNIQUE_ID
| As.StoreAddFlags.ONLY_NATIVE_LANGS
| As.StoreAddFlags.USE_MERGE_HEURISTIC);
locale = Environ.get_variable (Environ.get (), "LANG");
if (locale != null) {
// remove .UTF-8 from locale
locale = locale.split (".")[0];
} else {
locale = "C";
}
// load alpm databases in memory
unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache;
unowned Alpm.List<unowned Alpm.Group> groupcache = alpm_handle.localdb.groupcache;
unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
pkgcache = db.pkgcache;
groupcache = db.groupcache;
syncdbs.next ();
}
#if ENABLE_SNAP
// load snap plugin
if (config.support_snap) {
snap_plugin = config.get_snap_plugin ();
try {
app_store.load (As.StoreLoadFlags.APP_INFO_SYSTEM);
app_store.set_search_match (As.AppSearchMatch.PKGNAME
| As.AppSearchMatch.DESCRIPTION
| As.AppSearchMatch.NAME
| As.AppSearchMatch.KEYWORD);
} catch (Error e) {
alpm_config = new AlpmConfig ("/etc/pacman.conf");
alpm_handle = alpm_config.get_handle ();
if (alpm_handle == null) {
critical (dgettext (null, "Failed to initialize alpm library"));
return;
} else {
files_handle = alpm_config.get_handle (true);
}
public List<string> get_mirrors_countries () {
var countries = new List<string> ();
string countries_str;
int status;
Process.spawn_command_line_sync ("pacman-mirrors -l",
out countries_str,
null,
out status);
if (status == 0) {
foreach (unowned string country in countries_str.split ("\n")) {
if (country != "") {
countries.append (country);
}
}
}
} catch (SpawnError e) {
}
return countries;
}
public string get_mirrors_choosen_country () {
string country = "";
try {
string countries_str;
int status;
Process.spawn_command_line_sync ("pacman-mirrors -lc",
out countries_str,
null,
out status);
if (status == 0) {
// only take first country
country = countries_str.split ("\n", 2)[0];
}
} catch (SpawnError e) {
public string get_alpm_dep_name (string dep_string) {
return Alpm.Depend.from_string (dep_string).name;
}
public CompareFunc<string> vercmp = Alpm.pkg_vercmp;
var filenames_size = new HashTable<string, int64?> (str_hash, str_equal);
var pkg_version_filenames = new HashTable<string, SList<string>> (str_hash, str_equal);
var pkg_versions = new HashTable<string, SList<string>> (str_hash, str_equal);
// compute all infos
unowned Alpm.List<unowned string> cachedirs_names = alpm_handle.cachedirs;
while (cachedirs_names != null) {
unowned string cachedir_name = cachedirs_names.data;
var cachedir = File.new_for_path (cachedir_name);
try {
FileEnumerator enumerator = cachedir.enumerate_children ("standard::*", FileQueryInfoFlags.NONE);
FileInfo info;
while ((info = enumerator.next_file (null)) != null) {
unowned string filename = info.get_name ();
string absolute_filename = "%s%s".printf (cachedir_name, filename);
string name_version_release = filename.slice (0, filename.last_index_of_char ('-'));
int release_index = name_version_release.last_index_of_char ('-');
string name_version = name_version_release.slice (0, release_index);
int version_index = name_version.last_index_of_char ('-');
string name = name_version.slice (0, version_index);
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
continue;
}
filenames_size.insert (absolute_filename, info.get_size ());
if (pkg_versions.contains (name)) {
if (pkg_version_filenames.contains (name_version_release)) {
// case of .sig file
unowned SList<string> filenames = pkg_version_filenames.lookup (name_version_release);
filenames.append (absolute_filename);
} else {
unowned SList<string> versions = pkg_versions.lookup (name);
string version = name_version.slice (version_index + 1, name_version.length);
string release = name_version_release.slice (release_index + 1, name_version_release.length);
string version_release = "%s-%s".printf (version, release);
versions.append ((owned) version_release);
var filenames = new SList<string> ();
filenames.append (absolute_filename);
pkg_version_filenames.insert (name_version_release, (owned) filenames);
}
} else {
var versions = new SList<string> ();
string version = name_version.slice (version_index + 1, name_version.length);
string release = name_version_release.slice (release_index + 1, name_version_release.length);
string version_release = "%s-%s".printf (version, release);
versions.append ((owned) version_release);
pkg_versions.insert (name, (owned) versions);
var filenames = new SList<string> ();
filenames.append (absolute_filename);
pkg_version_filenames.insert (name_version_release, (owned) filenames);
}
}
} catch (GLib.Error e) {
return filenames_size;
}
// filter candidates
var iter = HashTableIter<string, SList<string>> (pkg_versions);
unowned string name;
unowned SList<string> versions;
while (iter.next (out name, out versions)) {
// sort versions
uint length = versions.length ();
versions.sort ((version1, version2) => {
// reverse version 1 and version2 to have higher versions first
return Alpm.pkg_vercmp (version2, version1);
});
}
uint i = 1;
foreach (unowned string version in versions) {
unowned SList<string>? filenames = pkg_version_filenames.lookup ("%s-%s".printf (name, version));
if (filenames != null) {
foreach (unowned string filename in filenames) {
filenames_size.remove (filename);
}
}
i++;
break;
}
}
}
return filenames_size;
}
async void enumerate_directory (string directory_path, HashTable<string, int64?> filenames_size) {
FileEnumerator enumerator = yield directory.enumerate_children_async ("standard::*", FileQueryInfoFlags.NONE);
FileInfo info;
while ((info = enumerator.next_file (null)) != null) {
string absolute_filename = Path.build_path ("/", directory.get_path (), info.get_name ());
if (info.get_file_type () == FileType.DIRECTORY) {
} else {
filenames_size.insert (absolute_filename, info.get_size ());
}
}
} catch (GLib.Error e) {
var filenames_size = new HashTable<string, int64?> (str_hash, str_equal);
enumerate_directory.begin (config.aur_build_dir, filenames_size, (obj, res) => {
loop.quit ();
});
loop.run ();
public bool is_installed_pkg (string pkgname) {
return alpm_handle.localdb.get_pkg (pkgname) != null;
}
return initialise_pkg (alpm_handle.localdb.get_pkg (pkgname));
public bool has_installed_satisfier (string depstring) {
return Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring) != null;
}
public AlpmPackage? get_installed_satisfier (string depstring) {
return initialise_pkg (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring));
}
public bool should_hold (string pkgname) {
if (alpm_config.get_holdpkgs ().find_custom (pkgname, strcmp) != null) {
return true;
}
return false;
}
public uint get_pkg_reason (string pkgname) {
unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname);
if (pkg != null) {
return pkg.reason;
}
return 0;
}
public List<string> get_uninstalled_optdeps (string pkgname) {
var optdeps = new List<string> ();
new Thread<int> ("get_uninstalled_optdeps", () => {
unowned Alpm.Package? pkg = get_syncpkg (pkgname);
if (pkg != null) {
unowned Alpm.List<unowned Alpm.Depend> optdepends = pkg.optdepends;
while (optdepends != null) {
string optdep = optdepends.data.compute_string ();
unowned Alpm.Package? satisfier = Alpm.find_satisfier (alpm_handle.localdb.pkgcache, optdep);
if (satisfier == null) {
optdeps.append ((owned) optdep);
}
optdepends.next ();
loop.quit ();
return 0;
});
loop.run ();
return (owned) optdeps;
string get_localized_string (HashTable<string,string> hashtable) {
unowned string val;
if (!hashtable.lookup_extended (locale, null, out val)) {
// try with just the language
if (!hashtable.lookup_extended (locale.split ("_")[0], null, out val)) {
// try C locale
if (!hashtable.lookup_extended ("C", null, out val)) {
return "";
}
}
}
return val;
}
string get_app_name (As.App app) {
return get_localized_string (app.get_names ());
}
string get_app_launchable (As.App app) {
As.Launchable? launchable = app.get_launchable_by_kind (As.LaunchableKind.DESKTOP_ID);
if (launchable != null) {
return launchable.get_value ();
}
return "";
}
string get_app_summary (As.App app) {
return get_localized_string (app.get_comments ());
}
string get_app_description (As.App app) {
return get_localized_string (app.get_descriptions ());
}
string get_app_icon (As.App app, string dbname) {
string icon = "";
app.get_icons ().foreach ((as_icon) => {
if (as_icon.get_kind () == As.IconKind.CACHED) {
if (as_icon.get_height () == 64) {
icon = "/usr/share/app-info/icons/archlinux-arch-%s/64x64/%s".printf (dbname, as_icon.get_name ());
}
}
});
return icon;
}
List<string> get_app_screenshots (As.App app) {
var screenshots = new List<string> ();
As.Image? as_image = as_screenshot.get_source ();
if (as_image != null) {
string? url = as_image.get_url ();
if (url != null) {
screenshots.append ((owned) url);
SList<As.App> get_pkgname_matching_apps (string pkgname) {
var matching_apps = new SList<As.App> ();
if (app.get_kind () == As.AppKind.DESKTOP) {
if (app.get_pkgname_default () == pkgname) {
matching_apps.append (app);
}
AlpmPackage? initialise_pkg (Alpm.Package? alpm_pkg) {
if (alpm_pkg == null) {
return null;
}
var pkg = new AlpmPackage ();
initialise_pkg_common (alpm_pkg, ref pkg);
if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) {
pkg.repo = alpm_pkg.db.name;
} else if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) {
unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name);
if (sync_pkg != null) {
pkg.repo = sync_pkg.db.name;
} else if (config.enable_aur) {
if (aur.get_infos (alpm_pkg.name) != null) {
pkg.repo = dgettext (null, "AUR");
// find if pkgname provides only one app
var matching_apps = get_pkgname_matching_apps (alpm_pkg.name);
if (matching_apps.length () == 1) {
initialize_app_data (matching_apps.nth_data (0), ref pkg);
}
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
void initialise_pkg_common (Alpm.Package alpm_pkg, ref AlpmPackage pkg) {
// name
pkg.name = alpm_pkg.name;
// version
pkg.version = alpm_pkg.version;
// desc can be null
if (alpm_pkg.desc != null) {
pkg.desc = alpm_pkg.desc;
}
// url can be null
if (alpm_pkg.url != null) {
pkg.url = alpm_pkg.url;
}
// packager can be null
pkg.packager = alpm_pkg.packager ?? "";
// groups
unowned Alpm.List<unowned string> list = alpm_pkg.groups;
while (list != null) {
pkg.groups_priv.append (list.data);
list.next ();
}
// licenses
list = alpm_pkg.licenses;
while (list != null) {
pkg.licenses_priv.append (list.data);
list.next ();
}
// build_date
pkg.builddate = alpm_pkg.builddate;
// installed_size
pkg.installed_size = alpm_pkg.isize;
// installed_size
pkg.download_size = alpm_pkg.download_size;
// local pkg
if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) {
// installed_version
pkg.installed_version = alpm_pkg.version;
// reason
if (alpm_pkg.reason == Alpm.Package.Reason.EXPLICIT) {
pkg.reason = dgettext (null, "Explicitly installed");
} else if (alpm_pkg.reason == Alpm.Package.Reason.DEPEND) {
pkg.reason = dgettext (null, "Installed as a dependency for another package");
} else {
pkg.reason = dgettext (null, "Unknown");
}
// install_date
pkg.installdate = alpm_pkg.installdate;
// backups
unowned Alpm.List<unowned Alpm.Backup> backups_list = alpm_pkg.backups;
while (backups_list != null) {
pkg.backups_priv.append ("/" + backups_list.data.name);
backups_list.next ();
}
// requiredby
Alpm.List<string> pkg_requiredby = alpm_pkg.compute_requiredby ();
unowned Alpm.List<string> string_list = pkg_requiredby;
while (string_list != null) {
pkg.requiredby_priv.append ((owned) string_list.data);
string_list.next ();
}
// optionalfor
Alpm.List<string> pkg_optionalfor = alpm_pkg.compute_optionalfor ();
string_list = pkg_optionalfor;
while (string_list != null) {
pkg.optionalfor_priv.append ((owned) string_list.data);
string_list.next ();
}
// sync pkg
} else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) {
// installed_version
unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (alpm_pkg.name);
if (local_pkg != null) {
pkg.installed_version = local_pkg.version;
}
// signature
if (alpm_pkg.base64_sig != null) {
pkg.has_signature = dgettext (null, "Yes");
} else {
pkg.has_signature = dgettext (null, "No");
}
}
// depends
unowned Alpm.List<unowned Alpm.Depend> depends_list = alpm_pkg.depends;
while (depends_list != null) {
pkg.depends_priv.append (depends_list.data.compute_string ());
depends_list.next ();
}
// optdepends
depends_list = alpm_pkg.optdepends;
while (depends_list != null) {
pkg.optdepends_priv.append (depends_list.data.compute_string ());
depends_list.next ();
}
// provides
depends_list = alpm_pkg.provides;
while (depends_list != null) {
pkg.provides_priv.append (depends_list.data.compute_string ());
depends_list.next ();
}
// replaces
depends_list = alpm_pkg.replaces;
while (depends_list != null) {
pkg.replaces_priv.append (depends_list.data.compute_string ());
depends_list.next ();
}
// conflicts
depends_list = alpm_pkg.conflicts;
while (depends_list != null) {
pkg.conflicts_priv.append (depends_list.data.compute_string ());
depends_list.next ();
}
}
void initialize_app_data (As.App app, ref AlpmPackage pkg) {
pkg.app_name = get_app_name (app);
pkg.launchable = get_app_launchable (app);
pkg.desc = get_app_summary (app);
try {
pkg.long_desc = As.markup_convert_simple (get_app_description (app));
} catch (Error e) {
critical ("%s\n", e.message);
}
pkg.icon = get_app_icon (app, pkg.repo);
pkg.screenshots_priv = get_app_screenshots (app);
}
List<AlpmPackage> initialise_pkgs (Alpm.List<unowned Alpm.Package>? alpm_pkgs) {
var pkgs = new List<AlpmPackage> ();
var data = new HashTable<string, AlpmPackage> (str_hash, str_equal);
string[] foreign_pkgnames = {};
while (alpm_pkgs != null) {
unowned Alpm.Package alpm_pkg = alpm_pkgs.data;
var pkg = new AlpmPackage ();
initialise_pkg_common (alpm_pkg, ref pkg);
if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) {
unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name);
if (sync_pkg != null) {
}
} else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) {
var apps = get_pkgname_matching_apps (alpm_pkg.name);
if (apps.length () > 0) {
unowned SList<As.App> apps_list = apps;
unowned As.App app = apps_list.data;
pkgs.append (pkg);
apps_list = apps_list.next;
while (apps_list != null) {
app = apps_list.data;
var pkg_dup = pkg.dup ();
}
alpm_pkgs.next ();
}
// get aur infos
if (foreign_pkgnames.length > 0) {
foreach (unowned Json.Object json_object in aur.get_multi_infos (foreign_pkgnames)) {
unowned AlpmPackage? pkg = data.lookup (json_object.get_string_member ("Name"));
}
var iter = HashTableIter<string, AlpmPackage> (data);
unowned AlpmPackage pkg;
public List<AlpmPackage> get_installed_pkgs () {
var pkgs = new List<AlpmPackage> ();
new Thread<int> ("get_installed_pkgs", () => {
pkgs = initialise_pkgs (alpm_handle.localdb.pkgcache);
pkgs.sort (pkg_compare_name);
loop.quit ();
return 0;
});
loop.run ();
return (owned) pkgs;
public List<AlpmPackage> get_installed_apps () {
var pkgs = new List<AlpmPackage> ();
new Thread<int> ("get_installed_apps", () => {
app_store.get_apps ().foreach ((app) => {
if (app.get_kind () == As.AppKind.DESKTOP) {
unowned string pkgname = app.get_pkgname_default ();
unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (pkgname);
if (local_pkg != null) {
unowned Alpm.Package? sync_pkg = get_syncpkg (pkgname);
if (sync_pkg != null) {
var pkg = new AlpmPackage ();
initialise_pkg_common (local_pkg, ref pkg);
pkg.repo = sync_pkg.db.name;
initialize_app_data (app, ref pkg);
pkgs.append (pkg);
}
public List<AlpmPackage> get_explicitly_installed_pkgs () {
var pkgs = new List<AlpmPackage> ();
new Thread<int> ("get_explicitly_installed_pkgs", () => {
Alpm.List<unowned Alpm.Package> alpm_pkgs = null;
unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache;
while (pkgcache != null) {
unowned Alpm.Package alpm_pkg = pkgcache.data;
if (alpm_pkg.reason == Alpm.Package.Reason.EXPLICIT) {
alpm_pkgs.add (alpm_pkg);
}
pkgcache.next ();
pkgs = initialise_pkgs (alpm_pkgs);
pkgs.sort (pkg_compare_name);
loop.quit ();
return 0;
});
loop.run ();
return (owned) pkgs;
public List<AlpmPackage> get_foreign_pkgs () {
var pkgs = new List<AlpmPackage> ();
new Thread<int> ("get_foreign_pkgs", () => {
Alpm.List<unowned Alpm.Package> alpm_pkgs = null;
unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache;
while (pkgcache != null) {
unowned Alpm.Package alpm_pkg = pkgcache.data;
bool sync_found = false;
unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
unowned Alpm.Package? sync_pkg = db.get_pkg (alpm_pkg.name);
if (sync_pkg != null) {
sync_found = true;
break;
}
syncdbs.next ();
if (sync_found == false) {
alpm_pkgs.add (alpm_pkg);
}
pkgcache.next ();
pkgs = initialise_pkgs (alpm_pkgs);
pkgs.sort (pkg_compare_name);
loop.quit ();
return 0;
});
loop.run ();
return (owned) pkgs;
public List<AlpmPackage> get_orphans () {
var pkgs = new List<AlpmPackage> ();
new Thread<int> ("get_orphans", () => {
Alpm.List<unowned Alpm.Package> alpm_pkgs = null;
unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache;
while (pkgcache != null) {
unowned Alpm.Package alpm_pkg = pkgcache.data;
if (alpm_pkg.reason == Alpm.Package.Reason.DEPEND) {
Alpm.List<string> requiredby = alpm_pkg.compute_requiredby ();
if (requiredby.length == 0) {
Alpm.List<string> optionalfor = alpm_pkg.compute_optionalfor ();
if (optionalfor.length == 0) {
alpm_pkgs.add (alpm_pkg);
} else {
optionalfor.free_inner (GLib.free);
}
pkgs = initialise_pkgs (alpm_pkgs);
pkgs.sort (pkg_compare_name);
loop.quit ();
return 0;
});
loop.run ();
}
unowned Alpm.Package? get_syncpkg (string name) {
unowned Alpm.Package? pkg = null;
unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
pkg = db.get_pkg (name);
if (pkg != null) {
break;
}
syncdbs.next ();
}
return pkg;
public bool is_sync_pkg (string pkgname) {
return get_syncpkg (pkgname) != null;
}
}
unowned Alpm.Package? find_dbs_satisfier (string depstring) {
unowned Alpm.Package? pkg = null;
unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
pkg = Alpm.find_satisfier (db.pkgcache, depstring);
if (pkg != null) {
break;
}
syncdbs.next ();
}
return pkg;
public bool has_sync_satisfier (string depstring) {
return find_dbs_satisfier (depstring) != null;
}
public AlpmPackage? get_sync_satisfier (string depstring) {
Alpm.List<unowned Alpm.Package> search_local_db (string search_string) {
Alpm.List<unowned string> needles = null;
string[] splitted = search_string.split (" ");
foreach (unowned string part in splitted) {
needles.add (part);
}
Alpm.List<unowned Alpm.Package> result = alpm_handle.localdb.search (needles);
// search in appstream
string[]? search_terms = As.utils_search_tokenize (search_string);
if (search_terms != null) {
Alpm.List<unowned Alpm.Package> appstream_result = null;
app_store.get_apps ().foreach ((app) => {
if (app.get_kind () == As.AppKind.DESKTOP) {
uint match_score = app.search_matches_all (search_terms);
if (match_score > 0) {
unowned string pkgname = app.get_pkgname_default ();
unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname);
if (alpm_pkg != null) {
if (appstream_result.find (alpm_pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) {
appstream_result.add (alpm_pkg);
}
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
}
}
}
});
result.join (appstream_result.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name));
}
return result;
}
Alpm.List<unowned Alpm.Package> search_sync_dbs (string search_string) {
Alpm.List<unowned string> needles = null;
string[] splitted = search_string.split (" ");
foreach (unowned string part in splitted) {
needles.add (part);
}
Alpm.List<unowned Alpm.Package> syncpkgs = null;
unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
if (syncpkgs.length == 0) {
syncpkgs = db.search (needles);
} else {
syncpkgs.join (db.search (needles).diff (syncpkgs, (Alpm.List.CompareFunc) alpm_pkg_compare_name));
}
syncdbs.next ();
}
// remove foreign pkgs
Alpm.List<unowned Alpm.Package> localpkgs = alpm_handle.localdb.search (needles);
Alpm.List<unowned Alpm.Package> result = syncpkgs.diff (localpkgs.diff (syncpkgs, (Alpm.List.CompareFunc) alpm_pkg_compare_name), (Alpm.List.CompareFunc) alpm_pkg_compare_name);
// search in appstream
string[]? search_terms = As.utils_search_tokenize (search_string);
if (search_terms != null) {
Alpm.List<unowned Alpm.Package> appstream_result = null;
app_store.get_apps ().foreach ((app) => {
if (app.get_kind () == As.AppKind.DESKTOP) {
uint match_score = app.search_matches_all (search_terms);
if (match_score > 0) {
unowned string pkgname = app.get_pkgname_default ();
unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname);
if (alpm_pkg == null) {
alpm_pkg = get_syncpkg (pkgname);
if (alpm_pkg != null) {
if (appstream_result.find (alpm_pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) {
appstream_result.add (alpm_pkg);
}
}
}
}
}
});
result.join (appstream_result.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name));
}
return result;
}
public List<AlpmPackage> search_installed_pkgs (string search_string) {
string search_string_down = search_string.down ();
var pkgs = new List<AlpmPackage> ();
new Thread<int> ("search_installed_pkgs", () => {
pkgs = initialise_pkgs (search_local_db (search_string_down));
// use custom sort function
global_search_string = (owned) search_string_down;
pkgs.sort (pkg_sort_search_by_relevance);
loop.quit ();
return 0;
});
loop.run ();
public List<AlpmPackage> search_repos_pkgs (string search_string) {
string search_string_down = search_string.down ();
var pkgs = new List<AlpmPackage> ();
new Thread<int> ("search_repos_pkgs", () => {
pkgs = initialise_pkgs (search_sync_dbs (search_string_down));
// use custom sort function
global_search_string = (owned) search_string_down;
pkgs.sort (pkg_sort_search_by_relevance);
loop.quit ();
return 0;
});
loop.run ();
Alpm.List<unowned Alpm.Package> search_all_dbs (string search_string) {
Alpm.List<unowned string> needles = null;
string[] splitted = search_string.split (" ");
foreach (unowned string part in splitted) {
needles.add (part);
}
Alpm.List<unowned Alpm.Package> result = alpm_handle.localdb.search (needles);
Alpm.List<unowned Alpm.Package> syncpkgs = null;
unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
if (syncpkgs.length == 0) {
syncpkgs = db.search (needles);
} else {
syncpkgs.join (db.search (needles).diff (syncpkgs, (Alpm.List.CompareFunc) alpm_pkg_compare_name));
}
syncdbs.next ();
}
result.join (syncpkgs.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name));
// search in appstream
string[]? search_terms = As.utils_search_tokenize (search_string);
if (search_terms != null) {
Alpm.List<unowned Alpm.Package> appstream_result = null;
app_store.get_apps ().foreach ((app) => {
if (app.get_kind () == As.AppKind.DESKTOP) {
uint match_score = app.search_matches_all (search_terms);
if (match_score > 0) {
unowned string pkgname = app.get_pkgname_default ();
unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname);
if (alpm_pkg == null) {
alpm_pkg = get_syncpkg (pkgname);
}
if (alpm_pkg != null) {
if (appstream_result.find (alpm_pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) {
appstream_result.add (alpm_pkg);
}
}
}
}
});
result.join (appstream_result.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name));
}
return result;
public List<AlpmPackage> search_pkgs (string search_string) {
string search_string_down = search_string.down ();
var pkgs = new List<AlpmPackage> ();
new Thread<int> ("search_pkgs", () => {
pkgs = initialise_pkgs (search_all_dbs (search_string_down));
// use custom sort function
global_search_string = (owned) search_string_down;
pkgs.sort (pkg_sort_search_by_relevance);
loop.quit ();
return 0;
});
loop.run ();
public List<AURPackage> search_aur_pkgs (string search_string) {
string search_string_down = search_string.down ();
var pkgs = new List<AURPackage> ();
if (config.enable_aur) {
new Thread<int> ("search_aur_pkgs", () => {
foreach (unowned Json.Object json_object in aur.search_aur (search_string_down)) {
unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (json_object.get_string_member ("Name"));
pkgs.append (initialise_aur_pkg (json_object, local_pkg));
}
loop.quit ();
return 0;
});
loop.run ();
}
public HashTable<string, Variant> search_files (string[] files) {
var result = new HashTable<string, Variant> (str_hash, str_equal);
foreach (unowned string file in files) {
// search in localdb
unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache;
while (pkgcache != null) {
unowned Alpm.Package alpm_pkg = pkgcache.data;
string[] found_files = {};
unowned Alpm.FileList filelist = alpm_pkg.files;
Alpm.File* file_ptr = filelist.files;
for (size_t i = 0; i < filelist.count; i++, file_ptr++) {
// exclude directory name
if (!file_ptr->name.has_suffix ("/")) {
// adding / to compare
real_file_name.append (file_ptr->name);
if (file in real_file_name.str) {
}
}
}
if (found_files.length > 0) {
result.insert (alpm_pkg.name, new Variant.strv (found_files));
}
pkgcache.next ();
}
// search in syncdbs
unowned Alpm.List<unowned Alpm.DB> syncdbs = files_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
pkgcache = db.pkgcache;
while (pkgcache != null) {
unowned Alpm.Package alpm_pkg = pkgcache.data;
string[] found_files = {};
unowned Alpm.FileList filelist = alpm_pkg.files;