From c7735f173dbc0ccf90cbf1115d6e47f4f697eb49 Mon Sep 17 00:00:00 2001 From: guinux Date: Thu, 26 Sep 2013 18:02:07 +0200 Subject: [PATCH] brand new pamac --- data/dbus/org.manjaro.pamac.conf | 16 - data/dbus/org.manjaro.pamac.service | 5 - data/polkit/org.manjaro.pamac.policy | 33 +- data/systemd/pamac.service | 7 - files_to_translate | 10 +- gui/dialogs.glade | 118 --- gui/dialogs.ui | 528 +++++++++++ gui/{manager.glade => manager.ui} | 626 ++++--------- gui/{updater.glade => updater.ui} | 19 +- pamac-daemon.py | 488 ---------- pamac-install.py | 144 ++- pamac-manager.py | 718 ++++++++++++++- pamac-refresh.py | 45 +- pamac-tray.py | 80 +- pamac-updater.py | 112 ++- pamac.pot | 596 ++++++------ pamac/main.py | 1269 -------------------------- pamac/transaction.py | 862 +++++++++++++++-- setup.py | 2 +- start-pamac-daemon | 3 - 20 files changed, 2835 insertions(+), 2846 deletions(-) delete mode 100644 data/dbus/org.manjaro.pamac.conf delete mode 100644 data/dbus/org.manjaro.pamac.service delete mode 100644 data/systemd/pamac.service delete mode 100644 gui/dialogs.glade create mode 100644 gui/dialogs.ui rename gui/{manager.glade => manager.ui} (69%) rename gui/{updater.glade => updater.ui} (89%) delete mode 100755 pamac-daemon.py mode change 100755 => 100644 pamac-install.py mode change 100755 => 100644 pamac-manager.py mode change 100755 => 100644 pamac-refresh.py mode change 100755 => 100644 pamac-tray.py mode change 100755 => 100644 pamac-updater.py delete mode 100644 pamac/main.py delete mode 100755 start-pamac-daemon diff --git a/data/dbus/org.manjaro.pamac.conf b/data/dbus/org.manjaro.pamac.conf deleted file mode 100644 index 2d727f7..0000000 --- a/data/dbus/org.manjaro.pamac.conf +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - diff --git a/data/dbus/org.manjaro.pamac.service b/data/dbus/org.manjaro.pamac.service deleted file mode 100644 index 1d8b045..0000000 --- a/data/dbus/org.manjaro.pamac.service +++ /dev/null @@ -1,5 +0,0 @@ -[D-BUS Service] -Name=org.manjaro.pamac -Exec=/usr/bin/pamac-daemon -User=root -SystemdService=pamac.service diff --git a/data/polkit/org.manjaro.pamac.policy b/data/polkit/org.manjaro.pamac.policy index 375e984..781081d 100644 --- a/data/polkit/org.manjaro.pamac.policy +++ b/data/polkit/org.manjaro.pamac.policy @@ -6,21 +6,46 @@ Manjaro http://manjaro.org/ package-x-generic - + Authentication is required no no auth_admin_keep + /usr/bin/python3 + /usr/bin/pamac-manager + true - - + + Authentication is required + + no + no + auth_admin_keep + + /usr/bin/python3 + /usr/bin/pamac-updater + true + + + Authentication is required + + no + no + auth_admin_keep + + /usr/bin/python3 + /usr/bin/pamac-install + true + + no no yes + /usr/bin/python3 + /usr/bin/pamac-refresh - diff --git a/data/systemd/pamac.service b/data/systemd/pamac.service deleted file mode 100644 index 536e633..0000000 --- a/data/systemd/pamac.service +++ /dev/null @@ -1,7 +0,0 @@ -[Unit] -Description=Pamac - -[Service] -Type=dbus -BusName=org.manjaro.pamac -ExecStart=/usr/bin/pamac-daemon diff --git a/files_to_translate b/files_to_translate index 463fb3f..de5ab10 100644 --- a/files_to_translate +++ b/files_to_translate @@ -1,7 +1,9 @@ -./pamac-daemon.py +./pamac-manager.py +./pamac-updater.py ./pamac-tray.py ./pamac-install.py -./pamac/main.py ./pamac/common.py -./gui/manager.glade -./gui/updater.glade +./pamac/transaction.py +./gui/manager.ui +./gui/updater.ui +./gui/dialogs.ui diff --git a/gui/dialogs.glade b/gui/dialogs.glade deleted file mode 100644 index a4aeaca..0000000 --- a/gui/dialogs.glade +++ /dev/null @@ -1,118 +0,0 @@ - - - - - False - False - True - center-on-parent - dialog - False - error - ok - - - False - vertical - - - False - end - - - False - True - end - 0 - - - - - - - - - - False - False - True - center-on-parent - dialog - ok - - - False - vertical - - - False - end - - - False - True - end - 0 - - - - - - - False - False - center-on-parent - dialog - question - yes-no - - - False - vertical - - - False - - - False - True - end - 0 - - - - - - - - - - False - False - center-on-parent - dialog - warning - ok - - - False - vertical - - - False - end - - - False - True - end - 0 - - - - - - - - - diff --git a/gui/dialogs.ui b/gui/dialogs.ui new file mode 100644 index 0000000..2b476ee --- /dev/null +++ b/gui/dialogs.ui @@ -0,0 +1,528 @@ + + + + + False + Choose + True + center-on-parent + system-software-install + dialog + False + + + False + vertical + + + False + end + + + gtk-ok + True + True + True + True + + + + False + True + 0 + + + + + False + True + end + 0 + + + + + True + False + + + False + True + 1 + + + + + True + True + in + 300 + 250 + + + True + True + choose_list + False + False + False + + + + + + + + + + + 0 + + + + + + 1 + + + + + + + + + True + True + 2 + + + + + + ChooseButton + + + + False + 5 + Summary + True + center-on-parent + system-software-install + dialog + False + + + True + False + vertical + 5 + + + True + False + + + False + True + 0 + + + + + True + False + True + True + in + 330 + 250 + + + True + True + True + True + transaction_sum + False + False + False + False + + + + + + + + 0 + 600 + + + 0 + + + + + + + + + + 1 + + + + + + + + + True + True + 1 + + + + + True + False + + + False + True + 2 + + + + + True + False + 7 + True + end + + + gtk-cancel + True + True + True + True + False + True + + + + False + True + 0 + + + + + gtk-ok + True + True + False + True + + + + False + True + 1 + + + + + False + True + 3 + + + + + + + False + False + True + center-on-parent + dialog + False + error + ok + + + False + vertical + + + False + end + + + False + True + end + 0 + + + + + + + + + + False + False + True + center-on-parent + dialog + ok + + + False + vertical + + + False + end + + + False + True + end + 0 + + + + + + + False + 5 + Progress + True + center-on-parent + 450 + system-software-install + dialog + False + False + + + True + False + vertical + 5 + + + True + False + 5 + + + True + False + + + False + True + 0 + + + + + True + False + + + False + True + 1 + + + + + False + True + 0 + + + + + True + False + 0.050000000000000003 + True + end + + + False + True + 1 + + + + + True + False + True + + + True + True + True + True + bottom-left + True + in + 200 + + + True + True + word + False + + + + + + + + True + False + details + + + + + False + True + 2 + + + + + True + False + 5 + end + + + gtk-cancel + True + True + True + True + + + + False + True + 0 + + + + + gtk-close + True + True + True + True + True + + + + False + True + 1 + + + + + False + True + 3 + + + + + + + False + False + center-on-parent + dialog + question + yes-no + + + False + vertical + + + False + + + False + True + end + 0 + + + + + + + + + + False + False + center-on-parent + dialog + warning + ok + + + False + vertical + + + False + end + + + False + True + end + 0 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/manager.glade b/gui/manager.ui similarity index 69% rename from gui/manager.glade rename to gui/manager.ui index 7db266c..423f3b3 100644 --- a/gui/manager.glade +++ b/gui/manager.ui @@ -1,38 +1,26 @@ - - + + False - Choose - True - center-on-parent - system-software-install + 5 + About Pamac dialog - False - ManagerWindow + Pamac + Copyright © 2013 Guillaume Benoit + A gtk3 frontend for pyalpm + http://manjaro.org + system-software-install + gpl-3-0 - + False vertical + 2 - + False end - - - gtk-ok - True - True - True - True - - - - False - True - 0 - - False @@ -42,205 +30,7 @@ - - True - False - - - False - True - 1 - - - - - True - True - in - 300 - 250 - - - True - True - choose_list - False - False - False - - - - - - - - - - - 0 - - - - - - 1 - - - - - - - - - True - True - 2 - - - - - - ChooseButton - - - - False - 5 - Summary - True - center-on-parent - system-software-install - dialog - False - ManagerWindow - - - True - False - vertical - 5 - - - True - False - - - False - True - 0 - - - - - True - False - True - True - in - 330 - 250 - - - True - True - True - True - transaction_sum - False - False - False - False - - - - - - - - 0 - 600 - - - 0 - - - - - - - - - - 1 - - - - - - - - - True - True - 1 - - - - - True - False - - - False - True - 2 - - - - - True - False - 7 - True - end - - - gtk-cancel - True - True - True - True - False - True - - - - False - True - 0 - - - - - gtk-ok - True - True - False - True - - - - False - True - 1 - - - - - False - True - 3 - + @@ -259,6 +49,68 @@ True False vertical + + + True + False + + + True + True + True + valid_icon + none + False + True + + + + False + True + 0 + + + + + True + True + True + cancel_icon + none + False + True + + + + False + True + 1 + + + + + True + True + True + end + True + menu_icon + none + True + + + False + True + 2 + + + + + False + True + 0 + + True @@ -395,17 +247,17 @@ True 2 - + True True - state_list + states_list False False False False - - + + @@ -502,14 +354,13 @@ True in - + 500 300 True True True True - packages_list 0 @@ -519,64 +370,54 @@ - + True + autosize State True - True - 1 + 0 + - - - 2 - + True + autosize Name True - True 0 + - - 0 - - - 0 - + True + autosize Version True - True - 7 + 0 + - - - 5 - + True + autosize Size True - True - 6 + 0 + - - - 3 - + @@ -865,131 +706,41 @@ True True - 5 - 2 - - - - - True - False - vertical - - - True - False - 5 - True - end - - - gtk-refresh - True - True - True - True - - - - False - True - 0 - - - - - gtk-apply - True - True - True - True - - - - False - True - 1 - - - - - gtk-undo - True - True - True - True - - - - False - True - 2 - - - - - gtk-quit - True - True - True - True - - - - False - True - 3 - - - - - False - True - 4 - 2 - - - - - False - True - 3 + 1 - - 250 - 60 + False 5 - Progress - False + Install local packages + GtkFileChooserDialog True center-on-parent - 250 - 60 - system-software-install dialog - False - ManagerWindow - False - - - True + False + package_filter + True + + + False vertical - 5 - - - True + 2 + + False - 5 + end - + + gtk-cancel True - False + True + True + True + False @@ -998,9 +749,13 @@ - + + gtk-open True - False + True + True + True + False @@ -1012,60 +767,24 @@ False True + end 0 - - True - False - 0.050000000000000003 - True - end - - - False - True - 1 - - - - - True - False - end - - - gtk-cancel - True - True - True - 1 - - - - False - True - 0 - - - - - False - True - 2 - + + + package_cancel_button + package_open_button + - - - - - - - + + True + False + gtk-cancel @@ -1101,18 +820,78 @@ + + True + False + 16 + emblem-package + + + True + False + + + gtk-refresh + True + False + True + True + + + + + + True + False + + + + + Install local packages + True + False + local_icon + False + + + + + + True + False + + + + + gtk-about + True + False + True + True + + + + + + True + False + gtk-execute + + + + application/x-xz-compressed-tar + + - - - + @@ -1129,18 +908,15 @@ - + - - - - - - - + + True + False + gtk-ok diff --git a/gui/updater.glade b/gui/updater.ui similarity index 89% rename from gui/updater.glade rename to gui/updater.ui index caf558a..daee356 100644 --- a/gui/updater.glade +++ b/gui/updater.ui @@ -1,6 +1,6 @@ - + False 5 @@ -21,7 +21,7 @@ False 5 - + True False 48 @@ -87,21 +87,6 @@ 1 - - - gtk-quit - True - True - True - True - - - - False - True - 2 - - False diff --git a/pamac-daemon.py b/pamac-daemon.py deleted file mode 100755 index bf97f8b..0000000 --- a/pamac-daemon.py +++ /dev/null @@ -1,488 +0,0 @@ -#! /usr/bin/python3 -# -*- coding:utf-8 -*- - -import dbus -import dbus.service -from dbus.mainloop.glib import DBusGMainLoop -from gi.repository import GObject - -import pyalpm -from multiprocessing import Process -from pamac import config, common - -# i18n -import gettext -gettext.bindtextdomain('pamac', '/usr/share/locale') -gettext.textdomain('pamac') -_ = gettext.gettext - -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') - self.t = None - self.task = None - self.error = '' - self.warning = '' - self.previous_action = '' - self.action = _('Preparing')+'...' - self.previous_icon = '' - self.icon = '/usr/share/pamac/icons/24x24/status/package-setup.png' - self.previous_target = '' - self.target = '' - self.previous_percent = 0 - self.percent = 0 - self.total_size = 0 - self.already_transferred = 0 - self.handle = config.handle() - - def get_handle(self): - print('daemon get handle') - self.handle = config.handle() - self.handle.dlcb = self.cb_dl - self.handle.totaldlcb = self.totaldlcb - self.handle.eventcb = self.cb_event - self.handle.questioncb = self.cb_conv - self.handle.progresscb = self.cb_progress - self.handle.logcb = self.cb_log - - @dbus.service.signal('org.manjaro.pamac') - def EmitAction(self, action): - pass - - @dbus.service.signal('org.manjaro.pamac') - def EmitIcon(self, icon): - pass - - @dbus.service.signal('org.manjaro.pamac') - def EmitTarget(self, target): - pass - - @dbus.service.signal('org.manjaro.pamac') - def EmitPercent(self, percent): - pass - - def cb_event(self, ID, event, tupel): - if ID is 1: - self.action = _('Checking dependencies')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-search.png' - elif ID is 2: - if self.warning: - self.EmitLogWarning(self.warning) - self.warning = '' - elif ID is 3: - self.action = _('Checking file conflicts')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-search.png' - elif ID is 5: - self.action = _('Resolving dependencies')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-setup.png' - elif ID is 6: - if self.warning: - self.EmitLogWarning(self.warning) - self.warning = '' - elif ID is 7: - self.action = _('Checking inter conflicts')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-search.png' - elif ID is 9: - self.action = _('Installing')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-add.png' - elif ID is 10: - formatted_event = 'Installed {pkgname} ({pkgversion})'.format(pkgname = tupel[0].name, pkgversion = tupel[0].version) - common.write_log_file(formatted_event) - print(formatted_event) - elif ID is 11: - self.action = _('Removing')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-delete.png' - elif ID is 12: - formatted_event = 'Removed {pkgname} ({pkgversion})'.format(pkgname = tupel[0].name, pkgversion = tupel[0].version) - common.write_log_file(formatted_event) - print(formatted_event) - elif ID is 13: - self.action = _('Upgrading')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-update.png' - elif ID is 14: - formatted_event = 'Upgraded {pkgname} ({oldversion} -> {newversion})'.format(pkgname = tupel[1].name, oldversion = tupel[1].version, newversion = tupel[0].version) - common.write_log_file(formatted_event) - print(formatted_event) - elif ID is 15: - self.action = _('Downgrading')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-add.png' - print('Downgrading a package') - #elif ID is 16: - #formatted_event = 'Downgraded {pkgname} ({oldversion} -> {newversion})'.format(pkgname = tupel[1].name, oldversion = tupel[1].version, newversion = tupel[0].version) - #common.write_log_file(formatted_event) - #print(formatted_event) - elif ID is 17: - self.action = _('Reinstalling')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-add.png' - print('Reinstalling a package') - #elif ID is 18: - #formatted_event = 'Reinstalled {pkgname} ({pkgversion})'.format(pkgname = tupel[0].name, pkgversion = tupel[0].version) - #common.write_log_file(formatted_event) - #print(formatted_event) - elif ID is 19: - self.action = _('Checking integrity')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-search.png' - self.already_transferred = 0 - elif ID is 21: - self.action = _('Loading packages files')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-search.png' - print('Loading packages files') - elif ID is 30: - self.action = _('Configuring')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-setup.png' - self.EmitPercent(2) - print('Configuring a package') - elif ID is 31: - print('Downloading a file') - elif ID is 36: - self.action = _('Checking keys in keyring')+'...' - self.icon = '/usr/share/pamac/icons/24x24/status/package-search.png' - print('Checking keys in keyring') - else : - self.action = '' - #self.EmitTarget('') - #self.EmitPercent(0) - if self.action != self.previous_action: - self.previous_action = self.action - self.EmitAction(self.action) - if self.icon != self.previous_icon: - self.previous_icon = self.icon - self.EmitIcon(self.icon) - print(ID,event) - - def cb_conv(self, *args): - print("conversation", args) - - def cb_log(self, level, line): - _logmask = pyalpm.LOG_ERROR | pyalpm.LOG_WARNING - if not (level & _logmask): - return - if level & pyalpm.LOG_ERROR: - #self.error += "ERROR: "+line - #self.EmitLogError(line) - print(line) - elif level & pyalpm.LOG_WARNING: - self.warning += "WARNING: "+line - #self.EmitLogWarning(line) - elif level & pyalpm.LOG_DEBUG: - line = "DEBUG: " + line - print(line) - elif level & pyalpm.LOG_FUNCTION: - line = "FUNC: " + line - print(line) - - @dbus.service.signal('org.manjaro.pamac') - def EmitLogError(self, message): - pass - - @dbus.service.signal('org.manjaro.pamac') - def EmitLogWarning(self, message): - pass - - def totaldlcb(self, _total_size): - self.total_size = _total_size - - def cb_dl(self, _target, _transferred, total): - if self.total_size > 0: - fraction = (_transferred+self.already_transferred)/self.total_size - size = 0 - try: - if (self.t.to_remove or self.t.to_add): - for pkg in self.t.to_remove+self.t.to_add: - if pkg.filename == _target: - size = pkg.size - if _transferred == size: - self.already_transferred += size - self.action = _('Downloading {size}').format(size = common.format_size(self.total_size)) - self.target = _target - self.percent = round(fraction, 2) - self.icon = '/usr/share/pamac/icons/24x24/status/package-download.png' - else: - self.action = _('Refreshing')+'...' - self.target = _target - self.percent = 2 - self.icon = '/usr/share/pamac/icons/24x24/status/refresh-cache.png' - if self.action != self.previous_action: - self.previous_action = self.action - self.EmitAction(self.action) - if self.icon != self.previous_icon: - self.previous_icon = self.icon - self.EmitIcon(self.icon) - if self.target != self.previous_target: - self.previous_target = self.target - self.EmitTarget(self.target) - if self.percent != self.previous_percent: - self.previous_percent = self.percent - self.EmitPercent(self.percent) - except pyalpm.error: - pass - - def cb_progress(self, _target, _percent, n, i): - self.target = _target+' ('+str(i)+'/'+str(n)+')' - #self.percent = round(_percent/100, 2) - self.percent = round(i/n, 2) - if self.target != self.previous_target: - self.previous_target = self.target - self.EmitTarget(self.target) - if self.percent != self.previous_percent: - self.previous_percent = self.percent - self.EmitPercent(self.percent) - - 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.signal('org.manjaro.pamac') - def EmitAvailableUpdates(self, updates_nb): - pass - - def CheckUpdates(self): - updates = 0 - _ignorepkgs = [] - for group in self.handle.ignoregrps: - db = self.handle.get_localdb() - grp = db.read_grp(group) - if grp: - name, pkg_list = grp - for pkg in pkg_list: - if not pkg.name in _ignorepkgs: - _ignorepkgs.append(pkg.name) - for name in self.handle.ignorepkgs: - pkg = self.handle.get_localdb().get_pkg(name) - if pkg: - if not pkg.name in _ignorepkgs: - _ignorepkgs.append(pkg.name) - if config.syncfirst: - for name in config.syncfirst: - pkg = self.handle.get_localdb().get_pkg(name) - if pkg: - candidate = pyalpm.sync_newversion(pkg, self.handle.get_syncdbs()) - if candidate: - updates += 1 - if not updates: - for pkg in self.handle.get_localdb().pkgcache: - candidate = pyalpm.sync_newversion(pkg, self.handle.get_syncdbs()) - if candidate: - if not candidate.name in _ignorepkgs: - updates += 1 - self.EmitAvailableUpdates(updates) - - @dbus.service.method('org.manjaro.pamac', '', 's', async_callbacks=('success', 'nosuccess')) - def Refresh(self, success, nosuccess): - def refresh(): - self.target = '' - self.percent = 0 - self.error = '' - self.get_handle() - for db in self.handle.get_syncdbs(): - try: - self.t = self.handle.init_transaction() - db.update(force = False) - except pyalpm.error as e: - self.error += ' --> '+str(e)+'\n' - break - finally: - try: - self.t.release() - except: - pass - if self.error: - self.EmitTransactionError(self.error) - else: - self.CheckUpdates() - self.EmitTransactionDone('') - self.task = Process(target=refresh) - self.task.start() - success('') - - @dbus.service.method('org.manjaro.pamac', 'a{sb}', 's')#, sender_keyword='sender', connection_keyword='connexion') - def Init(self, options):#, sender=None, connexion=None): - self.error = '' - #if self.policykit_test(sender,connexion,'org.manjaro.pamac.init_release'): - try: - self.get_handle() - self.t = self.handle.init_transaction(**options) - print('Init:',self.t.flags) - except pyalpm.error as e: - self.error += ' --> '+str(e)+'\n' - finally: - if self.error: - self.EmitTransactionError(self.error) - return self.error - #else: - # return _('Authentication failed') - - @dbus.service.method('org.manjaro.pamac', '', 's') - def Sysupgrade(self): - self.error = '' - try: - self.t.sysupgrade(downgrade=False) - print('to_upgrade:',self.t.to_add) - except pyalpm.error as e: - self.error += ' --> '+str(e)+'\n' - finally: - return self.error - - @dbus.service.method('org.manjaro.pamac', 's', 's') - def Remove(self, pkgname): - self.error = '' - try: - pkg = self.handle.get_localdb().get_pkg(pkgname) - if pkg is not None: - self.t.remove_pkg(pkg) - except pyalpm.error as e: - self.error += ' --> '+str(e)+'\n' - finally: - return self.error - - @dbus.service.method('org.manjaro.pamac', 's', 's') - def Add(self, pkgname): - self.error = '' - try: - for repo in self.handle.get_syncdbs(): - pkg = repo.get_pkg(pkgname) - if pkg: - self.t.add_pkg(pkg) - break - except pyalpm.error as e: - self.error += ' --> '+str(e)+'\n' - finally: - return self.error - - @dbus.service.method('org.manjaro.pamac', 's', 's') - def Load(self, tarball_path): - self.error = '' - try: - pkg = self.handle.load_pkg(tarball_path) - if pkg: - self.t.add_pkg(pkg) - except pyalpm.error: - self.error += _('{pkgname} is not a valid path or package name').format(pkgname = tarball_path) - finally: - return self.error - - @dbus.service.method('org.manjaro.pamac', '', 's') - def Prepare(self): - self.error = '' - try: - self.t.prepare() - except pyalpm.error as e: - self.error += ' --> '+str(e)+'\n' - finally: - return self.error - - @dbus.service.method('org.manjaro.pamac', '', 'a(ss)') - def To_Remove(self): - liste = [] - for pkg in self.t.to_remove: - liste.append((pkg.name, pkg.version)) - return liste - - @dbus.service.method('org.manjaro.pamac', '', 'a(ssi)') - def To_Add(self): - liste = [] - for pkg in self.t.to_add: - liste.append((pkg.name, pkg.version, pkg.download_size)) - return liste - - @dbus.service.method('org.manjaro.pamac', '', 's', async_callbacks=('success', 'nosuccess')) - def Interrupt(self, success, nosuccess): - def interrupt(): - self.error = '' - #try: - # self.t.interrupt() - #except pyalpm.error as e: - # self.error += ' --> '+str(e)+'\n' - try: - self.t.release() - #except pyalpm.error as e: - #self.error += ' --> '+str(e)+'\n' - except: - pass - #finally: - #if self.error: - #self.EmitTransactionError(self.error) - self.task.terminate() - interrupt() - success('') - - @dbus.service.method('org.manjaro.pamac', '', 's', sender_keyword='sender', connection_keyword='connexion', async_callbacks=('success', 'nosuccess')) - def Commit(self, success, nosuccess, sender=None, connexion=None): - def commit(): - self.error = '' - try: - self.t.commit() - except pyalpm.error as e: - self.error += ' --> '+str(e)+'\n' - #except dbus.exceptions.DBusException: - #pass - finally: - self.CheckUpdates() - if self.warning: - self.EmitLogWarning(self.warning) - self.warning = '' - if self.error: - self.EmitTransactionError(self.error) - else: - self.EmitTransactionDone(_('Transaction successfully finished')) - try: - authorized = self.policykit_test(sender,connexion,'org.manjaro.pamac.commit') - except dbus.exceptions.DBusException as e: - self.EmitTransactionError(_('Authentication failed')) - success('') - else: - if authorized: - self.task = Process(target=commit) - self.task.start() - else : - self.t.release() - self.EmitTransactionError(_('Authentication failed')) - success('') - - @dbus.service.signal('org.manjaro.pamac') - def EmitTransactionDone(self, message): - pass - - @dbus.service.signal('org.manjaro.pamac') - def EmitTransactionError(self, message): - pass - - @dbus.service.method('org.manjaro.pamac', '', 's')#, sender_keyword='sender', connection_keyword='connexion') - def Release(self):#, sender=None, connexion=None): - self.error = '' - #if self.policykit_test(sender,connexion,'org.manjaro.pamac.init_release'): - try: - self.t.release() - except pyalpm.error as e: - self.error += ' --> '+str(e)+'\n' - finally: - return self.error - #else : - # return _('Authentication failed') - - @dbus.service.method('org.manjaro.pamac') - def StopDaemon(self): - try: - self.t.release() - except: - pass - common.rm_pid_file() - mainloop.quit() - -GObject.threads_init() -DBusGMainLoop(set_as_default = True) -myservice = PamacDBusService() -common.write_pid_file() -mainloop = GObject.MainLoop() -mainloop.run() diff --git a/pamac-install.py b/pamac-install.py old mode 100755 new mode 100644 index 57460f8..82a0b87 --- a/pamac-install.py +++ b/pamac-install.py @@ -1,11 +1,10 @@ -#! /usr/bin/python3 +#! /usr/bin/pkexec /usr/bin/python3 # -*- coding:utf-8 -*- -from gi.repository import GObject +from gi.repository import Gtk from sys import argv -import dbus from os.path import abspath -from pamac import common +from pamac import common, transaction # i18n import gettext @@ -16,97 +15,84 @@ gettext.textdomain('pamac') _ = gettext.gettext def exiting(msg): - transaction.StopDaemon() print('exiting') loop.quit() -def new_on_TransCancelButton_clicked(self, *arg): - main.ProgressWindow.hide() - main.ConfDialog.hide() - transaction.Release() - exiting('') +def on_ProgressCloseButton_clicked(*args): + transaction.ProgressWindow.hide() + transaction.progress_buffer.delete(transaction.progress_buffer.get_start_iter(),transaction.progress_buffer.get_end_iter()) + common.rm_pid_file() + Gtk.main_quit() -def new_on_TransValidButton_clicked(self, *arg): - main.ConfDialog.hide() - main.finalize() +def on_ProgressCancelButton_clicked(*args): + trans.interrupt() -def get_pkgs(pkgs): +def on_TransCancelButton_clicked(self, *arg): + transaction.ConfDialog.hide() + trans.release() + common.rm_pid_file() + Gtk.main_quit() + +def on_TransValidButton_clicked(self, *arg): + transaction.ConfDialog.hide() + trans.finalize() + common.rm_pid_file() + Gtk.main_quit() + +def get_pkgs(pkgstr_list): get_error = '' - for pkg in pkgs: - if '.pkg.tar.' in pkg: - full_path = abspath(pkg) - transaction.to_load.add(full_path) - elif pkg in transaction.syncpkgs.keys(): - transaction.to_add.add(pkg) + for pkgstr in pkgstr_list: + if '.pkg.tar.' in pkgstr: + full_path = abspath(pkgstr) + trans.to_load.append(full_path) else: - if get_error: - get_error += '\n' - get_error += _('{pkgname} is not a valid path or package name').format(pkgname = pkg) + pkg = trans.get_syncpkg(pkgstr) + if pkg: + trans.to_add.append(pkg) + else: + if get_error: + get_error += '\n' + get_error += _('{pkgname} is not a valid path or package name').format(pkgname = pkgstr) if get_error: - main.handle_error(get_error) - exiting(get_error) + trans.handle_error(get_error) return False else: return True -def install(pkgs): - if get_pkgs(pkgs): - main.check_conflicts() - if transaction.to_add | transaction.to_load: - if transaction.init_transaction(noconflicts = True): - for pkgname in transaction.to_add: - transaction.Add(pkgname) - for pkg_path in transaction.to_load: - transaction.Load(pkg_path) - for pkgname in transaction.to_remove: - transaction.Remove(pkgname) - _error = transaction.Prepare() - if _error: - main.handle_error(_error) - exiting(_error) - else: - main.set_transaction_sum() - if len(main.transaction_sum) != 0: - main.ConfDialog.show_all() - loop.run() - else: - main.WarningDialog.format_secondary_text(_('Nothing to do')) - response = main.WarningDialog.run() - if response: - main.WarningDialog.hide() - exiting('') - else: - main.WarningDialog.format_secondary_text(_('Nothing to do')) - response = main.WarningDialog.run() - if response: - main.WarningDialog.hide() - exiting('') +signals = {'on_TransValidButton_clicked' : on_TransValidButton_clicked, + 'on_TransCancelButton_clicked' : on_TransCancelButton_clicked, + 'on_ChooseButton_clicked' : transaction.on_ChooseButton_clicked, + 'on_progress_textview_size_allocate' : transaction.on_progress_textview_size_allocate, + 'on_choose_renderertoggle_toggled' : transaction.on_choose_renderertoggle_toggled, + 'on_ProgressCancelButton_clicked' : on_ProgressCancelButton_clicked, + 'on_ProgressCloseButton_clicked' : on_ProgressCloseButton_clicked} if common.pid_file_exists(): - from pamac.main import ErrorDialog - ErrorDialog.format_secondary_text(_('Pamac is already running')) - response = ErrorDialog.run() + transaction.ErrorDialog.format_secondary_text(_('Pamac is already running')) + response = transaction.ErrorDialog.run() if response: - ErrorDialog.hide() + transaction.ErrorDialog.hide() else: - from pamac import transaction, main - transaction.get_handle() - transaction.update_db() - do_syncfirst, updates = transaction.get_updates() + trans = transaction.Transaction() + do_syncfirst, updates = trans.get_updates() if updates: - main.ErrorDialog.format_secondary_text(_('Some updates are available.\nPlease update your system first')) - response = main.ErrorDialog.run() + transaction.ErrorDialog.format_secondary_text(_('Some updates are available.\nPlease update your system first')) + response = transaction.ErrorDialog.run() if response: - main.ErrorDialog.hide() - transaction.StopDaemon() + transaction.ErrorDialog.hide() else: - loop = GObject.MainLoop() - main.config_signals() - bus = dbus.SystemBus() - bus.add_signal_receiver(exiting, dbus_interface = "org.manjaro.pamac", signal_name = "EmitTransactionDone") - bus.add_signal_receiver(exiting, dbus_interface = "org.manjaro.pamac", signal_name = "EmitTransactionError") - main.Handler.on_TransCancelButton_clicked = new_on_TransCancelButton_clicked - main.Handler.on_TransValidButton_clicked = new_on_TransValidButton_clicked - main.interface.connect_signals(main.Handler()) - pkgs_to_install = argv[1:] - install(pkgs_to_install) + transaction.interface.connect_signals(signals) + args_str = argv[1:] + if get_pkgs(args_str): + if trans.to_add or trans.to_load: + if trans.init(cascade = True): + for pkg in trans.to_add: + trans.add(pkg) + for path in trans.to_load: + trans.load(path) + if trans.prepare(): + common.write_pid_file() + trans.set_transaction_sum(True) + transaction.ConfDialog.show() + Gtk.main() + diff --git a/pamac-manager.py b/pamac-manager.py old mode 100755 new mode 100644 index 2dba882..4645259 --- a/pamac-manager.py +++ b/pamac-manager.py @@ -1,6 +1,718 @@ -#! /usr/bin/python3 +#! /usr/bin/pkexec /usr/bin/python3 # -*- coding:utf-8 -*- -from pamac import main +version = '0.8.0' -main.main('manager') +from gi.repository import Gtk, Gdk +from gi.repository.GdkPixbuf import Pixbuf +import pyalpm +from time import strftime, localtime + +from pamac import config, common, transaction + +# i18n +import gettext +import locale +locale.bindtextdomain('pamac', '/usr/share/locale') +gettext.bindtextdomain('pamac', '/usr/share/locale') +gettext.textdomain('pamac') +_ = gettext.gettext + +interface = transaction.interface + +interface.add_from_file('/usr/share/pamac/gui/manager.ui') +ManagerWindow = interface.get_object("ManagerWindow") +details_list = interface.get_object('details_list') +deps_list = interface.get_object('deps_list') +files_list = interface.get_object('files_list') +files_scrolledwindow = interface.get_object('files_scrolledwindow') +name_label = interface.get_object('name_label') +desc_label = interface.get_object('desc_label') +link_label = interface.get_object('link_label') +licenses_label = interface.get_object('licenses_label') +search_entry = interface.get_object('search_entry') +search_list = interface.get_object('search_list') +search_selection = interface.get_object('search_treeview_selection') +packages_list_treeview = interface.get_object('packages_list_treeview') +state_column = interface.get_object('state_column') +name_column = interface.get_object('name_column') +version_column = interface.get_object('version_column') +size_column = interface.get_object('size_column') +state_rendererpixbuf = interface.get_object('state_rendererpixbuf') +name_renderertext = interface.get_object('name_renderertext') +version_renderertext = interface.get_object('version_renderertext') +size_renderertext = interface.get_object('size_renderertext') +list_selection = interface.get_object('list_treeview_selection') +groups_list = interface.get_object('groups_list') +groups_selection = interface.get_object('groups_treeview_selection') +states_list = interface.get_object('states_list') +states_selection = interface.get_object('states_treeview_selection') +repos_list = interface.get_object('repos_list') +repos_selection = interface.get_object('repos_treeview_selection') +AboutDialog = interface.get_object('AboutDialog') +menu_button = interface.get_object('menu_button') +main_menu = interface.get_object('main_menu') +PackagesChooserDialog = interface.get_object('PackagesChooserDialog') + +AboutDialog.set_version(version) +menu_button.set_popup(main_menu) + +search_dict = {} +groups_dict = {} +states_dict = {} +repos_dict = {} +current_filter = (None, None) +right_click_menu = Gtk.Menu() + +installed_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-installed-updated.png') +uninstalled_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-available.png') +to_install_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-install.png') +to_reinstall_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-reinstall.png') +to_remove_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-remove.png') +locked_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-installed-locked.png') + +def state_column_display_func(column, cell, treemodel, treeiter, data): + if treemodel[treeiter][0] == _('No package found'): + pixbuf = None + elif treemodel[treeiter][0].name in config.holdpkg: + pixbuf = locked_icon + elif treemodel[treeiter][0].db.name == 'local': + if transaction.pkg_in_list(treemodel[treeiter][0], trans.to_add): + pixbuf = to_reinstall_icon + elif transaction.pkg_in_list(treemodel[treeiter][0], trans.to_remove): + pixbuf = to_remove_icon + else: + pixbuf = installed_icon + elif transaction.pkg_in_list(treemodel[treeiter][0], trans.to_add): + pixbuf = to_install_icon + else: + pixbuf = uninstalled_icon + cell.set_property("pixbuf", pixbuf) + +def state_column_sort_func(treemodel, treeiter1, treeiter2, data): + if treemodel[treeiter1][0].db.name == 'local': + num1 = 1 + else: + num1 = 0 + if treemodel[treeiter2][0].db.name == 'local': + num2 = 1 + else: + num2 = 0 + return num2 - num1 + +def name_column_display_func(column, cell, treemodel, treeiter, data): + if treemodel[treeiter][0] == _('No package found'): + cell.set_property("text", _('No package found')) + else: + cell.set_property("text", treemodel[treeiter][0].name) + +def name_column_sort_func(treemodel, treeiter1, treeiter2, data): + str1 = treemodel[treeiter1][0].name + str2 = treemodel[treeiter2][0].name + if str1 < str2: + return -1 + elif str1 > str2: + return 1 + else: + return 0 + +def version_column_display_func(column, cell, treemodel, treeiter, data): + if treemodel[treeiter][0] == _('No package found'): + cell.set_property("text", '') + else: + cell.set_property("text", treemodel[treeiter][0].version) + +def version_column_sort_func(treemodel, treeiter1, treeiter2, data): + return pyalpm.vercmp(treemodel[treeiter1][0].version, treemodel[treeiter2][0].version) + +def size_column_display_func(column, cell, treemodel, treeiter, data): + if treemodel[treeiter][0] == _('No package found'): + cell.set_property("text", '') + else: + cell.set_property("text", common.format_size(treemodel[treeiter][0].isize)) + +def size_column_sort_func(treemodel, treeiter1, treeiter2, data): + num1 = treemodel[treeiter1][0].isize + num2 = treemodel[treeiter2][0].isize + return num1 - num2 + +state_column.set_cell_data_func(state_rendererpixbuf, state_column_display_func) +name_column.set_cell_data_func(name_renderertext, name_column_display_func) +version_column.set_cell_data_func(version_renderertext, version_column_display_func) +size_column.set_cell_data_func(size_renderertext, size_column_display_func) + +def update_lists(): + for db in trans.handle.get_syncdbs(): + for name, pkgs in db.grpcache: + groups_list.append([name]) + groups_list.set_sort_column_id(0, Gtk.SortType.ASCENDING) + states = [_('Installed'), _('Uninstalled'), _('Orphans'), _('To install'), _('To remove')] + for state in states: + states_list.append([state]) + for db in trans.syncdbs: + repos_list.append([db.name]) + repos_list.append([_('local')]) + +def get_group_list(group): + global groups_dict + if group in groups_dict.keys(): + return groups_dict[group] + else: + groups_dict[group] = Gtk.ListStore(object) + dbs_list = [trans.localdb] + dbs_list.extend(trans.syncdbs.copy()) + pkgs = pyalpm.find_grp_pkgs(dbs_list, group) + for pkg in pkgs: + groups_dict[group].append([pkg]) + return groups_dict[group] + +def get_state_list(state): + global states_dict + if state == _('To install'): + liststore = Gtk.ListStore(object) + for pkg in trans.to_add: + liststore.append([pkg]) + return liststore + elif state == _('To remove'): + liststore = Gtk.ListStore(object) + for pkg in trans.to_remove: + liststore.append([pkg]) + return liststore + elif state in states_dict.keys(): + return states_dict[state] + else: + states_dict[state] = Gtk.ListStore(object) + if state == _('Installed'): + for pkg in trans.localdb.pkgcache: + states_dict[state].append([pkg]) + elif state == _('Uninstalled'): + for pkg in get_uninstalled_pkgs(): + states_dict[state].append([pkg]) + elif state == _('Orphans'): + for pkg in get_orphan_pkgs(): + states_dict[state].append([pkg]) + return states_dict[state] + + +def get_repo_list(repo): + global repos_dict + if repo in repos_dict.keys(): + return repos_dict[repo] + else: + repos_dict[repo] = Gtk.ListStore(object) + if repo == _('local'): + for pkg in trans.localdb.pkgcache: + if not trans.get_syncpkg(pkg.name): + repos_dict[repo].append([pkg]) + else: + for db in trans.syncdbs: + if db.name ==repo: + for pkg in db.pkgcache: + local_pkg = trans.get_localpkg(pkg.name) + if local_pkg: + repos_dict[repo].append([local_pkg]) + else: + repos_dict[repo].append([pkg]) + return repos_dict[repo] + +def search_pkgs(search_string): + global search_dict + if search_string in search_dict.keys(): + return search_dict[search_string] + else: + search_dict[search_string] = Gtk.ListStore(object) + names_list = [] + for pkg in trans.localdb.search(*search_string.split()): + if not pkg.name in names_list: + names_list.append(pkg.name) + search_dict[search_string].append([pkg]) + for db in trans.syncdbs: + for pkg in db.search(*search_string.split()): + if not pkg.name in names_list: + names_list.append(pkg.name) + search_dict[search_string].append([pkg]) + if not names_list: + search_dict[search_string].append([_('No package found')]) + else: + if not search_string in [row[0] for row in search_list]: + search_list.append([search_string]) + return search_dict[search_string] + +def get_uninstalled_pkgs(): + pkgs_list = [] + names_list = [] + for repo in trans.syncdbs: + for pkg in repo.pkgcache: + if not pkg.name in names_list: + names_list.append(pkg.name) + if not trans.get_localpkg(pkg.name): + pkgs_list.append(pkg) + return pkgs_list + +def get_orphan_pkgs(): + pkgs_list = [] + for pkg in trans.localdb.pkgcache: + if pkg.reason == pyalpm.PKG_REASON_DEPEND: + if not pkg.compute_requiredby(): + pkgs_list.append(pkg) + return pkgs_list + +def refresh_packages_list(liststore): + #~ packages_list_treeview.freeze_child_notify() + #~ packages_list_treeview.set_model(None) + liststore.set_sort_func(0, name_column_sort_func, None) + liststore.set_sort_column_id(0, Gtk.SortType.ASCENDING) + packages_list_treeview.set_model(liststore) + state_column.set_sort_indicator(False) + name_column.set_sort_indicator(True) + version_column.set_sort_indicator(False) + size_column.set_sort_indicator(False) + #~ packages_list_treeview.thaw_child_notify() + ManagerWindow.get_window().set_cursor(None) + +def set_infos_list(pkg): + name_label.set_markup('{} {}'.format(pkg.name, pkg.version)) + # fix &,-,>,< in desc + desc = pkg.desc.replace('&', '&') + desc = desc.replace('<->', '/') + desc_label.set_markup(desc) + # fix & in url + url = pkg.url.replace('&', '&') + link_label.set_markup('{_url}'.format(_url = url)) + licenses_label.set_markup(_('Licenses')+': {}'.format(' '.join(pkg.licenses))) + +def set_deps_list(pkg, style): + deps_list.clear() + if pkg.depends: + deps_list.append([_('Depends On')+':', '\n'.join(pkg.depends)]) + if pkg.optdepends: + optdeps = [] + for optdep in pkg.optdepends: + if trans.get_localpkg(optdep.split(':')[0]): + optdeps.append(optdep+' ['+_('Installed')+']') + else: + optdeps.append(optdep) + deps_list.append([_('Optional Deps')+':', '\n'.join(optdeps)]) + if style == 'local': + if pkg.compute_requiredby(): + deps_list.append([_('Required By')+':', '\n'.join(pkg.compute_requiredby())]) + if pkg.provides: + deps_list.append([_('Provides')+':', '\n'.join(pkg.provides)]) + if pkg.replaces: + deps_list.append([_('Replaces')+':', '\n'.join(pkg.replaces)]) + if pkg.conflicts: + deps_list.append([_('Conflicts With')+':', '\n'.join(pkg.conflicts)]) + +def set_details_list(pkg, style): + details_list.clear() + if style == 'sync': + details_list.append([_('Repository')+':', pkg.db.name]) + if pkg.groups: + details_list.append([_('Groups')+':', ' '.join(pkg.groups)]) + if style == 'sync': + details_list.append([_('Compressed Size')+':', common.format_size(pkg.size)]) + details_list.append([_('Download Size')+':', common.format_size(pkg.download_size)]) + if style == 'local': + details_list.append([_('Installed Size')+':', common.format_size(pkg.isize)]) + details_list.append([_('Packager')+':', pkg.packager]) + details_list.append([_('Architecture')+':', pkg.arch]) + #details_list.append([_('Build Date')+':', strftime("%a %d %b %Y %X %Z", localtime(pkg.builddate))]) + if style == 'local': + details_list.append([_('Install Date')+':', strftime("%a %d %b %Y %X %Z", localtime(pkg.installdate))]) + if pkg.reason == pyalpm.PKG_REASON_EXPLICIT: + reason = _('Explicitly installed') + elif pkg.reason == pyalpm.PKG_REASON_DEPEND: + reason = _('Installed as a dependency for another package') + else: + reason = _('Unknown') + details_list.append([_('Install Reason')+':', reason]) + if style == 'sync': + #details_list.append([_('Install Script')':', 'Yes' if pkg.has_scriptlet else 'No']) + #details_list.append(['MD5 Sum:', pkg.md5sum]) + #details_list.append(['SHA256 Sum:', pkg.sha256sum]) + details_list.append([_('Signatures')+':', 'Yes' if pkg.base64_sig else 'No']) + if style == 'local': + if len(pkg.backup) != 0: + #details_list.append(['_(Backup files)+':', '\n'.join(["%s %s" % (md5, file) for (file, md5) in pkg.backup])]) + details_list.append([_('Backup files')+':', '\n'.join(["%s" % (file) for (file, md5) in pkg.backup])]) + +def set_files_list(pkg): + files_list.clear() + if len(pkg.files) != 0: + for file in pkg.files: + files_list.append(['/'+file[0]]) + +def on_ManagerWindow_delete_event(*args): + Gtk.main_quit() + common.rm_pid_file() + +def on_TransValidButton_clicked(*args): + global search_dict + global groups_dict + global states_dict + global repos_dict + transaction.ConfDialog.hide() + trans.finalize() + trans.update_dbs() + search_dict = {} + groups_dict = {} + states_dict = {} + repos_dict = {} + if current_filter[0]: + refresh_packages_list(current_filter[0](current_filter[1])) + +def on_TransCancelButton_clicked(*args): + transaction.progress_buffer.delete(transaction.progress_buffer.get_start_iter(),transaction.progress_buffer.get_end_iter()) + transaction.ConfDialog.hide() + trans.release() + if current_filter[0]: + refresh_packages_list(current_filter[0](current_filter[1])) + +def on_ProgressCloseButton_clicked(*args): + transaction.ProgressWindow.hide() + transaction.progress_buffer.delete(transaction.progress_buffer.get_start_iter(),transaction.progress_buffer.get_end_iter()) + trans.do_sysupgrade(True) + +def on_ProgressCancelButton_clicked(*args): + trans.interrupt() + +def on_search_entry_icon_press(*args): + on_search_entry_activate(None) + +def on_search_entry_activate(widget): + global current_filter + current_filter = (search_pkgs, search_entry.get_text()) + refresh_packages_list(search_pkgs(search_entry.get_text())) + +def mark_to_install(widget, pkg): + trans.to_add.append(pkg) + +def mark_to_reinstall(widget, pkg): + trans.to_add.append(pkg) + +def mark_to_remove(widget, pkg): + trans.to_remove.append(pkg) + +def mark_to_unselect(widget, pkg): + if pkg.db.name == 'local': + if trans.pkg_in_list(pkg, trans.to_add): + transaction.remove_pkg_from_list(pkg, trans.to_add) + elif transaction.pkg_in_list(pkg, trans.to_remove): + transaction.remove_pkg_from_list(pkg, trans.to_remove) + else: + if transaction.pkg_in_list(pkg, trans.to_add): + transaction.remove_pkg_from_list(pkg, trans.to_add) + +def select_optdeps(widget, pkg, optdeps): + transaction.choose_only_one = False + transaction.choose_label.set_markup(_('{pkgname} has {number} uninstalled optional deps.\nPlease choose the one(s) you want to install:').format(pkgname = pkg.name, number = str(len(optdeps)))) + transaction.choose_list.clear() + transaction.choose_renderertoggle.set_radio(False) + for long_string in optdeps: + transaction.choose_list.append([False, long_string]) + transaction.ChooseDialog.run() + for long_string in trans.to_provide: + trans.to_add.append(trans.get_syncpkg(long_string.split(':')[0])) + +def install_with_optdeps(widget, pkg, optdeps): + select_optdeps(widget, pkg, optdeps) + trans.to_add.append(pkg) + +def on_list_treeview_button_press_event(treeview, event): + global right_click_menu + liststore = packages_list_treeview.get_model() + # Check if right mouse button was clicked + if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3: + ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) + while Gtk.events_pending(): + Gtk.main_iteration() + treepath, viewcolumn, x, y = treeview.get_path_at_pos(int(event.x), int(event.y)) + treeiter = liststore.get_iter(treepath) + if treeiter: + if liststore[treeiter][0] != _('No package found') and not liststore[treeiter][0].name in config.holdpkg: + right_click_menu = Gtk.Menu() + if transaction.pkg_in_list(liststore[treeiter][0], trans.to_remove) or transaction.pkg_in_list(liststore[treeiter][0], trans.to_add): + item = Gtk.ImageMenuItem(_('Unselect')) + item.set_image(Gtk.Image.new_from_stock('gtk-undo', Gtk.IconSize.MENU)) + item.set_always_show_image(True) + item.connect('activate', mark_to_unselect, liststore[treeiter][0]) + right_click_menu.append(item) + elif liststore[treeiter][0].db.name == 'local': + item = Gtk.ImageMenuItem(_('Remove')) + item.set_image(Gtk.Image.new_from_pixbuf(to_remove_icon)) + item.set_always_show_image(True) + item.connect('activate', mark_to_remove, liststore[treeiter][0]) + right_click_menu.append(item) + item = Gtk.ImageMenuItem(_('Reinstall')) + item.set_image(Gtk.Image.new_from_pixbuf(to_reinstall_icon)) + item.set_always_show_image(True) + item.connect('activate', mark_to_reinstall, liststore[treeiter][0]) + right_click_menu.append(item) + optdeps_strings = liststore[treeiter][0].optdepends + if optdeps_strings: + available_optdeps = [] + for optdep_string in optdeps_strings: + optdep = optdep_string.split(':')[0] + if not trans.get_localpkg(optdep): + available_optdeps.append(optdep_string) + if available_optdeps: + item = Gtk.ImageMenuItem(_('Install optional deps')) + item.set_image(Gtk.Image.new_from_pixbuf(to_install_icon)) + item.set_always_show_image(True) + item.connect('activate', select_optdeps, liststore[treeiter][0], available_optdeps) + right_click_menu.append(item) + else: + item = Gtk.ImageMenuItem(_('Install')) + item.set_image(Gtk.Image.new_from_pixbuf(to_install_icon)) + item.set_always_show_image(True) + item.connect('activate', mark_to_install, liststore[treeiter][0]) + right_click_menu.append(item) + optdeps_strings = liststore[treeiter][0].optdepends + if optdeps_strings: + available_optdeps = [] + for optdep_string in optdeps_strings: + optdep = optdep_string.split(':')[0] + if not trans.get_localpkg(optdep): + available_optdeps.append(optdep_string) + if available_optdeps: + item = Gtk.ImageMenuItem(_('Install with optional deps')) + item.set_image(Gtk.Image.new_from_pixbuf(to_install_icon)) + item.set_always_show_image(True) + item.connect('activate', install_with_optdeps, liststore[treeiter][0], available_optdeps) + right_click_menu.append(item) + treeview.grab_focus() + treeview.set_cursor(treepath, viewcolumn, 0) + ManagerWindow.get_window().set_cursor(None) + right_click_menu.show_all() + right_click_menu.popup(None, None, None, None, event.button, event.time) + return True + +def on_list_treeview_selection_changed(treeview): + liststore, treeiter = list_selection.get_selected() + if treeiter: + if liststore[treeiter][0] != _('No package found'): + set_infos_list(liststore[treeiter][0]) + if liststore[treeiter][0].db.name == 'local': + set_deps_list(liststore[treeiter][0], "local") + set_details_list(liststore[treeiter][0], "local") + set_files_list(liststore[treeiter][0]) + files_scrolledwindow.set_visible(True) + else: + set_deps_list(liststore[treeiter][0], "sync") + set_details_list(liststore[treeiter][0], "sync") + files_scrolledwindow.set_visible(False) + +def on_search_treeview_selection_changed(widget): + global current_filter + while Gtk.events_pending(): + Gtk.main_iteration() + liste, line = search_selection.get_selected() + if line: + ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) + while Gtk.events_pending(): + Gtk.main_iteration() + current_filter = (search_pkgs, search_list[line][0]) + refresh_packages_list(search_pkgs(search_list[line][0])) + +def on_groups_treeview_selection_changed(widget): + global current_filter + while Gtk.events_pending(): + Gtk.main_iteration() + liste, line = groups_selection.get_selected() + if line: + ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) + while Gtk.events_pending(): + Gtk.main_iteration() + current_filter = (get_group_list, groups_list[line][0]) + refresh_packages_list(get_group_list(groups_list[line][0])) + +def on_states_treeview_selection_changed(widget): + global current_filter + while Gtk.events_pending(): + Gtk.main_iteration() + liste, line = states_selection.get_selected() + if line: + ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) + while Gtk.events_pending(): + Gtk.main_iteration() + current_filter = (get_state_list, states_list[line][0]) + refresh_packages_list(get_state_list(states_list[line][0])) + +def on_repos_treeview_selection_changed(widget): + global current_filter + while Gtk.events_pending(): + Gtk.main_iteration() + liste, line = repos_selection.get_selected() + if line: + ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) + while Gtk.events_pending(): + Gtk.main_iteration() + current_filter = (get_repo_list, repos_list[line][0]) + refresh_packages_list(get_repo_list(repos_list[line][0])) + +def on_list_treeview_row_activated(treeview, treeiter, column): + liststore = treeview.get_model() + if not liststore[treeiter][0] == _('No package found'): + if not liststore[treeiter][0].name in config.holdpkg: + if liststore[treeiter][0].db.name == 'local': + if transaction.pkg_in_list(liststore[treeiter][0], trans.to_add): + transaction.remove_pkg_from_list(liststore[treeiter][0], trans.to_add) + elif transaction.pkg_in_list(liststore[treeiter][0], trans.to_remove): + transaction.remove_pkg_from_list(liststore[treeiter][0], trans.to_remove) + else: + trans.to_remove.append(liststore[treeiter][0]) + else: + if transaction.pkg_in_list(liststore[treeiter][0], trans.to_add): + transaction.remove_pkg_from_list(liststore[treeiter][0], trans.to_add) + else: + trans.to_add.append(liststore[treeiter][0]) + while Gtk.events_pending(): + Gtk.main_iteration() + +def on_notebook1_switch_page(notebook, page, page_num): + ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) + while Gtk.events_pending(): + Gtk.main_iteration() + if page_num == 0: + liste, line = search_selection.get_selected() + if line: + on_search_treeview_selection_changed(None) + elif search_entry.get_text(): + on_search_entry_activate(None) + elif page_num == 1: + on_groups_treeview_selection_changed(None) + elif page_num == 2: + on_states_treeview_selection_changed(None) + elif page_num == 3: + on_repos_treeview_selection_changed(None) + +def on_manager_valid_button_clicked(*args): + trans.run() + +def on_manager_cancel_button_clicked(*args): + trans.to_add.clear() + trans.to_remove.clear() + if current_filter[0]: + refresh_packages_list(current_filter[0](current_filter[1])) + +def on_refresh_item_activate(*args): + global search_dict + global groups_dict + global states_dict + global repos_dict + trans.refresh(False) + transaction.ProgressWindow.hide() + search_dict = {} + groups_dict = {} + states_dict = {} + repos_dict = {} + if current_filter[0]: + refresh_packages_list(current_filter[0](current_filter[1])) + trans.do_sysupgrade(True) + +def on_local_item_activate(*args): + response = PackagesChooserDialog.run() + if response: + PackagesChooserDialog.hide() + +def on_about_item_activate(*args): + response = AboutDialog.run() + if response: + AboutDialog.hide() + +def on_package_open_button_clicked(*args): + packages_paths = PackagesChooserDialog.get_filenames() + print(packages_paths) + if packages_paths: + PackagesChooserDialog.hide() + for path in packages_paths: + trans.to_load.append(path) + trans.run() + +def on_PackagesChooserDialog_file_activated(*args): + on_package_open_button_clicked(*args) + +def on_package_cancel_button_clicked(*args): + PackagesChooserDialog.hide() + +def on_state_column_clicked(column): + liststore = packages_list_treeview.get_model() + state_column.set_sort_indicator(True) + name_column.set_sort_indicator(False) + version_column.set_sort_indicator(False) + size_column.set_sort_indicator(False) + liststore.set_sort_func(0, state_column_sort_func, None) + +def on_name_column_clicked(column): + liststore = packages_list_treeview.get_model() + state_column.set_sort_indicator(False) + name_column.set_sort_indicator(True) + version_column.set_sort_indicator(False) + size_column.set_sort_indicator(False) + liststore.set_sort_func(0, name_column_sort_func, None) + +def on_version_column_clicked(column): + liststore = packages_list_treeview.get_model() + state_column.set_sort_indicator(False) + name_column.set_sort_indicator(False) + version_column.set_sort_indicator(True) + size_column.set_sort_indicator(False) + liststore.set_sort_func(0, version_column_sort_func, None) + +def on_size_column_clicked(column): + liststore = packages_list_treeview.get_model() + state_column.set_sort_indicator(False) + name_column.set_sort_indicator(False) + version_column.set_sort_indicator(False) + size_column.set_sort_indicator(True) + liststore.set_sort_func(0, size_column_sort_func, None) + +signals = {'on_ManagerWindow_delete_event' : on_ManagerWindow_delete_event, + 'on_TransValidButton_clicked' : on_TransValidButton_clicked, + 'on_TransCancelButton_clicked' : on_TransCancelButton_clicked, + 'on_ChooseButton_clicked' : transaction.on_ChooseButton_clicked, + 'on_progress_textview_size_allocate' : transaction.on_progress_textview_size_allocate, + 'on_choose_renderertoggle_toggled' : transaction.on_choose_renderertoggle_toggled, + 'on_ProgressCancelButton_clicked' : on_ProgressCancelButton_clicked, + 'on_ProgressCloseButton_clicked' : on_ProgressCloseButton_clicked, + 'on_search_entry_icon_press' : on_search_entry_icon_press, + 'on_search_entry_activate' : on_search_entry_activate, + 'on_list_treeview_button_press_event' : on_list_treeview_button_press_event, + 'on_list_treeview_selection_changed' : on_list_treeview_selection_changed, + 'on_search_treeview_selection_changed' : on_search_treeview_selection_changed, + 'on_groups_treeview_selection_changed' : on_groups_treeview_selection_changed, + 'on_states_treeview_selection_changed' : on_states_treeview_selection_changed, + 'on_repos_treeview_selection_changed' : on_repos_treeview_selection_changed, + 'on_list_treeview_row_activated' : on_list_treeview_row_activated, + 'on_notebook1_switch_page' : on_notebook1_switch_page, + 'on_manager_valid_button_clicked' : on_manager_valid_button_clicked, + 'on_manager_cancel_button_clicked' : on_manager_cancel_button_clicked, + 'on_refresh_item_activate' : on_refresh_item_activate, + 'on_local_item_activate' : on_local_item_activate, + 'on_about_item_activate' : on_about_item_activate, + 'on_package_open_button_clicked' : on_package_open_button_clicked, + 'on_package_cancel_button_clicked' : on_package_cancel_button_clicked, + 'on_PackagesChooserDialog_file_activated' : on_PackagesChooserDialog_file_activated, + 'on_state_column_clicked' : on_state_column_clicked, + 'on_name_column_clicked' : on_name_column_clicked, + 'on_version_column_clicked' : on_version_column_clicked, + 'on_size_column_clicked' : on_size_column_clicked} + +if common.pid_file_exists(): + transaction.ErrorDialog.format_secondary_text(_('Pamac is already running')) + response = transaction.ErrorDialog.run() + if response: + transaction.ErrorDialog.hide() +else: + common.write_pid_file() + interface.connect_signals(signals) + ManagerWindow.show_all() + trans = transaction.Transaction() + ManagerWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) + while Gtk.events_pending(): + Gtk.main_iteration() + trans.refresh(False) + update_lists() + trans.do_sysupgrade(True) + ManagerWindow.get_window().set_cursor(None) + Gtk.main() diff --git a/pamac-refresh.py b/pamac-refresh.py old mode 100755 new mode 100644 index 3ab8306..9061d62 --- a/pamac-refresh.py +++ b/pamac-refresh.py @@ -1,31 +1,22 @@ -#! /usr/bin/python3 +#! /usr/bin/pkexec /usr/bin/python3 # -*- coding:utf-8 -*- -from gi.repository import GObject -from pamac import common -import dbus - -def reply(reply): - transaction.StopDaemon() - print('check updates done') - loop.quit() - -def error(error): - transaction.StopDaemon() - print('check updates failed') - loop.quit() - -loop = GObject.MainLoop() +from pamac import common, config if not common.pid_file_exists(): - print('checking updates') - from pamac import transaction - bus = dbus.SystemBus() - bus.add_signal_receiver(reply, dbus_interface = "org.manjaro.pamac", signal_name = "EmitTransactionDone") - bus.add_signal_receiver(error, dbus_interface = "org.manjaro.pamac", signal_name = "EmitTransactionError") - try: - transaction.Refresh() - except: - pass - else: - loop.run() + print('refreshing') + handle = config.handle() + for db in handle.get_syncdbs(): + try: + t = handle.init_transaction() + db.update(force = False) + t.release() + except: + try: + t.release() + except: + pass + print('refreshing {} failed'.format(db.name)) + break + else: + print('refreshing {} succeeded'.format(db.name)) diff --git a/pamac-tray.py b/pamac-tray.py old mode 100755 new mode 100644 index 68bc0b7..a535ffd --- a/pamac-tray.py +++ b/pamac-tray.py @@ -2,11 +2,12 @@ # -*- coding:utf-8 -*- from gi.repository import Gtk, GObject -from subprocess import Popen -import dbus -import threading -from pamac import common +from subprocess import call from time import sleep +import threading +from pamac import common, transaction + +GObject.threads_init() # i18n import gettext @@ -14,8 +15,6 @@ gettext.bindtextdomain('pamac', '/usr/share/locale') gettext.textdomain('pamac') _ = gettext.gettext -GObject.threads_init() - update_icon = '/usr/share/pamac/icons/24x24/status/pamac-update.png' update_info = _('{number} available updates') one_update_info = _('1 available update') @@ -27,6 +26,7 @@ info = noupdate_info class Tray: def __init__(self): self.statusIcon = Gtk.StatusIcon() + self.statusIcon.set_visible(True) self.menu = Gtk.Menu() self.menuItem = Gtk.ImageMenuItem(_('Update Manager')) @@ -46,13 +46,14 @@ class Tray: self.statusIcon.connect('activate', self.activate_cb) def execute_update(self, widget, event, data = None): - Popen(['/usr/bin/pamac-updater']) + call(['/usr/bin/pamac-updater']) def execute_manager(self, widget, event, data = None): - Popen(['/usr/bin/pamac-manager']) + call(['/usr/bin/pamac-manager']) def quit_tray(self, widget, data = None): - t.shutdown() + t1.shutdown() + t2.shutdown() Gtk.main_quit() def popup_menu_cb(self, widget, button, time, data = None): @@ -63,16 +64,16 @@ class Tray: def activate_cb(self, widget, data = None): if icon == update_icon: - Popen(['/usr/bin/pamac-updater']) + call(['/usr/bin/pamac-updater']) def update_icon(self, icon, info): - self.statusIcon.set_from_file(icon) - self.statusIcon.set_tooltip_markup(info) + GObject.idle_add(self.statusIcon.set_from_file, icon) + GObject.idle_add(self.statusIcon.set_tooltip_markup, info) def set_visible(self, boolean): self.statusIcon.set_visible(boolean) -class PeriodicTask(threading.Thread): +class PeriodicRefresh(threading.Thread): """Thread that executes a task every N seconds""" def __init__(self): threading.Thread.__init__(self) @@ -88,15 +89,41 @@ class PeriodicTask(threading.Thread): self._finished.set() def run(self): - while 1: + while True: if self._finished.isSet(): return - self.task() - # sleep for interval or until shutdown + call(['/usr/bin/pamac-refresh']) self._finished.wait(self._interval) - def task(self): - Popen(['/usr/bin/pamac-refresh']) +class PeriodicCheck(threading.Thread): + """Thread that executes a task every N seconds""" + def __init__(self): + threading.Thread.__init__(self) + self._finished = threading.Event() + self._interval = 1 + self.trans = transaction.Transaction() + + def setInterval(self, interval): + """Set the number of seconds we sleep between executing our task""" + self._interval = interval + + def shutdown(self): + """Stop this thread""" + self._finished.set() + + def run(self): + pid_file = True + while True: + if self._finished.isSet(): + return + if common.pid_file_exists(): + pid_file = True + elif pid_file: + self.trans.update_dbs() + set_icon(len(self.trans.get_updates()[1])) + pid_file = False + else: + self._finished.wait(self._interval) def set_icon(updates): global icon @@ -107,23 +134,18 @@ def set_icon(updates): info = one_update_info else: info = update_info.format(number = updates) - tray.set_visible(True) - sleep(2) if not common.pid_file_exists(): - Popen(['notify-send', '-i', '/usr/share/pamac/icons/32x32/apps/pamac-updater.png', '-u', 'normal', _('Update Manager'), info]) + call(['notify-send', '-i', '/usr/share/pamac/icons/32x32/apps/pamac-updater.png', '-u', 'normal', _('Update Manager'), info]) else: icon = noupdate_icon info = noupdate_info - tray.set_visible(True) print(info) tray.update_icon(icon, info) - -from pamac import transaction -bus = dbus.SystemBus() -bus.add_signal_receiver(set_icon, dbus_interface = "org.manjaro.pamac", signal_name = "EmitAvailableUpdates") -transaction.StopDaemon() + return False tray = Tray() -t = PeriodicTask() -t.start() +t1 = PeriodicRefresh() +t1.start() +t2 = PeriodicCheck() +t2.start() Gtk.main() diff --git a/pamac-updater.py b/pamac-updater.py old mode 100755 new mode 100644 index f06b872..331bef4 --- a/pamac-updater.py +++ b/pamac-updater.py @@ -1,6 +1,112 @@ -#! /usr/bin/python3 +#! /usr/bin/pkexec /usr/bin/python3 # -*- coding:utf-8 -*- -from pamac import main +from gi.repository import Gtk, Gdk +import pyalpm -main.main('updater') +from pamac import config, common, transaction + +# i18n +import gettext +import locale +locale.bindtextdomain('pamac', '/usr/share/locale') +gettext.bindtextdomain('pamac', '/usr/share/locale') +gettext.textdomain('pamac') +_ = gettext.gettext + +interface = transaction.interface + +interface.add_from_file('/usr/share/pamac/gui/updater.ui') +UpdaterWindow = interface.get_object("UpdaterWindow") +update_listore = interface.get_object('update_list') +update_top_label = interface.get_object('update_top_label') +update_bottom_label = interface.get_object('update_bottom_label') + +update_top_label.set_markup(_('Your system is up-to-date')) +update_bottom_label.set_markup('') + +def have_updates(): + do_syncfirst, updates = trans.get_updates() + update_listore.clear() + update_top_label.set_justify(Gtk.Justification.CENTER) + if not updates: + update_bottom_label.set_markup('') + update_top_label.set_markup(_('Your system is up-to-date')) + else: + dsize = 0 + for pkg in updates: + pkgname = pkg.name+' '+pkg.version + update_listore.append([pkgname, common.format_size(pkg.size)]) + dsize += pkg.download_size + if dsize == 0: + update_bottom_label.set_markup('') + else: + update_bottom_label.set_markup(_('Total download size: ')+common.format_size(dsize)) + if len(updates) == 1: + update_top_label.set_markup(_('1 available update')) + else: + update_top_label.set_markup(_('{number} available updates').format(number = len(updates))) + +def on_TransValidButton_clicked(*arg): + transaction.ConfDialog.hide() + trans.finalize() + +def on_TransCancelButton_clicked(*arg): + transaction.progress_buffer.delete(transaction.progress_buffer.get_start_iter(),transaction.progress_buffer.get_end_iter()) + transaction.ConfDialog.hide() + trans.release() + +def on_ProgressCloseButton_clicked(*arg): + transaction.ProgressWindow.hide() + transaction.progress_buffer.delete(transaction.progress_buffer.get_start_iter(),transaction.progress_buffer.get_end_iter()) + have_updates() + +def on_ProgressCancelButton_clicked(*args): + trans.interrupt() + +def on_UpdaterWindow_delete_event(*arg): + Gtk.main_quit() + common.rm_pid_file() + +def on_Updater_ApplyButton_clicked(*arg): + UpdaterWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) + while Gtk.events_pending(): + Gtk.main_iteration() + trans.do_sysupgrade(False) + UpdaterWindow.get_window().set_cursor(None) + +def on_Updater_RefreshButton_clicked(*arg): + while Gtk.events_pending(): + Gtk.main_iteration() + UpdaterWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) + trans.refresh(False) + UpdaterWindow.get_window().set_cursor(None) + +signals = {'on_ChooseButton_clicked' : transaction.on_ChooseButton_clicked, + 'on_progress_textview_size_allocate' : transaction.on_progress_textview_size_allocate, + 'on_choose_renderertoggle_toggled' : transaction.on_choose_renderertoggle_toggled, + 'on_TransValidButton_clicked' :on_TransValidButton_clicked, + 'on_TransCancelButton_clicked' :on_TransCancelButton_clicked, + 'on_ProgressCloseButton_clicked' : on_ProgressCloseButton_clicked, + 'on_ProgressCancelButton_clicked' : on_ProgressCancelButton_clicked, + 'on_UpdaterWindow_delete_event' : on_UpdaterWindow_delete_event, + 'on_Updater_ApplyButton_clicked' : on_Updater_ApplyButton_clicked, + 'on_Updater_RefreshButton_clicked' : on_Updater_RefreshButton_clicked} + +if common.pid_file_exists(): + transaction.ErrorDialog.format_secondary_text(_('Pamac is already running')) + response = transaction.ErrorDialog.run() + if response: + transaction.ErrorDialog.hide() +else: + common.write_pid_file() + interface.connect_signals(signals) + UpdaterWindow.show_all() + trans = transaction.Transaction() + UpdaterWindow.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) + while Gtk.events_pending(): + Gtk.main_iteration() + trans.refresh(False) + have_updates() + UpdaterWindow.get_window().set_cursor(None) + Gtk.main() diff --git a/pamac.pot b/pamac.pot index 5adef06..0e58bd9 100644 --- a/pamac.pot +++ b/pamac.pot @@ -20,312 +20,206 @@ msgstr "" msgid "Authentication is required" msgstr "" -#: pamac-daemon.py:29 pamac/main.py:503 -msgid "Preparing" -msgstr "" - -#: pamac-daemon.py:68 -msgid "Checking dependencies" -msgstr "" - -#: pamac-daemon.py:75 -msgid "Checking file conflicts" -msgstr "" - -#: pamac-daemon.py:78 -msgid "Resolving dependencies" -msgstr "" - -#: pamac-daemon.py:85 -msgid "Checking inter conflicts" -msgstr "" - -#: pamac-daemon.py:88 pamac/main.py:51 -msgid "Installing" -msgstr "" - -#: pamac-daemon.py:95 pamac/main.py:51 -msgid "Removing" -msgstr "" - -#: pamac-daemon.py:102 pamac/main.py:51 -msgid "Upgrading" -msgstr "" - -#: pamac-daemon.py:109 pamac/main.py:51 -msgid "Downgrading" -msgstr "" - -#: pamac-daemon.py:117 pamac/main.py:51 -msgid "Reinstalling" -msgstr "" - -#: pamac-daemon.py:125 -msgid "Checking integrity" -msgstr "" - -#: pamac-daemon.py:129 -msgid "Loading packages files" -msgstr "" - -#: pamac-daemon.py:133 pamac/main.py:51 -msgid "Configuring" -msgstr "" - -#: pamac-daemon.py:140 -msgid "Checking keys in keyring" -msgstr "" - -#: pamac-daemon.py:198 -msgid "Downloading {size}" -msgstr "" - -#: pamac-daemon.py:203 pamac/main.py:437 pamac/main.py:1126 -msgid "Refreshing" -msgstr "" - -#: pamac-daemon.py:371 pamac-install.py:44 pamac/main.py:531 -msgid "{pkgname} is not a valid path or package name" -msgstr "" - -#: pamac-daemon.py:438 -msgid "Transaction successfully finished" -msgstr "" - -#: pamac-daemon.py:442 pamac-daemon.py:450 -msgid "Authentication failed" -msgstr "" - -#: pamac-tray.py:22 -msgid "{number} available updates" -msgstr "" - -#: pamac-tray.py:23 -msgid "1 available update" -msgstr "" - -#: pamac-tray.py:25 -msgid "Your system is up-to-date" -msgstr "" - -#: pamac-tray.py:113 gui/updater.glade:7 -msgid "Update Manager" -msgstr "" - -#: pamac-install.py:73 pamac-install.py:79 pamac/main.py:915 -msgid "Nothing to do" -msgstr "" - -#: pamac-install.py:87 pamac/main.py:1177 -msgid "Pamac is already running" -msgstr "" - -#: pamac-install.py:97 -msgid "" -"Some updates are available.\n" -"Please update your system first" -msgstr "" - -#: pamac/main.py:88 pamac/main.py:1083 -msgid "local" -msgstr "" - -#: pamac/main.py:178 pamac/main.py:973 pamac/main.py:1034 +#: pamac-manager.py:75 pamac-manager.py:104 pamac-manager.py:105 +#: pamac-manager.py:120 pamac-manager.py:129 pamac-manager.py:235 +#: pamac-manager.py:432 pamac-manager.py:493 pamac-manager.py:555 msgid "No package found" msgstr "" -#: pamac/main.py:229 -msgid "Licenses" -msgstr "" - -#: pamac/main.py:234 -msgid "Depends On" -msgstr "" - -#: pamac/main.py:239 pamac/main.py:1066 pamac/main.py:1251 +#: pamac-manager.py:149 pamac-manager.py:185 pamac-manager.py:292 msgid "Installed" msgstr "" -#: pamac/main.py:242 -msgid "Optional Deps" +#: pamac-manager.py:149 pamac-manager.py:188 +msgid "Uninstalled" msgstr "" -#: pamac/main.py:245 -msgid "Required By" +#: pamac-manager.py:149 pamac-manager.py:191 +msgid "Orphans" msgstr "" -#: pamac/main.py:247 -msgid "Provides" -msgstr "" - -#: pamac/main.py:249 -msgid "Replaces" -msgstr "" - -#: pamac/main.py:251 -msgid "Conflicts With" -msgstr "" - -#: pamac/main.py:256 -msgid "Repository" -msgstr "" - -#: pamac/main.py:258 gui/manager.glade:384 -msgid "Groups" -msgstr "" - -#: pamac/main.py:260 -msgid "Compressed Size" -msgstr "" - -#: pamac/main.py:261 -msgid "Download Size" -msgstr "" - -#: pamac/main.py:263 -msgid "Installed Size" -msgstr "" - -#: pamac/main.py:264 -msgid "Packager" -msgstr "" - -#: pamac/main.py:265 -msgid "Architecture" -msgstr "" - -#: pamac/main.py:268 -msgid "Install Date" -msgstr "" - -#: pamac/main.py:270 -msgid "Explicitly installed" -msgstr "" - -#: pamac/main.py:272 -msgid "Installed as a dependency for another package" -msgstr "" - -#: pamac/main.py:274 -msgid "Unknown" -msgstr "" - -#: pamac/main.py:275 -msgid "Install Reason" -msgstr "" - -#: pamac/main.py:280 -msgid "Signatures" -msgstr "" - -#: pamac/main.py:284 -msgid "Backup files" -msgstr "" - -#: pamac/main.py:324 -msgid "Transaction Summary" -msgstr "" - -#: pamac/main.py:326 pamac/main.py:1072 pamac/main.py:1251 +#: pamac-manager.py:149 pamac-manager.py:171 pamac/transaction.py:668 msgid "To install" msgstr "" -#: pamac/main.py:332 -msgid "To reinstall" -msgstr "" - -#: pamac/main.py:338 -msgid "To downgrade" -msgstr "" - -#: pamac/main.py:344 pamac/main.py:1074 pamac/main.py:1251 +#: pamac-manager.py:149 pamac-manager.py:176 pamac/transaction.py:660 msgid "To remove" msgstr "" -#: pamac/main.py:351 -msgid "To update" +#: pamac-manager.py:154 pamac-manager.py:203 +msgid "local" msgstr "" -#: pamac/main.py:362 pamac/main.py:459 -msgid "Total download size: " +#: pamac-manager.py:282 +msgid "Licenses" msgstr "" -#: pamac/main.py:452 pamac/main.py:1263 -msgid "Your system is up-to-date" +#: pamac-manager.py:287 +msgid "Depends On" msgstr "" -#: pamac/main.py:461 -msgid "1 available update" +#: pamac-manager.py:295 +msgid "Optional Deps" msgstr "" -#: pamac/main.py:463 -msgid "{number} available updates" +#: pamac-manager.py:298 +msgid "Required By" msgstr "" -#: pamac/main.py:549 pamac/main.py:550 -msgid "" -"The transaction cannot be performed because it needs to remove {pkgname1} " -"which is a locked package" +#: pamac-manager.py:300 +msgid "Provides" msgstr "" -#: pamac/main.py:585 pamac/main.py:586 pamac/main.py:697 pamac/main.py:698 -msgid "{pkgname1} will be replaced by {pkgname2}" +#: pamac-manager.py:302 +msgid "Replaces" msgstr "" -#: pamac/main.py:714 pamac/main.py:715 pamac/main.py:739 pamac/main.py:740 -#: pamac/main.py:760 pamac/main.py:761 pamac/main.py:791 pamac/main.py:792 -#: pamac/main.py:816 pamac/main.py:817 pamac/main.py:837 pamac/main.py:838 -msgid "{pkgname1} conflicts with {pkgname2}" +#: pamac-manager.py:304 +msgid "Conflicts With" msgstr "" -#: pamac/main.py:772 pamac/main.py:773 -msgid "" -"{pkgname1} conflicts with {pkgname2}\n" -"None of them will be installed" +#: pamac-manager.py:309 +msgid "Repository" msgstr "" -#: pamac/main.py:874 -msgid "" -"{pkgname} is provided by {number} packages.\n" -"Please choose the one(s) you want to install:" +#: pamac-manager.py:311 gui/manager.ui:237 +msgid "Groups" msgstr "" -#: pamac/main.py:957 +#: pamac-manager.py:313 +msgid "Compressed Size" +msgstr "" + +#: pamac-manager.py:314 +msgid "Download Size" +msgstr "" + +#: pamac-manager.py:316 +msgid "Installed Size" +msgstr "" + +#: pamac-manager.py:317 +msgid "Packager" +msgstr "" + +#: pamac-manager.py:318 +msgid "Architecture" +msgstr "" + +#: pamac-manager.py:321 +msgid "Install Date" +msgstr "" + +#: pamac-manager.py:323 +msgid "Explicitly installed" +msgstr "" + +#: pamac-manager.py:325 +msgid "Installed as a dependency for another package" +msgstr "" + +#: pamac-manager.py:327 +msgid "Unknown" +msgstr "" + +#: pamac-manager.py:328 +msgid "Install Reason" +msgstr "" + +#: pamac-manager.py:333 +msgid "Signatures" +msgstr "" + +#: pamac-manager.py:337 +msgid "Backup files" +msgstr "" + +#: pamac-manager.py:408 +#, python-brace-format msgid "" "{pkgname} has {number} uninstalled optional deps.\n" "Please choose the one(s) you want to install:" msgstr "" -#: pamac/main.py:976 +#: pamac-manager.py:435 msgid "Unselect" msgstr "" -#: pamac/main.py:982 +#: pamac-manager.py:441 msgid "Remove" msgstr "" -#: pamac/main.py:987 +#: pamac-manager.py:446 msgid "Reinstall" msgstr "" -#: pamac/main.py:1000 +#: pamac-manager.py:459 msgid "Install optional deps" msgstr "" -#: pamac/main.py:1006 +#: pamac-manager.py:465 msgid "Install" msgstr "" -#: pamac/main.py:1019 +#: pamac-manager.py:478 msgid "Install with optional deps" msgstr "" -#: pamac/main.py:1068 pamac/main.py:1251 -msgid "Uninstalled" +#: pamac-manager.py:702 pamac-updater.py:97 pamac-install.py:71 +msgid "Pamac is already running" msgstr "" -#: pamac/main.py:1070 pamac/main.py:1251 -msgid "Orphans" +#: pamac-updater.py:25 pamac-updater.py:34 +msgid "Your system is up-to-date" +msgstr "" + +#: pamac-updater.py:44 pamac/transaction.py:655 +msgid "Total download size: " +msgstr "" + +#: pamac-updater.py:46 +msgid "1 available update" +msgstr "" + +#: pamac-updater.py:48 +#, python-brace-format +msgid "{number} available updates" +msgstr "" + +#: pamac-tray.py:19 +#, python-brace-format +msgid "{number} available updates" +msgstr "" + +#: pamac-tray.py:20 +msgid "1 available update" +msgstr "" + +#: pamac-tray.py:22 +msgid "Your system is up-to-date" +msgstr "" + +#: pamac-tray.py:32 pamac-tray.py:138 gui/updater.ui:7 +msgid "Update Manager" +msgstr "" + +#: pamac-tray.py:36 gui/manager.ui:41 +msgid "Package Manager" +msgstr "" + +#: pamac-tray.py:40 +msgid "Quit" +msgstr "" + +#: pamac-install.py:55 pamac/transaction.py:559 +#, python-brace-format +msgid "{pkgname} is not a valid path or package name" +msgstr "" + +#: pamac-install.py:79 +msgid "" +"Some updates are available.\n" +"Please update your system first" msgstr "" #: pamac/common.py:13 @@ -338,58 +232,236 @@ msgstr "" msgid "%.2f MiB" msgstr "" -#: gui/manager.glade:6 -msgid "Choose" +#: pamac/transaction.py:50 +#, python-brace-format +msgid "" +"{pkgname} is provided by {number} packages.\n" +"Please choose the one you want to install:" msgstr "" -#: gui/manager.glade:109 -msgid "Summary" +#: pamac/transaction.py:174 +msgid "Checking dependencies" msgstr "" -#: gui/manager.glade:250 -msgid "Package Manager" +#: pamac/transaction.py:182 +msgid "Checking file conflicts" msgstr "" -#: gui/manager.glade:338 +#: pamac/transaction.py:188 +msgid "Resolving dependencies" +msgstr "" + +#: pamac/transaction.py:194 +msgid "Checking inter conflicts" +msgstr "" + +#: pamac/transaction.py:202 +#, python-brace-format +msgid "Installing {pkgname}" +msgstr "" + +#: pamac/transaction.py:211 +#, python-brace-format +msgid "Removing {pkgname}" +msgstr "" + +#: pamac/transaction.py:220 +#, python-brace-format +msgid "Upgrading {pkgname}" +msgstr "" + +#: pamac/transaction.py:229 +#, python-brace-format +msgid "Downgrading {pkgname}" +msgstr "" + +#: pamac/transaction.py:238 +#, python-brace-format +msgid "Reinstalling {pkgname}" +msgstr "" + +#: pamac/transaction.py:247 +msgid "Checking integrity" +msgstr "" + +#: pamac/transaction.py:254 +msgid "Loading packages files" +msgstr "" + +#: pamac/transaction.py:260 +msgid "Checking delta integrity" +msgstr "" + +#: pamac/transaction.py:266 +msgid "Applying deltas" +msgstr "" + +#: pamac/transaction.py:272 +msgid "Generating {} with {}" +msgstr "" + +#: pamac/transaction.py:276 +msgid "Generation succeeded!" +msgstr "" + +#: pamac/transaction.py:279 +msgid "Generation failed." +msgstr "" + +#: pamac/transaction.py:282 +#, python-brace-format +msgid "Configuring {pkgname}" +msgstr "" + +#: pamac/transaction.py:291 +msgid "Checking available disk space" +msgstr "" + +#: pamac/transaction.py:301 +msgid "Checking keyring" +msgstr "" + +#: pamac/transaction.py:308 +msgid "Downloading required keys" +msgstr "" + +#: pamac/transaction.py:331 +#, python-brace-format +msgid "{pkgname1} will replace by {pkgname2}\n" +msgstr "" + +#: pamac/transaction.py:334 +#, python-brace-format +msgid "{pkgname1} conflicts with {pkgname2}\n" +msgstr "" + +#: pamac/transaction.py:383 +#, python-brace-format +msgid "Refreshing {repo}" +msgstr "" + +#: pamac/transaction.py:387 +#, python-brace-format +msgid "Downloading {pkgname}" +msgstr "" + +#: pamac/transaction.py:443 +msgid "Refreshing" +msgstr "" + +#: pamac/transaction.py:581 +#, python-brace-format +msgid "" +"The transaction cannot be performed because it needs to remove {pkgname1} " +"which is a locked package" +msgstr "" + +#: pamac/transaction.py:600 pamac/transaction.py:603 +msgid "Transaction successfully finished" +msgstr "" + +#: pamac/transaction.py:622 +msgid "" +"The transaction was interrupted.\n" +"Now Pamac will quit." +msgstr "" + +#: pamac/transaction.py:632 +msgid "Transaction Summary" +msgstr "" + +#: pamac/transaction.py:676 +msgid "To reinstall" +msgstr "" + +#: pamac/transaction.py:684 +msgid "To downgrade" +msgstr "" + +#: pamac/transaction.py:693 +msgid "To update" +msgstr "" + +#: pamac/transaction.py:754 +msgid "Preparing" +msgstr "" + +#: pamac/transaction.py:782 +msgid "Nothing to do" +msgstr "" + +#: gui/manager.ui:7 +msgid "About Pamac" +msgstr "" + +#: gui/manager.ui:10 +msgid "Copyright © 2013 Guillaume Benoit" +msgstr "" + +#: gui/manager.ui:11 +msgid "A gtk3 frontend for pyalpm" +msgstr "" + +#: gui/manager.ui:191 msgid "Search" msgstr "" -#: gui/manager.glade:431 gui/manager.glade:524 +#: gui/manager.ui:284 gui/manager.ui:376 msgid "State" msgstr "" -#: gui/manager.glade:478 +#: gui/manager.ui:331 msgid "Repos" msgstr "" -#: gui/manager.glade:540 +#: gui/manager.ui:389 msgid "Name" msgstr "" -#: gui/manager.glade:558 +#: gui/manager.ui:402 msgid "Version" msgstr "" -#: gui/manager.glade:574 +#: gui/manager.ui:415 msgid "Size" msgstr "" -#: gui/manager.glade:675 +#: gui/manager.ui:513 msgid "Infos" msgstr "" -#: gui/manager.glade:735 +#: gui/manager.ui:573 msgid "Deps" msgstr "" -#: gui/manager.glade:800 +#: gui/manager.ui:638 msgid "Details" msgstr "" -#: gui/manager.glade:848 +#: gui/manager.ui:686 msgid "Files" msgstr "" -#: gui/manager.glade:970 +#: gui/manager.ui:718 +msgid "Install local packages" +msgstr "" + +#: gui/manager.ui:806 gui/manager.ui:807 +msgid " " +msgstr "" + +#: gui/dialogs.ui:6 +msgid "Choose" +msgstr "" + +#: gui/dialogs.ui:108 +msgid "Summary" +msgstr "" + +#: gui/dialogs.ui:306 msgid "Progress" msgstr "" + +#: gui/dialogs.ui:398 +msgid "details" +msgstr "" diff --git a/pamac/main.py b/pamac/main.py deleted file mode 100644 index 9dd1953..0000000 --- a/pamac/main.py +++ /dev/null @@ -1,1269 +0,0 @@ -#! /usr/bin/python3 -# -*- coding:utf-8 -*- - -from gi.repository import Gtk, Gdk -from gi.repository.GdkPixbuf import Pixbuf -import pyalpm -import dbus -from collections import OrderedDict -from time import strftime, localtime - -from pamac import config, common - -# i18n -import gettext -import locale -locale.bindtextdomain('pamac', '/usr/share/locale') -gettext.bindtextdomain('pamac', '/usr/share/locale') -gettext.textdomain('pamac') -_ = gettext.gettext - -interface = Gtk.Builder() -interface.set_translation_domain('pamac') - -interface.add_from_file('/usr/share/pamac/gui/dialogs.glade') -ErrorDialog = interface.get_object('ErrorDialog') -WarningDialog = interface.get_object('WarningDialog') -InfoDialog = interface.get_object('InfoDialog') -#QuestionDialog = interface.get_object('QuestionDialog') - -interface.add_from_file('/usr/share/pamac/gui/updater.glade') - -interface.add_from_file('/usr/share/pamac/gui/manager.glade') -ConfDialog = interface.get_object('ConfDialog') -transaction_sum = interface.get_object('transaction_sum') -sum_top_label = interface.get_object('sum_top_label') -sum_bottom_label = interface.get_object('sum_bottom_label') -ChooseDialog = interface.get_object('ChooseDialog') -choose_list = interface.get_object('choose_list') -choose_label = interface.get_object('choose_label') -ProgressWindow = interface.get_object('ProgressWindow') -progress_bar = interface.get_object('progressbar2') -progress_label = interface.get_object('progresslabel2') -action_icon = interface.get_object('action_icon') -ProgressCancelButton = interface.get_object('ProgressCancelButton') - -mode = None - -def action_signal_handler(action): - if action: - progress_label.set_text(action) - if (_('Installing') in action) or (_('Reinstalling') in action) or (_('Downgrading') in action) or (_('Removing') in action) or (_('Upgrading') in action) or (_('Configuring') in action): - ProgressCancelButton.set_visible(False) - else: - ProgressCancelButton.set_visible(True) - -def icon_signal_handler(icon): - action_icon.set_from_file(icon) - -def target_signal_handler(target): - progress_bar.set_text(target) - -def percent_signal_handler(percent): - if percent > 1: - progress_bar.pulse() - else: - progress_bar.set_fraction(percent) - -def get_groups(): - global groups_list_clearing - groups_list_clearing = True - groups_list.clear() - groups_list_clearing = False - tmp_list = set() - for repo in transaction.handle.get_syncdbs(): - for name, pkgs in repo.grpcache: - tmp_list.add(name) - tmp_list = sorted(tmp_list) - for name in tmp_list: - groups_list.append([name]) - -def get_repos(): - global repos_list_clearing - repos_list_clearing = True - repos_list.clear() - repos_list_clearing = False - for repo in transaction.handle.get_syncdbs(): - repos_list.append([repo.name]) - repos_list.append([_('local')]) - -def set_list_dict_search(*patterns): - global pkg_name_list - pkg_name_list.clear() - for db in transaction.handle.get_syncdbs(): - for pkg in db.search(*patterns): - pkg_name_list.add(pkg.name) - for pkg in transaction.handle.get_localdb().search(*patterns): - pkg_name_list.add(pkg.name) - if pkg_name_list: - joined = '' - for term in patterns: - joined += term - already_in_list = False - if len(search_list) != 0: - for line in search_list: - if joined == line[0]: - already_in_list = True - if not already_in_list: - search_list.append([joined]) - -def set_list_dict_group(group): - global pkg_name_list - pkg_name_list.clear() - for db in transaction.handle.get_syncdbs(): - grp = db.read_grp(group) - if grp is not None: - name, pkg_list = grp - for pkg in pkg_list: - pkg_name_list.add(pkg.name) - grp = transaction.handle.get_localdb().read_grp(group) - if grp is not None: - name, pkg_list = grp - for pkg in pkg_list: - pkg_name_list.add(pkg.name) - -def set_list_dict_installed(): - global pkg_name_list - pkg_name_list.clear() - pkg_name_list = set(transaction.localpkgs.keys()) - -def set_list_dict_uninstalled(): - global pkg_name_list - pkg_name_list.clear() - pkg_name_list = set(transaction.syncpkgs.keys()).difference(set(transaction.localpkgs.keys())) - -def set_list_dict_local(): - global pkg_name_list - pkg_name_list.clear() - pkg_name_list = set(transaction.localpkgs.keys()).difference(set(transaction.syncpkgs.keys())) - -def set_list_dict_orphans(): - global pkg_name_list - pkg_name_list.clear() - for pkg in transaction.localpkgs.values(): - if pkg.reason == 1: - required = set(pkg.compute_requiredby()) - required &= set(transaction.localpkgs.keys()) - if not required: - pkg_name_list.add(pkg.name) - -def set_list_dict_to_install(): - global pkg_name_list - pkg_name_list.clear() - pkg_name_list = transaction.to_add.copy() - -def set_list_dict_to_remove(): - global pkg_name_list - pkg_name_list.clear() - pkg_name_list = transaction.to_remove.copy() - -def set_list_dict_repos(repo): - global pkg_name_list - pkg_name_list.clear() - for db in transaction.handle.get_syncdbs(): - if db.name == repo: - for pkg in db.pkgcache: - pkg_name_list.add(pkg.name) - -def refresh_packages_list(): - if current_filter[0]: - Window.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) - while Gtk.events_pending(): - Gtk.main_iteration() - global packages_list_clearing - packages_list_clearing = True - packages_list.clear() - packages_list_clearing = False - if not pkg_name_list: - packages_list.append([_('No package found'), False, None, '', 0, '']) - else: - #installed = set(transaction.localpkgs.keys()) - transaction.to_remove - #uninstalled = (set(transaction.syncpkgs.keys()) - installed) - transaction.to_add - #to_lock = installed & set(config.holdpkg) - name_list = sorted(pkg_name_list) - for name in name_list: - if name in config.holdpkg: - packages_list.append([name, True, locked_icon, common.format_size(transaction.localpkgs[name].isize), transaction.localpkgs[name].isize, transaction.localpkgs[name].version]) - elif name in transaction.to_add: - packages_list.append([name, False, to_install_icon, common.format_size(transaction.syncpkgs[name].isize), transaction.syncpkgs[name].isize, transaction.syncpkgs[name].version]) - elif name in transaction.to_remove: - packages_list.append([name, True, to_remove_icon, common.format_size(transaction.localpkgs[name].isize), transaction.localpkgs[name].isize, transaction.localpkgs[name].version]) - elif name in transaction.localpkgs.keys(): - packages_list.append([name, True, installed_icon, common.format_size(transaction.localpkgs[name].isize), transaction.localpkgs[name].isize, transaction.localpkgs[name].version]) - #elif name in uninstalled: - else: - packages_list.append([name, False, uninstalled_icon, common.format_size(transaction.syncpkgs[name].isize), transaction.syncpkgs[name].isize, transaction.syncpkgs[name].version]) - Window.get_window().set_cursor(None) - -def set_packages_list(): - if current_filter[0] == 'search': - set_list_dict_search(*current_filter[1]) - elif current_filter[0] == 'group': - set_list_dict_group(current_filter[1]) - elif current_filter[0] == 'installed': - set_list_dict_installed() - elif current_filter[0] == 'uninstalled': - set_list_dict_uninstalled() - elif current_filter[0] == 'orphans': - set_list_dict_orphans() - elif current_filter[0] == 'local': - set_list_dict_local() - elif current_filter[0] == 'to_install': - set_list_dict_to_install() - elif current_filter[0] == 'to_remove': - set_list_dict_to_remove() - elif current_filter[0] == 'repo': - set_list_dict_repos(current_filter[1]) - if current_filter[0]: - refresh_packages_list() - -def set_infos_list(pkg): - name_label.set_markup('{} {}'.format(pkg.name, pkg.version)) - # fix &,-,>,< in desc - desc = pkg.desc.replace('&', '&') - desc = desc.replace('<->', '/') - desc_label.set_markup(desc) - # fix & in url - url = pkg.url.replace('&', '&') - link_label.set_markup('{_url}'.format(_url = url)) - licenses_label.set_markup(_('Licenses')+': {}'.format(' '.join(pkg.licenses))) - -def set_deps_list(pkg, style): - deps_list.clear() - if pkg.depends: - deps_list.append([_('Depends On')+':', '\n'.join(pkg.depends)]) - if pkg.optdepends: - optdeps = [] - for optdep in pkg.optdepends: - if optdep.split(':')[0] in transaction.localpkgs.keys(): - optdeps.append(optdep+' ['+_('Installed')+']') - else: - optdeps.append(optdep) - deps_list.append([_('Optional Deps')+':', '\n'.join(optdeps)]) - if style == 'local': - if pkg.compute_requiredby(): - deps_list.append([_('Required By')+':', '\n'.join(pkg.compute_requiredby())]) - if pkg.provides: - deps_list.append([_('Provides')+':', '\n'.join(pkg.provides)]) - if pkg.replaces: - deps_list.append([_('Replaces')+':', '\n'.join(pkg.replaces)]) - if pkg.conflicts: - deps_list.append([_('Conflicts With')+':', '\n'.join(pkg.conflicts)]) - -def set_details_list(pkg, style): - details_list.clear() - if style == 'sync': - details_list.append([_('Repository')+':', pkg.db.name]) - if pkg.groups: - details_list.append([_('Groups')+':', ' '.join(pkg.groups)]) - if style == 'sync': - details_list.append([_('Compressed Size')+':', common.format_size(pkg.size)]) - details_list.append([_('Download Size')+':', common.format_size(pkg.download_size)]) - if style == 'local': - details_list.append([_('Installed Size')+':', common.format_size(pkg.isize)]) - details_list.append([_('Packager')+':', pkg.packager]) - details_list.append([_('Architecture')+':', pkg.arch]) - #details_list.append([_('Build Date')+':', strftime("%a %d %b %Y %X %Z", localtime(pkg.builddate))]) - if style == 'local': - details_list.append([_('Install Date')+':', strftime("%a %d %b %Y %X %Z", localtime(pkg.installdate))]) - if pkg.reason == pyalpm.PKG_REASON_EXPLICIT: - reason = _('Explicitly installed') - elif pkg.reason == pyalpm.PKG_REASON_DEPEND: - reason = _('Installed as a dependency for another package') - else: - reason = _('Unknown') - details_list.append([_('Install Reason')+':', reason]) - if style == 'sync': - #details_list.append([_('Install Script')':', 'Yes' if pkg.has_scriptlet else 'No']) - #details_list.append(['MD5 Sum:', pkg.md5sum]) - #details_list.append(['SHA256 Sum:', pkg.sha256sum]) - details_list.append([_('Signatures')+':', 'Yes' if pkg.base64_sig else 'No']) - if style == 'local': - if len(pkg.backup) != 0: - #details_list.append(['_(Backup files)+':', '\n'.join(["%s %s" % (md5, file) for (file, md5) in pkg.backup])]) - details_list.append([_('Backup files')+':', '\n'.join(["%s" % (file) for (file, md5) in pkg.backup])]) - -def set_files_list(pkg): - files_list.clear() - if len(pkg.files) != 0: - for file in pkg.files: - files_list.append(['/'+file[0]]) - -def get_transaction_sum(): - transaction_dict = {'to_remove': [], 'to_install': [], 'to_update': [], 'to_reinstall': [], 'to_downgrade': []} - to_remove = sorted(transaction.To_Remove()) - for name, version in to_remove: - transaction_dict['to_remove'].append(name+' '+version) - others = sorted(transaction.To_Add()) - for name, version, dsize in others: - if name in transaction.localpkgs.keys(): - comp = pyalpm.vercmp(version, transaction.localpkgs[name].version) - if comp == 1: - transaction_dict['to_update'].append((name+' '+version, dsize)) - elif comp == 0: - transaction_dict['to_reinstall'].append((name+' '+version, dsize)) - elif comp == -1: - transaction_dict['to_downgrade'].append((name+' '+version, dsize)) - else: - transaction_dict['to_install'].append((name+' '+version, dsize)) - if transaction_dict['to_install']: - print('To install:', [name for name, size in transaction_dict['to_install']]) - if transaction_dict['to_reinstall']: - print('To reinstall:', [name for name, size in transaction_dict['to_reinstall']]) - if transaction_dict['to_downgrade']: - print('To downgrade:', [name for name, size in transaction_dict['to_downgrade']]) - if transaction_dict['to_remove']: - print('To remove:', [name for name in transaction_dict['to_remove']]) - if transaction_dict['to_update']: - print('To update:', [name for name, size in transaction_dict['to_update']]) - return transaction_dict - -def set_transaction_sum(): - transaction_sum.clear() - transaction_dict = get_transaction_sum() - sum_top_label.set_markup(_('Transaction Summary')) - if transaction_dict['to_install']: - transaction_sum.append([_('To install')+':', transaction_dict['to_install'][0][0]]) - i = 1 - while i < len(transaction_dict['to_install']): - transaction_sum.append([' ', transaction_dict['to_install'][i][0]]) - i += 1 - if transaction_dict['to_reinstall']: - transaction_sum.append([_('To reinstall')+':', transaction_dict['to_reinstall'][0][0]]) - i = 1 - while i < len(transaction_dict['to_reinstall']): - transaction_sum.append([' ', transaction_dict['to_reinstall'][i][0]]) - i += 1 - if transaction_dict['to_downgrade']: - transaction_sum.append([_('To downgrade')+':', transaction_dict['to_downgrade'][0][0]]) - i = 1 - while i < len(transaction_dict['to_downgrade']): - transaction_sum.append([' ', transaction_dict['to_downgrade'][i][0]]) - i += 1 - if transaction_dict['to_remove']: - transaction_sum.append([_('To remove')+':', transaction_dict['to_remove'][0]]) - i = 1 - while i < len(transaction_dict['to_remove']): - transaction_sum.append([' ', transaction_dict['to_remove'][i]]) - i += 1 - if mode != 'updater': - if transaction_dict['to_update']: - transaction_sum.append([_('To update')+':', transaction_dict['to_update'][0][0]]) - i = 1 - while i < len(transaction_dict['to_update']): - transaction_sum.append([' ', transaction_dict['to_update'][i][0]]) - i += 1 - dsize = 0 - for nameversion, size in transaction_dict['to_install'] + transaction_dict['to_update'] + transaction_dict['to_reinstall'] + transaction_dict['to_downgrade']: - dsize += size - if dsize == 0: - sum_bottom_label.set_markup('') - else: - sum_bottom_label.set_markup(_('Total download size: ')+common.format_size(dsize)) - -def handle_error(error): - ProgressWindow.hide() - #while Gtk.events_pending(): - # Gtk.main_iteration() - if error: - if not 'DBus.Error.NoReply' in str(error): - print(error) - ErrorDialog.format_secondary_text(error) - response = ErrorDialog.run() - if response: - ErrorDialog.hide() - try: - transaction.Release() - except: - pass - if mode == 'manager': - transaction.get_handle() - transaction.update_db() - transaction.to_add.clear() - transaction.to_remove.clear() - transaction.to_update.clear() - get_groups() - get_repos() - set_packages_list() - #if mode == 'updater': - #have_updates() - -def handle_reply(reply): - ProgressWindow.hide() - #while Gtk.events_pending(): - # Gtk.main_iteration() - if reply: - InfoDialog.format_secondary_text(reply) - response = InfoDialog.run() - if response: - InfoDialog.hide() - try: - transaction.Release() - except: - pass - transaction.get_handle() - transaction.update_db() - if mode == 'manager': - transaction.to_add.clear() - transaction.to_remove.clear() - transaction.to_update.clear() - get_groups() - get_repos() - set_packages_list() - do_syncfirst, updates = transaction.get_updates() - if updates: - do_sysupgrade() - if mode == 'updater': - have_updates() - -def log_error(msg): - ErrorDialog.format_secondary_text(msg) - response = ErrorDialog.run() - while Gtk.events_pending(): - Gtk.main_iteration() - if response: - ErrorDialog.hide() - -def log_warning(msg): - WarningDialog.format_secondary_text(msg) - response = WarningDialog.run() - while Gtk.events_pending(): - Gtk.main_iteration() - if response: - WarningDialog.hide() - -def do_refresh(): - """Sync databases like pacman -Sy""" - progress_label.set_text(_('Refreshing')+'...') - action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/refresh-cache.png') - progress_bar.set_text('') - progress_bar.set_fraction(0) - ProgressWindow.show_all() - while Gtk.events_pending(): - Gtk.main_iteration() - transaction.Refresh() - -def have_updates(): - do_syncfirst, updates = transaction.get_updates() - update_listore.clear() - update_top_label.set_justify(Gtk.Justification.CENTER) - if not updates: - update_bottom_label.set_markup('') - update_top_label.set_markup(_('Your system is up-to-date')) - else: - dsize = 0 - for pkg in updates: - pkgname = pkg.name+' '+pkg.version - update_listore.append([pkgname, common.format_size(pkg.size)]) - dsize += pkg.download_size - update_bottom_label.set_markup(_('Total download size: ')+common.format_size(dsize)) - if len(updates) == 1: - update_top_label.set_markup(_('1 available update')) - else: - update_top_label.set_markup(_('{number} available updates').format(number = len(updates))) - -def do_sysupgrade(): - """Upgrade a system like pacman -Su""" - do_syncfirst, updates = transaction.get_updates() - if updates: - transaction.to_add.clear() - transaction.to_remove.clear() - transaction.to_update = set([pkg.name for pkg in updates]) - check_conflicts() - init = False - error = '' - if do_syncfirst: - init = transaction.init_transaction(noconflicts = True, recurse = True) - else: - init = transaction.init_transaction(noconflicts = True) - #~ if init: - #~ error = transaction.Sysupgrade() - #~ if error: - #~ handle_error(error) - if init: - if not error: - for name in transaction.to_add | transaction.to_update: - transaction.Add(name) - for name in transaction.to_remove: - transaction.Remove(name) - error = transaction.Prepare() - if error: - handle_error(error) - else: - set_transaction_sum() - if mode == 'updater': - if len(transaction_sum) != 0: - ConfDialog.show_all() - else: - finalize() - else: - ConfDialog.show_all() - -def finalize(): - progress_label.set_text(_('Preparing')+'...') - action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-setup.png') - progress_bar.set_text('') - progress_bar.set_fraction(0) - ProgressWindow.show_all() - while Gtk.events_pending(): - Gtk.main_iteration() - try: - transaction.Commit() - except dbus.exceptions.DBusException as e: - handle_error(str(e)) - -def check_conflicts(): - warning = '' - error = '' - print('checking...') - if mode: - Window.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) - while Gtk.events_pending(): - Gtk.main_iteration() - to_check = [transaction.syncpkgs[name] for name in transaction.to_add | transaction.to_update] - if transaction.to_load: - for path in transaction.to_load: - try: - pkg = transaction.handle.load_pkg(path) - if pkg: - to_check.append(pkg) - except pyalpm.error: - error += _('{pkgname} is not a valid path or package name').format(pkgname = path) - already_checked = set(pkg.name for pkg in to_check) - depends = [to_check] - pkgs = transaction.handle.get_localdb().search('linux3') - installed_linux = [] - # get packages to remove - check_for_removal = transaction.to_remove.copy() - to_add_to_remove = set() - hold_requirement = {} - while check_for_removal: - for name in check_for_removal: - required = transaction.localpkgs[name].compute_requiredby() - for requirement in required: - if requirement in config.holdpkg: - for hold in config.holdpkg: - if requirement == hold: - if error: - error += '\n' - error += _('The transaction cannot be performed because it needs to remove {pkgname1} which is a locked package').format(pkgname1 = hold) - print(_('The transaction cannot be performed because it needs to remove {pkgname1} which is a locked package').format(pkgname1 = hold)) - else: - to_add_to_remove.add(requirement) - to_add_to_remove &= set(transaction.localpkgs.keys()) - check_for_removal = to_add_to_remove.copy() - transaction.to_remove |= to_add_to_remove - to_add_to_remove.clear() - if error: - break - # get installed kernels - for item in pkgs: - if len(item.name) == 7 or len(item.name) == 8: - installed_linux.append(item.name) - for to_install in transaction.to_add: - if 'linux3' in to_install: - if len(to_install) == 7 or len(to_install) == 8: - installed_linux.append(to_install) - # check if new pkgs will replace installed ones - to_replace = set() - do_syncfirst, updates = transaction.get_updates() - if transaction.to_update: - if not do_syncfirst: - for pkg in transaction.syncpkgs.values(): - for replace in pkg.replaces: - found_replace = pyalpm.find_satisfier(transaction.localpkgs.values(), replace) - if found_replace: - #if not common.format_pkg_name(replace) in transaction.syncpkgs.keys(): - if found_replace.name != pkg.name: - if not pkg.name in transaction.localpkgs.keys(): - if common.format_pkg_name(replace) in transaction.localpkgs.keys(): - if not found_replace.name in transaction.to_remove: - transaction.to_remove.add(found_replace.name) - to_replace.add(found_replace.name) - if warning: - warning += '\n' - warning += _('{pkgname1} will be replaced by {pkgname2}').format(pkgname1 = found_replace.name, pkgname2 = pkg.name) - print(_('{pkgname1} will be replaced by {pkgname2}').format(pkgname1 = found_replace.name, pkgname2 = pkg.name)) - if found_replace.name in transaction.to_update: - transaction.to_update.discard(found_replace.name) - index = None - for _pkg in depends[0]: - if _pkg.name == found_replace.name: - index = depends[0].index(_pkg) - depends[0].pop(index) - if not pkg.name in already_checked: - depends[0].append(pkg) - already_checked.add(pkg.name) - transaction.to_add.add(pkg.name) - - # start loops to check pkgs - i = 0 - while depends[i]: - # add a empty list for new pkgs to check next loop - depends.append([]) - # start to check one pkg - for pkg in depends[i]: - # check if the current pkg is a kernel and if so, check if a module is required to install - if 'linux3' in pkg.name: - for _pkg in transaction.localpkgs.values(): - for depend in _pkg.depends: - if '-modules' in depend: - for __pkg in transaction.syncpkgs.values(): - if not __pkg.name in transaction.localpkgs.keys(): - for provide in __pkg.provides: - for linux in installed_linux: - if linux in __pkg.name: - if common.format_pkg_name(depend) == common.format_pkg_name(provide): - if not __pkg.name in transaction.to_add: - if not __pkg.name in already_checked: - depends[i+1].append(__pkg) - already_checked.add(__pkg.name) - transaction.to_add.add(__pkg.name) - # check pkg deps - for depend in pkg.depends: - # check if dep is already installed - found_depend = pyalpm.find_satisfier(transaction.localpkgs.values(), depend) - if found_depend: - # check if the dep is a kernel module to provide and if so, auto-select it - if found_depend.name != common.format_pkg_name(depend): - if ('-modules' in depend) or ('linux' in depend): - for _pkg in transaction.syncpkgs.values(): - if not _pkg.name in transaction.localpkgs.keys(): - for name in _pkg.provides: - for linux in installed_linux: - if linux in _pkg.name: - if common.format_pkg_name(depend) == common.format_pkg_name(name): - if not _pkg.name in transaction.to_add: - if not _pkg.name in already_checked: - depends[i+1].append(_pkg) - already_checked.add(_pkg.name) - transaction.to_add.add(_pkg.name) - else: - # add the dep in list to check its deps in next loop - if not found_depend.name in already_checked: - depends[i+1].append(found_depend) - already_checked.add(found_depend.name) - else: - # found the dep in uninstalled pkgs - found_depend = pyalpm.find_satisfier(transaction.syncpkgs.values(), depend) - if found_depend: - if found_depend.name != common.format_pkg_name(depend): - # check if the dep is a kernel module to provide and if so, auto-select it - if ('-modules' in depend) or ('linux' in depend): - for _pkg in transaction.syncpkgs.values(): - if not _pkg.name in transaction.localpkgs.keys(): - for name in _pkg.provides: - for linux in installed_linux: - if linux in _pkg.name: - if common.format_pkg_name(depend) == common.format_pkg_name(name): - if not _pkg.name in transaction.to_add: - if not _pkg.name in already_checked: - depends[i+1].append(_pkg) - already_checked.add(_pkg.name) - transaction.to_add.add(_pkg.name) - else: - # so the dep is a virtual dep: check if it's already provides - already_provided = False - for pkgname in transaction.to_add: - _pkg = transaction.syncpkgs[pkgname] - found_depend = pyalpm.find_satisfier([_pkg], depend) - if found_depend: - already_provided = True - # if not already provided, run ChooseDialog (via choose_provides) - if not already_provided: - to_add_to_depends = choose_provides(depend) - for _pkg in to_add_to_depends: - if not _pkg.name in transaction.to_add: - if not _pkg.name in already_checked: - depends[i+1].append(_pkg) - already_checked.add(_pkg.name) - transaction.to_add.add(_pkg.name) - else: - # so the dep is not yet installed, add it in list to check its deps in next loop - if not found_depend.name in already_checked: - depends[i+1].append(found_depend) - already_checked.add(found_depend.name) - # check if the pkg replaces installed ones - if transaction.to_update: - for replace in pkg.replaces: - found_replace = pyalpm.find_satisfier(transaction.localpkgs.values(), replace) - if found_replace: - if found_replace.name != pkg.name: - if not found_replace.name in transaction.to_remove: - transaction.to_remove.add(found_replace.name) - to_replace.add(found_replace.name) - if warning: - warning += '\n' - warning += _('{pkgname1} will be replaced by {pkgname2}').format(pkgname1 = found_replace.name, pkgname2 = pkg.name) - print(_('{pkgname1} will be replaced by {pkgname2}').format(pkgname1 = found_replace.name, pkgname2 = pkg.name)) - if found_replace.name in transaction.to_update: - transaction.to_update.discard(found_replace.name) - # check pkg conflicts - for conflict in pkg.conflicts: - # check if the pkg conflicts with installed ones - found_conflict = pyalpm.find_satisfier(transaction.localpkgs.values(), conflict) - if found_conflict: - if found_conflict.name != pkg.name: - # if pkg provides the conflict no need to check if it can be safely removed - will_provide_conflict = pyalpm.find_satisfier([pkg], conflict) - if will_provide_conflict: - if not found_conflict.name in transaction.to_remove: - transaction.to_remove.add(found_conflict.name) - if warning: - warning += '\n' - warning += _('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = pkg.name, pkgname2 = found_conflict.name) - print(_('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = pkg.name, pkgname2 = found_conflict.name)) - else: - # if the conflict will be updated, check the conflicts of the new one - if found_conflict.name in transaction.to_update: - new_found_conflict = pyalpm.find_satisfier([transaction.syncpkgs[found_conflict.name]], conflict) - if new_found_conflict: - #~ # check if the conflict can be safely removed - #~ required = set(pkg.compute_requiredby()) - #~ required &= set(transaction.localpkgs.keys()) - #~ if required: - #~ str_required = '' - #~ for item in required: - #~ if str_required: - #~ str_required += ', ' - #~ str_required += item - #~ if error: - #~ error += '\n' - #~ error += _('{pkgname1} conflicts with {pkgname2} but cannot be removed because it is needed by {pkgname3}').format(pkgname1 = found_conflict.name, pkgname2 = pkg.name, pkgname3 = str_required) - #~ print(_('{pkgname1} conflicts with {pkgname2} but cannot be removed because it is needed by {pkgname3}').format(pkgname1 = found_conflict.name, pkgname2 = pkg.name, pkgname3 = str_required)) - #~ el - if not new_found_conflict.name in transaction.to_remove: - transaction.to_remove.add(new_found_conflict.name) - if warning: - warning += '\n' - warning += _('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = pkg.name, pkgname2 = new_found_conflict.name) - print(_('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = pkg.name, pkgname2 = new_found_conflict.name)) - else: - #~ # check if the conflict can be safely removed - #~ required = set(pkg.compute_requiredby()) - #~ required &= set(transaction.localpkgs.keys()) - #~ if required: - #~ str_required = '' - #~ for item in required: - #~ if str_required: - #~ str_required += ', ' - #~ str_required += item - #~ if error: - #~ error += '\n' - #~ error += _('{pkgname1} conflicts with {pkgname2} but cannot be removed because it is needed by {pkgname3}').format(pkgname1 = found_conflict.name, pkgname2 = pkg.name, pkgname3 = str_required) - #~ print(_('{pkgname1} conflicts with {pkgname2} but cannot be removed because it is needed by {pkgname3}').format(pkgname1 = found_conflict.name, pkgname2 = pkg.name, pkgname3 = str_required)) - #~ el - if not found_conflict.name in transaction.to_remove: - transaction.to_remove.add(found_conflict.name) - if warning: - warning += '\n' - warning += _('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = pkg.name, pkgname2 = found_conflict.name) - print(_('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = pkg.name, pkgname2 = found_conflict.name)) - # check if the pkg conflicts with the other ones to install - found_conflict = pyalpm.find_satisfier(depends[0], conflict) - if found_conflict: - if not common.format_pkg_name(conflict) == pkg.name: - if not common.format_pkg_name(conflict) in transaction.to_remove: - if pkg.name in transaction.to_add and common.format_pkg_name(conflict) in transaction.to_add: - transaction.to_add.discard(common.format_pkg_name(conflict)) - transaction.to_add.discard(pkg.name) - if warning: - warning += '\n' - warning += _('{pkgname1} conflicts with {pkgname2}\nNone of them will be installed').format(pkgname1 = pkg.name, pkgname2 = common.format_pkg_name(conflict)) - print(_('{pkgname1} conflicts with {pkgname2}\nNone of them will be installed').format(pkgname1 = pkg.name, pkgname2 = common.format_pkg_name(conflict))) - i += 1 - # end of the loop - - # check if installed pkgs conflicts with the ones to install - to_check = [transaction.syncpkgs[name] for name in transaction.to_add | transaction.to_update] - for pkg in transaction.localpkgs.values(): - for conflict in pkg.conflicts: - found_conflict = pyalpm.find_satisfier(to_check, conflict) - if found_conflict: - if found_conflict.name != pkg.name: - # if pkg provides the conflict no need to check if it can be safely removed - will_provide_conflict = pyalpm.find_satisfier([pkg], conflict) - if will_provide_conflict: - if not pkg.name in transaction.to_remove: - transaction.to_remove.add(pkg.name) - if warning: - warning += '\n' - warning += _('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = found_conflict.name, pkgname2 = pkg.name) - print(_('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = found_conflict.name, pkgname2 = pkg.name)) - else: - # if pkg will be updated, check the conflicts of this new one - if pkg.name in transaction.to_update: - for new_conflict in transaction.syncpkgs[pkg.name].conflicts: - if new_conflict == conflict: - #~ # check if the conflict can be safely removed - #~ required = set(pkg.compute_requiredby()) - #~ required &= set(transaction.localpkgs.keys()) - #~ if required: - #~ str_required = '' - #~ for item in required: - #~ if str_required: - #~ str_required += ', ' - #~ str_required += item - #~ if error: - #~ error += '\n' - #~ error += _('{pkgname1} conflicts with {pkgname2} but cannot be removed because it is needed by {pkgname3}').format(pkgname1 = pkg.name, pkgname2 = found_conflict.name, pkgname3 = str_required) - #~ print(_('{pkgname1} conflicts with {pkgname2} but cannot be removed because it is needed by {pkgname3}').format(pkgname1 = pkg.name, pkgname2 = found_conflict.name, pkgname3 = str_required)) - #~ el - if not pkg.name in transaction.to_remove: - transaction.to_remove.add(pkg.name) - if warning: - warning += '\n' - warning += _('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = found_conflict.name, pkgname2 = pkg.name) - print(_('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = found_conflict.name, pkgname2 = pkg.name)) - else: - #~ # check if the conflict can be safely removed - #~ required = set(pkg.compute_requiredby()) - #~ required &= set(transaction.localpkgs.keys()) - #~ if required: - #~ str_required = '' - #~ for item in required: - #~ if str_required: - #~ str_required += ', ' - #~ str_required += item - #~ if error: - #~ error += '\n' - #~ error += _('{pkgname1} conflicts with {pkgname2} but cannot be removed because it is needed by {pkgname3}').format(pkgname1 = pkg.name, pkgname2 = found_conflict.name, pkgname3 = str_required) - #~ print(_('{pkgname1} conflicts with {pkgname2} but cannot be removed because it is needed by {pkgname3}').format(pkgname1 = pkg.name, pkgname2 = found_conflict.name, pkgname3 = str_required)) - #~ el - if not pkg.name in transaction.to_remove: - transaction.to_remove.add(pkg.name) - if warning: - warning += '\n' - warning += _('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = found_conflict.name, pkgname2 = pkg.name) - print(_('{pkgname1} conflicts with {pkgname2}').format(pkgname1 = found_conflict.name, pkgname2 = pkg.name)) - - # remove in to_remove the packages which are needed by the names in to_add to avoid conflicts: - wont_be_removed = set() - for pkg_list in depends: - for pkg in pkg_list: - wont_be_removed.add(pkg.name) - wont_be_removed -= to_replace - transaction.to_remove -= wont_be_removed - - if mode: - Window.get_window().set_cursor(None) - print('check done') - if warning: - WarningDialog.format_secondary_text(warning) - response = WarningDialog.run() - if response: - WarningDialog.hide() - if error: - handle_error(error) - -def choose_provides(name): - provides = OrderedDict() - already_add = [] - for pkg in transaction.syncpkgs.values(): - # fix if find_satisfier misbehaved - if pkg.name == name: - return [pkg] - for provide in pkg.provides: - if common.format_pkg_name(name) == common.format_pkg_name(provide): - if not pkg.name in provides.keys(): - provides[pkg.name] = pkg - if provides: - if len(provides.keys()) == 1: - return [pkg for pkgname, pkg in provides.items()] - else: - choose_label.set_markup(_('{pkgname} is provided by {number} packages.\nPlease choose the one(s) you want to install:').format(pkgname = name, number = str(len(provides.keys())))) - choose_list.clear() - for name in provides.keys(): - if name in transaction.localpkgs.keys(): - choose_list.append([True, name]) - else: - choose_list.append([False, name]) - Window.get_window().set_cursor(None) - ChooseDialog.run() - Window.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) - return [provides[pkgname] for pkgname in transaction.to_provide] - else: - return [] - -class Handler: - #Manager Handlers - def on_ManagerWindow_delete_event(self, *arg): - transaction.StopDaemon() - Gtk.main_quit() - - def on_Manager_QuitButton_clicked(self, *arg): - transaction.StopDaemon() - Gtk.main_quit() - - def on_Manager_ValidButton_clicked(self, *arg): - transaction.to_update.clear() - if transaction.to_add | transaction.to_remove: - check_conflicts() - if transaction.to_add | transaction.to_remove: - if transaction.init_transaction(noconflicts = True): - for pkgname in transaction.to_add: - transaction.Add(pkgname) - for pkgname in transaction.to_remove: - transaction.Remove(pkgname) - error = transaction.Prepare() - if error: - handle_error(error) - else: - set_transaction_sum() - ConfDialog.show_all() - else: - WarningDialog.format_secondary_text(_('Nothing to do')) - response = WarningDialog.run() - if response: - WarningDialog.hide() - refresh_packages_list() - - def on_Manager_EraseButton_clicked(self, *arg): - transaction.to_add.clear() - transaction.to_remove.clear() - transaction.to_update.clear() - refresh_packages_list() - - def on_Manager_RefreshButton_clicked(self, *arg): - do_refresh() - - def on_TransCancelButton_clicked(self, *arg): - ProgressWindow.hide() - ConfDialog.hide() - transaction.Release() - if mode == 'manager': - refresh_packages_list() - - def on_TransValidButton_clicked(self, *arg): - ConfDialog.hide() - finalize() - - def on_search_entry_icon_press(self, *arg): - global current_filter - current_filter = ('search', search_entry.get_text().split()) - set_packages_list() - - def on_search_entry_activate(self, widget): - global current_filter - current_filter = ('search', search_entry.get_text().split()) - set_packages_list() - - menu = Gtk.Menu() - def on_list_treeview_button_press_event(self, treeview, event): - def mark_to_reinstall(widget, treeiter): - packages_list[treeiter][2] = to_reinstall_icon - transaction.to_add.add(packages_list[treeiter][0]) - def select_optdeps(widget, pkgname, optdeps): - choose_label.set_markup(_('{pkgname} has {number} uninstalled optional deps.\nPlease choose the one(s) you want to install:').format(pkgname = pkgname, number = str(len(optdeps)))) - choose_list.clear() - for long_string in optdeps: - choose_list.append([False, long_string]) - ChooseDialog.run() - for long_string in transaction.to_provide: - transaction.to_add.add(long_string.split(':')[0]) - def install_with_optdeps(widget, treeiter, pkgname, optdeps): - select_optdeps(widget, pkgname, optdeps) - packages_list[treeiter][2] = to_install_icon - transaction.to_add.add(packages_list[treeiter][0]) - # Check if right mouse button was clicked - if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3: - treepath, viewcolumn, x, y = treeview.get_path_at_pos(int(event.x), int(event.y)) - treeiter = packages_list.get_iter(treepath) - if treeiter: - if packages_list[treeiter][0] != _('No package found') and not packages_list[treeiter][0] in config.holdpkg: - self.menu = Gtk.Menu() - if packages_list[treeiter][0] in transaction.to_remove | transaction.to_add: - item = Gtk.ImageMenuItem(_('Unselect')) - item.set_image(Gtk.Image.new_from_stock('gtk-undo', Gtk.IconSize.MENU)) - item.set_always_show_image(True) - item.connect('activate', self.on_list_treeview_row_activated, treeiter, viewcolumn) - self.menu.append(item) - elif packages_list[treeiter][0] in transaction.localpkgs.keys(): - item = Gtk.ImageMenuItem(_('Remove')) - item.set_image(Gtk.Image.new_from_pixbuf(to_remove_icon)) - item.set_always_show_image(True) - item.connect('activate', self.on_list_treeview_row_activated, treeiter, viewcolumn) - self.menu.append(item) - item = Gtk.ImageMenuItem(_('Reinstall')) - item.set_image(Gtk.Image.new_from_pixbuf(to_reinstall_icon)) - item.set_always_show_image(True) - item.connect('activate', mark_to_reinstall, treeiter) - self.menu.append(item) - optdeps_strings = transaction.localpkgs[packages_list[treeiter][0]].optdepends - if optdeps_strings: - available_optdeps = [] - for optdep_string in optdeps_strings: - optdep = optdep_string.split(':')[0] - if not optdep in transaction.localpkgs.keys(): - available_optdeps.append(optdep_string) - if available_optdeps: - item = Gtk.ImageMenuItem(_('Install optional deps')) - item.set_image(Gtk.Image.new_from_pixbuf(to_install_icon)) - item.set_always_show_image(True) - item.connect('activate', select_optdeps, packages_list[treeiter][0], available_optdeps) - self.menu.append(item) - else: - item = Gtk.ImageMenuItem(_('Install')) - item.set_image(Gtk.Image.new_from_pixbuf(to_install_icon)) - item.set_always_show_image(True) - item.connect('activate', self.on_list_treeview_row_activated, treeiter, viewcolumn) - self.menu.append(item) - optdeps_strings = transaction.syncpkgs[packages_list[treeiter][0]].optdepends - if optdeps_strings: - available_optdeps = [] - for optdep_string in optdeps_strings: - optdep = optdep_string.split(':')[0] - if not optdep in transaction.localpkgs.keys(): - available_optdeps.append(optdep_string) - if available_optdeps: - item = Gtk.ImageMenuItem(_('Install with optional deps')) - item.set_image(Gtk.Image.new_from_pixbuf(to_install_icon)) - item.set_always_show_image(True) - item.connect('activate', install_with_optdeps, treeiter, packages_list[treeiter][0], available_optdeps) - self.menu.append(item) - treeview.grab_focus() - treeview.set_cursor(treepath, viewcolumn, 0) - self.menu.show_all() - self.menu.popup(None, None, None, None, event.button, event.time) - return True - - def on_list_treeview_selection_changed(self, treeview): - if not packages_list_clearing: - liststore, treeiter = list_selection.get_selected() - if treeiter: - if packages_list[treeiter][0] != _('No package found'): - if packages_list[treeiter][0] in transaction.localpkgs.keys(): - set_infos_list(transaction.localpkgs[packages_list[treeiter][0]]) - set_deps_list(transaction.localpkgs[packages_list[treeiter][0]], "local") - set_details_list(transaction.localpkgs[packages_list[treeiter][0]], "local") - set_files_list(transaction.localpkgs[packages_list[treeiter][0]]) - files_scrolledwindow.set_visible(True) - elif packages_list[treeiter][0] in transaction.syncpkgs.keys(): - set_infos_list(transaction.syncpkgs[packages_list[treeiter][0]]) - set_deps_list(transaction.syncpkgs[packages_list[treeiter][0]], "sync") - set_details_list(transaction.syncpkgs[packages_list[treeiter][0]], "sync") - files_scrolledwindow.set_visible(False) - - def on_search_treeview_selection_changed(self, widget): - liste, line = search_selection.get_selected() - if line: - global current_filter - current_filter = ('search', search_list[line][0].split()) - set_packages_list() - - def on_groups_treeview_selection_changed(self, widget): - if not groups_list_clearing: - liste, line = groups_selection.get_selected() - if line: - global current_filter - current_filter = ('group', groups_list[line][0]) - set_packages_list() - - def on_state_treeview_selection_changed(self, widget): - liste, line = state_selection.get_selected() - if line: - global current_filter - if state_list[line][0] == _('Installed'): - current_filter = ('installed', None) - if state_list[line][0] == _('Uninstalled'): - current_filter = ('uninstalled', None) - if state_list[line][0] == _('Orphans'): - current_filter = ('orphans', None) - if state_list[line][0] == _('To install'): - current_filter = ('to_install', None) - if state_list[line][0] == _('To remove'): - current_filter = ('to_remove', None) - set_packages_list() - - def on_repos_treeview_selection_changed(self, widget): - if not repos_list_clearing: - liste, line = repos_selection.get_selected() - if line: - global current_filter - if repos_list[line][0] == _('local'): - current_filter = ('local', None) - else: - current_filter = ('repo', repos_list[line][0]) - set_packages_list() - - def on_list_treeview_row_activated(self, treeview, treeiter, column): - if not packages_list[treeiter][0] in config.holdpkg: - if packages_list[treeiter][1] is True: - if packages_list[treeiter][0] in transaction.to_add: - packages_list[treeiter][2] = installed_icon - transaction.to_add.discard(packages_list[treeiter][0]) - elif packages_list[treeiter][0] in transaction.to_remove: - packages_list[treeiter][2] = installed_icon - transaction.to_remove.discard(packages_list[treeiter][0]) - else: - packages_list[treeiter][2] = to_remove_icon - transaction.to_remove.add(packages_list[treeiter][0]) - if packages_list[treeiter][1] is False: - if packages_list[treeiter][0] in transaction.to_add: - packages_list[treeiter][2] = uninstalled_icon - transaction.to_add.discard(packages_list[treeiter][0]) - else: - packages_list[treeiter][2] = to_install_icon - transaction.to_add.add(packages_list[treeiter][0]) - - def on_cellrenderertoggle2_toggled(self, widget, line): - choose_list[line][0] = not choose_list[line][0] - - def on_ChooseButton_clicked(self, *arg): - ChooseDialog.hide() - line = 0 - transaction.to_provide.clear() - while line < len(choose_list): - if choose_list[line][0] is True: - if not choose_list[line][1] in transaction.localpkgs.keys(): - transaction.to_provide.add(choose_list[line][1]) - if choose_list[line][0] is False: - transaction.to_provide.discard(choose_list[line][1]) - line += 1 - - def on_ProgressCancelButton_clicked(self, *arg): - print('cancelled') - if not _('Refreshing') in progress_label.get_text(): - error = transaction.Interrupt() - if error: - handle_error(error) - else: - handle_reply('') - - def on_notebook1_switch_page(self, notebook, page, page_num): - if page_num == 0: - liste, line = search_selection.get_selected() - if line: - self.on_search_treeview_selection_changed(self) - elif search_entry.get_text(): - self.on_search_entry_activate(self) - elif page_num == 1: - self.on_groups_treeview_selection_changed(self) - elif page_num == 2: - self.on_state_treeview_selection_changed(self) - elif page_num == 3: - self.on_repos_treeview_selection_changed(self) - - #Updater Handlers - def on_UpdaterWindow_delete_event(self, *arg): - transaction.StopDaemon() - Gtk.main_quit() - - def on_Updater_QuitButton_clicked(self, *arg): - transaction.StopDaemon() - Gtk.main_quit() - - def on_Updater_ApplyButton_clicked(self, *arg): - do_sysupgrade() - - def on_Updater_RefreshButton_clicked(self, *arg): - do_refresh() - -def config_signals(): - global transaction - from pamac import transaction - bus = dbus.SystemBus() - 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") - bus.add_signal_receiver(target_signal_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitTarget") - bus.add_signal_receiver(percent_signal_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitPercent") - bus.add_signal_receiver(handle_reply, dbus_interface = "org.manjaro.pamac", signal_name = "EmitTransactionDone") - bus.add_signal_receiver(handle_error, dbus_interface = "org.manjaro.pamac", signal_name = "EmitTransactionError") - bus.add_signal_receiver(log_error, dbus_interface = "org.manjaro.pamac", signal_name = "EmitLogError") - bus.add_signal_receiver(log_warning, dbus_interface = "org.manjaro.pamac", signal_name = "EmitLogWarning") - -def main(_mode): - if common.pid_file_exists(): - ErrorDialog.format_secondary_text(_('Pamac is already running')) - response = ErrorDialog.run() - if response: - ErrorDialog.hide() - else: - config_signals() - global mode - mode = _mode - interface.connect_signals(Handler()) - do_refresh() - global Window - if mode == 'manager': - ManagerWindow = interface.get_object("ManagerWindow") - global details_list - global deps_list - global files_list - global files_scrolledwindow - global name_label - global desc_label - global link_label - global licenses_label - global search_entry - global search_list - global search_selection - global packages_list - global list_selection - global groups_list - global groups_selection - global state_list - global state_selection - global repos_list - global repos_selection - details_list = interface.get_object('details_list') - deps_list = interface.get_object('deps_list') - files_list = interface.get_object('files_list') - files_scrolledwindow = interface.get_object('files_scrolledwindow') - name_label = interface.get_object('name_label') - desc_label = interface.get_object('desc_label') - link_label = interface.get_object('link_label') - licenses_label = interface.get_object('licenses_label') - search_entry = interface.get_object('search_entry') - search_list = interface.get_object('search_list') - search_selection = interface.get_object('search_treeview_selection') - packages_list = interface.get_object('packages_list') - list_selection = interface.get_object('list_treeview_selection') - groups_list = interface.get_object('groups_list') - groups_selection = interface.get_object('groups_treeview_selection') - state_list = interface.get_object('state_list') - state_selection = interface.get_object('state_treeview_selection') - repos_list = interface.get_object('repos_list') - repos_selection = interface.get_object('repos_treeview_selection') - global installed_icon - global uninstalled_icon - global to_install_icon - global to_reinstall_icon - global to_remove_icon - global locked_icon - installed_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-installed-updated.png') - uninstalled_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-available.png') - to_install_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-install.png') - to_reinstall_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-reinstall.png') - to_remove_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-remove.png') - locked_icon = Pixbuf.new_from_file('/usr/share/pamac/icons/16x16/actions/package-installed-locked.png') - global pkg_name_list - pkg_name_list = set() - global current_filter - current_filter = (None, None) - global packages_list_clearing - global repos_list_clearing - global groups_list_clearing - packages_list_clearing = False - repos_list_clearing = False - groups_list_clearing = False - global states - states = [_('Installed'), _('Uninstalled'), _('Orphans'), _('To install'), _('To remove')] - for state in states: - state_list.append([state]) - Window = ManagerWindow - if mode == 'updater': - UpdaterWindow = interface.get_object("UpdaterWindow") - global update_listore - global update_top_label - global update_bottom_label - update_listore = interface.get_object('update_list') - update_top_label = interface.get_object('update_top_label') - update_bottom_label = interface.get_object('update_bottom_label') - update_top_label.set_markup(_('Your system is up-to-date')) - update_bottom_label.set_markup('') - Window = UpdaterWindow - Window.show_all() - while Gtk.events_pending(): - Gtk.main_iteration() - Gtk.main() diff --git a/pamac/transaction.py b/pamac/transaction.py index 326e302..25930af 100644 --- a/pamac/transaction.py +++ b/pamac/transaction.py @@ -2,97 +2,787 @@ # -*- coding:utf-8 -*- import pyalpm -from collections import OrderedDict -import dbus -from dbus.mainloop.glib import DBusGMainLoop +from gi.repository import Gtk from pamac import config, common -to_remove = set() -to_add = set() -to_load = set() -to_update = set() -to_provide = set() -handle = None -syncpkgs = OrderedDict() -localpkgs = OrderedDict() +# i18n +import gettext +import locale +locale.bindtextdomain('pamac', '/usr/share/locale') +gettext.bindtextdomain('pamac', '/usr/share/locale') +gettext.textdomain('pamac') +_ = gettext.gettext -def get_handle(): - global handle - handle = config.handle() - print('get handle') +interface = Gtk.Builder() +interface.set_translation_domain('pamac') -def update_db(): - #get_handle() - global syncpkgs - global localpkgs - syncpkgs = OrderedDict() - localpkgs = OrderedDict() - if handle: - for repo in handle.get_syncdbs(): - for pkg in repo.pkgcache: - if not pkg.name in syncpkgs.keys(): - syncpkgs[pkg.name] = pkg - for pkg in handle.get_localdb().pkgcache: - if not pkg.name in localpkgs.keys(): - localpkgs[pkg.name] = pkg +interface.add_from_file('/usr/share/pamac/gui/dialogs.ui') +ErrorDialog = interface.get_object('ErrorDialog') +WarningDialog = interface.get_object('WarningDialog') +InfoDialog = interface.get_object('InfoDialog') +#QuestionDialog = interface.get_object('QuestionDialog') +ConfDialog = interface.get_object('ConfDialog') +transaction_sum = interface.get_object('transaction_sum') +sum_top_label = interface.get_object('sum_top_label') +sum_bottom_label = interface.get_object('sum_bottom_label') +ChooseDialog = interface.get_object('ChooseDialog') +choose_list = interface.get_object('choose_list') +choose_label = interface.get_object('choose_label') +choose_renderertoggle = interface.get_object('choose_renderertoggle') +ProgressWindow = interface.get_object('ProgressWindow') +progress_bar = interface.get_object('progressbar2') +progress_label = interface.get_object('progresslabel2') +action_icon = interface.get_object('action_icon') +ProgressCancelButton = interface.get_object('ProgressCancelButton') +ProgressCloseButton = interface.get_object('ProgressCloseButton') +progress_textview = interface.get_object('progress_textview') +progress_expander = interface.get_object('progress_expander') -DBusGMainLoop(set_as_default = True) -bus = dbus.SystemBus() -proxy = bus.get_object('org.manjaro.pamac','/org/manjaro/pamac', introspect = False) -Refresh = proxy.get_dbus_method('Refresh','org.manjaro.pamac') -Init = proxy.get_dbus_method('Init','org.manjaro.pamac') -Sysupgrade = proxy.get_dbus_method('Sysupgrade','org.manjaro.pamac') -Remove = proxy.get_dbus_method('Remove','org.manjaro.pamac') -Add = proxy.get_dbus_method('Add','org.manjaro.pamac') -Load = proxy.get_dbus_method('Load','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') -Interrupt = proxy.get_dbus_method('Interrupt','org.manjaro.pamac') -Release = proxy.get_dbus_method('Release','org.manjaro.pamac') -StopDaemon = proxy.get_dbus_method('StopDaemon','org.manjaro.pamac') +progress_buffer = progress_textview.get_buffer() +choose_only_one = False -def init_transaction(**options): - error = Init(dbus.Dictionary(options, signature='sb')) - if not error: - return True - else: - return False +def choose_provides(data): + global choose_only_one + choose_only_one = True + providers = data[0] + dep_to_provide = data[1] + choose_label.set_markup(_('{pkgname} is provided by {number} packages.\nPlease choose the one you want to install:').format(pkgname = dep_to_provide, number = str(len(providers)))) + choose_list.clear() + choose_renderertoggle.set_radio(True) + for pkg in providers: + choose_list.append([False, pkg.name]) + ChooseDialog.run() + index = 0 + if to_provide: + for pkg in providers: + if to_provide[0] == pkg.name: + index = providers.index(pkg) + return index -def get_updates(): - """Return a list of package objects in local db which can be updated""" - do_syncfirst = False - list_first = [] - _ignorepkgs = [] - update_db() - if handle: - for group in handle.ignoregrps: - db = handle.get_localdb() - grp = db.read_grp(group) - if grp: - name, pkg_list = grp - for pkg in pkg_list: - if not pkg.name in _ignorepkgs: - _ignorepkgs.append(pkg.name) - for pkgname in handle.ignorepkgs: - if pkgname in localpkgs.keys(): - if not pkgname in _ignorepkgs: - _ignorepkgs.append(pkgname) - if config.syncfirst: - for name in config.syncfirst: - if name in localpkgs.keys(): - candidate = pyalpm.sync_newversion(localpkgs[name], handle.get_syncdbs()) - if candidate: - list_first.append(candidate) - if list_first: - do_syncfirst = True - return do_syncfirst, list_first - result = [] - for pkg in localpkgs.values(): - candidate = pyalpm.sync_newversion(pkg, handle.get_syncdbs()) - if candidate: - if not candidate.name in _ignorepkgs: - result.append(candidate) - return do_syncfirst, result +def on_choose_renderertoggle_toggled(widget, line): + global choose_only_one + choose_list[line][0] = not choose_list[line][0] + if choose_only_one: + for row in choose_list: + if not row[1] == choose_list[line][1]: + row[0] = False + +def on_ChooseButton_clicked(*arg): + ChooseDialog.hide() + line = 0 + to_provide.clear() + while line < len(choose_list): + if choose_list[line][0] is True: + to_provide.append(choose_list[line][1]) + line += 1 + +def on_progress_textview_size_allocate(*arg): + #auto-scrolling method + adj = progress_textview.get_vadjustment() + adj.set_value(adj.get_upper() - adj.get_page_size()) + +#~ 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 + +#~ def sort_pkgs_list(self, pkgs_list): + #~ result = [] + #~ names_list = sorted([pkg.name for pkg in pkgs_list]) + #~ for name in names_list: + #~ for pkg in pkgs_list: + #~ if name == pkg.name: + #~ result.append(pkg) + #~ return result + +def remove_pkg_from_list(pkg, pkgs_list): + if pkgs_list: + for _pkg in pkgs_list: + if (pkg.name == _pkg.name and pkg.version == _pkg.version and pkg.arch == _pkg.arch): + target = _pkg + pkgs_list.remove(_pkg) + +def pkg_in_list(pkg, pkgs_list): + result = False + if pkgs_list: + for _pkg in pkgs_list: + if (pkg.name == _pkg.name and pkg.version == _pkg.version and pkg.arch == _pkg.arch): + result = True + return result + +class Transaction(): + def __init__(self): + self.t = None + self.to_remove = [] + self.to_add = [] + self.to_load = [] + self.to_provide = [] + self.error = '' + self.warning = '' + self.previous_action = '' + self.previous_action_long = '' + self.previous_icon = '' + self.previous_target = '' + self.previous_percent = 0 + self.total_size = 0 + self.already_transferred = 0 + self.handle = config.handle() + self.syncdbs = self.handle.get_syncdbs() + self.localdb = self.handle.get_localdb() + self.handle.dlcb = self.cb_dl + self.handle.totaldlcb = self.totaldlcb + self.handle.eventcb = self.cb_event + self.handle.questioncb = self.cb_question + self.handle.progresscb = self.cb_progress + self.handle.logcb = self.cb_log + + def update_dbs(self): + self.handle = config.handle() + self.syncdbs = self.handle.get_syncdbs() + self.localdb = self.handle.get_localdb() + self.handle.dlcb = self.cb_dl + self.handle.totaldlcb = self.totaldlcb + self.handle.eventcb = self.cb_event + self.handle.questioncb = self.cb_question + self.handle.progresscb = self.cb_progress + self.handle.logcb = self.cb_log + + def get_localpkg(self, name): + return self.localdb.get_pkg(name) + + def get_syncpkg(self, name): + for repo in self.syncdbs: + pkg = repo.get_pkg(name) + if pkg: + return pkg + + def cb_event(self, event, tupel): + global progress_buffer + action = self.previous_action + action_long = self.previous_action_long + icon = self.previous_icon + if event == 'ALPM_EVENT_CHECKDEPS_START': + action = _('Checking dependencies')+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-search.png' + elif event == 'ALPM_EVENT_CHECKDEPS_DONE': + if self.warning: + self.handle_warning(self.warning) + self.warning = '' + elif event == 'ALPM_EVENT_FILECONFLICTS_START': + action = _('Checking file conflicts')+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-search.png' + elif event == 'ALPM_EVENT_FILECONFLICTS_DONE': + pass + elif event == 'ALPM_EVENT_RESOLVEDEPS_START': + action = _('Resolving dependencies')+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-setup.png' + elif event == 'ALPM_EVENT_RESOLVEDEPS_DONE': + pass + elif event == 'ALPM_EVENT_INTERCONFLICTS_START': + action = _('Checking inter conflicts')+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-search.png' + elif event == 'ALPM_EVENT_INTERCONFLICTS_DONE': + if self.warning: + self.handle_warning(self.warning) + self.warning = '' + elif event == 'ALPM_EVENT_ADD_START': + string = _('Installing {pkgname}').format(pkgname = tupel[0].name) + action = string+'...' + action_long = '{} ({})\n'.format(string, tupel[0].version) + icon = '/usr/share/pamac/icons/24x24/status/package-add.png' + ProgressCancelButton.set_visible(False) + elif event == 'ALPM_EVENT_ADD_DONE': + formatted_event = 'Installed {pkgname} ({pkgversion})'.format(pkgname = tupel[0].name, pkgversion = tupel[0].version) + common.write_log_file(formatted_event) + elif event == 'ALPM_EVENT_REMOVE_START': + string = _('Removing {pkgname}').format(pkgname = tupel[0].name) + action = string+'...' + action_long = '{} ({})\n'.format(string, tupel[0].version) + icon = '/usr/share/pamac/icons/24x24/status/package-delete.png' + ProgressCancelButton.set_visible(False) + elif event == 'ALPM_EVENT_REMOVE_DONE': + formatted_event = 'Removed {pkgname} ({pkgversion})'.format(pkgname = tupel[0].name, pkgversion = tupel[0].version) + common.write_log_file(formatted_event) + elif event == 'ALPM_EVENT_UPGRADE_START': + string = _('Upgrading {pkgname}').format(pkgname = tupel[1].name) + action = string+'...' + action_long = '{} ({} -> {})\n'.format(string, tupel[1].version, tupel[0].version) + icon = '/usr/share/pamac/icons/24x24/status/package-update.png' + ProgressCancelButton.set_visible(False) + elif event == 'ALPM_EVENT_UPGRADE_DONE': + formatted_event = 'Upgraded {pkgname} ({oldversion} -> {newversion})'.format(pkgname = tupel[1].name, oldversion = tupel[1].version, newversion = tupel[0].version) + common.write_log_file(formatted_event) + elif event == 'ALPM_EVENT_DOWNGRADE_START': + string = _('Downgrading {pkgname}').format(pkgname = tupel[1].name) + action = string+'...' + action_long = '{} ({} -> {})'.format(string, tupel[1].version, tupel[0].version) + icon = '/usr/share/pamac/icons/24x24/status/package-add.png' + ProgressCancelButton.set_visible(False) + elif event == 'ALPM_EVENT_DOWNGRADE_DONE': + formatted_event = 'Downgraded {pkgname} ({oldversion} -> {newversion})'.format(pkgname = tupel[1].name, oldversion = tupel[1].version, newversion = tupel[0].version) + common.write_log_file(formatted_event) + elif event == 'ALPM_EVENT_REINSTALL_START': + string = _('Reinstalling {pkgname}').format(pkgname = tupel[0].name) + action = string+'...' + action_long = '{} ({})'.format(string, tupel[0].version) + icon = '/usr/share/pamac/icons/24x24/status/package-add.png' + ProgressCancelButton.set_visible(False) + elif event == 'ALPM_EVENT_REINSTALL_DONE': + formatted_event = 'Reinstalled {pkgname} ({pkgversion})'.format(pkgname = tupel[0].name, pkgversion = tupel[0].version) + common.write_log_file(formatted_event) + elif event == 'ALPM_EVENT_INTEGRITY_START': + action = _('Checking integrity')+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-search.png' + self.already_transferred = 0 + elif event == 'ALPM_EVENT_INTEGRITY_DONE': + pass + elif event == 'ALPM_EVENT_LOAD_START': + action = _('Loading packages files')+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-search.png' + elif event == 'ALPM_EVENT_LOAD_DONE': + pass + elif event == 'ALPM_EVENT_DELTA_INTEGRITY_START': + action = _('Checking delta integrity')+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-search.png' + elif event == 'ALPM_EVENT_DELTA_INTEGRITY_DONE': + pass + elif event == 'ALPM_EVENT_DELTA_PATCHES_START': + action = _('Applying deltas')+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-setup.png' + elif event == 'ALPM_EVENT_DELTA_PATCHES_DONE': + pass + elif event == 'ALPM_EVENT_DELTA_PATCH_START': + action = _('Generating {} with {}').format(tupel[0], tupel[1])+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-setup.png' + elif event == 'ALPM_EVENT_DELTA_PATCH_DONE': + action = _('Generation succeeded!') + action_long = action+'\n' + elif event == 'ALPM_EVENT_DELTA_PATCH_FAILED': + action = _('Generation failed.') + action_long = action+'\n' + elif event == 'ALPM_EVENT_SCRIPTLET_INFO': + action =_('Configuring {pkgname}').format(pkgname = self.previous_target)+'...' + action_long = tupel[0] + icon = '/usr/share/pamac/icons/24x24/status/package-setup.png' + progress_bar.pulse() + progress_expander.set_expanded(True) + elif event == 'ALPM_EVENT_RETRIEVE_START': + # handled by download callback + ProgressCancelButton.set_visible(True) + elif event == 'ALPM_EVENT_DISKSPACE_START': + action = _('Checking available disk space')+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-search.png' + elif event == 'ALPM_EVENT_OPTDEP_REQUIRED': + print('Optionnal deps exist') + elif event == 'ALPM_EVENT_DATABASE_MISSING': + #action =_('Database file for {} does not exist').format(tupel[0])+'...' + #action_long = action + pass + elif event == 'ALPM_EVENT_KEYRING_START': + action = _('Checking keyring')+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-search.png' + ProgressCancelButton.set_visible(True) + elif event == 'ALPM_EVENT_KEYRING_DONE': + pass + elif event == 'ALPM_EVENT_KEY_DOWNLOAD_START': + action = _('Downloading required keys')+'...' + action_long = action+'\n' + elif event == 'ALPM_EVENT_KEY_DOWNLOAD_DONE': + pass + if action != self.previous_action: + self.previous_action = action + progress_label.set_text(action) + if action_long != self.previous_action_long: + self.previous_action_long != action_long + end_iter = progress_buffer.get_end_iter() + progress_buffer.insert(end_iter, action_long) + if icon != self.previous_icon: + self.previous_icon = icon + action_icon.set_from_file(icon) + while Gtk.events_pending(): + Gtk.main_iteration() + print(event) + + def cb_question(self, event, data_tupel, extra_data): + print('question', event, data_tupel, extra_data) + if event == 'ALPM_QUESTION_INSTALL_IGNOREPKG': + return 0 #Do not install package in IgnorePkg/IgnoreGroup + if event == 'ALPM_QUESTION_REPLACE_PKG': + self.warning += _('{pkgname1} will replace by {pkgname2}\n').format(pkgname1 = data_tupel[0].name, pkgname2 = data_tupel[1].name) + return 1 #Auto-remove conflicts in case of replaces + if event == 'ALPM_QUESTION_CONFLICT_PKG': + self.warning += _('{pkgname1} conflicts with {pkgname2}\n').format(pkgname1 = data_tupel[0], pkgname2 = data_tupel[1]) + return 1 #Auto-remove conflicts + if event == 'ALPM_QUESTION_CORRUPTED_PKG': + return 1 #Auto-remove corrupted pkgs in cache + if event == 'ALPM_QUESTION_REMOVE_PKGS': + return 1 #Do not upgrade packages which have unresolvable dependencies + if event == 'ALPM_QUESTION_SELECT_PROVIDER': + return choose_provides(data_tupel) + if event == 'ALPM_QUESTION_IMPORT_KEY': + # data_tupel = (revoked(int), length(int), pubkey_algo(string), fingerprint(string), uid(string), created_time(int)) + if data_tupel[0] is 0: # not revoked + return 1 #Auto import not revoked key + if data_tupel[0] is 1: # revoked + return 0 #Do not import revoked key + + def cb_log(self, level, line): + global progress_buffer + _logmask = pyalpm.LOG_ERROR | pyalpm.LOG_WARNING + if not (level & _logmask): + return + if level & pyalpm.LOG_ERROR: + self.error += line + _error = "ERROR: "+line + end_iter = progress_buffer.get_end_iter() + progress_buffer.insert(end_iter, _error) + progress_expander.set_expanded(True) + while Gtk.events_pending(): + Gtk.main_iteration() + print(line) + elif level & pyalpm.LOG_WARNING: + self.warning += line + _warning = "WARNING: "+line + end_iter = progress_buffer.get_end_iter() + progress_buffer.insert(end_iter, _warning) + while Gtk.events_pending(): + Gtk.main_iteration() + elif level & pyalpm.LOG_DEBUG: + line = "DEBUG: " + line + print(line) + elif level & pyalpm.LOG_FUNCTION: + line = "FUNC: " + line + print(line) + + def totaldlcb(self, _total_size): + self.total_size = _total_size + + def cb_dl(self, _target, _transferred, _total): + global progress_buffer + if _target.endswith('.db'): + action = _('Refreshing {repo}').format(repo = _target.rstrip('.db'))+'...' + action_long = '' + icon = '/usr/share/pamac/icons/24x24/status/refresh-cache.png' + else: + action = _('Downloading {pkgname}').format(pkgname = _target.rstrip('.pkg.tar.xz'))+'...' + action_long = action+'\n' + icon = '/usr/share/pamac/icons/24x24/status/package-download.png' + if self.total_size > 0: + percent = round((_transferred+self.already_transferred)/self.total_size, 2) + #~ target = '{transferred}/{size}'.format(transferred = common.format_size(_transferred+self.already_transferred), size = common.format_size(self.total_size)) + else: + percent = round(_transferred/_total, 2) + #~ percent = 2.0 + #~ target = '' + if action != self.previous_action: + self.previous_action = action + progress_label.set_text(action) + if action_long != self.previous_action_long: + self.previous_action_long = action_long + end_iter = progress_buffer.get_end_iter() + progress_buffer.insert(end_iter, action_long) + if icon != self.previous_icon: + self.previous_icon = icon + action_icon.set_from_file(icon) + #~ if target != self.previous_target: + #~ self.previous_target = target + #~ progress_bar.set_text(target) + #~ if percent == 2.0: + #~ progress_bar.pulse() + elif percent != self.previous_percent: + self.previous_percent = percent + if 0 <= percent <= 1: + progress_bar.set_fraction(percent) + else: + progress_bar.pulse() + elif _transferred == _total: + self.already_transferred += _total + #~ if self.already_transferred == self.total_size: + #~ progress_bar.set_text('') + while Gtk.events_pending(): + Gtk.main_iteration() + + def cb_progress(self, event, target, _percent, n, i): + if event in ('ALPM_PROGRESS_ADD_START', 'ALPM_PROGRESS_UPGRADE_START', 'ALPM_PROGRESS_DOWNGRADE_START', 'ALPM_PROGRESS_REINSTALL_START', 'ALPM_PROGRESS_REMOVE_START'): + percent = round(((i-1)/n)+(_percent/(100*n)), 2) + else: + percent = round(_percent/100, 2) + if target != self.previous_target: + self.previous_target = target.format() + if percent != self.previous_percent: + progress_bar.set_text('{}/{}'.format(str(i), str(n))) + self.previous_percent = percent + if 0 <= percent <= 1: + progress_bar.set_fraction(percent) + else: + progress_bar.pulse() + while Gtk.events_pending(): + Gtk.main_iteration() + + def refresh(self, force_update): + progress_label.set_text(_('Refreshing')+'...') + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/refresh-cache.png') + progress_bar.set_text('') + progress_bar.set_fraction(0) + ProgressCloseButton.set_visible(False) + ProgressCancelButton.set_visible(True) + ProgressWindow.show() + while Gtk.events_pending(): + Gtk.main_iteration() + self.error = '' + for db in self.syncdbs: + try: + self.t = self.handle.init_transaction() + db.update(force = force_update) + self.t.release() + except pyalpm.error as e: + self.release() + self.error += str(e)+'\n' + break + self.update_dbs() + ProgressWindow.hide() + if self.error: + self.handle_error(self.error) + + def get_updates(self): + do_syncfirst = False + list_first = set() + _ignorepkgs = set() + if self.handle: + for group in self.handle.ignoregrps: + db = self.handle.get_localdb() + grp = db.read_grp(group) + if grp: + name, pkg_list = grp + for pkg in pkg_list: + _ignorepkgs.add(pkg.name) + for name in self.handle.ignorepkgs: + if self.get_localpkg(name): + _ignorepkgs.add(name) + if config.syncfirst: + for name in config.syncfirst: + if self.get_localpkg(name): + candidate = pyalpm.sync_newversion(self.get_localpkg(name), self.syncdbs) + if candidate: + list_first.add(candidate) + if list_first: + do_syncfirst = True + return do_syncfirst, list_first + result = set() + for pkg in self.localdb.pkgcache: + candidate = pyalpm.sync_newversion(pkg, self.syncdbs) + if candidate: + if not candidate.name in _ignorepkgs: + result.add(candidate) + return do_syncfirst, result + + def init(self, **options): + self.error = '' + try: + self.t = self.handle.init_transaction(**options) + except pyalpm.error as e: + self.error += str(e)+'\n' + finally: + if self.error: + self.handle_error(self.error) + return False + else: + return True + + def sysupgrade(self, force_downgrade): + try: + self.t.sysupgrade(downgrade = force_downgrade) + except pyalpm.error as e: + self.error += str(e)+'\n' + self.t.release() + finally: + if self.error: + self.handle_error(self.error) + return False + else: + return True + + def remove(self, pkg): + try: + self.t.remove_pkg(pkg) + except pyalpm.error as e: + self.error += str(e)+'\n' + self.t.release() + finally: + if self.error: + self.handle_error(self.error) + return False + else: + return True + + def add(self, pkg): + try: + self.t.add_pkg(pkg) + except pyalpm.error as e: + # skip duplicate target error + if not 'pm_errno 25' in str(e): + self.error += str(e)+'\n' + self.t.release() + finally: + if self.error: + self.handle_error(self.error) + return False + else: + return True + + def load(self, tarball_path): + try: + pkg = self.handle.load_pkg(tarball_path) + if pkg: + self.t.add_pkg(pkg) + else: + self.error += _('{pkgname} is not a valid path or package name').format(pkgname = tarball_path) + except pyalpm.error as e: + # skip duplicate target error + if not 'pm_errno 25' in str(e): + self.error += str(e)+'\n' + self.t.release() + finally: + if self.error: + self.handle_error(self.error) + return False + else: + return True + + def prepare(self): + try: + self.t.prepare() + except pyalpm.error as e: + self.error += str(e)+'\n' + self.t.release() + else: + for pkg in self.t.to_remove: + if pkg.name in config.holdpkg: + self.error += _('The transaction cannot be performed because it needs to remove {pkgname1} which is a locked package').format(pkgname1 = pkg.name) + self.t.release() + break + finally: + if self.error: + self.handle_error(self.error) + return False + else: + return True + + def commit(self): + try: + self.t.commit() + except pyalpm.error as e: + self.error += str(e)+'\n' + else: + global progress_buffer + ProgressCloseButton.set_visible(True) + action_icon.set_from_icon_name('dialog-information', Gtk.IconSize.BUTTON) + progress_label.set_text(_('Transaction successfully finished')) + progress_bar.set_text('') + end_iter = progress_buffer.get_end_iter() + progress_buffer.insert(end_iter, _('Transaction successfully finished')) + finally: + self.release() + if self.warning: + self.handle_warning(self.warning) + self.warning = '' + if self.error: + self.handle_error(self.error) + + def interrupt(self): + try: + self.t.interrupt() + except: + pass + try: + self.t.release() + except: + pass + # Fix me, pyalpm don't stop so we inform and force quit to really interrupt the transaction + InfoDialog.format_secondary_text(_('The transaction was interrupted.\nNow Pamac will quit.')) + response = InfoDialog.run() + if response: + InfoDialog.hide() + common.rm_pid_file() + print('interrupted') + exit(0) + + def set_transaction_sum(self, show_updates): + transaction_sum.clear() + sum_top_label.set_markup(_('Transaction Summary')) + _to_remove = self.t.to_remove + _to_install = [] + _to_reinstall = [] + _to_downgrade = [] + _to_update = [] + dsize = 0 + for pkg in self.t.to_add: + dsize += pkg.download_size + installed = self.get_localpkg(pkg.name) + if not installed: + _to_install.append(pkg) + else: + comp = pyalpm.vercmp(pkg.version, installed.version) + if comp == 0: + _to_reinstall.append(pkg) + elif comp == -1: + _to_downgrade.append(pkg) + elif comp == 1: + _to_update.append(pkg) + if dsize == 0: + sum_bottom_label.set_markup('') + else: + sum_bottom_label.set_markup(_('Total download size: ')+common.format_size(dsize)) + i = 0 + while i < len(_to_remove): + pkg = _to_remove[i] + if i == 0: + transaction_sum.append([_('To remove')+':', pkg.name+' '+pkg.version]) + else: + transaction_sum.append(['', pkg.name+' '+pkg.version]) + i += 1 + i = 0 + while i < len(_to_install): + pkg = _to_install[i] + if i == 0: + transaction_sum.append([_('To install')+':', pkg.name+' '+pkg.version]) + else: + transaction_sum.append(['', pkg.name+' '+pkg.version]) + i += 1 + i = 0 + while i < len(_to_reinstall): + pkg = _to_reinstall[i] + if i == 0: + transaction_sum.append([_('To reinstall')+':', pkg.name+' '+pkg.version]) + else: + transaction_sum.append(['', pkg.name+' '+pkg.version]) + i += 1 + i = 0 + while i < len(_to_downgrade): + pkg = _to_downgrade[i] + if i == 0: + transaction_sum.append([_('To downgrade')+':', pkg.name+' '+pkg.version]) + else: + transaction_sum.append(['', pkg.name+' '+pkg.version]) + i += 1 + if show_updates: + i = 0 + while i < len(_to_update): + pkg = _to_update[i] + if i == 0: + transaction_sum.append([_('To update')+':', pkg.name+' '+pkg.version]) + else: + transaction_sum.append(['', pkg.name+' '+pkg.version]) + i += 1 + + def handle_error(self, error): + ProgressWindow.hide() + print(error) + ErrorDialog.format_secondary_text(error) + response = ErrorDialog.run() + if response: + ErrorDialog.hide() + + def handle_warning(self, warning): + WarningDialog.format_secondary_text(warning) + response = WarningDialog.run() + if response: + WarningDialog.hide() + + def do_sysupgrade(self, show_updates): + do_syncfirst, to_update = self.get_updates() + if to_update: + self.to_add.clear() + self.to_remove.clear() + self.error = '' + if do_syncfirst: + if self.init(recurse = True): + for pkg in to_update: + self.add(pkg) + if self.prepare(): + self.set_transaction_sum(show_updates) + if show_updates: + ConfDialog.show_all() + while Gtk.events_pending(): + Gtk.main_iteration() + else: + if len(transaction_sum) != 0: + ConfDialog.show_all() + while Gtk.events_pending(): + Gtk.main_iteration() + else: + self.finalize() + else: + if self.init(): + if self.sysupgrade(False): + if self.prepare(): + self.set_transaction_sum(show_updates) + if show_updates: + ConfDialog.show_all() + while Gtk.events_pending(): + Gtk.main_iteration() + else: + if len(transaction_sum) != 0: + ConfDialog.show_all() + while Gtk.events_pending(): + Gtk.main_iteration() + else: + self.finalize() + + def finalize(self): + global progress_buffer + progress_label.set_text(_('Preparing')+'...') + action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/package-setup.png') + progress_bar.set_text('') + progress_bar.set_fraction(0) + progress_buffer.delete(progress_buffer.get_start_iter(),progress_buffer.get_end_iter()) + ProgressCloseButton.set_visible(False) + ProgressWindow.show() + while Gtk.events_pending(): + Gtk.main_iteration() + self.commit() + self.to_add.clear() + self.to_remove.clear() + + def run(self): + if self.to_add or self.to_remove or self.to_load: + if self.init(cascade = True): + for pkg in self.to_add: + self.add(pkg) + for pkg in self.to_remove: + self.remove(pkg) + for path in self.to_load: + self.load(path) + if self.prepare(): + self.set_transaction_sum(True) + ConfDialog.show() + while Gtk.events_pending(): + Gtk.main_iteration() + else: + self.handle_warning(_('Nothing to do')) + + def release(self): + try: + self.t.release() + except: + pass diff --git a/setup.py b/setup.py index 67c08d0..5d1694d 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from distutils.core import setup setup(name='Pamac', - version='0.7', + version='0.8', description='A gtk3 frontend for pyalpm', license='GPL', author='Guillaume Benoit', diff --git a/start-pamac-daemon b/start-pamac-daemon deleted file mode 100755 index efe0c72..0000000 --- a/start-pamac-daemon +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh - -/usr/bin/pamac-daemon &