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 {
AlpmConfig alpm_config;
Alpm.Handle? alpm_handle;
Alpm.Handle? files_handle;
HashTable<string, Json.Array> aur_search_results;
HashTable<string, Json.Object> aur_infos;
As.Store app_store;
string locale;
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;
}
}
public signal void get_updates_progress (uint percent);
public Config config { get; construct set; }
public Database (Config config) {
Object (config: config);
}
construct {
refresh ();
aur_search_results = new HashTable<string, Json.Array> (str_hash, str_equal);
aur_infos = new HashTable<string, Json.Object> (str_hash, str_equal);
// 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 ();
}
}
public void enable_appstream () {
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) {
stderr.printf ("Error: %s\n", e.message);
}
if (alpm_handle == null) {
critical (dgettext (null, "Failed to initialize alpm library"));
return;
} else {
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) {
stderr.printf ("Error: %s\n", e.message);
}
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) {
stderr.printf ("Error: %s\n", e.message);
public string get_alpm_dep_name (string dep_string) {
return Alpm.Depend.from_string (dep_string).name;
}
public CompareFunc<string> vercmp = Alpm.pkg_vercmp;
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
public HashTable<string, int64?> get_clean_cache_details (uint64 keep_nb, bool only_uninstalled) {
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);
if (only_uninstalled && is_installed_pkg (name)) {
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) {
stderr.printf ("Error: %s\n", e.message);
}
cachedirs_names.next ();
}
if (keep_nb == 0) {
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 ();
if (length > keep_nb) {
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++;
if (i > keep_nb) {
break;
}
}
}
return filenames_size;
}
void enumerate_directory (string directory_path, ref HashTable<string, int64?> filenames_size) {
var directory = GLib.File.new_for_path (directory_path);
try {
FileEnumerator enumerator = directory.enumerate_children ("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) {
enumerate_directory (absolute_filename, ref filenames_size);
} else {
filenames_size.insert (absolute_filename, info.get_size ());
}
}
} catch (GLib.Error e) {
stderr.printf ("Error: %s\n", e.message);
}
}
public HashTable<string, int64?> get_build_files_details (string aur_build_dir) {
var filenames_size = new HashTable<string, int64?> (str_hash, str_equal);
enumerate_directory (aur_build_dir, ref filenames_size);
return filenames_size;
}
var result = new List<string> ();
unowned Alpm.List<unowned string> ignorepkgs = alpm_handle.ignorepkgs;
while (ignorepkgs != null) {
unowned string ignorepkg = ignorepkgs.data;
result.append (ignorepkg);
ignorepkgs.next ();
}
return result;
public bool is_installed_pkg (string pkgname) {
return alpm_handle.localdb.get_pkg (pkgname) != null;
}
return initialise_pkg (alpm_handle.localdb.get_pkg (pkgname));
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> ();
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 ();
}
}
return optdeps;
}
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
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_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;
}
string get_app_screenshot (As.App app) {
string screenshot = "";
app.get_screenshots ().foreach ((as_screenshot) => {
if (as_screenshot.get_kind () == As.ScreenshotKind.DEFAULT) {
As.Image? as_image = as_screenshot.get_source ();
if (as_image != null) {
unowned string? url = as_image.get_url ();
if (url != null) {
screenshot = 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);
}
Package initialise_pkg (Alpm.Package? alpm_pkg) {
var pkg = new Package ();
pkg.name = alpm_pkg.name;
pkg.version = alpm_pkg.version;
pkg.installed_size = alpm_pkg.isize;
pkg.download_size = alpm_pkg.download_size;
pkg.builddate = alpm_pkg.builddate;
pkg.installdate = alpm_pkg.installdate;
if (alpm_pkg.desc != null) {
pkg.desc = alpm_pkg.desc;
}
unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name);
if (sync_pkg != null) {
} else if (config.enable_aur) {
var loop = new MainLoop ();
get_aur_pkg.begin (alpm_pkg.name, (obj, res) => {
var aur_pkg = get_aur_pkg.end (res);
if (aur_pkg.name != "") {
}
loop.quit ();
});
loop.run ();
}
} else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) {
unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (alpm_pkg.name);
if (local_pkg != null) {
if (pkg.repo != "" && pkg.repo != dgettext (null, "AUR")) {
var matching_apps = get_pkgname_matching_apps (alpm_pkg.name);
if (matching_apps.length () == 1) {
As.App app = matching_apps.nth_data (0);
pkg.app_name = get_app_name (app);
pkg.desc = get_app_summary (app);
pkg.icon = get_app_icon (app, pkg.repo);
List<Package> initialise_pkgs (Alpm.List<unowned Alpm.Package>? alpm_pkgs) {
var data = new HashTable<string, Package> (str_hash, str_equal);
string[] foreign_pkgnames = {};
while (alpm_pkgs != null) {
unowned Alpm.Package alpm_pkg = alpm_pkgs.data;
var pkg = new Package ();
pkg.name = alpm_pkg.name;
pkg.version = alpm_pkg.version;
if (alpm_pkg.desc != null) {
pkg.desc = alpm_pkg.desc;
}
pkg.installed_size = alpm_pkg.isize;
pkg.download_size = alpm_pkg.download_size;
pkg.builddate = alpm_pkg.builddate;
pkg.installdate = alpm_pkg.installdate;
unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name);
if (sync_pkg != null) {
}
} else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) {
unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (alpm_pkg.name);
if (local_pkg != null) {
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;
pkg.app_name = get_app_name (app);
pkg.desc = get_app_summary (app);
pkg.icon = get_app_icon (app, pkg.repo);
pkgs.append (pkg);
apps_list = apps_list.next;
while (apps_list != null) {
app = apps_list.data;
var pkg_dup = pkg.dup ();
pkg_dup.app_name = get_app_name (app);
pkg_dup.desc = get_app_summary (app);
pkg_dup.icon = get_app_icon (app, pkg_dup.repo);
pkgs.append (pkg_dup);
apps_list = apps_list.next;
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
}
alpm_pkgs.next ();
}
// get aur infos
if (foreign_pkgnames.length > 0) {
var loop = new MainLoop ();
get_aur_pkgs.begin (foreign_pkgnames, (obj, res) => {
var aur_pkgs = get_aur_pkgs.end (res);
var iter = HashTableIter<string, AURPackage> (aur_pkgs);
unowned string pkgname;
unowned AURPackage aur_pkg;
while (iter.next (out pkgname, out aur_pkg)) {
if (aur_pkg.name != "") {
unowned Package pkg = data.lookup (pkgname);
if (pkg != null) {
pkg.repo = dgettext (null, "AUR");
}
}
}
loop.quit ();
});
loop.run ();
var iter = HashTableIter<string, Package> (data);
unowned Package pkg;
while (iter.next (null, out pkg)) {
pkgs.append (pkg);
var pkgs = initialise_pkgs (alpm_handle.localdb.pkgcache);
pkgs.sort (pkg_compare_name);
var result = new List<Package> ();
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 Package ();
pkg.name = sync_pkg.name;
pkg.app_name = get_app_name (app);
pkg.version = sync_pkg.version;
pkg.installed_version = local_pkg.version;
pkg.desc = get_app_summary (app);
pkg.repo = sync_pkg.db.name;
pkg.installed_size = local_pkg.isize;
pkg.download_size = sync_pkg.download_size;
pkg.builddate = local_pkg.builddate;
pkg.installdate = local_pkg.installdate;
pkg.icon = get_app_icon (app, sync_pkg.db.name);
result.append (pkg);
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) {
var pkgs = initialise_pkgs (alpm_pkgs);
pkgs.sort (pkg_compare_name);
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) {
var pkgs = initialise_pkgs (alpm_pkgs);
pkgs.sort (pkg_compare_name);
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) {
} else {
optionalfor.free_inner (GLib.free);
}
} else {
requiredby.free_inner (GLib.free);
}
}
pkgcache.next ();
}
var pkgs = initialise_pkgs (alpm_pkgs);
pkgs.sort (pkg_compare_name);
var pkgs = new List<Package> ();
new Thread<int> ("get_installed_pkgs", () => {
pkgs = get_installed_pkgs ();
Idle.add (get_installed_pkgs_async.callback);
return 0;
});
yield;
return (owned) pkgs;
var pkgs = new List<Package> ();
new Thread<int> ("get_installed_apps", () => {
pkgs = get_installed_apps ();
Idle.add (get_installed_apps_async.callback);
return 0;
});
yield;
return (owned) pkgs;
public async List<Package> get_explicitly_installed_pkgs_async () {
var pkgs = new List<Package> ();
new Thread<int> ("get_explicitly_installed_pkgs", () => {
pkgs = get_explicitly_installed_pkgs ();
Idle.add (get_explicitly_installed_pkgs_async.callback);
return 0;
});
yield;
return (owned) pkgs;
var pkgs = new List<Package> ();
new Thread<int> ("get_foreign_pkgs", () => {
pkgs = get_foreign_pkgs ();
Idle.add (get_foreign_pkgs_async.callback);
return 0;
});
yield;
return (owned) pkgs;
var pkgs = new List<Package> ();
new Thread<int> ("get_orphans", () => {
pkgs = get_orphans ();
Idle.add (get_orphans_async.callback);
return 0;
});
yield;
return (owned) pkgs;
}
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;
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);
}
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
}
}
}
});
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> localpkgs = 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 ();
}
// remove localpkgs
Alpm.List<unowned Alpm.Package> result = syncpkgs.diff (localpkgs, (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<Package> search_installed_pkgs (string search_string) {
var pkgs = initialise_pkgs (search_local_db (search_string));
// use custom sort function
global_search_string = search_string;
pkgs.sort (pkg_sort_search_by_relevance);
return pkgs;
}
public async List<Package> search_installed_pkgs_async (string search_string) {
var pkgs = new List<Package> ();
new Thread<int> ("search_installed_pkgs", () => {
pkgs = search_installed_pkgs (search_string);
Idle.add (search_installed_pkgs_async.callback);
return 0;
});
yield;
return (owned) pkgs;
}
public List<Package> search_repos_pkgs (string search_string) {
var pkgs = initialise_pkgs (search_sync_dbs (search_string));
// use custom sort function
global_search_string = search_string;
pkgs.sort (pkg_sort_search_by_relevance);
return pkgs;
}
public async List<Package> search_repos_pkgs_async (string search_string) {
var pkgs = new List<Package> ();
new Thread<int> ("search_repos_pkgs", () => {
pkgs = search_repos_pkgs (search_string);
Idle.add (search_repos_pkgs_async.callback);
return 0;
});
yield;
return (owned) pkgs;
}
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;
var pkgs = initialise_pkgs (search_all_dbs (search_string));
// use custom sort function
global_search_string = search_string;
pkgs.sort (pkg_sort_search_by_relevance);
public async List<Package> search_pkgs_async (string search_string) {
var pkgs = new List<Package> ();
new Thread<int> ("search_pkgs", () => {
pkgs = search_pkgs (search_string);
Idle.add (search_pkgs_async.callback);
return 0;
});
yield;
return (owned) pkgs;
AURPackage initialise_aur_pkg (Json.Object? json_object) {
var aur_pkg = new AURPackage ();
return aur_pkg;
}
aur_pkg.name = json_object.get_string_member ("Name");
aur_pkg.version = json_object.get_string_member ("Version");
// desc can be null
aur_pkg.desc = json_object.get_null_member ("Description") ? "" : json_object.get_string_member ("Description");
aur_pkg.popularity = json_object.get_double_member ("Popularity");
aur_pkg.packagebase = json_object.get_string_member ("PackageBase");
aur_pkg.lastmodified = (uint64) json_object.get_int_member ("LastModified");
unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (json_object.get_string_member ("Name"));
if (pkg != null) {
// set out of date
unowned Json.Node? out_node = json_object.get_member ("OutOfDate");
if (!out_node.is_null ()) {
public async List<AURPackage> search_in_aur (string search_string) {
if (!aur_search_results.contains (search_string)) {
Json.Array pkgs = yield aur_search (search_string.split (" "));
aur_search_results.insert (search_string, pkgs);
var json_array = aur_search_results.get (search_string);
json_array.foreach_element ((array, index, node) => {
Json.Object json_object = node.get_object ();
// remove results which is installed or exist in repos
if (alpm_handle.localdb.get_pkg (json_object.get_string_member ("Name")) == null
&& get_syncpkg (json_object.get_string_member ("Name")) == null) {
result.append (initialise_aur_pkg (json_object));
}
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) {
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
}
}
}
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;
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
var real_file_name = new StringBuilder ();
real_file_name.append (alpm_handle.root);
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 ();
}
syncdbs.next ();
}
}
return result;