#! /usr/bin/python # -*-coding:utf-8 -*- from gi.repository import Gtk import pyalpm from time import strftime, localtime from pamac import config, common, transaction interface = Gtk.Builder() interface.add_from_file('/usr/share/pamac/gui/manager.glade') #interface.add_from_file('/usr/share/pamac/gui/dialogs.glade') MainWindow = interface.get_object("MainWindow") packages_list = interface.get_object('packages_list') groups_list = interface.get_object('groups_list') package_desc = interface.get_object('package_desc') toggle = interface.get_object('cellrenderertoggle1') search_entry = interface.get_object('search_entry') tree2 = interface.get_object('treeview2_selection') tree1 = interface.get_object('treeview1_selection') installed_column = interface.get_object('installed_column') name_column = interface.get_object('name_column') ConfDialog = interface.get_object('ConfDialog') transaction_sum = interface.get_object('transaction_sum') top_label = interface.get_object('top_label') bottom_label = interface.get_object('bottom_label') ChooseDialog = interface.get_object('ChooseDialog') choose_list = interface.get_object('choose_list') choose_label = interface.get_object('choose_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]) pkg_name_list = [] pkg_object_dict = {} pkg_installed_dict = {} list_dict = None current_group = None transaction_type = None transaction_dict = {} def set_list_dict_search(*patterns): global pkg_name_list global pkg_object_dict global pkg_installed_dict pkg_name_list = [] pkg_object_dict = {} pkg_installed_dict = {} for db in transaction.handle.get_syncdbs(): for pkg_object in db.search(*patterns): if not pkg_object.name in pkg_name_list: pkg_name_list.append(pkg_object.name) pkg_object_dict[pkg_object.name] = pkg_object pkg_installed_dict[pkg_object.name] = False for pkg_object in transaction.handle.get_localdb().search(*patterns): if not pkg_object.name in pkg_name_list: pkg_name_list.append(pkg_object.name) pkg_installed_dict[pkg_object.name] = True pkg_object_dict[pkg_object.name] = pkg_object pkg_name_list = sorted(pkg_name_list) def set_list_dict_group(group): global pkg_name_list global pkg_object_dict global pkg_installed_dict pkg_name_list = [] pkg_object_dict = {} pkg_installed_dict = {} for db in transaction.handle.get_syncdbs(): grp = db.read_grp(group) if grp is not None: name, pkg_list = grp for pkg_object in pkg_list: if not pkg_object.name in pkg_name_list: pkg_name_list.append(pkg_object.name) pkg_object_dict[pkg_object.name] = pkg_object pkg_installed_dict[pkg_object.name] = False db = config.pacman_conf.initialize_alpm().get_localdb() grp = db.read_grp(group) if grp is not None: name, pkg_list = grp for pkg_object in pkg_list: if not pkg_object.name in pkg_name_list: pkg_name_list.append(pkg_object.name) pkg_installed_dict[pkg_object.name] = True pkg_object_dict[pkg_object.name] = pkg_object pkg_name_list = sorted(pkg_name_list) def refresh_packages_list(): global packages_list packages_list.clear() if not pkg_name_list: packages_list.append(["No package found", False, False]) else: for name in pkg_name_list: if name in config.holdpkg: packages_list.append([name, pkg_installed_dict[name], False]) elif transaction_type is "install": if pkg_installed_dict[name] is True: packages_list.append([name, pkg_installed_dict[name], False]) elif name in transaction_dict.keys(): packages_list.append([name, True, True]) else: packages_list.append([name, pkg_installed_dict[name], True]) elif transaction_type is "remove": if pkg_installed_dict[name] is False: packages_list.append([name, pkg_installed_dict[name], False]) elif name in transaction_dict.keys(): packages_list.append([name, False, True]) else: packages_list.append([name, pkg_installed_dict[name], True]) else: packages_list.append([name, pkg_installed_dict[name], True]) def set_packages_list(): global list_dict transaction.get_handle() if list_dict == "search": search_strings_list = search_entry.get_text().split() set_list_dict_search(*search_strings_list) if list_dict == "group": set_list_dict_group(current_group) refresh_packages_list() def set_desc(pkg, style): """ Args : pkg_object -- the package to display style -- 'local' or 'sync' """ if style not in ['local', 'sync', 'file']: raise ValueError('Invalid style for package info formatting') package_desc.clear() if style == 'sync': package_desc.append(['Repository:', pkg.db.name]) package_desc.append(['Name:', pkg.name]) package_desc.append(['Version:', pkg.version]) package_desc.append(['Description:', pkg.desc]) package_desc.append(['URL:', pkg.url]) package_desc.append(['Licenses:', ' '.join(pkg.licenses)]) package_desc.append(['Groups:', ' '.join(pkg.groups)]) package_desc.append(['Provides:', ' '.join(pkg.provides)]) package_desc.append(['Depends On:', ' '.join(pkg.depends)]) package_desc.append(['Optional Deps:', '\n'.join(pkg.optdepends)]) if style == 'local': package_desc.append(['Required By:', ' '.join(pkg.compute_requiredby())]) package_desc.append(['Conflicts With:', ' '.join(pkg.conflicts)]) package_desc.append(['Replaces:', ' '.join(pkg.replaces)]) if style == 'sync': package_desc.append(['Download Size:', common.format_size(pkg.size)]) if style == 'file': package_desc.append(['Compressed Size:', common.format_size(pkg.size)]) package_desc.append(['Installed Size:', common.format_size(pkg.isize)]) package_desc.append(['Packager:', pkg.packager]) package_desc.append(['Architecture:', pkg.arch]) package_desc.append(['Build Date:', strftime("%a %d %b %Y %X %Z", localtime(pkg.builddate))]) if style == 'local': package_desc.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 = 'N/A' package_desc.append(['Install Reason:', reason]) if style != 'sync': package_desc.append(['Install Script:', 'Yes' if pkg.has_scriptlet else 'No']) if style == 'sync': package_desc.append(['MD5 Sum:', pkg.md5sum]) package_desc.append(['SHA256 Sum:', pkg.sha256sum]) package_desc.append(['Signatures:', 'Yes' if pkg.base64_sig else 'No']) if style == 'local': if len(pkg.backup) == 0: package_desc.append(['Backup files:', '']) else: package_desc.append(['Backup files:', '\n'.join(["%s %s" % (md5, file) for (file, md5) in pkg.backup])]) def set_transaction_sum(): transaction_sum.clear() if transaction.to_remove: transaction_sum.append(['To remove:', transaction.to_remove[0]]) i = 1 while i < len(transaction.to_remove): transaction_sum.append([' ', transaction.to_remove[i]]) i += 1 bottom_label.set_markup('') if transaction.to_add: installed = [] for pkg_object in config.pacman_conf.initialize_alpm().get_localdb().pkgcache: installed.append(pkg_object.name) transaction.to_update = sorted(set(installed).intersection(transaction.to_add)) to_remove_from_add = sorted(set(transaction.to_update).intersection(transaction.to_add)) for name in to_remove_from_add: transaction.to_add.remove(name) if transaction.to_add: transaction_sum.append(['To install:', transaction.to_add[0]]) i = 1 while i < len(transaction.to_add): transaction_sum.append([' ', transaction.to_add[i]]) i += 1 if transaction.to_update: transaction_sum.append(['To update:', transaction.to_update[0]]) i = 1 while i < len(transaction.to_update): transaction_sum.append([' ', transaction.to_update[i]]) i += 1 bottom_label.set_markup('') #bottom_label.set_markup('Total Download size: '+common.format_size(totaldlcb)) top_label.set_markup('Transaction Summary') def handle_error(error): global transaction_type global transaction_dict if not 'DBus.Error.NoReply' in str(error): transaction.ErrorDialog.format_secondary_text('Error:\n'+str(error)) response = transaction.ErrorDialog.run() if response: transaction.ErrorDialog.hide() transaction.t_lock = False transaction.Release() transaction.ProgressWindow.hide() transaction.to_add = [] transaction.to_remove = [] transaction_dict.clear() transaction_type = None set_packages_list() print('error',error) def handle_reply(reply): global transaction_type global transaction_dict if str(reply): transaction.ErrorDialog.format_secondary_text('Error:\n'+str(reply)) response = transaction.ErrorDialog.run() if response: transaction.ErrorDialog.hide() if transaction.do_syncfirst is True: transaction.do_syncfirst = False transaction.list_first = [] transaction.t_lock = False transaction.Release() transaction.ProgressWindow.hide() transaction.to_add = [] transaction.to_remove = [] transaction_dict.clear() if (transaction_type == "install") or (transaction_type == "remove"): transaction_type = None set_packages_list() else: transaction_type = None if transaction.get_updates(): do_sysupgrade() def do_refresh(): """Sync databases like pacman -Sy""" transaction.get_handle() if transaction.t_lock is False: transaction.t_lock = True transaction.progress_label.set_text('Refreshing...') transaction.action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/refresh-cache.png') transaction.ProgressWindow.show_all() while Gtk.events_pending(): Gtk.main_iteration() transaction.Refresh(reply_handler = handle_reply, error_handler = handle_error, timeout = 2000*1000) def do_sysupgrade(): global transaction_type """Upgrade a system like pacman -Su""" if transaction.t_lock is False: transaction_type = "update" if transaction.do_syncfirst is True: if transaction.init_transaction(recurse = True): for pkg in transaction.list_first: transaction.Add(pkg.name) transaction.get_to_remove() transaction.get_to_add() transaction.check_conflicts() transaction.Release() set_transaction_sum() ConfDialog.show_all() else: if transaction.init_transaction(): error = transaction.Sysupgrade() if error: handle_error(error) else: transaction.get_to_remove() transaction.get_to_add() transaction.check_conflicts() transaction.Release() if len(transaction.to_add) + len(transaction.to_update) + len(transaction.to_remove) != 0: set_transaction_sum() ConfDialog.show_all() else: transaction.Release() transaction.t_lock = False def choose_provides(): to_check = [] depends = [] provides = {} already_provided = False for pkgname in transaction.to_add: for repo in transaction.handle.get_syncdbs(): pkg = repo.get_pkg(pkgname) if pkg: to_check.append(pkg) break for target in to_check: for name in target.depends: depends.append(common.format_pkg_name(name)) for installed_pkg in transaction.handle.get_localdb().pkgcache: if installed_pkg.name in depends: depends.remove(installed_pkg.name) for repo in transaction.handle.get_syncdbs(): for pkg in repo.pkgcache: if pkg.name in depends: depends.remove(pkg.name) if depends: for repo in transaction.handle.get_syncdbs(): for pkg in repo.pkgcache: for depend in depends: for name in pkg.provides: if common.format_pkg_name(name) == depend: if not provides.__contains__(depend): provides[depend] = [] if not pkg.name in provides.get(depend): provides.get(depend).append(pkg.name) if provides: for virtualdep, liste in provides.items(): if ('-module' in virtualdep) or ('linux' in virtualdep): pkgs = transaction.handle.get_localdb().search('linux3') installed_linux = [] to_remove_from_add = [] for i in pkgs: if len(i.name) == 7: installed_linux.append(i.name) for to_install in transaction.to_add: if 'linux3' in to_install: if len(to_install) == 7: if to_install in transaction_dict.keys(): installed_linux.append(to_install) else: to_remove_from_add.append(to_install) for name in liste: if name == to_install: if not to_install in transaction_dict.keys(): to_remove_from_add.append(to_install) for to_remove in to_remove_from_add: transaction.to_add.remove(to_remove) for name in liste: for linux in installed_linux: if not transaction.handle.get_localdb().get_pkg(name): if linux in name: transaction.to_add.append(name) already_provided = True for installed_pkg in transaction.handle.get_localdb().pkgcache: for name in installed_pkg.provides: if common.format_pkg_name(name) == virtualdep: already_provided = True if already_provided: pass else: choose_label.set_markup('{} is provided by {} packages.\nPlease choose the one(s) you want to install:'.format(virtualdep,str(len(liste)))) choose_list.clear() for name in liste: if transaction.handle.get_localdb().get_pkg(name): choose_list.append([True, name]) else: choose_list.append([False, name]) ChooseDialog.run() class Handler: def on_MainWindow_delete_event(self, *arg): transaction.StopDaemon() if __name__ == "__main__": Gtk.main_quit() else: MainWindow.hide() def on_QuitButton_clicked(self, *arg): transaction.StopDaemon() if __name__ == "__main__": Gtk.main_quit() else: MainWindow.hide() def on_ValidButton_clicked(self, *arg): if not transaction_dict: transaction.ErrorDialog.format_secondary_text("No package is selected") response = transaction.ErrorDialog.run() if response: transaction.ErrorDialog.hide() else: if transaction.t_lock is True: print('Transaction locked') else: if transaction_type is "remove": if transaction.init_transaction(cascade = True): for pkgname in transaction_dict.keys(): transaction.Remove(pkgname) error = transaction.Prepare() if error: handle_error(error) else: transaction.get_to_remove() transaction.get_to_add() set_transaction_sum() ConfDialog.show_all() if transaction_type is "install": if transaction.init_transaction(noconflicts = True): for pkgname in transaction_dict.keys(): transaction.Add(pkgname) error = transaction.Prepare() if error: handle_error(error) else: transaction.get_to_remove() transaction.get_to_add() transaction.Release() choose_provides() transaction.check_conflicts() 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: transaction.get_to_remove() transaction.get_to_add() transaction.Release() if len(transaction.to_add) + len(transaction.to_remove) != 0: set_transaction_sum() ConfDialog.show_all() else: transaction.WarningDialog.format_secondary_text('Nothing to do due to packages conflicts') response = transaction.WarningDialog.run() if response: transaction.WarningDialog.hide() transaction.t_lock = False def on_EraseButton_clicked(self, *arg): global transaction_type global transaction_dict transaction_dict.clear() transaction_type = None refresh_packages_list() def on_RefreshButton_clicked(self, *arg): transaction.do_refresh() set_packages_list() def on_TransCancelButton_clicked(self, *arg): global transaction_type transaction.ProgressWindow.hide() ConfDialog.hide() transaction.t_lock = False transaction.Release() if transaction_type == "update": transaction_type = None def on_TransValidButton_clicked(self, *arg): ConfDialog.hide() transaction.progress_label.set_text('Preparing...') transaction.action_icon.set_from_file('/usr/share/pamac/icons/24x24/status/setup.png') transaction.progress_bar.set_text('') while Gtk.events_pending(): Gtk.main_iteration() if transaction_type == "remove": transaction.ProgressWindow.show_all() while Gtk.events_pending(): Gtk.main_iteration() transaction.Commit(reply_handler = handle_reply, error_handler = handle_error, timeout = 2000*1000) if (transaction_type == "install") or (transaction_type == "update"): if transaction.init_transaction(noconflicts = True, nodeps = True): for pkgname in transaction.to_update: transaction.Add(pkgname) 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: transaction.ProgressWindow.show_all() while Gtk.events_pending(): Gtk.main_iteration() transaction.Commit(reply_handler = handle_reply, error_handler = handle_error, timeout = 2000*1000) def on_search_button_clicked(self, widget): global list_dict list_dict = "search" set_packages_list() def on_search_entry_icon_press(self, *arg): global list_dict list_dict = "search" set_packages_list() def on_search_entry_activate(self, widget): global list_dict list_dict = "search" set_packages_list() def on_treeview2_selection_changed(self, widget): liste, line = tree2.get_selected() if line is not None: if packages_list[line][0] in pkg_object_dict.keys(): pkg_object = pkg_object_dict[packages_list[line][0]] if pkg_installed_dict[packages_list[line][0]] is True: style = "local" else: style = "sync" set_desc(pkg_object, style) def on_treeview1_selection_changed(self, widget): global list_dict global current_group liste, line = tree1.get_selected() if line is not None: list_dict = "group" current_group = groups_list[line][0] set_packages_list() def on_installed_column_clicked(self, widget): installed_column.set_sort_column_id(1) def on_name_column_clicked(self, widget): name_column.set_sort_column_id(0) def on_cellrenderertoggle1_toggled(self, widget, line): global transaction_type global transaction_dict global pkg_object_dict if packages_list[line][0] in transaction_dict.keys(): transaction_dict.pop(packages_list[line][0]) if not transaction_dict: transaction_type = None lin = 0 while lin < len(packages_list): if packages_list[lin][0] in config.holdpkg: packages_list[lin][2] = False else: packages_list[lin][2] = True lin += 1 pass else: if packages_list[line][1] is True: transaction_type = "remove" transaction_dict[packages_list[line][0]] = pkg_object_dict[packages_list[line][0]] lin = 0 while lin < len(packages_list): if not packages_list[lin][0] in transaction_dict.keys(): if packages_list[lin][1] is False: packages_list[lin][2] = False lin += 1 if packages_list[line][1] is False: transaction_type = "install" transaction_dict[packages_list[line][0]] = pkg_object_dict[packages_list[line][0]] lin = 0 while lin < len(packages_list): if not packages_list[lin][0] in transaction_dict.keys(): if packages_list[lin][1] is True: packages_list[lin][2] = False lin += 1 packages_list[line][1] = not packages_list[line][1] packages_list[line][2] = True 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 while line < len(choose_list): if choose_list[line][0] is True: if not choose_list[line][1] in transaction.to_add: if not transaction.handle.get_localdb().get_pkg(choose_list[line][1]): transaction.to_add.append(choose_list[line][1]) if choose_list[line][0] is False: if choose_list[line][1] in transaction.to_add: transaction.to_add.remove(choose_list[line][1]) line += 1 def main(): interface.connect_signals(Handler()) do_refresh() MainWindow.show_all() while Gtk.events_pending(): Gtk.main_iteration() if __name__ == "__main__": main() Gtk.main()