From a769f4e397440526a5659b003474c1c78fa8ce73 Mon Sep 17 00:00:00 2001
From: guinux <nuxgui@gmail.com>
Date: Sat, 26 Jan 2013 14:42:01 +0100
Subject: [PATCH] improve updates and conflicts handling

---
 pamac/manager.py      | 76 ++++++++++++++++++++++++++++++----
 pamac/pamac-daemon.py |  1 -
 pamac/transaction.py  | 62 ++++++++++++++++++----------
 pamac/updater.py      | 96 ++++++++++++++++++++++---------------------
 4 files changed, 158 insertions(+), 77 deletions(-)

diff --git a/pamac/manager.py b/pamac/manager.py
index f2fab2a1..0736ff5a 100755
--- a/pamac/manager.py
+++ b/pamac/manager.py
@@ -4,11 +4,7 @@
 from gi.repository import Gtk
 
 import pyalpm
-import math
-import sys
 from time import strftime, localtime
-from os import geteuid
-import traceback
 
 from pamac import config, common, transaction
 
@@ -227,6 +223,42 @@ def set_transaction_sum():
 		#bottom_label.set_markup('<b>Total Download size: </b>'+common.format_size(totaldlcb))
 	top_label.set_markup('<big><b>Transaction Summary</b></big>')
 
+def do_sysupgrade():
+	global transaction_type
+	"""Upgrade a system like pacman -Su"""
+	if transaction.t_lock is False:
+		transaction_type = "update"
+		if transaction.do_syncfirst is True:
+			if transaction.init_transaction(recurse = True):
+				for pkg in transaction.list_first:
+					transaction.Add(pkg.name)
+				transaction.get_to_remove()
+				transaction.get_to_add()
+				transaction.check_conflicts()
+				transaction.Release()
+				set_transaction_sum()
+				ConfDialog.show_all()
+		else:
+			if transaction.init_transaction():
+				error = transaction.Sysupgrade()
+				if error:
+					transaction.ErrorDialog.format_secondary_text(error)
+					response = transaction.ErrorDialog.run()
+					if response:
+						transaction.ErrorDialog.hide()
+					transaction.Release()
+					transaction.t_lock = False
+				transaction.get_to_remove()
+				transaction.get_to_add()
+				transaction.check_conflicts()
+				transaction.Release()
+				if len(transaction.to_add) + len(transaction.to_update) + len(transaction.to_remove) != 0:
+					set_transaction_sum()
+					ConfDialog.show_all()
+				else:
+					transaction.Release()
+					transaction.t_lock = False
+
 def handle_error(error):
 	global transaction_type
 	global transaction_dict
@@ -252,6 +284,9 @@ def handle_reply(reply):
 		response = transaction.ErrorDialog.run()
 		if response:
 			transaction.ErrorDialog.hide()
+	if transaction.do_syncfirst is True:
+		transaction.do_syncfirst = False
+		transaction.list_first = []
 	transaction.t_lock = False
 	transaction.Release()
 	transaction.ProgressWindow.hide()
@@ -318,8 +353,15 @@ class Handler:
 						transaction.get_to_add()
 						transaction.check_conflicts()
 						transaction.Release()
-						set_transaction_sum()
-						ConfDialog.show_all()
+						if len(transaction.to_add) + len(transaction.to_update) + len(transaction.to_remove) != 0:
+							set_transaction_sum()
+							ConfDialog.show_all()
+						else:
+							transaction.WarningDialog.format_secondary_text('Nothing to do due to packages conflicts')
+							response = transaction.WarningDialog.run()
+							if response:
+								transaction.WarningDialog.hide()
+							transaction.t_lock = False
 
 	def on_EraseButton_clicked(self, *arg):
 		global transaction_type
@@ -333,9 +375,13 @@ class Handler:
 		refresh_packages_list()
 
 	def on_TransCancelButton_clicked(self, *arg):
+		global transaction_type
+		transaction.ProgressWindow.hide()
 		ConfDialog.hide()
 		transaction.t_lock = False
 		transaction.Release()
+		if transaction_type == "update":
+			transaction_type = None
 
 	def on_TransValidButton_clicked(self, *arg):
 		ConfDialog.hide()
