pamac-classic/src/pamac-user-daemon/user_daemon.vala

1046 lines
32 KiB
Vala
Raw Permalink Normal View History

2017-07-29 10:35:04 -04:00
/*
* pamac-vala
*
2017-10-10 16:29:22 -03:00
* Copyright (C) 2017 Chris Cromer <cromer@cromnix.org>
2017-07-29 10:35:04 -04:00
* Copyright (C) 2014-2017 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/>.
*/
// i18n
const string GETTEXT_PACKAGE = "pamac";
Pamac.UserDaemon user_daemon;
MainLoop loop;
namespace Pamac {
2017-10-10 16:29:22 -03:00
[DBus (name = "org.pamac.user")]
2017-07-29 10:35:04 -04:00
public class UserDaemon: Object {
private AlpmConfig alpm_config;
private Alpm.Handle? alpm_handle;
private Alpm.Handle? files_handle;
2017-10-10 16:29:22 -03:00
#if DISABLE_AUR
#else
2017-07-29 10:35:04 -04:00
private bool check_aur_updates;
private bool aur_updates_checked;
2017-10-02 10:23:53 -03:00
private Json.Array aur_updates_results;
2017-07-29 10:35:04 -04:00
private HashTable<string, Json.Array> aur_search_results;
private HashTable<string, Json.Object> aur_infos;
2019-07-06 20:28:51 -04:00
#endif
2017-07-29 10:35:04 -04:00
public signal void get_updates_finished (Updates updates);
public UserDaemon () {
alpm_config = new AlpmConfig ("/etc/pacman.conf");
2017-10-10 16:29:22 -03:00
#if DISABLE_AUR
#else
2017-10-02 10:23:53 -03:00
aur_updates_results = new Json.Array ();
2017-07-29 10:35:04 -04:00
aur_search_results = new HashTable<string, Json.Array> (str_hash, str_equal);
aur_infos = new HashTable<string, Json.Object> (str_hash, str_equal);
2017-10-10 16:29:22 -03:00
#endif
2019-07-06 20:28:51 -04:00
try {
refresh_handle ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
} catch (DBusError e) {
stderr.printf ("DBusError: %s\n", e.message);
}
2017-07-29 10:35:04 -04:00
}
2019-07-06 20:28:51 -04:00
public void refresh_handle () throws DBusError, IOError {
2017-10-02 10:38:49 -03:00
alpm_config.reload ();
2017-07-29 10:35:04 -04:00
alpm_handle = alpm_config.get_handle ();
if (alpm_handle == null) {
return;
} else {
var pamac_config = new Pamac.Config ();
if (pamac_config.update_files_db) {
files_handle = alpm_config.get_handle (true);
} else {
files_handle = alpm_config.get_handle (false);
}
2017-07-29 10:35:04 -04:00
}
}
2019-07-06 20:28:51 -04:00
public bool get_checkspace () throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
return alpm_handle.checkspace == 1 ? true : false;
}
2019-07-06 20:28:51 -04:00
public string get_lockfile () throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
return alpm_handle.lockfile;
}
2019-07-06 20:28:51 -04:00
public string[] get_ignorepkgs () throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
string[] result = {};
unowned Alpm.List<unowned string> ignorepkgs = alpm_handle.ignorepkgs;
while (ignorepkgs != null) {
unowned string ignorepkg = ignorepkgs.data;
result += ignorepkg;
ignorepkgs.next ();
}
return result;
}
2019-07-06 20:28:51 -04:00
public bool should_hold (string pkgname) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
if (alpm_config.get_holdpkgs ().find_custom (pkgname, strcmp) != null) {
return true;
}
return false;
}
2019-07-06 20:28:51 -04:00
public uint get_pkg_reason (string pkgname) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname);
if (pkg != null) {
return pkg.reason;
}
return 0;
}
2019-07-06 20:28:51 -04:00
public uint get_pkg_origin (string pkgname) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname);
if (pkg != null) {
return pkg.origin;
} else {
pkg = get_syncpkg (pkgname);
if (pkg != null) {
return pkg.origin;
}
}
return 0;
}
private AlpmPackage initialise_pkg_struct (Alpm.Package? alpm_pkg) {
if (alpm_pkg != null) {
string installed_version = "";
string repo_name = "";
if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) {
installed_version = alpm_pkg.version;
unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name);
if (sync_pkg != null) {
repo_name = sync_pkg.db.name;
}
} 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) {
installed_version = local_pkg.version;
}
repo_name = alpm_pkg.db.name;
}
return AlpmPackage () {
name = alpm_pkg.name,
version = alpm_pkg.version,
installed_version = (owned) installed_version,
2017-10-02 10:23:53 -03:00
// desc can be null
desc = alpm_pkg.desc ?? "",
2017-07-29 10:35:04 -04:00
repo = (owned) repo_name,
size = alpm_pkg.isize,
download_size = alpm_pkg.download_size,
2017-10-02 10:23:53 -03:00
origin = (uint) alpm_pkg.origin
2017-07-29 10:35:04 -04:00
};
} else {
return AlpmPackage () {
name = "",
version = "",
installed_version = "",
desc = "",
2017-10-02 10:23:53 -03:00
repo = ""
2017-07-29 10:35:04 -04:00
};
}
}
2019-07-06 20:28:51 -04:00
public async AlpmPackage[] get_installed_pkgs () throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
AlpmPackage[] pkgs = {};
unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache;
while (pkgcache != null) {
unowned Alpm.Package alpm_pkg = pkgcache.data;
2017-10-02 10:23:53 -03:00
pkgs += initialise_pkg_struct (alpm_pkg);
2017-07-29 10:35:04 -04:00
pkgcache.next ();
}
return pkgs;
}
2019-07-06 20:28:51 -04:00
public async AlpmPackage[] get_explicitly_installed_pkgs () throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
AlpmPackage[] pkgs = {};
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) {
2017-10-02 10:23:53 -03:00
pkgs += initialise_pkg_struct (alpm_pkg);
2017-07-29 10:35:04 -04:00
}
pkgcache.next ();
}
return pkgs;
}
2019-07-06 20:28:51 -04:00
public async AlpmPackage[] get_foreign_pkgs () throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
AlpmPackage[] pkgs = {};
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) {
2017-10-02 10:23:53 -03:00
pkgs += initialise_pkg_struct (alpm_pkg);
2017-07-29 10:35:04 -04:00
}
pkgcache.next ();
}
return pkgs;
}
2019-07-06 20:28:51 -04:00
public async AlpmPackage[] get_orphans () throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
AlpmPackage[] pkgs = {};
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 ();
2021-07-09 08:00:59 -04:00
if (requiredby.length () == 0) {
2017-07-29 10:35:04 -04:00
Alpm.List<string> optionalfor = alpm_pkg.compute_optionalfor ();
2021-07-09 08:00:59 -04:00
if (optionalfor.length () == 0) {
2017-10-02 10:23:53 -03:00
pkgs += initialise_pkg_struct (alpm_pkg);
2017-07-29 10:35:04 -04:00
} else {
optionalfor.free_inner (GLib.free);
}
} else {
requiredby.free_inner (GLib.free);
}
}
pkgcache.next ();
}
return pkgs;
}
2019-07-06 20:28:51 -04:00
public AlpmPackage get_installed_pkg (string pkgname) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
return initialise_pkg_struct (alpm_handle.localdb.get_pkg (pkgname));
}
2019-07-06 20:28:51 -04:00
public AlpmPackage find_installed_satisfier (string depstring) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
return initialise_pkg_struct (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring));
}
private 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;
}
2019-07-06 20:28:51 -04:00
public AlpmPackage get_sync_pkg (string pkgname) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
return initialise_pkg_struct (get_syncpkg (pkgname));
}
private 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;
}
2019-07-06 20:28:51 -04:00
public AlpmPackage find_sync_satisfier (string depstring) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
return initialise_pkg_struct (find_dbs_satisfier (depstring));
}
private 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);
}
2021-07-09 08:00:59 -04:00
Alpm.List<unowned Alpm.Package> result;
// TODO: handle return value
alpm_handle.localdb.search (needles, out result);
2017-07-29 10:35:04 -04:00
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;
2021-07-09 08:00:59 -04:00
if (syncpkgs.length () == 0) {
db.search (needles, out syncpkgs);
2017-07-29 10:35:04 -04:00
} else {
2021-07-09 08:00:59 -04:00
Alpm.List<unowned Alpm.Package> newsyncpkgs = null;
db.search (needles, out newsyncpkgs);
syncpkgs.join (newsyncpkgs.diff (syncpkgs, (Alpm.List.CompareFunc) alpm_pkg_compare_name));
2017-07-29 10:35:04 -04:00
}
syncdbs.next ();
}
result.join (syncpkgs.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name));
// use custom sort function
global_search_string = search_string;
2021-07-09 08:00:59 -04:00
result.sort (result.length (), (Alpm.List.CompareFunc) alpm_pkg_sort_search_by_relevance);
2017-07-29 10:35:04 -04:00
return result;
}
2019-07-06 20:28:51 -04:00
public async AlpmPackage[] search_pkgs (string search_string) throws DBusError, IOError {
2017-10-02 10:23:53 -03:00
AlpmPackage[] result = {};
2017-07-29 10:35:04 -04:00
Alpm.List<unowned Alpm.Package> alpm_pkgs = search_all_dbs (search_string);
unowned Alpm.List<unowned Alpm.Package> list = alpm_pkgs;
while (list != null) {
unowned Alpm.Package alpm_pkg = list.data;
2017-10-02 10:23:53 -03:00
result += initialise_pkg_struct (alpm_pkg);
2017-07-29 10:35:04 -04:00
list.next ();
}
2017-10-02 10:23:53 -03:00
return result;
2017-07-29 10:35:04 -04:00
}
2017-10-10 16:29:22 -03:00
#if DISABLE_AUR
#else
2017-07-29 10:35:04 -04:00
private AURPackage initialise_aur_struct (Json.Object json_object) {
string installed_version = "";
unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (json_object.get_string_member ("Name"));
if (pkg != null) {
installed_version = pkg.version;
}
return AURPackage () {
name = json_object.get_string_member ("Name"),
version = json_object.get_string_member ("Version"),
installed_version = (owned) installed_version,
// desc can be null
desc = json_object.get_null_member ("Description") ? "" : json_object.get_string_member ("Description"),
popularity = json_object.get_double_member ("Popularity")
};
}
2019-07-06 20:28:51 -04:00
public async AURPackage[] search_in_aur (string search_string) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
if (!aur_search_results.contains (search_string)) {
2019-07-06 20:28:51 -04:00
Json.Array pkgs = yield search (search_string.split (" "));
2017-07-29 10:35:04 -04:00
aur_search_results.insert (search_string, pkgs);
}
AURPackage[] result = {};
Json.Array aur_pkgs = aur_search_results.get (search_string);
aur_pkgs.foreach_element ((array, index, node) => {
Json.Object aur_pkg = node.get_object ();
// remove results which exist in repos
if (get_syncpkg (aur_pkg.get_string_member ("Name")) == null) {
result += initialise_aur_struct (node.get_object ());
}
});
return result;
}
2019-07-06 20:28:51 -04:00
public async AURPackageDetails get_aur_details (string pkgname) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
string name = "";
string version = "";
string desc = "";
double popularity = 0;
string packagebase = "";
string url = "";
string maintainer = "";
2017-10-02 10:23:53 -03:00
int64 firstsubmitted = 0;
int64 lastmodified = 0;
int64 outofdate = 0;
2017-07-29 10:35:04 -04:00
int64 numvotes = 0;
string[] licenses = {};
string[] depends = {};
string[] makedepends = {};
string[] checkdepends = {};
string[] optdepends = {};
string[] provides = {};
string[] replaces = {};
string[] conflicts = {};
var details = AURPackageDetails ();
if (!aur_infos.contains (pkgname)) {
2019-07-06 20:28:51 -04:00
Json.Array results = yield multiinfo ({pkgname});
2017-07-29 10:35:04 -04:00
if (results.get_length () > 0) {
aur_infos.insert (pkgname, results.get_object_element (0));
}
}
unowned Json.Object? json_object = aur_infos.lookup (pkgname);
if (json_object != null) {
// name
name = json_object.get_string_member ("Name");
// version
version = json_object.get_string_member ("Version");
// desc can be null
if (!json_object.get_null_member ("Description")) {
desc = json_object.get_string_member ("Description");
}
popularity = json_object.get_double_member ("Popularity");
// packagebase
packagebase = json_object.get_string_member ("PackageBase");
// url can be null
unowned Json.Node? node = json_object.get_member ("URL");
if (!node.is_null ()) {
url = node.get_string ();
}
// maintainer can be null
node = json_object.get_member ("Maintainer");
if (!node.is_null ()) {
maintainer = node.get_string ();
}
// firstsubmitted
2017-10-02 10:23:53 -03:00
firstsubmitted = json_object.get_int_member ("FirstSubmitted");
2017-07-29 10:35:04 -04:00
// lastmodified
2017-10-02 10:23:53 -03:00
lastmodified = json_object.get_int_member ("LastModified");
2017-07-29 10:35:04 -04:00
// outofdate can be null
node = json_object.get_member ("OutOfDate");
if (!node.is_null ()) {
2017-10-02 10:23:53 -03:00
outofdate = node.get_int ();
2017-07-29 10:35:04 -04:00
}
//numvotes
numvotes = json_object.get_int_member ("NumVotes");
// licenses
node = json_object.get_member ("License");
if (!node.is_null ()) {
node.get_array ().foreach_element ((array, index, _node) => {
licenses += _node.get_string ();
});
} else {
licenses += _("Unknown");
}
// depends
node = json_object.get_member ("Depends");
if (node != null) {
node.get_array ().foreach_element ((array, index, _node) => {
depends += _node.get_string ();
});
}
// optdepends
node = json_object.get_member ("OptDepends");
if (node != null) {
node.get_array ().foreach_element ((array, index, _node) => {
optdepends += _node.get_string ();
});
}
// makedepends
node = json_object.get_member ("MakeDepends");
if (node != null) {
node.get_array ().foreach_element ((array, index, _node) => {
makedepends += _node.get_string ();
});
}
// checkdepends
node = json_object.get_member ("CheckDepends");
if (node != null) {
node.get_array ().foreach_element ((array, index, _node) => {
checkdepends += _node.get_string ();
});
}
// provides
node = json_object.get_member ("Provides");
if (node != null) {
node.get_array ().foreach_element ((array, index, _node) => {
provides += _node.get_string ();
});
}
// replaces
node = json_object.get_member ("Replaces");
if (node != null) {
node.get_array ().foreach_element ((array, index, _node) => {
replaces += _node.get_string ();
});
}
// conflicts
node = json_object.get_member ("Conflicts");
if (node != null) {
node.get_array ().foreach_element ((array, index, _node) => {
conflicts += _node.get_string ();
});
}
}
details.name = (owned) name;
details.version = (owned) version ;
details.desc = (owned) desc;
details.popularity = popularity;
details.packagebase = (owned) packagebase;
details.url = (owned) url;
details.maintainer = (owned) maintainer ;
details.firstsubmitted = firstsubmitted;
details.lastmodified = lastmodified;
details.outofdate = outofdate;
details.numvotes = numvotes;
details.licenses = (owned) licenses;
details.depends = (owned) depends;
details.optdepends = (owned) optdepends;
details.checkdepends = (owned) checkdepends;
details.makedepends = (owned) makedepends;
details.provides = (owned) provides;
details.replaces = (owned) replaces;
details.conflicts = (owned) conflicts;
return details;
}
2017-10-10 16:29:22 -03:00
#endif
2017-07-29 10:35:04 -04:00
2019-07-06 20:28:51 -04:00
public string[] get_repos_names () throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
string[] repos_names = {};
unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
repos_names += db.name;
syncdbs.next ();
}
return repos_names;
}
2019-07-06 20:28:51 -04:00
public async AlpmPackage[] get_repo_pkgs (string repo) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
AlpmPackage[] pkgs = {};
unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
if (db.name == repo) {
unowned Alpm.List<unowned Alpm.Package> pkgcache = db.pkgcache;
while (pkgcache != null) {
unowned Alpm.Package sync_pkg = pkgcache.data;
unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (sync_pkg.name);
if (local_pkg != null) {
2017-10-02 10:23:53 -03:00
pkgs += initialise_pkg_struct (local_pkg);
2017-07-29 10:35:04 -04:00
} else {
2017-10-02 10:23:53 -03:00
pkgs += initialise_pkg_struct (sync_pkg);
2017-07-29 10:35:04 -04:00
}
pkgcache.next ();
}
break;
}
syncdbs.next ();
}
return pkgs;
}
2019-07-06 20:28:51 -04:00
public string[] get_groups_names () throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
string[] groups_names = {};
unowned Alpm.List<unowned Alpm.Group> groupcache = alpm_handle.localdb.groupcache;
while (groupcache != null) {
unowned Alpm.Group group = groupcache.data;
2017-10-10 16:29:22 -03:00
if (!(group.name in groups_names)) {
2017-07-29 10:35:04 -04:00
groups_names += group.name;
}
groupcache.next ();
}
unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
groupcache = db.groupcache;
while (groupcache != null) {
unowned Alpm.Group group = groupcache.data;
2017-10-10 16:29:22 -03:00
if (!(group.name in groups_names)) {
2017-07-29 10:35:04 -04:00
groups_names += group.name;
}
groupcache.next ();
}
syncdbs.next ();
}
return groups_names;
}
private Alpm.List<unowned Alpm.Package> group_pkgs (string group_name) {
Alpm.List<unowned Alpm.Package> result = null;
unowned Alpm.Group? grp = alpm_handle.localdb.get_group (group_name);
if (grp != null) {
unowned Alpm.List<unowned Alpm.Package> packages = grp.packages;
while (packages != null) {
unowned Alpm.Package pkg = packages.data;
result.add (pkg);
packages.next ();
}
}
unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
grp = db.get_group (group_name);
if (grp != null) {
unowned Alpm.List<unowned Alpm.Package> packages = grp.packages;
while (packages != null) {
unowned Alpm.Package pkg = packages.data;
if (result.find (pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) {
result.add (pkg);
}
packages.next ();
}
}
syncdbs.next ();
}
return result;
}
2019-07-06 20:28:51 -04:00
public async AlpmPackage[] get_group_pkgs (string groupname) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
AlpmPackage[] pkgs = {};
Alpm.List<unowned Alpm.Package> alpm_pkgs = group_pkgs (groupname);
unowned Alpm.List<unowned Alpm.Package> list = alpm_pkgs;
while (list != null) {
unowned Alpm.Package alpm_pkg = list.data;
2017-10-02 10:23:53 -03:00
pkgs += initialise_pkg_struct (alpm_pkg);
2017-07-29 10:35:04 -04:00
list.next ();
}
return pkgs;
}
2019-07-06 20:28:51 -04:00
public string[] get_pkg_uninstalled_optdeps (string pkgname) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
string[] optdeps = {};
unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname);
if (alpm_pkg == null) {
alpm_pkg = get_syncpkg (pkgname);
}
if (alpm_pkg != null) {
unowned Alpm.List<unowned Alpm.Depend> optdepends = alpm_pkg.optdepends;
while (optdepends != null) {
unowned Alpm.Depend optdep = optdepends.data;
if (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, optdep.name) == null) {
optdeps += optdep.compute_string ();
}
optdepends.next ();
}
}
return optdeps;
}
2019-07-06 20:28:51 -04:00
public AlpmPackageDetails get_pkg_details (string pkgname) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
string name = "";
string version = "";
string desc = "";
string url = "";
string repo = "";
string has_signature = "";
string reason = "";
string packager = "";
string builddate = "";
string installdate = "";
string downloadsize = "";
string installsize = "";
2017-07-29 10:35:04 -04:00
string[] groups = {};
string[] backups = {};
string[] licenses = {};
string[] depends = {};
string[] optdepends = {};
string[] requiredby = {};
string[] optionalfor = {};
string[] provides = {};
string[] replaces = {};
string[] conflicts = {};
var details = AlpmPackageDetails ();
unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname);
if (alpm_pkg == null) {
2017-10-02 10:23:53 -03:00
alpm_pkg = get_syncpkg (pkgname);
2017-07-29 10:35:04 -04:00
}
unowned Alpm.Package? alpm_pkg_sync = get_syncpkg (alpm_pkg.name);
if (alpm_pkg_sync == null) {
alpm_pkg_sync = get_syncpkg (pkgname);
}
2017-07-29 10:35:04 -04:00
if (alpm_pkg != null) {
// name
name = alpm_pkg.name;
// version
version = alpm_pkg.version;
// desc can be null
if (alpm_pkg.desc != null) {
desc = alpm_pkg.desc;
}
details.origin = (uint) alpm_pkg.origin;
// url can be null
if (alpm_pkg.url != null) {
url = alpm_pkg.url;
}
// packager can be null
packager = alpm_pkg.packager ?? "";
// groups
unowned Alpm.List list = alpm_pkg.groups;
while (list != null) {
groups += ((Alpm.List<unowned string>) list).data;
list.next ();
}
// download size
if (alpm_pkg_sync != null) {
downloadsize = alpm_pkg_sync.download_size.to_string ();
} else {
downloadsize = alpm_pkg.download_size.to_string ();
}
// installed size
installsize = alpm_pkg.isize.to_string ();
2017-07-29 10:35:04 -04:00
// licenses
list = alpm_pkg.licenses;
while (list != null) {
licenses += ((Alpm.List<unowned string>) list).data;
list.next ();
}
// build_date
GLib.Time time = GLib.Time.local ((time_t) alpm_pkg.builddate);
2017-10-02 10:23:53 -03:00
builddate = time.format ("%a %d %b %Y %X %Z");
2017-07-29 10:35:04 -04:00
// local pkg
if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) {
// repo
2017-10-02 10:23:53 -03:00
unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name);
2017-07-29 10:35:04 -04:00
if (sync_pkg != null) {
repo = sync_pkg.db.name;
}
// reason
if (alpm_pkg.reason == Alpm.Package.Reason.EXPLICIT) {
reason = _("Explicitly installed");
} else if (alpm_pkg.reason == Alpm.Package.Reason.DEPEND) {
reason = _("Installed as a dependency for another package");
} else {
reason = _("Unknown");
}
// install_date
time = GLib.Time.local ((time_t) alpm_pkg.installdate);
2017-10-02 10:23:53 -03:00
installdate = time.format ("%a %d %b %Y %X %Z");
2017-07-29 10:35:04 -04:00
// backups
list = alpm_pkg.backups;
while (list != null) {
backups += "/" + ((Alpm.List<unowned Alpm.Backup>) list).data.name;
list.next ();
}
// requiredby
Alpm.List<string> pkg_requiredby = alpm_pkg.compute_requiredby ();
list = pkg_requiredby;
while (list != null) {
requiredby += ((Alpm.List<unowned string>) list).data;
list.next ();
}
pkg_requiredby.free_inner (GLib.free);
// optionalfor
Alpm.List<string> pkg_optionalfor = alpm_pkg.compute_optionalfor ();
list = pkg_optionalfor;
while (list != null) {
optionalfor += ((Alpm.List<unowned string>) list).data;
list.next ();
}
pkg_optionalfor.free_inner (GLib.free);
// sync pkg
} else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) {
// repos
repo = alpm_pkg.db.name;
// signature
has_signature = alpm_pkg.base64_sig != null ? _("Yes") : _("No");
}
// depends
list = alpm_pkg.depends;
while (list != null) {
depends += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string ();
list.next ();
}
// optdepends
list = alpm_pkg.optdepends;
while (list != null) {
optdepends += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string ();
list.next ();
}
// provides
list = alpm_pkg.provides;
while (list != null) {
provides += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string ();
list.next ();
}
// replaces
list = alpm_pkg.replaces;
while (list != null) {
replaces += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string ();
list.next ();
}
// conflicts
list = alpm_pkg.conflicts;
while (list != null) {
conflicts += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string ();
list.next ();
}
}
details.name = (owned) name;
details.version = (owned) version;
details.desc = (owned) desc;
details.repo = (owned) repo;
details.url = (owned) url;
details.packager = (owned) packager;
details.builddate = (owned) builddate;
details.installdate = (owned) installdate;
details.reason = (owned) reason;
details.downloadsize = (owned) downloadsize;
details.installsize = (owned) installsize;
2017-07-29 10:35:04 -04:00
details.has_signature = (owned) has_signature;
details.licenses = (owned) licenses;
details.depends = (owned) depends;
details.optdepends = (owned) optdepends;
details.requiredby = (owned) requiredby;
details.optionalfor = (owned) optionalfor;
details.provides = (owned) provides;
details.replaces = (owned) replaces;
details.conflicts = (owned) conflicts;
details.groups = (owned) groups;
details.backups = (owned) backups;
return details;
}
2019-07-06 20:28:51 -04:00
public string[] get_pkg_files (string pkgname) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
string[] files = {};
unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname);
if (alpm_pkg != null) {
unowned Alpm.FileList filelist = alpm_pkg.files;
Alpm.File* file_ptr = filelist.files;
for (size_t i = 0; i < filelist.count; i++, file_ptr++) {
if (!file_ptr->name.has_suffix ("/")) {
files += "/" + file_ptr->name;
}
}
} else {
unowned Alpm.List<unowned Alpm.DB> syncdbs = files_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
unowned Alpm.Package? files_pkg = db.get_pkg (pkgname);
if (files_pkg != null) {
unowned Alpm.FileList filelist = files_pkg.files;
Alpm.File* file_ptr = filelist.files;
for (size_t i = 0; i < filelist.count; i++, file_ptr++) {
if (!file_ptr->name.has_suffix ("/")) {
files += "/" + file_ptr->name;
}
}
break;
}
syncdbs.next ();
}
}
return files;
}
private int get_updates () {
2017-10-02 10:23:53 -03:00
AlpmPackage[] updates_infos = {};
2019-07-06 20:28:51 -04:00
#if DISABLE_AUR
#else
2017-07-29 10:35:04 -04:00
unowned Alpm.Package? pkg = null;
2019-07-06 20:28:51 -04:00
#endif
2017-07-29 10:35:04 -04:00
unowned Alpm.Package? candidate = null;
// use a tmp handle
var tmp_handle = alpm_config.get_handle (false, true);
// refresh tmp dbs
unowned Alpm.List<unowned Alpm.DB> syncdbs = tmp_handle.syncdbs;
2021-07-09 08:00:59 -04:00
// TODO: read return value
tmp_handle.update_dbs(syncdbs, 0);
2017-08-22 06:11:31 -03:00
// refresh file dbs
var pamac_config = new Pamac.Config ();
if (pamac_config.update_files_db) {
var tmp_files_handle = alpm_config.get_handle (true, true);
syncdbs = tmp_files_handle.syncdbs;
2021-07-09 08:00:59 -04:00
tmp_files_handle.update_dbs(syncdbs, 0);
} else {
var tmp_files_handle = alpm_config.get_handle (false, true);
syncdbs = tmp_files_handle.syncdbs;
2021-07-09 08:00:59 -04:00
tmp_files_handle.update_dbs(syncdbs, 0);
2017-08-22 06:11:31 -03:00
}
2019-07-06 20:28:51 -04:00
#if DISABLE_AUR
#else
2017-07-29 10:35:04 -04:00
string[] local_pkgs = {};
2019-07-06 20:28:51 -04:00
#endif
2017-07-29 10:35:04 -04:00
unowned Alpm.List<unowned Alpm.Package> pkgcache = tmp_handle.localdb.pkgcache;
while (pkgcache != null) {
unowned Alpm.Package installed_pkg = pkgcache.data;
// check if installed_pkg is in IgnorePkg or IgnoreGroup
if (tmp_handle.should_ignore (installed_pkg) == 0) {
2019-10-23 14:41:05 -03:00
candidate = installed_pkg.get_new_version (tmp_handle.syncdbs);
2017-07-29 10:35:04 -04:00
if (candidate != null) {
var infos = initialise_pkg_struct (candidate);
infos.installed_version = installed_pkg.version;
2017-10-02 10:23:53 -03:00
updates_infos += (owned) infos;
2017-10-10 16:29:22 -03:00
#if DISABLE_AUR
#else
2017-07-29 10:35:04 -04:00
} else {
if (check_aur_updates && (!aur_updates_checked)) {
// check if installed_pkg is a local pkg
syncdbs = tmp_handle.syncdbs;
while (syncdbs != null) {
unowned Alpm.DB db = syncdbs.data;
pkg = Alpm.find_satisfier (db.pkgcache, installed_pkg.name);
if (pkg != null) {
break;
}
syncdbs.next ();
}
if (pkg == null) {
local_pkgs += installed_pkg.name;
}
}
2017-10-10 16:29:22 -03:00
#endif
2017-07-29 10:35:04 -04:00
}
}
pkgcache.next ();
}
2017-10-10 16:29:22 -03:00
#if DISABLE_AUR
#else
2017-07-29 10:35:04 -04:00
if (check_aur_updates) {
// get aur updates
if (!aur_updates_checked) {
2019-07-06 20:28:51 -04:00
multiinfo.begin (local_pkgs, (obj, res) => {
aur_updates_results = multiinfo.end (res);
2017-07-29 10:35:04 -04:00
aur_updates_checked = true;
var updates = Updates () {
2017-10-02 10:23:53 -03:00
repos_updates = (owned) updates_infos,
aur_updates = get_aur_updates_infos ()
2017-07-29 10:35:04 -04:00
};
get_updates_finished (updates);
});
} else {
var updates = Updates () {
2017-10-02 10:23:53 -03:00
repos_updates = (owned) updates_infos,
aur_updates = get_aur_updates_infos ()
2017-07-29 10:35:04 -04:00
};
get_updates_finished (updates);
}
} else {
2017-10-10 16:29:22 -03:00
#endif
2017-07-29 10:35:04 -04:00
var updates = Updates () {
2017-10-10 16:29:22 -03:00
#if DISABLE_AUR
repos_updates = (owned) updates_infos
#else
2017-10-02 10:23:53 -03:00
repos_updates = (owned) updates_infos,
2017-07-29 10:35:04 -04:00
aur_updates = {}
2017-10-10 16:29:22 -03:00
#endif
2017-07-29 10:35:04 -04:00
};
get_updates_finished (updates);
2017-10-10 16:29:22 -03:00
#if DISABLE_AUR
#else
2017-07-29 10:35:04 -04:00
}
2017-10-10 16:29:22 -03:00
#endif
2017-07-29 10:35:04 -04:00
return 0;
}
2017-10-10 16:29:22 -03:00
#if DISABLE_AUR
#else
2017-10-02 10:23:53 -03:00
private AURPackage[] get_aur_updates_infos () {
AURPackage[] aur_updates_infos = {};
aur_updates_results.foreach_element ((array, index, node) => {
2017-07-29 10:35:04 -04:00
unowned Json.Object pkg_info = node.get_object ();
unowned string name = pkg_info.get_string_member ("Name");
unowned string new_version = pkg_info.get_string_member ("Version");
unowned string old_version = alpm_handle.localdb.get_pkg (name).version;
if (Alpm.pkg_vercmp (new_version, old_version) == 1) {
var infos = initialise_aur_struct (pkg_info);
infos.installed_version = old_version;
2017-10-02 10:23:53 -03:00
aur_updates_infos += (owned) infos;
2017-07-29 10:35:04 -04:00
}
});
2017-10-02 10:23:53 -03:00
return aur_updates_infos;
2017-07-29 10:35:04 -04:00
}
2017-10-10 16:29:22 -03:00
#endif
2017-07-29 10:35:04 -04:00
2017-10-10 16:29:22 -03:00
#if DISABLE_AUR
2019-07-06 20:28:51 -04:00
public void start_get_updates () throws DBusError, IOError {
2017-10-10 16:29:22 -03:00
#else
2019-07-06 20:28:51 -04:00
public void start_get_updates (bool check_aur_updates_) throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
check_aur_updates = check_aur_updates_;
2017-10-10 16:29:22 -03:00
#endif
2017-07-29 10:35:04 -04:00
new Thread<int> ("get updates thread", get_updates);
}
[DBus (no_reply = true)]
2019-07-06 20:28:51 -04:00
public void quit () throws DBusError, IOError {
2017-07-29 10:35:04 -04:00
loop.quit ();
}
// End of Daemon Object
}
}
2017-10-10 16:29:22 -03:00
private int alpm_pkg_compare_name (Alpm.Package pkg_a, Alpm.Package pkg_b) {
return strcmp (pkg_a.name, pkg_b.name);
}
private string global_search_string;
private int alpm_pkg_sort_search_by_relevance (Alpm.Package pkg_a, Alpm.Package pkg_b) {
if (global_search_string != null) {
// display exact match first
if (pkg_a.name == global_search_string) {
return 0;
}
if (pkg_b.name == global_search_string) {
return 1;
}
if (pkg_a.name.has_prefix (global_search_string + "-")) {
if (pkg_b.name.has_prefix (global_search_string + "-")) {
return strcmp (pkg_a.name, pkg_b.name);
}
return 0;
}
if (pkg_b.name.has_prefix (global_search_string + "-")) {
if (pkg_a.name.has_prefix (global_search_string + "-")) {
return strcmp (pkg_a.name, pkg_b.name);
}
return 1;
}
if (pkg_a.name.has_prefix (global_search_string)) {
if (pkg_b.name.has_prefix (global_search_string)) {
return strcmp (pkg_a.name, pkg_b.name);
}
return 0;
}
if (pkg_b.name.has_prefix (global_search_string)) {
if (pkg_a.name.has_prefix (global_search_string)) {
return strcmp (pkg_a.name, pkg_b.name);
}
return 1;
}
if (pkg_a.name.contains (global_search_string)) {
if (pkg_b.name.contains (global_search_string)) {
return strcmp (pkg_a.name, pkg_b.name);
}
return 0;
}
if (pkg_b.name.contains (global_search_string)) {
if (pkg_a.name.contains (global_search_string)) {
return strcmp (pkg_a.name, pkg_b.name);
}
return 1;
}
}
return strcmp (pkg_a.name, pkg_b.name);
}
2017-07-29 10:35:04 -04:00
void on_bus_acquired (DBusConnection conn) {
user_daemon = new Pamac.UserDaemon ();
try {
2017-10-10 16:29:22 -03:00
conn.register_object ("/org/pamac/user", user_daemon);
2017-07-29 10:35:04 -04:00
}
catch (IOError e) {
stderr.printf ("Could not register service\n");
loop.quit ();
}
}
void main () {
// i18n
2019-07-06 20:28:51 -04:00
Intl.bindtextdomain(Constants.GETTEXT_PACKAGE, Path.build_filename(Constants.DATADIR,"locale"));
2017-07-29 10:35:04 -04:00
Intl.setlocale (LocaleCategory.ALL, "");
2019-07-06 20:28:51 -04:00
Intl.textdomain(Constants.GETTEXT_PACKAGE);
Intl.bind_textdomain_codeset(Constants.GETTEXT_PACKAGE, "utf-8" );
2017-07-29 10:35:04 -04:00
Bus.own_name (BusType.SESSION,
2017-10-10 16:29:22 -03:00
"org.pamac.user",
2017-07-29 10:35:04 -04:00
BusNameOwnerFlags.NONE,
on_bus_acquired,
null,
() => {
stderr.printf ("Could not acquire name\n");
loop.quit ();
});
loop = new MainLoop ();
loop.run ();
}