diff --git a/data/dbus/org.manjaro.pamac.service b/data/dbus/org.manjaro.pamac.service index 66c27a6..1d8b045 100644 --- a/data/dbus/org.manjaro.pamac.service +++ b/data/dbus/org.manjaro.pamac.service @@ -1,5 +1,5 @@ [D-BUS Service] Name=org.manjaro.pamac -Exec=/usr/bin/python /usr/lib/python3.3/site-packages/pamac/pamac-daemon.py +Exec=/usr/bin/pamac-daemon User=root SystemdService=pamac.service diff --git a/data/networkmanager/99_update_pamac_tray b/data/networkmanager/99_update_pamac_tray index 0bb2e42..3d3fde6 100755 --- a/data/networkmanager/99_update_pamac_tray +++ b/data/networkmanager/99_update_pamac_tray @@ -5,6 +5,6 @@ STATUS=$2 # The new state of the interface case "$STATUS" in 'up') # $INTERFACE is up - pamac-check-updates + /usr/bin/pamac-check-updates ;; esac diff --git a/data/systemd/pamac.service b/data/systemd/pamac.service index b93f9be..536e633 100644 --- a/data/systemd/pamac.service +++ b/data/systemd/pamac.service @@ -4,4 +4,4 @@ Description=Pamac [Service] Type=dbus BusName=org.manjaro.pamac -ExecStart=/usr/bin/python /usr/lib/python3.3/site-packages/pamac/pamac-daemon.py +ExecStart=/usr/bin/pamac-daemon diff --git a/gui/manager.glade b/gui/manager.glade index d9e7d02..b755f45 100644 --- a/gui/manager.glade +++ b/gui/manager.glade @@ -10,6 +10,7 @@ dialog True True + False False diff --git a/pamac-daemon b/pamac-daemon new file mode 100755 index 0000000..0fa9710 --- /dev/null +++ b/pamac-daemon @@ -0,0 +1,335 @@ +#! /usr/bin/python +# -*-coding:utf-8-*- + +import dbus +import dbus.service +from dbus.mainloop.glib import DBusGMainLoop +from gi.repository import GObject + +import pyalpm +import traceback +from pamac import config, common + +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.error = '' + self.warning = '' + self.action = 'Preparing...' + self.icon = '/usr/share/pamac/icons/24x24/status/setup.png' + self.target = '' + self.percent = 0 + self.total_size = 0 + self.already_transferred = 0 + config.handle.dlcb = self.cb_dl + config.handle.totaldlcb = self.totaldlcb + config.handle.eventcb = self.cb_event + config.handle.questioncb = self.cb_conv + config.handle.progresscb = self.cb_progress + config.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 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/setup.png' + 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 {} ({})'.format(tupel[0].name, 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 {} ({})'.format(tupel[0].name, 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 {} ({} -> {})'.format(tupel[1].name, tupel[1].version, tupel[0].version) + common.write_log_file(formatted_event) + print(formatted_event) + elif ID is 15: + self.action = 'Checking integrity...' + self.icon = '/usr/share/pamac/icons/24x24/status/package-search.png' + self.already_transferred = 0 + elif ID is 17: + self.action = 'Loading packages files...' + self.icon = '/usr/share/pamac/icons/24x24/status/package-search.png' + print('Loading packages files') + elif ID is 26: + self.action = 'Configuring...' + self.icon = '/usr/share/pamac/icons/24x24/status/setup.png' + print('Configuring a package') + elif ID is 27: + print('Downloading a file') + else : + self.action = '' + self.EmitTarget('') + self.EmitPercent(str(0)) + self.EmitAction(self.action) + self.EmitIcon(self.icon) + print(ID,event) + + def cb_conv(self, *args): + print("conversation", args) + + def cb_log(self, level, line): + #global t + _logmask = pyalpm.LOG_ERROR | pyalpm.LOG_WARNING + if not (level & _logmask): + return + if level & pyalpm.LOG_ERROR: + self.error += "ERROR: "+line + print(self.error) + #t.release() + elif level & pyalpm.LOG_WARNING: + self.warning += "WARNING: "+line + 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): + if self.total_size > 0: + fraction = (_transferred+self.already_transferred)/self.total_size + size = 0 + if (t.to_remove or t.to_add): + for pkg in t.to_remove+t.to_add: + if pkg.name+'-'+pkg.version in _target: + size = pkg.size + if _transferred == size: + self.already_transferred += size + self.action = 'Downloading '+common.format_size(self.total_size) + self.target = _target + if fraction > 1: + self.percent = 0 + else: + self.percent = fraction + self.icon = '/usr/share/pamac/icons/24x24/status/package-download.png' + else: + self.action = 'Refreshing...' + self.target = _target + self.percent = 0 + self.icon = '/usr/share/pamac/icons/24x24/status/refresh-cache.png' + self.EmitAction(self.action) + self.EmitIcon(self.icon) + self.EmitTarget(self.target) + self.EmitPercent(str(self.percent)) + + def cb_progress(self, _target, _percent, n, i): + self.target = _target+' ('+str(i)+'/'+str(n)+')' + self.percent = _percent/100 + self.EmitTarget(self.target) + self.EmitPercent(str(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 = False + for pkg in config.handle.get_localdb().pkgcache: + candidate = pyalpm.sync_newversion(pkg, config.handle.get_syncdbs()) + if candidate: + updates = True + self.EmitAvailableUpdates(updates) + + @dbus.service.method('org.manjaro.pamac', '', 's') + def Refresh(self): + global t + self.error = '' + for db in config.handle.get_syncdbs(): + try: + t = config.handle.init_transaction() + db.update(force=False) + t.release() + except pyalpm.error as e: + self.error += ' --> '+str(e)+'\n' + t.release() + #break + self.CheckUpdates() + return self.error + + @dbus.service.method('org.manjaro.pamac', 'a{sb}', 's', sender_keyword='sender', connection_keyword='connexion') + def Init(self, options, sender=None, connexion=None): + global t + self.error = '' + if self.policykit_test(sender,connexion,'org.manjaro.pamac.init_release'): + try: + t = config.handle.init_transaction(**options) + print('Init:',t.flags) + except pyalpm.error as e: + self.error += ' --> '+str(e)+'\n' + finally: + return self.error + else : + return 'You are not authorized' + + @dbus.service.method('org.manjaro.pamac', '', 's') + def Sysupgrade(self): + global t + self.error = '' + try: + t.sysupgrade(downgrade=False) + print('to_upgrade:',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): + global t + self.error = '' + try: + pkg = config.handle.get_localdb().get_pkg(pkgname) + if pkg is not None: + 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): + global t + self.error = '' + try: + for repo in config.handle.get_syncdbs(): + pkg = repo.get_pkg(pkgname) + if pkg: + 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') + def Prepare(self): + global t + self.error = '' + try: + t.prepare() + print('to_add:',t.to_add) + print('to_remove:',t.to_remove) + except pyalpm.error as e: + print(e) + self.error += ' --> '+str(e)+'\n' + finally: + return self.error + + @dbus.service.method('org.manjaro.pamac', '', 'as') + def To_Remove(self): + global t + liste = [] + for pkg in t.to_remove: + liste.append(pkg.name) + return liste + + @dbus.service.method('org.manjaro.pamac', '', 'as') + def To_Add(self): + global t + liste = [] + for pkg in t.to_add: + liste.append(pkg.name) + return liste + + @dbus.service.method('org.manjaro.pamac', '', 's', sender_keyword='sender', connection_keyword='connexion')#, async_callbacks=('success', 'nosuccess')) + def Commit(self, sender=None, connexion=None):#success, nosuccess, sender=None, connexion=None): + global t + self.error = '' + if self.policykit_test(sender,connexion,'org.manjaro.pamac.commit'): + try: + t.commit() + #success('') + except pyalpm.error as e: + #error = traceback.format_exc() + self.error += ' --> '+str(e)+'\n' + #nosuccess(error) + #except dbus.exceptions.DBusException: + #pass + finally: + self.CheckUpdates() + return self.error + else : + return 'You are not authorized' + + @dbus.service.method('org.manjaro.pamac', '', 's', sender_keyword='sender', connection_keyword='connexion') + def Release(self, sender=None, connexion=None): + global t + self.error = '' + if self.policykit_test(sender,connexion,'org.manjaro.pamac.init_release'): + try: + t.release() + except pyalpm.error as e: + self.error += ' --> '+str(e)+'\n' + finally: + return self.error + else : + return 'You are not authorized' + + @dbus.service.method('org.manjaro.pamac') + def StopDaemon(self): + global t + try: + t.release() + except: + pass + mainloop.quit() + +DBusGMainLoop(set_as_default=True) +myservice = PamacDBusService() +mainloop = GObject.MainLoop() +mainloop.run() diff --git a/pamac/main.py b/pamac/main.py index b0a7ecf..44a6d4e 100644 --- a/pamac/main.py +++ b/pamac/main.py @@ -48,15 +48,15 @@ update_label = interface.get_object('update_label') installed_column.set_sort_column_id(1) name_column.set_sort_column_id(0) -transaction.get_handle() -tmp_list = [] -for repo in transaction.handle.get_syncdbs(): - for name, pkgs in repo.grpcache: - if not name in tmp_list: - tmp_list.append(name) -tmp_list = sorted(tmp_list) -for name in tmp_list: - groups_list.append([name]) +def get_groups(): + tmp_list = [] + for repo in transaction.handle.get_syncdbs(): + for name, pkgs in repo.grpcache: + if not name in tmp_list: + tmp_list.append(name) + tmp_list = sorted(tmp_list) + for name in tmp_list: + groups_list.append([name]) pkg_name_list = [] pkg_object_dict = {} @@ -210,6 +210,7 @@ def set_desc(pkg, style): def set_transaction_sum(): transaction_sum.clear() if transaction.to_remove: + transaction.to_remove = sorted(transaction.to_remove) transaction_sum.append(['To remove:', transaction.to_remove[0]]) i = 1 while i < len(transaction.to_remove): @@ -217,6 +218,7 @@ def set_transaction_sum(): i += 1 sum_bottom_label.set_markup('') if transaction.to_add: + transaction.to_add = sorted(transaction.to_add) installed = [] for pkg_object in config.pacman_conf.initialize_alpm().get_localdb().pkgcache: installed.append(pkg_object.name) @@ -245,9 +247,9 @@ def handle_error(error): global transaction_type global transaction_dict if error: - if not 'DBus.Error.NoReply' in str(error): + if not 'DBus.Error.NoReply' in error: print('error',error) - transaction.ErrorDialog.format_secondary_text('Error:\n'+str(error)) + transaction.ErrorDialog.format_secondary_text(error) response = transaction.ErrorDialog.run() if response: transaction.ErrorDialog.hide() @@ -260,6 +262,7 @@ def handle_error(error): transaction_dict.clear() transaction_type = None transaction.update_db() + get_groups() set_packages_list() if mode == 'updater': have_updates() @@ -269,7 +272,7 @@ def handle_reply(reply): global transaction_type global transaction_dict if reply: - transaction.ErrorDialog.format_secondary_text('Error:\n'+str(reply)) + transaction.ErrorDialog.format_secondary_text(reply) response = transaction.ErrorDialog.run() if response: transaction.ErrorDialog.hide() @@ -280,6 +283,7 @@ def handle_reply(reply): transaction.to_remove = [] transaction_dict.clear() transaction.update_db() + get_groups() if (transaction_type == "install") or (transaction_type == "remove"): transaction_type = None set_packages_list() @@ -384,6 +388,7 @@ def finalize(): def check_conflicts(pkg_list): depends = [pkg_list] warning = '' + error = '' pkgs = transaction.handle.get_localdb().search('linux3') installed_linux = [] for i in pkgs: @@ -442,12 +447,19 @@ def check_conflicts(pkg_list): depends[i+1].append(_pkg) transaction.to_add.append(_pkg.name) else: - to_add_to_depends = choose_provides(depend) - print(to_add_to_depends) - for _pkg in to_add_to_depends: - if not _pkg.name in transaction.to_add: - depends[i+1].append(_pkg) - transaction.to_add.append(_pkg.name) + already_provided = False + for pkgname in transaction.to_add: + _pkg = transaction.syncpkgs[pkgname] + print('test',transaction.to_add) + provide = pyalpm.find_satisfier([_pkg], depend) + if provide: + already_provided = True + 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: + depends[i+1].append(_pkg) + transaction.to_add.append(_pkg.name) else: depends[i+1].append(provide) for replace in pkg.replaces: @@ -510,6 +522,20 @@ def check_conflicts(pkg_list): response = transaction.WarningDialog.run() if response: transaction.WarningDialog.hide() + for pkgname in transaction.to_remove: + pkg = transaction.localpkgs[pkgname] + required = pkg.compute_requiredby() + if required: + str_required = '' + for i in required: + if str_required: + str_required += ', ' + str_required += i + if error: + error = error+'\n' + error += 'Cannot remove {} because it is needed by {}'.format(pkgname, str_required) + if error: + handle_error(error) def choose_provides(name): provides = OrderedDict() diff --git a/start-pamac-daemon b/start-pamac-daemon index 5b835e1..efe0c72 100755 --- a/start-pamac-daemon +++ b/start-pamac-daemon @@ -1,3 +1,3 @@ #! /bin/sh -/usr/bin/python /usr/lib/python3.3/site-packages/pamac/pamac-daemon.py & +/usr/bin/pamac-daemon &