@@ -343,13 +389,15 @@ class Handler:
 		transaction.action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/setup.png')
 		while Gtk.events_pending():
 			Gtk.main_iteration()
-		if transaction_type is "remove":
+		if transaction_type == "remove":
 			transaction.ProgressWindow.show_all()
 			while Gtk.events_pending():
 				Gtk.main_iteration()
 			transaction.Commit(reply_handler = handle_reply, error_handler = handle_error, timeout = 2000*1000)
-		if transaction_type is "install":
+		if transaction_type == ("install" or "update"):
 			if transaction.init_transaction(noconflicts = True, nodeps = True):
+				for pkgname in transaction.to_update:
+					transaction.Add(pkgname)
 				for pkgname in transaction.to_add:
 					transaction.Add(pkgname)
 				for pkgname in transaction.to_remove:
@@ -449,7 +497,19 @@ class Handler:
 
 def main():
 	interface.connect_signals(Handler())
+	transaction.do_refresh()
+	do_sysupgrade()
+	#~ if transaction.get_updates():
+		#~ transaction.QuestionDialog.format_secondary_text("Some updates are available.\nIt is higly recommended to update your system before installing/removing software.\nDo you want to update your system now ?")
+		#~ response = transaction.QuestionDialog.run()
+		#~ if response == Gtk.ResponseType.YES:
+			#~ transaction.QuestionDialog.hide()
+			#~ do_sysupgrade()
+		#~ else:
+			#~ transaction.QuestionDialog.hide()
 	MainWindow.show_all()
+	while Gtk.events_pending():
+		Gtk.main_iteration()
 
 if __name__ == "__main__":
 	main()
diff --git a/pamac/pamac-daemon.py b/pamac/pamac-daemon.py
index 08d09c75..deff79bf 100755
--- a/pamac/pamac-daemon.py
+++ b/pamac/pamac-daemon.py
@@ -165,7 +165,6 @@ class PamacDBusService(dbus.service.Object):
 			try:
 				t = config.handle.init_transaction()
 				db.update(force=False)
-				print('refresh')
 				t.release()
 			except pyalpm.error:
 				error = traceback.format_exc()
diff --git a/pamac/transaction.py b/pamac/transaction.py
index bc416bc5..2a1a4e4a 100755
--- a/pamac/transaction.py
+++ b/pamac/transaction.py
@@ -1,10 +1,9 @@
 #! /usr/bin/python
 # -*-coding:utf-8-*-
 
-from gi.repository import Gtk, GObject
+from gi.repository import Gtk
 
 import pyalpm
-import traceback
 import dbus
 from dbus.mainloop.glib import DBusGMainLoop
 
@@ -15,6 +14,7 @@ interface.add_from_file('/usr/share/pamac/gui/dialogs.glade')
 
 ErrorDialog = interface.get_object('ErrorDialog')
 WarningDialog = interface.get_object('WarningDialog')
+QuestionDialog = interface.get_object('QuestionDialog')
 ProgressWindow = interface.get_object('ProgressWindow')
 progress_bar = interface.get_object('progressbar2')
 progress_label = interface.get_object('progresslabel2')
@@ -64,10 +64,10 @@ def target_signal_handler(target):
 	progress_bar.set_text(target)
 
 def percent_signal_handler(percent):
