From 5ecbbbd9c3e50bc0c928d081bbc28a47fd5c75b5 Mon Sep 17 00:00:00 2001
From: guinux <nuxgui@gmail.com>
Date: Sat, 29 Dec 2012 15:06:44 +0100
Subject: [PATCH] fix handling conflicts (I hope)

---
 backend/__init__.py    |   0
 backend/config.py      |   0
 backend/transaction.py |  52 +++++++-------------
 backend/tray.py        |  51 ++++++++++++++++++++
 backend/update.py      |  60 +++++++++++++++++++++++
 gui/dialogs.glade      |   1 +
 pamac                  | 105 ++++++++++++++++++++++++++++-------------
 pamac-update           |  58 +++--------------------
 8 files changed, 208 insertions(+), 119 deletions(-)
 mode change 100755 => 100644 backend/__init__.py
 mode change 100644 => 100755 backend/config.py
 create mode 100755 backend/tray.py
 create mode 100755 backend/update.py

diff --git a/backend/__init__.py b/backend/__init__.py
old mode 100755
new mode 100644
diff --git a/backend/config.py b/backend/config.py
old mode 100644
new mode 100755
diff --git a/backend/transaction.py b/backend/transaction.py
index 5c9945e4..08aa98ab 100755
--- a/backend/transaction.py
+++ b/backend/transaction.py
@@ -5,7 +5,7 @@ from gi.repository import Gtk
 
 import pyalpm
 import traceback
-import sys
+
 from backend import config
 
 interface = Gtk.Builder()
@@ -55,43 +55,30 @@ def init_transaction(handle, **options):
 def check_conflicts():
 	global conflict_to_remove
 	conflict_to_remove = {}
-	installed_conflicts = {}
-	for pkg in config.handle.get_localdb().pkgcache:
-		if pkg.conflicts:
-			installed_conflicts[pkg.name] = pkg.conflicts
-	targets_conflicts = {}
-	targets_replaces = {}
-	for pkg in t.to_add:
-		if pkg.replaces:
-			targets_replaces[pkg.name] = pkg.replaces
-		if pkg.conflicts:
-			targets_conflicts[pkg.name] = pkg.conflicts
 	warning = ''
-	if targets_replaces:
-		for key, value in targets_replaces.items():
-			for name in value:
+	for target in t.to_add:
+		if target.replaces:
+			for name in target.replaces:
 				pkg = config.handle.get_localdb().get_pkg(name)
 				if pkg:
 					if not pkg.name in conflict_to_remove.keys():
 						conflict_to_remove[pkg.name] = pkg
 						if warning:
 							warning = warning+'\n'
-						warning = warning+pkg.name+' will be replaced by '+key 
-	if targets_conflicts:
-		for key, value in targets_conflicts.items():
-			for name in value:
+						warning = warning+pkg.name+' will be replaced by '+target.name
+		if target.conflicts:
+			for name in target.conflicts:
 				pkg = config.handle.get_localdb().get_pkg(name)
 				if pkg:
 					if not pkg.name in conflict_to_remove.keys():
 						conflict_to_remove[pkg.name] = pkg
-	if installed_conflicts:
-		for key, value in installed_conflicts.items():
-			for name in value:
-				for pkg in t.to_add:
-					if pkg.name == name:
-						if not pkg.name in conflict_to_remove.keys():
-							conflict_to_remove[pkg.name] = pkg
-	if conflict_to_remove:
+		for installed_pkg in config.handle.get_localdb().pkgcache:
+			if installed_pkg.conflicts:
+				for name in installed_pkg.conflicts:
+					if name == target.name:
+						if not name in conflict_to_remove.keys():
+							conflict_to_remove[installed_pkg.name] = installed_pkg
+	if warning:
 		WarningDialog.format_secondary_text(warning)
 		response = WarningDialog.run()
 		if response:
@@ -101,7 +88,6 @@ def do_refresh():
 	"""Sync databases like pacman -Sy"""
 	global t
 	global t_lock
-	ProgressWindow.show_all()
 	for db in config.handle.get_syncdbs():
 		if t_lock is False:
 			t = init_transaction(config.handle)
@@ -116,7 +102,6 @@ def do_refresh():
 					ErrorDialog.hide()
 				t_lock = False
 				break
-	ProgressWindow.hide()
 	progress_label.set_text('')
 	progress_bar.set_text('')
 
@@ -164,7 +149,7 @@ def do_sysupgrade():
 				print("Nothing to update")
 			else:
 				t.release()
-				t = init_transaction(config.handle, noconflicts = True, nodeps = True, nodepversion = True)
+				t = init_transaction(config.handle, noconflicts = True, nodeps = True)
 				for pkg in to_add:
 					t.add_pkg(pkg)
 				for pkg in conflict_to_remove.values():
