From 598297365623486d0cadc0733a413d292a83acbd Mon Sep 17 00:00:00 2001 From: guinux Date: Sun, 6 Jan 2013 19:10:13 +0100 Subject: [PATCH] big rewrite with a dbus service, not finished atm --- TODO | 1 + backend/transaction.py | 270 ------------------ .../pamac-manager.desktop} | 2 +- .../pamac-updater.desktop} | 2 +- data/dbus/org.manjaro.pamac.conf | 19 ++ data/dbus/org.manjaro.pamac.service | 5 + data/polkit/org.manjaro.pamac.policy | 26 ++ gui/dialogs.glade | 2 +- gui/{pamac.glade => manager.glade} | 5 +- gui/{pamac_update.glade => updater.glade} | 6 +- pamac-manager | 3 + pamac-update | 16 -- pamac-updater | 3 + {backend => pamac}/__init__.py | 0 pamac/callbacks.py | 120 ++++++++ {backend => pamac}/config.py | 0 pamac => pamac/manager.py | 156 +++++----- pamac/pamac-daemon.py | 161 +++++++++++ pamac/transaction.py | 178 ++++++++++++ {backend => pamac}/tray.py | 26 +- backend/update.py => pamac/updater.py | 51 ++-- setup.py | 2 +- start-pamac-daemon | 4 + test.py | 27 ++ tray | 3 + 25 files changed, 682 insertions(+), 406 deletions(-) delete mode 100755 backend/transaction.py rename data/{pamac.desktop => applications/pamac-manager.desktop} (99%) rename data/{pamac-update.desktop => applications/pamac-updater.desktop} (99%) create mode 100644 data/dbus/org.manjaro.pamac.conf create mode 100644 data/dbus/org.manjaro.pamac.service create mode 100644 data/polkit/org.manjaro.pamac.policy rename gui/{pamac.glade => manager.glade} (99%) rename gui/{pamac_update.glade => updater.glade} (98%) create mode 100755 pamac-manager delete mode 100755 pamac-update create mode 100755 pamac-updater rename {backend => pamac}/__init__.py (100%) create mode 100755 pamac/callbacks.py rename {backend => pamac}/config.py (100%) rename pamac => pamac/manager.py (78%) create mode 100755 pamac/pamac-daemon.py create mode 100755 pamac/transaction.py rename {backend => pamac}/tray.py (56%) rename backend/update.py => pamac/updater.py (78%) create mode 100755 start-pamac-daemon create mode 100755 test.py create mode 100755 tray diff --git a/TODO b/TODO index e69de29..8b13789 100644 --- a/TODO +++ b/TODO @@ -0,0 +1 @@ + diff --git a/backend/transaction.py b/backend/transaction.py deleted file mode 100755 index 437821f..0000000 --- a/backend/transaction.py +++ /dev/null @@ -1,270 +0,0 @@ -#! /usr/bin/python -# -*-coding:utf-8-*- - -from gi.repository import Gtk - -import pyalpm -import traceback - -from backend import config - -interface = Gtk.Builder() -interface.add_from_file('/usr/share/pamac/dialogs.glade') - -ProgressWindow = interface.get_object('ProgressWindow') -progress_bar = interface.get_object('progressbar2') -progress_label = interface.get_object('progresslabel2') -action_icon = interface.get_object('action_icon') -ErrorDialog = interface.get_object('ErrorDialog') -WarningDialog = interface.get_object('WarningDialog') -QuestionDialog = interface.get_object('QuestionDialog') - -t = None -t_lock = False -conflict_to_remove = None -to_remove = None -to_add = None -to_update = None -do_syncfirst = False -list_first = [] - -def init_transaction(handle, **options): - "Transaction initialization" - global t_lock - handle.dlcb = cb_dl - handle.totaldlcb = totaldlcb - handle.eventcb = cb_event - handle.questioncb = cb_conv - handle.progresscb = cb_progress - handle.logcb = cb_log - try: - _t = handle.init_transaction(**options) - print(_t.flags) - t_lock = True - return _t - except pyalpm.error: - ErrorDialog.format_secondary_text(traceback.format_exc()) - response = ErrorDialog.run() - if response: - ErrorDialog.hide() - return False - -def check_conflicts(): - global conflict_to_remove - conflict_to_remove = {} - warning = '' - 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 '+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 - 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: - WarningDialog.hide() - -def do_refresh(): - """Sync databases like pacman -Sy""" - global t - global t_lock - for db in config.handle.get_syncdbs(): - if t_lock is False: - t = init_transaction(config.handle) - try: - db.update(force=False) - t.release() - t_lock = False - except pyalpm.error: - ErrorDialog.format_secondary_text(traceback.format_exc()) - response = ErrorDialog.run() - if response: - ErrorDialog.hide() - t_lock = False - break - progress_label.set_text('') - progress_bar.set_text('') - -def t_finalize(t): - ProgressWindow.show_all() - try: - t.prepare() - except pyalpm.error: - ErrorDialog.format_secondary_text(traceback.format_exc()) - response = ErrorDialog.run() - if response: - ErrorDialog.hide() - try: - t.commit() - except pyalpm.error: - ErrorDialog.format_secondary_text(traceback.format_exc()) - response = ErrorDialog.run() - if response: - ErrorDialog.hide() - t_lock = False - ProgressWindow.hide() - t.release() - -def get_updates(): - """Return a list of package objects in local db which can be updated""" - global do_syncfirst - global list_first - if config.syncfirst: - for name in config.syncfirst: - pkg = config.handle.get_localdb().get_pkg(name) - candidate = pyalpm.sync_newversion(pkg, config.handle.get_syncdbs()) - if candidate: - list_first.append(candidate) - if list_first: - do_syncfirst = True - return list_first - result = [] - installed_pkglist = config.handle.get_localdb().pkgcache - for pkg in installed_pkglist: - candidate = pyalpm.sync_newversion(pkg, config.handle.get_syncdbs()) - if candidate: - result.append(candidate) - return result - -def get_new_version_available(pkgname): - for repo in config.handle.get_syncdbs(): - pkg = repo.get_pkg(pkgname) - if pkg is not None: - return pkg.version - break - -def format_size(size): - KiB_size = size / 1024 - if KiB_size < 1000: - size_string = '%.1f KiB' % (KiB_size) - return size_string - else: - size_string = '%.2f MiB' % (KiB_size / 1024) - return size_string - - -# Callbacks -event_text = ' ' -def cb_event(ID, event, tupel): - global event_text - while Gtk.events_pending(): - Gtk.main_iteration() - if ID is 1: - progress_label.set_text('Checking dependencies') - action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/package-search.png') - elif ID is 3: - progress_label.set_text('Checking file conflicts') - action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/package-search.png') - elif ID is 5: - progress_label.set_text('Resolving dependencies') - action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/setup.png') - elif ID is 7: - progress_label.set_text('Checking inter conflicts') - action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/package-search.png') - elif ID is 9: - progress_label.set_text('Installing packages') - action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/package-add.png') - elif ID is 11: - progress_label.set_text('Removing packages') - action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/package-delete.png') - elif ID is 13: - progress_label.set_text('Upgrading packages') - action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/package-update.png') - elif ID is 15: - progress_label.set_text('Checking integrity') - action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/package-search.png') - elif ID is 17: - progress_label.set_text('Checking signatures') - action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/package-search.png') - print('Checking signatures') - elif ID is 27: - print('Downloading a file') - else : - progress_label.set_text('') - progress_bar.set_fraction(0.0) - progress_bar.set_text('') - print(ID,event) - -def cb_conv(*args): - print("conversation", args) - -_logmask = pyalpm.LOG_ERROR | pyalpm.LOG_WARNING - -def cb_log(level, line): - #global t - if not (level & _logmask): - return - if level & pyalpm.LOG_ERROR: - ErrorDialog.format_secondary_text("ERROR: "+line) - response = ErrorDialog.run() - if response: - ErrorDialog.hide() - #t.release() - elif level & pyalpm.LOG_WARNING: - WarningDialog.format_secondary_text("WARNING: "+line) - response = WarningDialog.run() - if response: - WarningDialog.hide() - elif level & pyalpm.LOG_DEBUG: - line = "DEBUG: " + line - print(line) - elif level & pyalpm.LOG_FUNCTION: - line = "FUNC: " + line - print(line) - -total_size = 0 -def totaldlcb(_total_size): - global total_size - total_size = _total_size - -already_transferred = 0 -def cb_dl(_target, _transferred, total): - global already_transferred - while Gtk.events_pending(): - Gtk.main_iteration() - if total_size > 0: - fraction = (_transferred+already_transferred)/total_size - size = 0 - if (to_remove or to_add): - for pkg in to_remove+to_add: - if pkg.name+'-'+pkg.version in _target: - size = pkg.size - if _transferred == size: - already_transferred += size - progress_label.set_text('Downloading '+format_size(total_size)) - progress_bar.set_text(_target) - progress_bar.set_fraction(fraction) - action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/package-download.png') - else: - progress_label.set_text('Refreshing...') - progress_bar.set_text(_target) - progress_bar.pulse() - action_icon.set_from_file('/usr/share/icons/hicolor/24x24/status/refresh-cache.png') - -def cb_progress(_target, _percent, n, i): - while Gtk.events_pending(): - Gtk.main_iteration() - target = _target+' ('+str(i)+'/'+str(n)+')' - progress_bar.set_fraction(_percent/100) - progress_bar.set_text(target) - - -if __name__ == "__main__": - True diff --git a/data/pamac.desktop b/data/applications/pamac-manager.desktop similarity index 99% rename from data/pamac.desktop rename to data/applications/pamac-manager.desktop index b72a7ea..935ed7b 100644 --- a/data/pamac.desktop +++ b/data/applications/pamac-manager.desktop @@ -131,7 +131,7 @@ Comment[zh_CN]=添加或删除系统中安装的软件 Comment[zh_HK]=加入或移除系統上安裝的軟件 Comment[zh_TW]=加入或移除系統上安裝的軟體 Icon=system-software-install -Exec=gksu pamac +Exec=gksu pamac-manager Terminal=false Type=Application Categories=GNOME;GTK;System; diff --git a/data/pamac-update.desktop b/data/applications/pamac-updater.desktop similarity index 99% rename from data/pamac-update.desktop rename to data/applications/pamac-updater.desktop index ba6f331..3059aff 100644 --- a/data/pamac-update.desktop +++ b/data/applications/pamac-updater.desktop @@ -127,7 +127,7 @@ Comment[zh_CN]=更新本系统中安装的软件 Comment[zh_HK]=更新系統中已安裝的軟件 Comment[zh_TW]=更新系統中已安裝的軟體 Icon=system-software-update -Exec=gksu pamac-update +Exec=gksu pamac-updater Terminal=false Type=Application Categories=GNOME;GTK;System; diff --git a/data/dbus/org.manjaro.pamac.conf b/data/dbus/org.manjaro.pamac.conf new file mode 100644 index 0000000..d53cca6 --- /dev/null +++ b/data/dbus/org.manjaro.pamac.conf @@ -0,0 +1,19 @@ + + + + system + + + + + + + + + + + + + + diff --git a/data/dbus/org.manjaro.pamac.service b/data/dbus/org.manjaro.pamac.service new file mode 100644 index 0000000..6448986 --- /dev/null +++ b/data/dbus/org.manjaro.pamac.service @@ -0,0 +1,5 @@ +[D-BUS Service] +Name=org.manjaro.pamac +Exec=/usr/bin/start-pamac-daemon +User=root + diff --git a/data/polkit/org.manjaro.pamac.policy b/data/polkit/org.manjaro.pamac.policy new file mode 100644 index 0000000..91f2d77 --- /dev/null +++ b/data/polkit/org.manjaro.pamac.policy @@ -0,0 +1,26 @@ + + + + Manjaro + pamac + + Authentication is required to change alpm database + L'authentification est nécessaire pour changer la base de données alpm + + no + no + auth_admin_keep + + + + + + no + no + yes + + + + diff --git a/gui/dialogs.glade b/gui/dialogs.glade index 4dda61e..fb038f0 100644 --- a/gui/dialogs.glade +++ b/gui/dialogs.glade @@ -42,7 +42,7 @@ center 250 60 - /usr/share/icons/hicolor/22x22/status/setup.png + /usr/share/pamac/icons/22x22/status/setup.png True False diff --git a/gui/pamac.glade b/gui/manager.glade similarity index 99% rename from gui/pamac.glade rename to gui/manager.glade index 2ed31b4..950f4b3 100644 --- a/gui/pamac.glade +++ b/gui/manager.glade @@ -7,7 +7,7 @@ center 350 250 - /usr/share/icons/hicolor/22x22/status/package-info.png + /usr/share/pamac/icons/22x22/status/package-info.png True False @@ -146,12 +146,11 @@ 800 500 - True False Pamac 800 500 - /usr/share/icons/hicolor/22x22/status/package-sources.png + /usr/share/pamac/icons/22x22/status/package-sources.png diff --git a/gui/pamac_update.glade b/gui/updater.glade similarity index 98% rename from gui/pamac_update.glade rename to gui/updater.glade index a456eac..c0f9db4 100644 --- a/gui/pamac_update.glade +++ b/gui/updater.glade @@ -7,7 +7,7 @@ center 350 250 - /usr/share/icons/hicolor/22x22/status/package-info.png + /usr/share/pamac/icons/22x22/status/package-info.png True False @@ -16,7 +16,7 @@ False vertical - + True False label @@ -147,7 +147,7 @@ False Update Manager center - /usr/share/icons/hicolor/22x22/status/package-update.png + /usr/share/pamac/icons/22x22/status/package-update.png diff --git a/pamac-manager b/pamac-manager new file mode 100755 index 0000000..1a3537f --- /dev/null +++ b/pamac-manager @@ -0,0 +1,3 @@ +#! /bin/sh + +exec /usr/lib/python3.3/site-packages/pamac/manager.py diff --git a/pamac-update b/pamac-update deleted file mode 100755 index a10f4d9..0000000 --- a/pamac-update +++ /dev/null @@ -1,16 +0,0 @@ -#! /usr/bin/python -# -*-coding:utf-8 -*- - -from os import geteuid - -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() - transaction.ProgressWindow.hide() - update.main() diff --git a/pamac-updater b/pamac-updater new file mode 100755 index 0000000..ca19274 --- /dev/null +++ b/pamac-updater @@ -0,0 +1,3 @@ +#! /bin/sh + +exec /usr/lib/python3.3/site-packages/pamac/updater.py diff --git a/backend/__init__.py b/pamac/__init__.py similarity index 100% rename from backend/__init__.py rename to pamac/__init__.py diff --git a/pamac/callbacks.py b/pamac/callbacks.py new file mode 100755 index 0000000..2c0d2e2 --- /dev/null +++ b/pamac/callbacks.py @@ -0,0 +1,120 @@ +#! /usr/bin/python +# -*-coding:utf-8-*- + +from gi.repository import Gtk +import pyalpm +from pamac import config + + +# Callbacks +interface = Gtk.Builder() +interface.add_from_file('/usr/share/pamac/gui/dialogs.glade') + +ProgressWindow = interface.get_object('ProgressWindow') +progress_bar = interface.get_object('progressbar2') +progress_label = interface.get_object('progresslabel2') +action_icon = interface.get_object('action_icon') + +event_text = ' ' +def cb_event(ID, event, tupel): + global event_text + while Gtk.events_pending(): + Gtk.main_iteration() + if ID is 1: + progress_label.set_text('Checking dependencies') + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-search.png') + elif ID is 3: + progress_label.set_text('Checking file conflicts') + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-search.png') + elif ID is 5: + progress_label.set_text('Resolving dependencies') + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/setup.png') + elif ID is 7: + progress_label.set_text('Checking inter conflicts') + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-search.png') + elif ID is 9: + progress_label.set_text('Installing packages') + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-add.png') + elif ID is 11: + progress_label.set_text('Removing packages') + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-delete.png') + elif ID is 13: + progress_label.set_text('Upgrading packages') + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-update.png') + elif ID is 15: + progress_label.set_text('Checking integrity') + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-search.png') + elif ID is 17: + progress_label.set_text('Checking signatures') + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-search.png') + print('Checking signatures') + elif ID is 27: + print('Downloading a file') + else : + progress_label.set_text('') + progress_bar.set_fraction(0.0) + progress_bar.set_text('') + print(ID,event) + +def cb_conv(*args): + print("conversation", args) + +_logmask = pyalpm.LOG_ERROR | pyalpm.LOG_WARNING + +def cb_log(level, line): + #global t + if not (level & _logmask): + return + if level & pyalpm.LOG_ERROR: + ErrorDialog.format_secondary_text("ERROR: "+line) + response = ErrorDialog.run() + if response: + ErrorDialog.hide() + #t.release() + elif level & pyalpm.LOG_WARNING: + WarningDialog.format_secondary_text("WARNING: "+line) + response = WarningDialog.run() + if response: + WarningDialog.hide() + elif level & pyalpm.LOG_DEBUG: + line = "DEBUG: " + line + print(line) + elif level & pyalpm.LOG_FUNCTION: + line = "FUNC: " + line + print(line) + +total_size = 0 +def totaldlcb(_total_size): + global total_size + total_size = _total_size + +already_transferred = 0 +def cb_dl(_target, _transferred, total): + global already_transferred + while Gtk.events_pending(): + Gtk.main_iteration() + if total_size > 0: + fraction = (_transferred+already_transferred)/total_size + size = 0 + if (to_remove or to_add): + for pkg in to_remove+to_add: + if pkg.name+'-'+pkg.version in _target: + size = pkg.size + if _transferred == size: + already_transferred += size + progress_label.set_text('Downloading '+format_size(total_size)) + progress_bar.set_text(_target) + progress_bar.set_fraction(fraction) + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-download.png') + else: + progress_label.set_text('Refreshing...') + progress_bar.set_text(_target) + progress_bar.pulse() + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/refresh-cache.png') + +def cb_progress(_target, _percent, n, i): + while Gtk.events_pending(): + Gtk.main_iteration() + target = _target+' ('+str(i)+'/'+str(n)+')' + progress_bar.set_fraction(_percent/100) + progress_bar.set_text(target) diff --git a/backend/config.py b/pamac/config.py similarity index 100% rename from backend/config.py rename to pamac/config.py diff --git a/pamac b/pamac/manager.py similarity index 78% rename from pamac rename to pamac/manager.py index b2f33b0..8ab3174 100755 --- a/pamac +++ b/pamac/manager.py @@ -10,11 +10,13 @@ from time import strftime, localtime from os import geteuid import traceback -from backend import transaction, config +from pamac import transaction, config, callbacks interface = Gtk.Builder() -interface.add_from_file('/usr/share/pamac/pamac.glade') -interface.add_from_file('/usr/share/pamac/dialogs.glade') +interface.add_from_file('/usr/share/pamac/gui/manager.glade') +interface.add_from_file('/usr/share/pamac/gui/dialogs.glade') + +MainWindow = interface.get_object("MainWindow") packages_list = interface.get_object('packages_list') groups_list = interface.get_object('groups_list') @@ -64,6 +66,7 @@ def set_list_dict_search(*patterns): pkg_object_dict[pkg_object.name] = pkg_object pkg_installed_dict[pkg_object.name] = False for pkg_object in config.handle.get_localdb().search(*patterns): + print(pkg_object) if not pkg_object.name in pkg_name_list: pkg_name_list.append(pkg_object.name) pkg_installed_dict[pkg_object.name] = True @@ -123,6 +126,7 @@ def refresh_packages_list(): packages_list.append([name, pkg_installed_dict[name], True]) else: packages_list.append([name, pkg_installed_dict[name], True]) + print(name,pkg_installed_dict[name]) def set_packages_list(): global list_dict @@ -194,28 +198,25 @@ def set_desc(pkg, style): def set_transaction_sum(): transaction_sum.clear() if transaction.to_remove: - transaction_sum.append(['To remove:', transaction.to_remove[0].name]) + transaction_sum.append(['To remove:', transaction.to_remove[0]]) i = 1 while i < len(transaction.to_remove): - transaction_sum.append([' ', transaction.to_remove[i].name]) + transaction_sum.append([' ', transaction.to_remove[i]]) i += 1 bottom_label.set_markup('') if transaction.to_add: - installed_name = [] + installed = [] for pkg_object in config.handle.get_localdb().pkgcache: - installed_name.append(pkg_object.name) - to_add_name = [] - for pkg_object in transaction.to_add: - to_add_name.append(pkg_object.name) - transaction.to_update = sorted(set(installed_name).intersection(to_add_name)) - to_remove_from_add_name = sorted(set(transaction.to_update).intersection(to_add_name)) - for name in to_remove_from_add_name: - to_add_name.remove(name) - if to_add_name: - transaction_sum.append(['To install:', to_add_name[0]]) + installed.append(pkg_object.name) + transaction.to_update = sorted(set(installed).intersection(transaction.to_add)) + to_remove_from_add = sorted(set(transaction.to_update).intersection(transaction.to_add)) + for name in to_remove_from_add: + transaction.to_add.remove(name) + if transaction.to_add: + transaction_sum.append(['To install:', transaction.to_add[0]]) i = 1 - while i < len(to_add_name): - transaction_sum.append([' ', to_add_name[i]]) + while i < len(transaction.to_add): + transaction_sum.append([' ', transaction.to_add[i]]) i += 1 if transaction.to_update: transaction_sum.append(['To update:', transaction.to_update[0]]) @@ -225,25 +226,32 @@ def set_transaction_sum(): i += 1 bottom_label.set_markup('') #bottom_label.set_markup('Total Download size: '+format_size(totaldlcb)) - top_label.set_markup('Transaction Summary') + top_label.set_markup('Transaction Summary') class Handler: def on_MainWindow_delete_event(self, *arg): - Gtk.main_quit() + if __name__ == "__main__": + Gtk.main_quit() + else: + MainWindow.hide() def on_QuitButton_clicked(self, *arg): - Gtk.main_quit() + if __name__ == "__main__": + Gtk.main_quit() + else: + MainWindow.hide() def on_ValidButton_clicked(self, *arg): global t global transaction_type global transaction_dict - if not geteuid() == 0: - transaction.ErrorDialog.format_secondary_text("You need to be root to run packages transactions") - response = transaction.ErrorDialog.run() - if response: - transaction.ErrorDialog.hide() - elif not transaction_dict: + #if not geteuid() == 0: + #transaction.ErrorDialog.format_secondary_text("You need to be root to run packages transactions") + #response = transaction.ErrorDialog.run() + #if response: + #transaction.ErrorDialog.hide() + #el + if not transaction_dict: transaction.ErrorDialog.format_secondary_text("No package is selected") response = transaction.ErrorDialog.run() if response: @@ -253,42 +261,37 @@ class Handler: print('Transaction locked') else: 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) - try: - transaction.t.prepare() - except pyalpm.error: - transaction.ErrorDialog.format_secondary_text(traceback.format_exc()) + transaction.init_transaction(cascade = True) + for pkgname in transaction_dict.keys(): + transaction.Remove(pkgname) + error = transaction.Prepare() + if error: + transaction.ErrorDialog.format_secondary_text(error) response = transaction.ErrorDialog.run() if response: transaction.ErrorDialog.hide() - transaction.t.release() + transaction.Release() transaction.t_lock = False - transaction.to_remove = transaction.t.to_remove - transaction.to_add = transaction.t.to_add + transaction.get_to_remove() + #transaction.get_to_add() set_transaction_sum() ConfDialog.show_all() 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()) + transaction.init_transaction(noconflicts = True) + for pkgname in transaction_dict.keys(): + transaction.Add(pkgname) + error = transaction.Prepare() + if error: + transaction.ErrorDialog.format_secondary_text(error) response = transaction.ErrorDialog.run() if response: transaction.ErrorDialog.hide() - transaction.t.release() + transaction.Release() transaction.t_lock = False + transaction.get_to_remove() + transaction.get_to_add() 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.Release() set_transaction_sum() ConfDialog.show_all() @@ -306,37 +309,31 @@ class Handler: def on_TransCancelButton_clicked(self, *arg): ConfDialog.hide() transaction.t_lock = False - try: - transaction.t.release() - except: - pass + transaction.Release() def on_TransValidButton_clicked(self, *arg): global transaction_type ConfDialog.hide() + while Gtk.events_pending(): + Gtk.main_iteration() if transaction_type is "remove": - transaction.ProgressWindow.show_all() - try: - transaction.t.commit() - except pyalpm.error: - transaction.ErrorDialog.format_secondary_text(traceback.format_exc()) + error = transaction.Commit() + if error: + transaction.ErrorDialog.format_secondary_text(error) response = transaction.ErrorDialog.run() if response: transaction.ErrorDialog.hide() - transaction_dict.clear() - transaction_type = None - set_packages_list() - transaction.ProgressWindow.hide() + transaction.Release() if transaction_type is "install": - transaction.t = transaction.init_transaction(config.handle, noconflicts = True, nodeps = True) - for pkg in transaction.to_add: - transaction.t.add_pkg(pkg) - for pkg in transaction.to_remove: - transaction.t.remove_pkg(pkg) - transaction.t_finalize(transaction.t) - transaction_dict.clear() - transaction_type = None - set_packages_list() + transaction.init_transaction(noconflicts = True, nodeps = True) + for pkgname in transaction.to_add: + transaction.Add(pkgname) + for pkgname in transaction.to_remove: + transaction.Remove(pkgname) + transaction.finalize() + transaction_dict.clear() + transaction_type = None + set_packages_list() transaction.t_lock = False def on_search_button_clicked(self, widget): @@ -418,15 +415,16 @@ class Handler: packages_list[line][1] = not packages_list[line][1] packages_list[line][2] = True +def main(): + interface.connect_signals(Handler()) + MainWindow.show_all() + 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.action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/refresh-cache.png') transaction.do_refresh() - transaction.ProgressWindow.hide() - interface.connect_signals(Handler()) - MainWindow = interface.get_object("MainWindow") - MainWindow.show_all() + main() Gtk.main() + diff --git a/pamac/pamac-daemon.py b/pamac/pamac-daemon.py new file mode 100755 index 0000000..40f16f1 --- /dev/null +++ b/pamac/pamac-daemon.py @@ -0,0 +1,161 @@ +#! /usr/bin/python +# -*-coding:utf-8-*- + +import dbus +import dbus.service +from dbus.mainloop.glib import DBusGMainLoop +import os +from gi.repository import GObject, Gtk + +import pyalpm +import traceback +from pamac import config, callbacks + +LANG = os.environ['LANG'] + +t = None +error = '' + +class PamacDBusService(dbus.service.Object): + def __init__(self): + bus=dbus.SystemBus() + bus_name = dbus.service.BusName('org.manjaro.pamac', bus) + dbus.service.Object.__init__(self, bus_name, '/org/manjaro/pamac') + + def policykit_test(self,sender,connexion,action): + bus = dbus.SystemBus() + proxy_dbus = connexion.get_object('org.freedesktop.DBus','/org/freedesktop/DBus/Bus', False) + dbus_info = dbus.Interface(proxy_dbus,'org.freedesktop.DBus') + sender_pid = dbus_info.GetConnectionUnixProcessID(sender) + proxy_policykit = bus.get_object('org.freedesktop.PolicyKit1','/org/freedesktop/PolicyKit1/Authority',False) + policykit_authority = dbus.Interface(proxy_policykit,'org.freedesktop.PolicyKit1.Authority') + + Subject = ('unix-process', {'pid': dbus.UInt32(sender_pid, variant_level=1), + 'start-time': dbus.UInt64(0, variant_level=1)}) + (is_authorized,is_challenge,details) = policykit_authority.CheckAuthorization(Subject, action, {'': ''}, dbus.UInt32(1), '') + return is_authorized + + @dbus.service.method('org.manjaro.pamac', 'a{sb}', 's', sender_keyword='sender', connection_keyword='connexion') + def Init(self, options, sender=None, connexion=None): + global t + global error + if self.policykit_test(sender,connexion,'org.manjaro.pamac.init_release'): + error = '' + try: + config.handle.dlcb = callbacks.cb_dl + config.handle.totaldlcb = callbacks.totaldlcb + config.handle.eventcb = callbacks.cb_event + config.handle.questioncb = callbacks.cb_conv + config.handle.progresscb = callbacks.cb_progress + config.handle.logcb = callbacks.cb_log + t = config.handle.init_transaction(**options) + print('Init:',t.flags) + except pyalpm.error: + error = traceback.format_exc() + finally: + return error + else : + return 'You are not authorized' + + @dbus.service.method('org.manjaro.pamac', 's', 's', sender_keyword='sender', connection_keyword='connexion') + def Remove(self, pkgname, sender=None, connexion=None): + global t + global error + error = '' + try: + pkg = config.handle.get_localdb().get_pkg(pkgname) + if pkg is not None: + t.remove_pkg(pkg) + except pyalpm.error: + error = traceback.format_exc() + finally: + return error + + @dbus.service.method('org.manjaro.pamac', 's', 's', sender_keyword='sender', connection_keyword='connexion') + def Add(self, pkgname, sender=None, connexion=None): + global t + global error + error = '' + try: + for repo in config.handle.get_syncdbs(): + pkg = repo.get_pkg(pkgname) + if pkg: + t.add_pkg(pkg) + break + except pyalpm.error: + error = traceback.format_exc() + finally: + return error + + @dbus.service.method('org.manjaro.pamac', '', 's', sender_keyword='sender', connection_keyword='connexion') + def Prepare(self, sender=None, connexion=None): + global t + global error + error = '' + try: + t.prepare() + except pyalpm.error: + error = traceback.format_exc() + finally: + print('to_add:',t.to_add) + print('to_remove:',t.to_remove) + return error + + @dbus.service.method('org.manjaro.pamac', '', 'as', sender_keyword='sender', connection_keyword='connexion') + def To_Remove(self, sender=None, connexion=None): + global t + liste = [] + for pkg in t.to_remove: + liste.append(pkg.name) + return liste + + @dbus.service.method('org.manjaro.pamac', '', 'as', sender_keyword='sender', connection_keyword='connexion') + def To_Add(self, sender=None, connexion=None): + global t + liste = [] + for pkg in t.to_add: + liste.append(pkg.name) + return liste + + @dbus.service.method('org.manjaro.pamac', '', 's',sender_keyword='sender', connection_keyword='connexion') + def Commit(self, sender=None, connexion=None): + global t + global error + if self.policykit_test(sender,connexion,'org.manjaro.pamac.commit'): + try: + callbacks.ProgressWindow.show_all() + while Gtk.events_pending(): + Gtk.main_iteration() + t.commit() + except pyalpm.error: + error = traceback.format_exc() + finally: + return error + else : + return 'You are not authorized' + + @dbus.service.method('org.manjaro.pamac', '', 's', sender_keyword='sender', connection_keyword='connexion') + def Release(self, sender=None, connexion=None): + global t + global error + if self.policykit_test(sender,connexion,'org.manjaro.pamac.init_release'): + error = '' + try: + callbacks.ProgressWindow.hide() + t.release() + except pyalpm.error: + error = traceback.format_exc() + finally: + return error + else : + return 'You are not authorized' + + @dbus.service.method('org.manjaro.pamac',sender_keyword='sender', connection_keyword='connexion') + def StopDaemon(self,sender=None, connexion=None): + loop.quit() + + +DBusGMainLoop(set_as_default=True) +myservice = PamacDBusService() +loop = GObject.MainLoop() +loop.run() diff --git a/pamac/transaction.py b/pamac/transaction.py new file mode 100755 index 0000000..65936b5 --- /dev/null +++ b/pamac/transaction.py @@ -0,0 +1,178 @@ +#! /usr/bin/python +# -*-coding:utf-8-*- + +from gi.repository import Gtk + +import pyalpm +import traceback +import dbus + +from pamac import config + +interface = Gtk.Builder() +interface.add_from_file('/usr/share/pamac/gui/dialogs.glade') + +ErrorDialog = interface.get_object('ErrorDialog') +WarningDialog = interface.get_object('WarningDialog') + +t = None +t_lock = False +conflict_to_remove = None +to_remove = None +to_add = None +to_update = None +do_syncfirst = False +list_first = [] + +proxy = dbus.SystemBus().get_object('org.manjaro.pamac','/org/manjaro/pamac') +Init = proxy.get_dbus_method('Init','org.manjaro.pamac') +Remove = proxy.get_dbus_method('Remove','org.manjaro.pamac') +Add = proxy.get_dbus_method('Add','org.manjaro.pamac') +Prepare = proxy.get_dbus_method('Prepare','org.manjaro.pamac') +To_Remove = proxy.get_dbus_method('To_Remove','org.manjaro.pamac') +To_Add = proxy.get_dbus_method('To_Add','org.manjaro.pamac') +Commit = proxy.get_dbus_method('Commit','org.manjaro.pamac') +Release = proxy.get_dbus_method('Release','org.manjaro.pamac') + +def init_transaction(**options): + "Transaction initialization" + global t_lock + global proxy + error = Init(options) + print(error) + if not error: + t_lock = True + return True + else: + ErrorDialog.format_secondary_text(error) + response = ErrorDialog.run() + if response: + ErrorDialog.hide() + return False + +def check_conflicts(): + global conflict_to_remove + global to_add + global to_remove + conflict_to_remove = {} + to_check = [] + warning = '' + for pkgname in to_add: + for repo in config.handle.get_syncdbs(): + pkg = repo.get_pkg(pkgname) + if pkg: + to_check.append(pkg) + break + for target in to_check: + if target.replaces: + for name in target.replaces: + pkg = config.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+' 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 to_remove: + to_remove.append(pkg.name) + 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 to_remove: + to_remove.append(installed_pkg.name) + if warning: + WarningDialog.format_secondary_text(warning) + response = WarningDialog.run() + if response: + WarningDialog.hide() + +def get_to_remove(): + global to_remove + to_remove = To_Remove() + +def get_to_add(): + global to_add + to_add = To_Add() + +def finalize(): + global t_lock + while Gtk.events_pending(): + Gtk.main_iteration() + error = Prepare() + if error: + ErrorDialog.format_secondary_text(error) + response = ErrorDialog.run() + if response: + transaction.ErrorDialog.hide() + error = Commit() + if error: + ErrorDialog.format_secondary_text(error) + response = ErrorDialog.run() + if response: + transaction.ErrorDialog.hide() + t_lock = False + Release() + +def do_refresh(): + """Sync databases like pacman -Sy""" + global t + global t_lock + for db in config.handle.get_syncdbs(): + if t_lock is False: + t = init_transaction() + try: + db.update(force=False) + t.release() + t_lock = False + except pyalpm.error: + ErrorDialog.format_secondary_text(traceback.format_exc()) + response = ErrorDialog.run() + if response: + ErrorDialog.hide() + t_lock = False + break + t_lock = False + progress_label.set_text('') + progress_bar.set_text('') + +def get_updates(): + """Return a list of package objects in local db which can be updated""" + global do_syncfirst + global list_first + if config.syncfirst: + for name in config.syncfirst: + pkg = config.handle.get_localdb().get_pkg(name) + candidate = pyalpm.sync_newversion(pkg, config.handle.get_syncdbs()) + if candidate: + list_first.append(candidate) + if list_first: + do_syncfirst = True + return list_first + result = [] + installed_pkglist = config.handle.get_localdb().pkgcache + for pkg in installed_pkglist: + candidate = pyalpm.sync_newversion(pkg, config.handle.get_syncdbs()) + if candidate: + result.append(candidate) + return result + +def get_new_version_available(pkgname): + for repo in config.handle.get_syncdbs(): + pkg = repo.get_pkg(pkgname) + if pkg is not None: + return pkg.version + break + +def format_size(size): + KiB_size = size / 1024 + if KiB_size < 1000: + size_string = '%.1f KiB' % (KiB_size) + return size_string + else: + size_string = '%.2f MiB' % (KiB_size / 1024) + return size_string diff --git a/backend/tray.py b/pamac/tray.py similarity index 56% rename from backend/tray.py rename to pamac/tray.py index 828f855..db94835 100755 --- a/backend/tray.py +++ b/pamac/tray.py @@ -3,7 +3,7 @@ from gi.repository import Gtk -import transaction, update +from pamac import transaction, updater, manager class Tray: def __init__(self, icon, info): @@ -15,23 +15,26 @@ class Tray: 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.menuItem = Gtk.ImageMenuItem('Check for updates') + self.menuItem.connect('activate', self.execute_update, self.statusIcon) + self.menu.append(self.menuItem) + self.menuItem = Gtk.ImageMenuItem('Run pamac') + self.menuItem.connect('activate', self.execute_manager, self.statusIcon) self.menu.append(self.menuItem) self.menuItem = Gtk.ImageMenuItem(Gtk.STOCK_QUIT) - self.menuItem.connect('activate', self.quit_cb, self.statusIcon) + self.menuItem.connect('activate', self.quit_tray, 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_update(self, widget, event, data = None): + updater.main() - def execute_cb(self, widget, event, data = None): - update.main() + def execute_manager(self, widget, event, data = None): + manager.main() - def quit_cb(self, widget, data = None): + def quit_tray(self, widget, data = None): Gtk.main_quit() def popup_menu_cb(self, widget, button, time, data = None): @@ -43,9 +46,10 @@ class Tray: if __name__ == "__main__": updates = transaction.get_updates() if updates: - icon = '/usr/share/icons/hicolor/24x24/status/update-normal.png' + icon = '/usr/share/pamac/icons/24x24/status/update-normal.png' info = str(len(updates))+' update(s) available' else: - icon = '/usr/share/icons/hicolor/24x24/status/update-enhancement.png' + icon = '/usr/share/pamac/icons/24x24/status/update-enhancement.png' info = ' No update available' tray = Tray(icon, info) + Gtk.main() diff --git a/backend/update.py b/pamac/updater.py similarity index 78% rename from backend/update.py rename to pamac/updater.py index 506c7b5..d00423a 100755 --- a/backend/update.py +++ b/pamac/updater.py @@ -6,11 +6,13 @@ from gi.repository import Gtk import pyalpm from os import geteuid -from backend import config, transaction +from pamac import config, transaction interface = Gtk.Builder() -interface.add_from_file('/usr/share/pamac/pamac_update.glade') -interface.add_from_file('/usr/share/pamac/dialogs.glade') +interface.add_from_file('/usr/share/pamac/gui/updater.glade') +interface.add_from_file('/usr/share/pamac/gui/dialogs.glade') + +UpdateWindow = interface.get_object("UpdateWindow") ConfDialog = interface.get_object('ConfDialog') transaction_add = interface.get_object('transaction_add') @@ -62,12 +64,6 @@ def set_transaction_add(): while i < len(to_add_name): transaction_add.append([' ', to_add_name[i]]) i += 1 - if transaction.to_update: - transaction_add.append(['To update:', transaction.to_update[0]]) - i = 1 - while i < len(transaction.to_update): - transaction_add.append([' ', transaction.to_update[i]]) - i += 1 bottom_label.set_markup('') #bottom_label.set_markup('Total Download size: '+format_size(totaldlcb)) top_label.set_markup('Additionnal Transaction(s)') @@ -76,16 +72,21 @@ def do_sysupgrade(): """Upgrade a system like pacman -Su""" if transaction.t_lock is False: if transaction.do_syncfirst is True: - transaction.t = transaction.init_transaction(config.handle, recurse = True) - for pkg in list_first: + transaction.t = transaction.init_transaction(recurse = True) + for pkg in transaction.list_first: transaction.t.add_pkg(pkg) transaction.to_remove = transaction.t.to_remove transaction.to_add = transaction.t.to_add set_transaction_add() - ConfDialog.show_all() + if len(transaction_add) != 0: + ConfDialog.show_all() + else: + transaction.t_finalize(transaction.t) + transaction.do_syncfirst = False + transaction.list_first = [] else: try: - transaction.t = transaction.init_transaction(config.handle) + transaction.t = transaction.init_transaction() transaction.t.sysupgrade(downgrade=False) except pyalpm.error: ErrorDialog.format_secondary_text(traceback.format_exc()) @@ -105,7 +106,7 @@ def do_sysupgrade(): print("Nothing to update") else: transaction.t.release() - transaction.t = transaction.init_transaction(config.handle, noconflicts = True, nodeps = True) + transaction.t = transaction.init_transaction(noconflicts = True, nodeps = True) for pkg in transaction.to_add: transaction.t.add_pkg(pkg) for pkg in transaction.conflict_to_remove.values(): @@ -113,17 +114,23 @@ def do_sysupgrade(): transaction.to_remove = transaction.t.to_remove transaction.to_add = transaction.t.to_add set_transaction_add() - if len(transaction.to_update) + len(transaction.to_remove) != 0: + if len(transaction_add) != 0: ConfDialog.show_all() else: - transaction.t_finalize(t) + transaction.t_finalize(transaction.t) class Handler: def on_UpdateWindow_delete_event(self, *arg): - Gtk.main_quit() + if __name__ == "__main__": + Gtk.main_quit() + else: + UpdateWindow.hide() def on_QuitButton_clicked(self, *arg): - Gtk.main_quit() + if __name__ == "__main__": + Gtk.main_quit() + else: + UpdateWindow.hide() def on_ApplyButton_clicked(self, *arg): do_sysupgrade() @@ -145,11 +152,15 @@ class Handler: 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.progress_label.set_text('Refreshing...') + transaction.progress_bar.pulse() + transaction.action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/refresh-cache.png') + transaction.ProgressWindow.show_all() transaction.do_refresh() + transaction.ProgressWindow.hide() main() + Gtk.main() diff --git a/setup.py b/setup.py index 8162fe2..9fdf13f 100644 --- a/setup.py +++ b/setup.py @@ -9,5 +9,5 @@ setup(name='Pamac', author='Guillaume Benoit', author_email='guillaume@manjaro.org', url='https://git.manjaro.org/core/pamac', - packages=['backend'], + packages=['pamac'], ) diff --git a/start-pamac-daemon b/start-pamac-daemon new file mode 100755 index 0000000..6dc35a3 --- /dev/null +++ b/start-pamac-daemon @@ -0,0 +1,4 @@ +#! /bin/bash + +/usr/bin/pamac-daemon.py & + diff --git a/test.py b/test.py new file mode 100755 index 0000000..f94ac92 --- /dev/null +++ b/test.py @@ -0,0 +1,27 @@ +#! /usr/bin/python +# -*-coding:utf-8-*- + +import dbus, os +from pamac import transaction + +def policykit_auth(): + bus_name = dbus.service.BusName('apps.nano77.gdm3setup', bus) + dbus.service.Object.__init__(self, bus_name, '/apps/nano77/gdm3setup') + +def policykit_test(sender,connexion,action): + bus = dbus.SystemBus() + proxy_dbus = connexion.get_object('org.freedesktop.DBus','/org/freedesktop/DBus/Bus', False) + dbus_info = dbus.Interface(proxy_dbus,'org.freedesktop.DBus') + sender_pid = dbus_info.GetConnectionUnixProcessID(sender) + proxy_policykit = bus.get_object('org.freedesktop.PolicyKit1','/org/freedesktop/PolicyKit1/Authority',False) + policykit_authority = dbus.Interface(proxy_policykit,'org.freedesktop.PolicyKit1.Authority') + + Subject = ('unix-process', {'pid': dbus.UInt32(sender_pid, variant_level=1), + 'start-time': dbus.UInt64(0, variant_level=1)}) + (is_authorized,is_challenge,details) = policykit_authority.CheckAuthorization(Subject, action, {'': ''}, dbus.UInt32(1), '') + return is_authorized +return pk_granted + +if policykit_auth() == 1: + print('ok') + transaction.do_refresh() diff --git a/tray b/tray new file mode 100755 index 0000000..10ce7ba --- /dev/null +++ b/tray @@ -0,0 +1,3 @@ +#! /bin/sh + +exec /usr/lib/python3.3/site-packages/pamac/tray.py