-	if percent == '0':
-		progress_bar.pulse()
-	else:
-		progress_bar.set_fraction(float(percent))
+	#~ if percent == '0':
+		#~ progress_bar.pulse()
+	#~ else:
+	progress_bar.set_fraction(float(percent))
 
 bus.add_signal_receiver(action_signal_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitAction")
 bus.add_signal_receiver(icon_signal_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitIcon")
@@ -82,7 +82,7 @@ def init_transaction(**options):
 		t_lock = True
 		return True
 	else:
-		ErrorDialog.format_secondary_text(error)
+		ErrorDialog.format_secondary_text('Init Error:\n'+str(error))
 		response = ErrorDialog.run()
 		if response:
 			ErrorDialog.hide()
@@ -111,16 +111,28 @@ def check_conflicts():
 						warning = warning+pkg.name+' will be replaced by '+target.name
 		if target.conflicts:
 			for name in target.conflicts:
+				if name in to_add:
+					to_add.remove(name)
+					to_add.remove(target.name)
+					if warning:
+						warning = warning+'\n'
+					warning = warning+name+' conflicts with '+target.name+'\nNone of them will be installed'
 				pkg = handle.get_localdb().get_pkg(name)
 				if pkg:
 					if not pkg.name in to_remove:
 						to_remove.append(pkg.name)
+						if warning:
+							warning = warning+'\n'
+						warning = warning+pkg.name+' conflicts with '+target.name
 		for installed_pkg in handle.get_localdb().pkgcache:
 			if installed_pkg.conflicts:
 				for name in installed_pkg.conflicts:
 					if name == target.name:
 						if not name in to_remove:
 							to_remove.append(installed_pkg.name)
+							if warning:
+								warning = warning+'\n'
+							warning = warning+installed_pkg.name+' conflicts with '+target.name
 	for repo in handle.get_syncdbs():
 		for pkg in repo.pkgcache:
 			if pkg.replaces:
@@ -141,8 +153,6 @@ def check_conflicts():
 		if response:
 			WarningDialog.hide()
 
-
-
 def get_to_remove():
 	global to_remove
 	to_remove = To_Remove()
@@ -154,21 +164,31 @@ def get_to_add():
 def do_refresh():
 	"""Sync databases like pacman -Sy"""
 	global t_lock
-	ProgressWindow.show_all()
-	print('show')
+	get_handle()
 	if t_lock is False:
 		t_lock = True
+		progress_label.set_text('Refreshing...')
+		action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/refresh-cache.png')
 		ProgressWindow.show_all()
-		error = Refresh(timeout = 2000*1000)
-		if error:
-			ErrorDialog.format_secondary_text(error)
-			response = ErrorDialog.run()
-			if response:
-				ErrorDialog.hide()
-			Release()
-		ProgressWindow.hide()
-		print('hide')
-		t_lock = False
+		while Gtk.events_pending():
+			Gtk.main_iteration()
+		Refresh(reply_handler = handle_reply, error_handler = handle_error, timeout = 2000*1000)
+
+def handle_error(error):
+	global t_lock
+	if not 'DBus.Error.NoReply' in str(error):
+		transaction.ErrorDialog.format_secondary_text('Refresh Error:\n'+str(error))
+		response = transaction.ErrorDialog.run()
+		if response:
+			transaction.ErrorDialog.hide()
+	t_lock = False
+	Release()
+	ProgressWindow.hide()
+
+def handle_reply(reply):
+	global t_lock
+	t_lock = False
+	ProgressWindow.hide()
 
 def get_updates():
 	"""Return a list of package objects in local db which can be updated"""
diff --git a/pamac/updater.py b/pamac/updater.py
index ee14112a..03a35293 100755
--- a/pamac/updater.py
+++ b/pamac/updater.py
@@ -3,9 +3,6 @@
 
 from gi.repository import Gtk
 
-import pyalpm
-from os import geteuid
-
 from pamac import config, common, transaction
 
 interface = Gtk.Builder()
@@ -65,45 +62,6 @@ def set_transaction_add():
 		#bottom_label.set_markup('<b>Total Download size: </b>'+format_size(totaldlcb))
 	top_label.set_markup('<big><b>Additionnal Transaction(s)</b></big>')
 
-def finalize():
-	error = transaction.Prepare()
-	if error:
-		ErrorDialog.format_secondary_text(error)
-		response = ErrorDialog.run()
-		if response:
-			ErrorDialog.hide()
-		transaction.Release()
-		transaction.t_lock = False
-	else:
-		transaction.progress_label.set_text('Preparing...')
-		transaction.action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/setup.png')
-		transaction.ProgressWindow.show_all()
-		while Gtk.events_pending():
-			Gtk.main_iteration()
-		transaction.Commit(reply_handler = handle_reply, error_handler = handle_error, timeout = 2000*1000)
-
-def handle_error(error):
-	if not 'DBus.Error.NoReply' in str(error):
-		transaction.ErrorDialog.format_secondary_text('Commit Error:\n'+str(error))
-		response = transaction.ErrorDialog.run()
-		if response:
-			transaction.ErrorDialog.hide()
-	transaction.t_lock = False
-	transaction.Release()
-	transaction.ProgressWindow.hide()
-	have_updates()
-
-def handle_reply(reply):
-	if str(reply):
-		transaction.ErrorDialog.format_secondary_text('Commit Error:\n'+str(reply))
-		response = transaction.ErrorDialog.run()
-		if response:
-			transaction.ErrorDialog.hide()
-	transaction.t_lock = False
-	transaction.Release()
-	transaction.ProgressWindow.hide()
-	have_updates()
-
 def do_sysupgrade():
 	"""Upgrade a system like pacman -Su"""
 	if transaction.t_lock is False:
@@ -114,12 +72,10 @@ def do_sysupgrade():
 				transaction.get_to_remove()
 				transaction.get_to_add()
 				set_transaction_add()
-				if len(transaction.to_add) != 0:
+				if len(transaction.to_add) + len(transaction.to_remove) != 0:
 					ConfDialog.show_all()
 				else:
 					finalize()
-				transaction.do_syncfirst = False
-				transaction.list_first = []
 		else:
 			if transaction.init_transaction():
 				error = transaction.Sysupgrade()
@@ -134,21 +90,65 @@ def do_sysupgrade():
 				transaction.get_to_add()
 				transaction.check_conflicts()
 				transaction.Release()
-				if len(transaction.to_add) + len(transaction.to_remove) == 0:
+				if len(transaction.to_update) == 0:
 					transaction.t_lock = False
 					print("Nothing to update")
 				else:
 					if transaction.init_transaction(noconflicts = True, nodeps = True):
+						for pkgname in transaction.to_update:
+							transaction.Add(pkgname)
 						for pkgname in transaction.to_add:
 							transaction.Add(pkgname)
 						for pkgname in transaction.to_remove:
 							transaction.Remove(pkgname)
 						set_transaction_add()
-						if len(transaction_add) != 0:
+						if len(transaction.to_add) + len(transaction.to_remove) != 0:
 							ConfDialog.show_all()
 						else:
 							finalize()
 
+def finalize():
+	error = transaction.Prepare()
+	if error:
+		transaction.ErrorDialog.format_secondary_text(error)
+		response = transaction.ErrorDialog.run()
+		if response:
+			transaction.ErrorDialog.hide()
+		transaction.Release()
+		transaction.t_lock = False
+	else:
+		transaction.progress_label.set_text('Preparing...')
+		transaction.action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/setup.png')
+		transaction.ProgressWindow.show_all()
+		while Gtk.events_pending():
+			Gtk.main_iteration()
+		transaction.Commit(reply_handler = handle_reply, error_handler = handle_error, timeout = 2000*1000)
+
+def handle_error(error):
+	if not 'DBus.Error.NoReply' in str(error):
+		transaction.ErrorDialog.format_secondary_text('Commit Error:\n'+str(error))
+		response = transaction.ErrorDialog.run()
+		if response:
+			transaction.ErrorDialog.hide()
+	transaction.t_lock = False
+	transaction.Release()
+	transaction.ProgressWindow.hide()
+	have_updates()
+
+def handle_reply(reply):
+	if str(reply):
+		transaction.ErrorDialog.format_secondary_text('Commit Error:\n'+str(reply))
+		response = transaction.ErrorDialog.run()
+		if response:
+			transaction.ErrorDialog.hide()
+	if transaction.do_syncfirst is True:
+		transaction.do_syncfirst = False
+		transaction.list_first = []
+	transaction.t_lock = False
+	transaction.Release()
+	transaction.ProgressWindow.hide()
+	have_updates()
+
 class Handler:
 	def on_UpdateWindow_delete_event(self, *arg):
 		transaction.StopDaemon()
@@ -191,6 +191,8 @@ def main():
 	have_updates()
 	interface.connect_signals(Handler())
 	UpdateWindow.show_all()
+	while Gtk.events_pending():
+		Gtk.main_iteration()
 
 if __name__ == "__main__":
 	main()
-- 
GitLab