@@ -188,6 +173,7 @@ def do_sysupgrade():
 
 def t_finalize(t):
 	ConfDialog.hide()
+	ProgressWindow.show_all()
 	try:
 		t.prepare()
 	except pyalpm.error:
@@ -288,7 +274,6 @@ def set_transaction_desc(mode):
 event_text = ' '
 def cb_event(ID, event, tupel):
 	global event_text
-	ProgressWindow.show_all()
 	while Gtk.events_pending():
 		Gtk.main_iteration()
 	if ID is 1:
@@ -334,10 +319,6 @@ _logmask = pyalpm.LOG_ERROR | pyalpm.LOG_WARNING
 
 def cb_log(level, line):
 	#global t
-	#try:
-	#	_line = str(_line, encoding='utf-8').strip("\n")
-	#except:
-	#	_line = str(_line, encoding='latin-1').strip("\n")
 	if not (level & _logmask):
 		return
 	if level & pyalpm.LOG_ERROR:
@@ -357,7 +338,6 @@ def cb_log(level, line):
 	elif level & pyalpm.LOG_FUNCTION:
 		line = "FUNC: " + line
 		print(line)
-	#sys.stderr.write(line)
 
 total_size = 0
 def totaldlcb(_total_size):
diff --git a/backend/tray.py b/backend/tray.py
new file mode 100755
index 00000000..828f8558
--- /dev/null
+++ b/backend/tray.py
@@ -0,0 +1,51 @@
+#! /usr/bin/python
+# -*-coding:utf-8-*-
+
+from gi.repository import Gtk
+
+import transaction, update
+
+class Tray:
+	def __init__(self, icon, info):
+		self.icon = icon
+		self.info = info
+		self.statusIcon = Gtk.StatusIcon()
+		self.statusIcon.set_from_file(icon)
+		self.statusIcon.set_visible(True)
+		self.statusIcon.set_tooltip_markup(info)
+
+		self.menu = Gtk.Menu()
+		self.menuItem = Gtk.ImageMenuItem()
+		self.menuItem.seet_image('/usr/share/icons/hicolor/24x24/status/package-update.png')
+		self.menuItem.connect('activate', self.execute_cb, self.statusIcon)
+		self.menu.append(self.menuItem)
+		self.menuItem = Gtk.ImageMenuItem(Gtk.STOCK_QUIT)
+		self.menuItem.connect('activate', self.quit_cb, self.statusIcon)
+		self.menu.append(self.menuItem)
+
+		self.statusIcon.connect('popup-menu', self.popup_menu_cb, self.menu)
+		self.statusIcon.set_visible(1)
+
+		Gtk.main()
+
+	def execute_cb(self, widget, event, data = None):
+		update.main()
+
+	def quit_cb(self, widget, data = None):
+		Gtk.main_quit()
+
+	def popup_menu_cb(self, widget, button, time, data = None):
+		if button == 3:
+			if data:
+				data.show_all()
+				data.popup(None, None, Gtk.StatusIcon.position_menu, self.statusIcon, 3, time)
+
+if __name__ == "__main__":
+	updates = transaction.get_updates()
+	if updates:
+		icon = '/usr/share/icons/hicolor/24x24/status/update-normal.png'
+		info = str(len(updates))+' update(s) available'
+	else:
+		icon = '/usr/share/icons/hicolor/24x24/status/update-enhancement.png'
+		info = ' No update available'
+	tray = Tray(icon, info)
diff --git a/backend/update.py b/backend/update.py
new file mode 100755
index 00000000..5321bb8c
--- /dev/null
+++ b/backend/update.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+# -*-coding:utf-8 -*-
+
+from gi.repository import Gtk
+
+import pyalpm
+from os import geteuid
+
+from backend import transaction
+
+interface = Gtk.Builder()
+interface.add_from_file('/usr/share/pamac/pamac_update.glade')
+interface.add_from_file('/usr/share/pamac/dialogs.glade')
+
+update_listore = interface.get_object('update_list')
+top_label = interface.get_object('top_label')
+
+def have_updates():
+	available_updates = transaction.get_updates()
+	update_listore.clear()
+	top_label.set_justify(Gtk.Justification.CENTER)
+	if not available_updates:
+		update_listore.append(["", ""])
+		top_label.set_markup("<big><b>No update available</b></big>")
+		return False
+	else:
+		for pkg in available_updates:
+			pkgname = pkg.name
+			newversion = transaction.get_new_version_available(pkgname)
+			pkgname = pkg.name+" "+newversion
+			update_listore.append([pkgname, transaction.format_size(pkg.size)])
+		top_label.set_markup("<big><b>Available updates</b></big>")
+		return True
+
+class Handler:
+	def on_UpdateWindow_delete_event(self, *arg):
+		Gtk.main_quit()
+
+	def on_QuitButton_clicked(self, *arg):
+		Gtk.main_quit()
+
+	def on_ApplyButton_clicked(self, *arg):
+		transaction.do_sysupgrade()
+		have_updates()
+
+	def on_RefreshButton_clicked(self, *arg):
+		transaction.do_refresh()
+		have_updates()
+
+def main():
+	have_updates()
+	interface.connect_signals(Handler())
+	UpdateWindow = interface.get_object("UpdateWindow")
+	UpdateWindow.show_all()
+	Gtk.main()
+
+if __name__ == "__main__":
+	if geteuid() == 0:
+		transaction.do_refresh()
+	main()
diff --git a/gui/dialogs.glade b/gui/dialogs.glade
index 95526fa5..955e61f2 100644
--- a/gui/dialogs.glade
+++ b/gui/dialogs.glade
@@ -49,6 +49,7 @@
               <object class="GtkTreeView" id="treeview4">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="hexpand">True</property>
                 <property name="vexpand">True</property>
                 <property name="model">transaction_desc</property>
                 <property name="headers_visible">False</property>
