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
- 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
+
+
+
+
+
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 &