pamac-classic/src/transaction.vala

962 lines
33 KiB
Vala
Raw Normal View History

2014-10-22 13:44:02 -03:00
/*
* pamac-vala
*
* Copyright (C) 2014 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/>.
*/
using Gtk;
using Vte;
using Alpm;
namespace Pamac {
[DBus (name = "org.manjaro.pamac")]
public interface Daemon : Object {
public abstract void write_config (HashTable<string,string> new_conf) throws IOError;
2014-10-30 10:44:09 -03:00
public abstract void refresh (int force, bool emit_signal) throws IOError;
2014-10-22 13:44:02 -03:00
public abstract ErrorInfos trans_init (TransFlag transflags) throws IOError;
public abstract ErrorInfos trans_sysupgrade (int enable_downgrade) throws IOError;
public abstract ErrorInfos trans_add_pkg (string pkgname) throws IOError;
public abstract ErrorInfos trans_remove_pkg (string pkgname) throws IOError;
public abstract ErrorInfos trans_load_pkg (string pkgpath) throws IOError;
2014-10-30 10:44:09 -03:00
public abstract void trans_prepare () throws IOError;
2014-10-22 13:44:02 -03:00
public abstract void choose_provider (int provider) throws IOError;
public abstract UpdatesInfos[] trans_to_add () throws IOError;
public abstract UpdatesInfos[] trans_to_remove () throws IOError;
2014-10-30 10:44:09 -03:00
public abstract void trans_commit () throws IOError;
2014-10-22 13:44:02 -03:00
public abstract void trans_release () throws IOError;
public abstract void trans_cancel () throws IOError;
[DBus (no_reply = true)]
public abstract void quit () throws IOError;
2014-10-26 08:30:04 -03:00
public signal void emit_event (uint event, string[] details);
2014-10-22 13:44:02 -03:00
public signal void emit_providers (string depend, string[] providers);
2014-10-26 08:30:04 -03:00
public signal void emit_progress (uint progress, string pkgname, int percent, uint n_targets, uint current_target);
2014-10-22 13:44:02 -03:00
public signal void emit_download (string filename, uint64 xfered, uint64 total);
public signal void emit_totaldownload (uint64 total);
public signal void emit_log (uint level, string msg);
public signal void emit_refreshed (ErrorInfos error);
public signal void emit_trans_prepared (ErrorInfos error);
public signal void emit_trans_committed (ErrorInfos error);
}
public class Transaction: Object {
public Daemon daemon;
2014-10-30 10:44:09 -03:00
public string[] syncfirst;
public string[] holdpkg;
public string[] ignorepkg;
public Handle handle;
2014-10-22 13:44:02 -03:00
public Pamac.Config pamac_config;
2014-10-30 10:44:09 -03:00
public Alpm.TransFlag flags;
// those hashtables will be used as set
public HashTable<string, string> to_add;
public HashTable<string, string> to_remove;
public HashTable<string, string> to_load;
public HashTable<string, string> to_build;
2014-10-22 13:44:02 -03:00
public Mode mode;
uint64 total_download;
uint64 already_downloaded;
string previous_label;
string previous_textbar;
double previous_percent;
string previous_filename;
uint build_timeout_id;
bool sysupgrade_after_trans;
bool sysupgrade_after_build;
2014-10-26 08:30:04 -03:00
int build_status;
2014-10-22 13:44:02 -03:00
Terminal term;
2014-10-24 10:29:39 -03:00
Pty pty;
2014-10-22 13:44:02 -03:00
//dialogs
ChooseProviderDialog choose_provider_dialog;
TransactionSumDialog transaction_sum_dialog;
TransactionInfoDialog transaction_info_dialog;
2014-10-30 10:44:09 -03:00
ProgressDialog progress_dialog;
2014-10-22 13:44:02 -03:00
//parent window
ApplicationWindow? window;
public signal void finished (bool error);
public Transaction (ApplicationWindow? window, Pamac.Config pamac_config) {
2014-10-30 10:44:09 -03:00
refresh_alpm_config ();
2014-10-22 13:44:02 -03:00
this.pamac_config = pamac_config;
mode = Mode.MANAGER;
2014-10-30 10:44:09 -03:00
flags = Alpm.TransFlag.CASCADE;
to_add = new HashTable<string, string> (str_hash, str_equal);
to_remove = new HashTable<string, string> (str_hash, str_equal);
to_load = new HashTable<string, string> (str_hash, str_equal);
to_build = new HashTable<string, string> (str_hash, str_equal);
2014-10-22 13:44:02 -03:00
connecting_dbus_signals ();
//creating dialogs
this.window = window;
choose_provider_dialog = new ChooseProviderDialog (window);
transaction_sum_dialog = new TransactionSumDialog (window);
transaction_info_dialog = new TransactionInfoDialog (window);
2014-10-30 10:44:09 -03:00
progress_dialog = new ProgressDialog (this, window);
2014-10-22 13:44:02 -03:00
//creating terminal
term = new Terminal ();
term.scroll_on_output = false;
term.expand = true;
term.height_request = 200;
term.set_visible (true);
2014-10-24 10:29:39 -03:00
// creating pty for term
try {
pty = term.pty_new_sync (PtyFlags.NO_HELPER);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
// connect to child_exited signal which will only be emit after a call to watch_child
term.child_exited.connect (on_term_child_exited);
2014-10-22 13:44:02 -03:00
// add term in a grid with a scrollbar
var grid = new Grid ();
grid.expand = true;
grid.set_visible (true);
var sb = new Scrollbar (Orientation.VERTICAL, term.vadjustment);
sb.set_visible (true);
grid.attach (term, 0, 0, 1, 1);
grid.attach (sb, 1, 0, 1, 1);
2014-10-30 10:44:09 -03:00
progress_dialog.expander.add (grid);
2014-10-22 13:44:02 -03:00
// progress data
total_download = 0;
already_downloaded = 0;
previous_label = "";
previous_textbar = "";
previous_percent = 0.0;
previous_filename = "";
sysupgrade_after_trans = false;
sysupgrade_after_build = false;
2014-10-26 08:30:04 -03:00
build_status = 0;
2014-10-22 13:44:02 -03:00
}
public void write_config (HashTable<string,string> new_conf) {
try {
daemon.write_config (new_conf);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
public void refresh_alpm_config () {
2014-10-30 10:44:09 -03:00
var alpm_config = new Alpm.Config ("/etc/pacman.conf");
syncfirst = alpm_config.get_syncfirst ();
holdpkg = alpm_config.get_holdpkg ();
ignorepkg = alpm_config.get_ignore_pkgs ();
handle = alpm_config.get_handle ();
2014-10-22 13:44:02 -03:00
}
public void refresh (int force) {
2014-10-26 08:30:04 -03:00
string action = dgettext (null, "Synchronizing package databases") + "...";
spawn_in_term ({"/usr/bin/echo", action});
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (action);
progress_dialog.progressbar.set_fraction (0);
progress_dialog.progressbar.set_text ("");
progress_dialog.cancel_button.set_visible (true);
progress_dialog.close_button.set_visible (false);
progress_dialog.show ();
try {
daemon.refresh (force, true);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
2014-10-22 13:44:02 -03:00
}
public void sysupgrade_simple (int enable_downgrade) {
2014-10-26 08:30:04 -03:00
print ("simple sysupgrade\n");
2014-10-30 10:44:09 -03:00
progress_dialog.progressbar.set_fraction (0);
progress_dialog.cancel_button.set_visible (true);
2014-10-22 13:44:02 -03:00
ErrorInfos err = ErrorInfos ();
try {
err = daemon.trans_init (0);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str != "") {
finished (true);
handle_error (err);
} else {
try {
err = daemon.trans_sysupgrade (enable_downgrade);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str == "") {
2014-10-30 10:44:09 -03:00
progress_dialog.show ();
2014-10-22 13:44:02 -03:00
while (Gtk.events_pending ())
Gtk.main_iteration ();
2014-10-30 10:44:09 -03:00
try {
daemon.trans_prepare ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
2014-10-22 13:44:02 -03:00
} else {
release ();
finished (true);
handle_error (err);
}
}
}
public void sysupgrade (int enable_downgrade) {
2014-10-26 08:30:04 -03:00
string action = dgettext (null, "Starting full system upgrade") + "...";
spawn_in_term ({"/usr/bin/echo", action});
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (action);
progress_dialog.progressbar.set_fraction (0);
progress_dialog.progressbar.set_text ("");
progress_dialog.cancel_button.set_visible (true);
progress_dialog.close_button.set_visible (false);
2014-10-22 13:44:02 -03:00
while (Gtk.events_pending ())
Gtk.main_iteration ();
// sysupgrade
2014-10-26 08:30:04 -03:00
print ("get syncfirst\n");
2014-10-22 13:44:02 -03:00
// get syncfirst updates
2014-10-30 10:44:09 -03:00
UpdatesInfos[] syncfirst_updates = get_syncfirst_updates (handle, syncfirst);
2014-10-22 13:44:02 -03:00
if (syncfirst_updates.length != 0) {
clear_lists ();
if (mode == Mode.MANAGER)
sysupgrade_after_trans = true;
foreach (UpdatesInfos infos in syncfirst_updates)
2014-10-30 10:44:09 -03:00
to_add.insert (infos.name, infos.name);
2014-10-22 13:44:02 -03:00
// run as a standard transaction
run ();
} else {
if (pamac_config.enable_aur) {
2014-10-26 08:30:04 -03:00
print ("get aur updates\n");
2014-10-30 10:44:09 -03:00
UpdatesInfos[] aur_updates = get_aur_updates (handle, ignorepkg);
2014-10-22 13:44:02 -03:00
if (aur_updates.length != 0) {
clear_lists ();
sysupgrade_after_build = true;
foreach (UpdatesInfos infos in aur_updates)
2014-10-30 10:44:09 -03:00
to_build.insert (infos.name, infos.name);
2014-10-22 13:44:02 -03:00
}
}
sysupgrade_simple (enable_downgrade);
}
}
public void clear_lists () {
2014-10-30 10:44:09 -03:00
to_add.steal_all ();
to_remove.steal_all ();
to_build.steal_all ();
2014-10-22 13:44:02 -03:00
}
public void run () {
string action = dgettext (null,"Preparing") + "...";
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", action});
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (action);
progress_dialog.progressbar.set_fraction (0);
progress_dialog.progressbar.set_text ("");
progress_dialog.cancel_button.set_visible (true);
progress_dialog.close_button.set_visible (false);
progress_dialog.show ();
2014-10-22 13:44:02 -03:00
while (Gtk.events_pending ())
Gtk.main_iteration ();
// run
ErrorInfos err = ErrorInfos ();
2014-10-30 10:44:09 -03:00
if (to_add.size () == 0
&& to_remove.size () == 0
&& to_load.size () == 0
&& to_build.size () != 0) {
2014-10-22 13:44:02 -03:00
// there only AUR packages to build so no need to prepare transaction
on_emit_trans_prepared (err);
} else {
try {
2014-10-30 10:44:09 -03:00
err = daemon.trans_init (flags);
2014-10-22 13:44:02 -03:00
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str != "") {
finished (true);
handle_error (err);
} else {
2014-10-30 10:44:09 -03:00
foreach (string name in to_add.get_keys ()) {
2014-10-22 13:44:02 -03:00
try {
err = daemon.trans_add_pkg (name);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str != "")
break;
}
2014-10-30 10:44:09 -03:00
foreach (string name in to_remove.get_keys ()) {
2014-10-22 13:44:02 -03:00
try {
err = daemon.trans_remove_pkg (name);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str != "")
break;
}
2014-10-30 10:44:09 -03:00
foreach (string path in to_load.get_keys ()) {
2014-10-22 13:44:02 -03:00
try {
err = daemon.trans_load_pkg (path);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
if (err.str != "")
break;
}
if (err.str == "") {
2014-10-30 10:44:09 -03:00
try {
daemon.trans_prepare ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
2014-10-22 13:44:02 -03:00
} else {
release ();
finished (true);
handle_error (err);
}
}
}
}
public void choose_provider (string depend, string[] providers) {
int len = providers.length;
2014-10-26 08:30:04 -03:00
choose_provider_dialog.label.set_markup ("<b>%s</b>".printf (dgettext (null, "Choose a provider for %s").printf (depend, len)));
2014-10-22 13:44:02 -03:00
choose_provider_dialog.comboboxtext.remove_all ();
foreach (string provider in providers)
choose_provider_dialog.comboboxtext.append_text (provider);
choose_provider_dialog.comboboxtext.active = 0;
choose_provider_dialog.run ();
choose_provider_dialog.hide ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
try {
daemon.choose_provider (choose_provider_dialog.comboboxtext.active);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
public int set_transaction_sum () {
// return 1 if transaction_sum is empty, 0 otherwise
int ret = 1;
uint64 dsize = 0;
UpdatesInfos[] prepared_to_add = {};
UpdatesInfos[] prepared_to_remove = {};
string[] to_downgrade = {};
string[] to_install = {};
string[] to_reinstall = {};
string[] to_update = {};
2014-10-30 10:44:09 -03:00
string[] _to_build = {};
2014-10-22 13:44:02 -03:00
TreeIter iter;
transaction_sum_dialog.top_label.set_markup ("<big><b>%s</b></big>".printf (dgettext (null, "Transaction Summary")));
transaction_sum_dialog.sum_list.clear ();
try {
prepared_to_add = daemon.trans_to_add ();
prepared_to_remove = daemon.trans_to_remove ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
foreach (UpdatesInfos pkg_info in prepared_to_add) {
dsize += pkg_info.download_size;
2014-10-30 10:44:09 -03:00
unowned Alpm.Package? local_pkg = handle.localdb.get_pkg (pkg_info.name);
2014-10-22 13:44:02 -03:00
if (local_pkg == null) {
to_install += "%s %s".printf (pkg_info.name, pkg_info.version);
} else {
int cmp = pkg_vercmp (pkg_info.version, local_pkg.version);
if (cmp == 1)
to_update += "%s %s".printf (pkg_info.name, pkg_info.version);
else if (cmp == 0)
to_reinstall += "%s %s".printf (pkg_info.name, pkg_info.version);
else
to_downgrade += "%s %s".printf (pkg_info.name, pkg_info.version);
}
}
2014-10-30 10:44:09 -03:00
foreach (string name in to_build.get_keys ())
_to_build += name;
2014-10-22 13:44:02 -03:00
int len = prepared_to_remove.length;
int i;
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To remove") + ":",
1, "%s %s".printf (prepared_to_remove[0].name, prepared_to_remove[0].version));
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
1, "%s %s".printf (prepared_to_remove[i].name, prepared_to_remove[i].version));
i++;
}
}
len = to_downgrade.length;
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To downgrade") + ":",
1, to_downgrade[0]);
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
1, to_downgrade[i]);
i++;
}
}
2014-10-30 10:44:09 -03:00
len = _to_build.length;
2014-10-22 13:44:02 -03:00
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To build") + ":",
2014-10-30 10:44:09 -03:00
1, _to_build[0]);
2014-10-22 13:44:02 -03:00
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
2014-10-30 10:44:09 -03:00
1, _to_build[i]);
2014-10-22 13:44:02 -03:00
i++;
}
}
len = to_install.length;
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To install") + ":",
1, to_install[0]);
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
1, to_install[i]);
i++;
}
}
len = to_reinstall.length;
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To reinstall") + ":",
1, to_reinstall[0]);
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
1, to_reinstall[i]);
i++;
}
}
if (mode == Mode.MANAGER) {
len = to_update.length;
if (len != 0) {
ret = 0;
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
0, dgettext (null, "To update") + ":",
1, to_update[0]);
i = 1;
while (i < len) {
transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
1, to_update[i]);
i++;
}
}
}
if (dsize == 0)
transaction_sum_dialog.bottom_label.set_visible (false);
else {
2014-10-26 08:30:04 -03:00
transaction_sum_dialog.bottom_label.set_markup ("<b>%s: %s</b>".printf (dgettext (null, "Total download size"), format_size (dsize)));
2014-10-22 13:44:02 -03:00
transaction_sum_dialog.bottom_label.set_visible (true);
}
return ret;
}
public void commit () {
2014-10-30 10:44:09 -03:00
progress_dialog.cancel_button.set_visible (false);
try {
daemon.trans_commit ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
2014-10-22 13:44:02 -03:00
}
public void build_aur_packages () {
2014-10-24 10:29:39 -03:00
print ("building packages\n");
2014-10-22 13:44:02 -03:00
string action = dgettext (null,"Building packages") + "...";
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", "-n", action});
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (action);
progress_dialog.progressbar.set_fraction (0);
progress_dialog.progressbar.set_text ("");
progress_dialog.cancel_button.set_visible (false);
progress_dialog.close_button.set_visible (false);
progress_dialog.expander.set_expanded (true);
progress_dialog.width_request = 700;
2014-10-22 13:44:02 -03:00
term.grab_focus ();
2014-10-30 10:44:09 -03:00
build_timeout_id = Timeout.add (500, (GLib.SourceFunc) progress_dialog.progressbar.pulse);
2014-10-24 10:29:39 -03:00
string[] cmds = {"/usr/bin/yaourt", "-S"};
2014-10-30 10:44:09 -03:00
foreach (string name in to_build.get_keys ())
2014-10-24 10:29:39 -03:00
cmds += name;
Pid child_pid;
spawn_in_term (cmds, out child_pid);
// watch_child is needed in order to have the child_exited signal emitted
term.watch_child (child_pid);
2014-10-22 13:44:02 -03:00
}
public void cancel () {
try {
daemon.trans_cancel ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
public void release () {
try {
daemon.trans_release ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
public void stop_daemon () {
try {
daemon.quit ();
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
2014-10-26 08:30:04 -03:00
public void spawn_in_term (string[] args, out int pid = null) {
2014-10-24 10:29:39 -03:00
try {
Process.spawn_async (null, args, null, SpawnFlags.DO_NOT_REAP_CHILD, pty.child_setup, out pid);
} catch (SpawnError e) {
stderr.printf ("SpawnError: %s\n", e.message);
}
term.set_pty (pty);
}
2014-10-26 08:30:04 -03:00
void on_emit_event (uint event, string[] details) {
string msg;
2014-10-22 13:44:02 -03:00
switch (event) {
case Event.CHECKDEPS_START:
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Checking dependencies") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.FILECONFLICTS_START:
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Checking file conflicts") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.RESOLVEDEPS_START:
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Resolving dependencies") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.INTERCONFLICTS_START:
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Checking inter-conflicts") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.ADD_START:
2014-10-30 10:44:09 -03:00
progress_dialog.cancel_button.set_visible (false);
2014-10-26 08:30:04 -03:00
previous_filename = details[0];
msg = dgettext (null, "Installing %s").printf (details[0]) + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Installing %s").printf ("%s (%s)".printf (details[0], details[1]))+ "...";
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
2014-10-26 08:30:04 -03:00
case Event.REINSTALL_START:
2014-10-30 10:44:09 -03:00
progress_dialog.cancel_button.set_visible (false);
2014-10-26 08:30:04 -03:00
previous_filename = details[0];
msg = dgettext (null, "Reinstalling %s").printf (details[0]) + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Reinstalling %s").printf ("%s (%s)".printf (details[0], details[1]))+ "...";
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.REMOVE_START:
2014-10-30 10:44:09 -03:00
progress_dialog.cancel_button.set_visible (false);
2014-10-26 08:30:04 -03:00
previous_filename = details[0];
msg = dgettext (null, "Removing %s").printf (details[0]) + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Removing %s").printf ("%s (%s)".printf (details[0], details[1]))+ "...";
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.UPGRADE_START:
2014-10-30 10:44:09 -03:00
progress_dialog.cancel_button.set_visible (false);
2014-10-26 08:30:04 -03:00
previous_filename = details[0];
msg = dgettext (null, "Upgrading %s").printf (details[0]) + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Upgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2]))+ "...";
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.DOWNGRADE_START:
2014-10-30 10:44:09 -03:00
progress_dialog.cancel_button.set_visible (false);
2014-10-26 08:30:04 -03:00
previous_filename = details[0];
msg = dgettext (null, "Downgrading %s").printf (details[0]) + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Downgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2]))+ "...";
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.INTEGRITY_START:
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Checking integrity") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.KEYRING_START:
2014-10-30 10:44:09 -03:00
progress_dialog.cancel_button.set_visible (true);
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Checking keyring") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
break;
case Event.KEY_DOWNLOAD_START:
msg = dgettext (null, "Downloading required keys") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.LOAD_START:
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Loading packages files") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
break;
case Event.DELTA_INTEGRITY_START:
msg = dgettext (null, "Checking delta integrity") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
break;
case Event.DELTA_PATCHES_START:
msg = dgettext (null, "Applying deltas") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
break;
case Event.DELTA_PATCH_START:
msg = dgettext (null, "Generating %s with %s").printf (details[0], details[1]) + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
break;
case Event.DELTA_PATCH_DONE:
msg = dgettext (null, "Generation succeeded") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
break;
case Event.DELTA_PATCH_FAILED:
msg = dgettext (null, "Generation failed") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.SCRIPTLET_INFO:
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (dgettext (null, "Configuring %s").printf (previous_filename) + "...");
progress_dialog.expander.set_expanded (true);
2014-11-01 13:59:16 -03:00
spawn_in_term ({"/usr/bin/echo", "-n", details[0]});
2014-10-22 13:44:02 -03:00
break;
case Event.RETRIEVE_START:
2014-10-30 10:44:09 -03:00
progress_dialog.cancel_button.set_visible (true);
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Downloading") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
case Event.DISKSPACE_START:
2014-10-26 08:30:04 -03:00
msg = dgettext (null, "Checking available disk space") + "...";
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (msg);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", msg});
2014-10-22 13:44:02 -03:00
break;
2014-10-26 08:30:04 -03:00
case Event.OPTDEP_REQUIRED:
spawn_in_term ({"/usr/bin/echo", dgettext (null, "%s optionally requires %s").printf (details[0], details[1])});
break;
case Event.DATABASE_MISSING:
spawn_in_term ({"/usr/bin/echo", dgettext (null, "Database file for %s does not exist").printf (details[0])});
2014-10-22 13:44:02 -03:00
break;
default:
break;
}
2014-10-26 08:30:04 -03:00
while (Gtk.events_pending ())
Gtk.main_iteration ();
2014-10-22 13:44:02 -03:00
}
void on_emit_providers (string depend, string[] providers) {
choose_provider (depend, providers);
}
2014-10-26 08:30:04 -03:00
void on_emit_progress (uint progress, string pkgname, int percent, uint n_targets, uint current_target) {
2014-10-22 13:44:02 -03:00
double fraction;
switch (progress) {
case Progress.ADD_START:
case Progress.UPGRADE_START:
case Progress.DOWNGRADE_START:
case Progress.REINSTALL_START:
case Progress.REMOVE_START:
fraction = ((float) (current_target-1)/n_targets)+((float) percent/(100*n_targets));
break;
case Progress.CONFLICTS_START:
case Progress.DISKSPACE_START:
case Progress.INTEGRITY_START:
case Progress.KEYRING_START:
case Progress.LOAD_START:
default:
fraction = (float) percent/100;
break;
}
string textbar = "%lu/%lu".printf (current_target, n_targets);
if (textbar != previous_textbar) {
previous_textbar = textbar;
2014-10-30 10:44:09 -03:00
progress_dialog.progressbar.set_text (textbar);
2014-10-22 13:44:02 -03:00
}
if (fraction != previous_percent) {
previous_percent = fraction;
2014-10-30 10:44:09 -03:00
progress_dialog.progressbar.set_fraction (fraction);
2014-10-22 13:44:02 -03:00
}
while (Gtk.events_pending ())
Gtk.main_iteration ();
}
void on_emit_download (string filename, uint64 xfered, uint64 total) {
string label;
string textbar;
double fraction;
if (filename != previous_filename) {
previous_filename = filename;
if (filename.has_suffix (".db")) {
2014-10-26 08:30:04 -03:00
label = dgettext (null, "Refreshing %s").printf (filename.replace (".db", "")) + "...";
2014-10-22 13:44:02 -03:00
} else {
2014-10-26 08:30:04 -03:00
label = dgettext (null, "Downloading %s").printf (filename.replace (".pkg.tar.xz", "")) + "...";
2014-10-22 13:44:02 -03:00
}
if (label != previous_label) {
previous_label = label;
2014-10-30 10:44:09 -03:00
progress_dialog.action_label.set_text (label);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", label});
2014-10-22 13:44:02 -03:00
}
}
if (total_download > 0) {
fraction = (float) (xfered + already_downloaded) / total_download;
textbar = "%s/%s".printf (format_size (xfered + already_downloaded), format_size (total_download));
} else {
fraction = (float) xfered / total;
textbar = "%s/%s".printf (format_size (xfered), format_size (total));
}
if (fraction != previous_percent) {
previous_percent = fraction;
2014-10-30 10:44:09 -03:00
progress_dialog.progressbar.set_fraction (fraction);
2014-10-22 13:44:02 -03:00
}
if (textbar != previous_textbar) {
previous_textbar = textbar;
2014-10-30 10:44:09 -03:00
progress_dialog.progressbar.set_text (textbar);
2014-10-22 13:44:02 -03:00
}
if (xfered == total)
already_downloaded += total;
}
void on_emit_totaldownload (uint64 total) {
total_download = total;
}
void on_emit_log (uint level, string msg) {
// msg ends with \n
string? line = null;
TextIter end_iter;
if ((Alpm.LogLevel) level == Alpm.LogLevel.WARNING) {
2014-11-01 13:59:16 -03:00
line = dgettext (null, "Warning") + ": " + previous_filename + ": " + msg;
2014-10-22 13:44:02 -03:00
transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
transaction_info_dialog.textbuffer.insert (ref end_iter, msg, msg.length);
} else if ((Alpm.LogLevel) level == Alpm.LogLevel.ERROR) {
2014-11-01 13:59:16 -03:00
line = dgettext (null, "Error") + ": " + previous_filename + ": " + msg;
2014-10-22 13:44:02 -03:00
}
if (line != null) {
2014-10-30 10:44:09 -03:00
progress_dialog.expander.set_expanded (true);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", "-n", line});
2014-10-22 13:44:02 -03:00
}
}
2014-10-26 08:30:04 -03:00
public void show_warnings () {
2014-10-22 13:44:02 -03:00
if (transaction_info_dialog.textbuffer.text != "") {
transaction_info_dialog.set_title (dgettext (null, "Warning"));
transaction_info_dialog.label.set_visible (false);
transaction_info_dialog.expander.set_visible (true);
transaction_info_dialog.expander.set_expanded (true);
transaction_info_dialog.run ();
transaction_info_dialog.hide ();
TextIter start_iter;
TextIter end_iter;
transaction_info_dialog.textbuffer.get_start_iter (out start_iter);
transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
transaction_info_dialog.textbuffer.delete (ref start_iter, ref end_iter);
}
}
public void handle_error (ErrorInfos error) {
2014-10-30 10:44:09 -03:00
progress_dialog.expander.set_expanded (true);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", "-n", error.str});
2014-10-22 13:44:02 -03:00
TextIter start_iter;
TextIter end_iter;
transaction_info_dialog.set_title (dgettext (null, "Error"));
transaction_info_dialog.label.set_visible (true);
2014-10-26 08:30:04 -03:00
transaction_info_dialog.label.set_markup (error.str);
2014-10-22 13:44:02 -03:00
if (error.details.length != 0) {
2014-10-26 08:30:04 -03:00
transaction_info_dialog.textbuffer.get_start_iter (out start_iter);
transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
transaction_info_dialog.textbuffer.delete (ref start_iter, ref end_iter);
transaction_info_dialog.expander.set_visible (true);
transaction_info_dialog.expander.set_expanded (true);
spawn_in_term ({"/usr/bin/echo", ":"});
2014-10-22 13:44:02 -03:00
foreach (string detail in error.details) {
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", detail});
string str = detail + "\n";
2014-10-22 13:44:02 -03:00
transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
2014-10-26 08:30:04 -03:00
transaction_info_dialog.textbuffer.insert (ref end_iter, str, str.length);
2014-10-22 13:44:02 -03:00
}
} else
transaction_info_dialog.expander.set_visible (false);
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo"});
2014-10-22 13:44:02 -03:00
transaction_info_dialog.run ();
transaction_info_dialog.hide ();
2014-10-30 10:44:09 -03:00
progress_dialog.hide ();
2014-10-26 08:30:04 -03:00
transaction_info_dialog.textbuffer.get_start_iter (out start_iter);
transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
transaction_info_dialog.textbuffer.delete (ref start_iter, ref end_iter);
2014-10-22 13:44:02 -03:00
while (Gtk.events_pending ())
Gtk.main_iteration ();
}
public void on_emit_refreshed (ErrorInfos error) {
2014-10-26 08:30:04 -03:00
print ("transaction refreshed\n");
2014-10-22 13:44:02 -03:00
refresh_alpm_config ();
if (error.str == "") {
if (mode == Mode.UPDATER) {
2014-10-30 10:44:09 -03:00
progress_dialog.hide ();
2014-10-22 13:44:02 -03:00
finished (false);
} else {
sysupgrade (0);
}
} else {
handle_error (error);
finished (true);
}
}
public void on_emit_trans_prepared (ErrorInfos error) {
print ("transaction prepared\n");
if (error.str == "") {
2014-10-26 08:30:04 -03:00
show_warnings ();
2014-10-22 13:44:02 -03:00
int ret = set_transaction_sum ();
if (ret == 0) {
2014-10-30 10:44:09 -03:00
if (to_add.size () == 0
&& to_remove.size () == 0
&& to_load.size () == 0
&& to_build.size () != 0) {
2014-10-22 13:44:02 -03:00
// there only AUR packages to build or we update AUR packages first
release ();
if (transaction_sum_dialog.run () == ResponseType.OK) {
transaction_sum_dialog.hide ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
ErrorInfos err = ErrorInfos ();
on_emit_trans_committed (err);
} else {
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", dgettext (null, "Transaction cancelled") + ".\n"});
2014-10-30 10:44:09 -03:00
progress_dialog.hide ();
2014-10-22 13:44:02 -03:00
transaction_sum_dialog.hide ();
finished (true);
}
} else if (sysupgrade_after_build) {
2014-10-26 08:30:04 -03:00
print ("sysupgrade_after_build\n");
2014-10-22 13:44:02 -03:00
sysupgrade_after_build = false;
commit ();
} else if (transaction_sum_dialog.run () == ResponseType.OK) {
transaction_sum_dialog.hide ();
while (Gtk.events_pending ())
Gtk.main_iteration ();
commit ();
} else {
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", dgettext (null, "Transaction cancelled") + ".\n"});
2014-10-30 10:44:09 -03:00
progress_dialog.hide ();
2014-10-22 13:44:02 -03:00
transaction_sum_dialog.hide ();
release ();
finished (true);
}
} else if (mode == Mode.UPDATER) {
commit ();
} else {
//ErrorInfos err = ErrorInfos ();
//err.str = dgettext (null, "Nothing to do") + "\n";
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", dgettext (null, "Nothing to do") + ".\n"});
2014-10-30 10:44:09 -03:00
progress_dialog.hide ();
2014-10-22 13:44:02 -03:00
release ();
clear_lists ();
finished (false);
//handle_error (err);
}
} else {
finished (true);
handle_error (error);
}
}
public void on_emit_trans_committed (ErrorInfos error) {
2014-10-26 08:30:04 -03:00
print ("transaction committed\n");
2014-10-22 13:44:02 -03:00
if (error.str == "") {
2014-10-30 10:44:09 -03:00
if (to_build.size () != 0) {
if (to_add.size () != 0
|| to_remove.size () != 0
|| to_load.size () != 0) {
2014-10-26 08:30:04 -03:00
spawn_in_term ({"/usr/bin/echo", dgettext (null, "Transaction successfully finished") + ".\n"});
2014-10-24 10:29:39 -03:00
}
2014-10-22 13:44:02 -03:00
build_aur_packages ();
} else {
2014-10-30 10:44:09 -03:00
//progress_dialog.action_label.set_text (dgettext (null, "Transaction successfully finished"));
//progress_dialog.close_button.set_visible (true);
2014-10-22 13:44:02 -03:00
clear_lists ();
2014-10-26 08:30:04 -03:00
show_warnings ();
2014-10-22 13:44:02 -03:00
refresh_alpm_config ();
if (sysupgrade_after_trans) {
sysupgrade_after_trans = false;
sysupgrade (0);
} else if (sysupgrade_after_build) {
sysupgrade_simple (0);
} else {
2014-10-26 08:30:04 -03:00
if (build_status == 0)
spawn_in_term ({"/usr/bin/echo", dgettext (null, "Transaction successfully finished") + ".\n"});
else
spawn_in_term ({"/usr/bin/echo"});
2014-10-30 10:44:09 -03:00
progress_dialog.hide ();
2014-10-22 13:44:02 -03:00
finished (false);
}
}
} else {
2014-10-26 08:30:04 -03:00
refresh_alpm_config ();
2014-10-22 13:44:02 -03:00
finished (true);
handle_error (error);
}
total_download = 0;
already_downloaded = 0;
2014-10-26 08:30:04 -03:00
build_status = 0;
2014-10-22 13:44:02 -03:00
}
void on_term_child_exited (int status) {
Source.remove (build_timeout_id);
2014-10-30 10:44:09 -03:00
to_build.steal_all ();
2014-10-26 08:30:04 -03:00
build_status = status;
2014-10-22 13:44:02 -03:00
ErrorInfos err = ErrorInfos ();
on_emit_trans_committed (err);
}
void connecting_dbus_signals () {
try {
daemon = Bus.get_proxy_sync (BusType.SYSTEM, "org.manjaro.pamac",
"/org/manjaro/pamac");
// Connecting to signals
daemon.emit_event.connect (on_emit_event);
daemon.emit_providers.connect (on_emit_providers);
daemon.emit_progress.connect (on_emit_progress);
daemon.emit_download.connect (on_emit_download);
daemon.emit_totaldownload.connect (on_emit_totaldownload);
daemon.emit_log.connect (on_emit_log);
daemon.emit_refreshed.connect (on_emit_refreshed);
daemon.emit_trans_prepared.connect (on_emit_trans_prepared);
daemon.emit_trans_committed.connect (on_emit_trans_committed);
} catch (IOError e) {
stderr.printf ("IOError: %s\n", e.message);
}
}
}
}