diff --git a/pamac b/pamac
index 3bb14a2b..19f4c4e9 100755
--- a/pamac
+++ b/pamac
@@ -9,6 +9,7 @@ import sys
 from time import strftime, localtime
 from os import geteuid
 import traceback
+
 from backend import transaction, config
 
 interface = Gtk.Builder()
@@ -210,48 +211,83 @@ class Handler:
 			if transaction.t_lock is True:
 				pass
 			else:
-				transaction.t = transaction.init_transaction(config.handle, cascade = True)
-				if transaction_type is "install":
-					for pkg in transaction_dict.values():
-						transaction.t.add_pkg(pkg)
 				if transaction_type is "remove":
+					transaction.t = transaction.init_transaction(config.handle, cascade = True)
 					for pkg in transaction_dict.values():
 						transaction.t.remove_pkg(pkg)
-				transaction.check_conflicts()
-				if transaction.conflict_to_remove:
-					for pkg in transaction.conflict_to_remove.values():
-						transaction.t.remove_pkg(pkg)
-				try:
-					transaction.t.prepare()
-				except pyalpm.error:
-					transaction.ErrorDialog.format_secondary_text(traceback.format_exc())
-					response = transaction.ErrorDialog.run()
-					if response:
-						transaction.ErrorDialog.hide()
-					transaction.t.release()
-					transaction.t_lock = False
-				transaction.to_remove = transaction.t.to_remove
-				transaction.to_add = transaction.t.to_add
-				transaction.set_transaction_desc('normal')
-				response = transaction.ConfDialog.run()
-				if response == Gtk.ResponseType.OK:
-					transaction.ConfDialog.hide()
 					try:
-						transaction.t.commit()
+						transaction.t.prepare()
+					except pyalpm.error:
+						transaction.ErrorDialog.format_secondary_text(traceback.format_exc())
+						response = transaction.ErrorDialog.run()
+						if response:
+							transaction.ErrorDialog.hide()
+						transaction.t.release()
+						transaction.t_lock = False
+					transaction.to_remove = transaction.t.to_remove
+					transaction.to_add = transaction.t.to_add
+					transaction.set_transaction_desc('normal')
+					response = transaction.ConfDialog.run()
+					if response == Gtk.ResponseType.OK:
+						transaction.ConfDialog.hide()
+						transaction.ProgressWindow.show_all()
+						try:
+							transaction.t.commit()
+						except pyalpm.error:
+							transaction.ErrorDialog.format_secondary_text(traceback.format_exc())
+							response = transaction.ErrorDialog.run()
+							if response:
+								transaction.ErrorDialog.hide()
+						transaction_dict.clear()
+						transaction_type = None
+						set_packages_list()
+						transaction.ProgressWindow.hide()
+					if response == Gtk.ResponseType.CANCEL or Gtk.ResponseType.CLOSE or Gtk.ResponseType.DELETE_EVENT:
+						transaction.ProgressWindow.hide()
+						transaction.ConfDialog.hide()
+						transaction.t.release()
+						transaction.t_lock = False
+				if transaction_type is "install":
+					transaction.t = transaction.init_transaction(config.handle, noconflicts = True)
+					for pkg in transaction_dict.values():
+						transaction.t.add_pkg(pkg)
+					try:
+						transaction.t.prepare()
 					except pyalpm.error:
 						transaction.ErrorDialog.format_secondary_text(traceback.format_exc())
 						response = transaction.ErrorDialog.run()
 						if response:
 							transaction.ErrorDialog.hide()
