#! /usr/bin/python3 # -*- coding:utf-8 -*- import pyalpm import dbus from gi.repository import Gtk from dbus.mainloop.glib import DBusGMainLoop from pamac import config, common to_remove = set() to_add = set() to_update = set() to_load = set() handle = None syncdbs =None localdb = None # 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.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') progress_buffer = progress_textview.get_buffer() DBusGMainLoop(set_as_default = True) bus = dbus.SystemBus() def get_dbus_methods(): proxy = bus.get_object('org.manjaro.pamac','/org/manjaro/pamac', introspect = False) global Refresh global Init global Sysupgrade global Remove global Add global Load global Prepare global To_Remove global To_Add global Commit global Interrupt global Release global StopDaemon 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') def config_dbus_signals(): bus.add_signal_receiver(action_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitAction") bus.add_signal_receiver(action_long_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitActionLong") bus.add_signal_receiver(icon_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitIcon") bus.add_signal_receiver(target_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitTarget") bus.add_signal_receiver(percent_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitPercent") bus.add_signal_receiver(need_details_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitNeedDetails") bus.add_signal_receiver(download_start_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitDownloadStart") bus.add_signal_receiver(transaction_start_handler, dbus_interface = "org.manjaro.pamac", signal_name = "EmitTransactionStart") 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 action_handler(action): progress_label.set_text(action) def action_long_handler(action_long): global progress_buffer end_iter = progress_buffer.get_end_iter() progress_buffer.insert(end_iter, action_long) def need_details_handler(need): progress_expander.set_expanded(need) def icon_handler(icon): action_icon.set_from_file(icon) def target_handler(target): progress_bar.set_text(target) def percent_handler(percent): if percent > 1: progress_bar.pulse() else: progress_bar.set_fraction(percent) def transaction_start_handler(msg): ProgressCancelButton.set_visible(False) ProgressWindow.show() while Gtk.events_pending(): Gtk.main_iteration() def download_start_handler(msg): ProgressWindow.show() while Gtk.events_pending(): Gtk.main_iteration() 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 choose_provides(data): virtual_dep = str(data[1]) providers = data[0] choose_label.set_markup(_('{pkgname} is provided by {number} packages.\nPlease choose the one(s) you want to install:').format(pkgname = virtual_dep, number = str(len(providers)))) choose_list.clear() for name in providers: choose_list.append([False, str(name)]) lenght = len(to_add) ChooseDialog.run() if len(to_add) == lenght: # no choice was done by the user to_add.add(choose_list.get(choose_list.get_iter_first(), 1)[0]) # add first provider def on_choose_renderertoggle_toggled(widget, line): choose_list[line][0] = not choose_list[line][0] def on_ChooseButton_clicked(*arg): ChooseDialog.hide() while Gtk.events_pending(): Gtk.main_iteration() for row in choose_list: if row[0] is True: to_add.add(row[1].split(':')[0]) # split done in case of optdep choice 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 get_handle(): global handle handle = config.handle() print('get handle') def update_dbs(): global handle global syncdbs global localdb handle = config.handle() syncdbs = handle.get_syncdbs() localdb = handle.get_localdb() def get_localpkg(name): return localdb.get_pkg(name) def get_syncpkg(name): for repo in syncdbs: pkg = repo.get_pkg(name) if pkg: return pkg def refresh(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) ProgressCancelButton.set_visible(True) ProgressCloseButton.set_visible(False) while Gtk.events_pending(): Gtk.main_iteration() Refresh(force_update) def init_transaction(**options): return Init(dbus.Dictionary(options, signature='sb')) def run(): if to_add | to_remove | to_load: error = '' trans_flags = {'cascade' : True} error += init_transaction(**trans_flags) if not error: for name in to_add: error += Add(name) for name in to_remove: error += Remove(name) for path in to_load: error += Load(path) if not error: error += prepare(False, **trans_flags) if error: Release() return(error) else: return (_('Nothing to do')) def prepare(show_updates, **trans_flags): global to_add error = '' ret = Prepare() if ret[0][0]: # providers are emitted Release() for item in ret: choose_provides(item) error += init_transaction(**trans_flags) if not error: for name in to_add: error += Add(name) for name in to_remove: error += Remove(name) for path in to_load: error += Load(path) if not error: ret = Prepare() if ret[0][1]: error = str(ret[0][1]) elif ret[0][1]: # an error is emitted error = str(ret[0][1]) if not error: 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: finalize() return(error) def finalize(): 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()) ProgressCancelButton.set_visible(True) ProgressCloseButton.set_visible(False) #~ try: Commit() #~ except dbus.exceptions.DBusException as e: #~ handle_error(str(e)) while Gtk.events_pending(): Gtk.main_iteration() def get_updates(): do_syncfirst = False list_first = [] _ignorepkgs = set() if handle: for group in handle.ignoregrps: db = localdb grp = db.read_grp(group) if grp: name, pkg_list = grp for pkg in pkg_list: _ignorepkgs.add(pkg.name) for name in handle.ignorepkgs: if get_localpkg(name): _ignorepkgs.add(name) if config.syncfirst: for name in config.syncfirst: pkg = get_localpkg(name) if pkg: candidate = pyalpm.sync_newversion(pkg, syncdbs) if candidate: list_first.append(candidate) if list_first: do_syncfirst = True return do_syncfirst, list_first result = [] for pkg in localdb.pkgcache: candidate = pyalpm.sync_newversion(pkg, syncdbs) if candidate: if not candidate.name in _ignorepkgs: result.append(candidate) return do_syncfirst, result def get_transaction_sum(): transaction_dict = {'to_remove': [], 'to_install': [], 'to_update': [], 'to_reinstall': [], 'to_downgrade': []} to_remove = sorted(To_Remove()) for name, version in to_remove: transaction_dict['to_remove'].append(name+' '+version) others = sorted(To_Add()) for name, version, dsize in others: pkg = get_localpkg(name) if pkg: comp = pyalpm.vercmp(version, pkg.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(show_updates): 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 show_updates: 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 sysupgrade(show_updates): global to_update global to_add global to_remove do_syncfirst, updates = get_updates() if updates: to_update = set([pkg.name for pkg in updates]) to_add.clear() to_remove.clear() error = '' if do_syncfirst: error += init_transaction() if not error: for name in to_add: error += Add(name) else: error += init_transaction() if not error: error += Sysupgrade() if not error: error += prepare(show_updates) if error: Release() return error