-					transaction_dict.clear()
-					transaction_type = None
-					set_packages_list()
-					transaction.ProgressWindow.hide()
-				if response == Gtk.ResponseType.CANCEL or Gtk.ResponseType.CLOSE or Gtk.ResponseType.DELETE_EVENT:
-					transaction.ProgressWindow.hide()
-					transaction.ConfDialog.hide()
+						transaction.t.release()
+						transaction.t_lock = False
+					transaction.check_conflicts()
+					transaction.to_add = transaction.t.to_add
+					transaction.to_remove = []
+					if transaction.conflict_to_remove:
+						for pkg in transaction.conflict_to_remove.values():
+							transaction.to_remove.append(pkg)
 					transaction.t.release()
-					transaction.t_lock = False
+					transaction.set_transaction_desc('normal')
+					response = transaction.ConfDialog.run()
+					if response == Gtk.ResponseType.OK:
+						transaction.ConfDialog.hide()
+						transaction.t = transaction.init_transaction(config.handle, noconflicts = True, nodeps = True)
+						print(transaction.to_add, transaction.to_remove)
+						for pkg in transaction.to_add:
+							print(pkg)
+							transaction.t.add_pkg(pkg)
+						for pkg in transaction.to_remove:
+							print(pkg)
+							transaction.t.remove_pkg(pkg)
+						transaction.t_finalize(transaction.t)
+						transaction_dict.clear()
+						transaction_type = None
+						set_packages_list()
+					if response == Gtk.ResponseType.CANCEL or Gtk.ResponseType.CLOSE or Gtk.ResponseType.DELETE_EVENT:
+						transaction.ProgressWindow.hide()
+						transaction.ConfDialog.hide()
+						transaction.t.release()
+						transaction.t_lock = False
 
 	def on_EraseButton_clicked(self, *arg):
 		global transaction_type
@@ -345,7 +381,12 @@ class Handler:
 
 if __name__ == "__main__":
 	if geteuid() == 0:
+		transaction.progress_label.set_text('Refreshing...')
+		transaction.progress_bar.pulse()
+		transaction.action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/refresh-cache.png')
+		transaction.ProgressWindow.show_all()
 		transaction.do_refresh()
+		transaction.ProgressWindow.hide()
 	interface.connect_signals(Handler())
 	MainWindow = interface.get_object("MainWindow")
 	MainWindow.show_all()
diff --git a/pamac-update b/pamac-update
index 0f261930..a10f4d9d 100755
--- a/pamac-update
+++ b/pamac-update
@@ -1,60 +1,16 @@
 #! /usr/bin/python
 # -*-coding:utf-8 -*-
 
-from gi.repository import Gtk, GdkPixbuf, Gdk
-
-import pyalpm
-from time import strftime, localtime
 from os import geteuid
-from backend import transaction
-
-interface = Gtk.Builder()
-interface.add_from_file('/usr/share/pamac/pamac_update.glade')
-interface.add_from_file('/usr/share/pamac/dialogs.glade')
-
-update_listore = interface.get_object('update_list')
-top_label = interface.get_object('top_label')
-
-def have_updates():
-	available_updates = transaction.get_updates()
-	update_listore.clear()
-	top_label.set_justify(Gtk.Justification.CENTER)
-	if not available_updates:
-		update_listore.append(["", ""])
-		top_label.set_markup("<big><b>No update available</b></big>")
-		return False
-	else:
-		for pkg in available_updates:
-			pkgname = pkg.name
-			newversion = transaction.get_new_version_available(pkgname)
-			pkgname = pkg.name+" "+newversion
-			update_listore.append([pkgname, transaction.format_size(pkg.size)])
-		top_label.set_markup("<big><b>Available updates</b></big>")
-		return True
-
-class Handler:
-	def on_UpdateWindow_delete_event(self, *arg):
-		Gtk.main_quit()
-
-	def on_QuitButton_clicked(self, *arg):
-		Gtk.main_quit()
-
-	def on_ApplyButton_clicked(self, *arg):
-		transaction.do_sysupgrade()
-		have_updates()
-
-	def on_RefreshButton_clicked(self, *arg):
-		transaction.do_refresh()
-		have_updates()
 
-def main():
-	have_updates()
-	interface.connect_signals(Handler())
-	UpdateWindow = interface.get_object("UpdateWindow")
-	UpdateWindow.show_all()
-	Gtk.main()
+from backend import update, transaction
 
 if __name__ == "__main__":
 	if geteuid() == 0:
+		transaction.progress_label.set_text('Refreshing...')
+		transaction.progress_bar.pulse()
+		transaction.action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/refresh-cache.png')
+		transaction.ProgressWindow.show_all()
 		transaction.do_refresh()
-	main()
+		transaction.ProgressWindow.hide()
+	update.main()
-- 
GitLab