#!/usr/bin/env python # # main.py # Copyright (C) Yasumichi Akahoshi 2011 # # pygtk-rpminstall is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # pygtk-rpminstall is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . from gi.repository import Gtk, GdkPixbuf, Gdk import os, sys, fnmatch import rpm import progress, dependdialog, installed #Comment the first line and uncomment the second before installing #or making the tarball (alternatively, use project variables) UI_FILE = "ui/rpminstall.ui" RPM_ICON = "ui/icons/rpm.png" rpmtsCallback_fd = None # # Class for main window # class GUI: def __init__(self): # Build user interface self.builder = Gtk.Builder() self.builder.set_translation_domain('rpminstall') self.builder.add_from_file(os.path.join (os.path.dirname(__file__), UI_FILE)) self.builder.connect_signals(self) self.build_file_list_view() # add packages from command line arguments self.add_packages_from_argv () # Show window self.window = self.builder.get_object('window') self.window.show_all() # # Build file list view # def build_file_list_view(self): # Build Column column_file = Gtk.TreeViewColumn(_("RPM Package")) renderer_pixbuf = Gtk.CellRendererPixbuf() column_file.pack_start(renderer_pixbuf,False) column_file.add_attribute(renderer_pixbuf,"pixbuf",0) renderer_text = Gtk.CellRendererText() column_file.pack_start(renderer_text, True) column_file.add_attribute(renderer_text, "text", 1) file_list_view = self.builder.get_object('file_list_view') file_list_view.append_column(column_file) # Enable multi select selection = file_list_view.get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) self.progress = 0 # # add packages from command line arguments # def add_packages_from_argv(self): file_liststore = self.builder.get_object('file_liststore') pixbuf = GdkPixbuf.Pixbuf.new_from_file(os.path.join(os.path.dirname(__file__), RPM_ICON)) for arg in sys.argv: for pattern in self.get_installable_pattern_list(): if fnmatch.fnmatchcase(arg, pattern): file_liststore.append([pixbuf, arg]) break # # Callback when add button is clicked # def add_button_clicked(self, window): dialog = Gtk.FileChooserDialog(_("Please choose a file"), window, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dialog.set_select_multiple(True) filter_text = Gtk.FileFilter() filter_text.set_name(_("RPM Binary Package")) for pattern in self.get_installable_pattern_list(): filter_text.add_pattern(pattern) dialog.add_filter(filter_text) if dialog.run() == Gtk.ResponseType.OK: file_liststore = self.builder.get_object('file_liststore') pixbuf = GdkPixbuf.Pixbuf.new_from_file(os.path.join(os.path.dirname(__file__), RPM_ICON)) for fname in dialog.get_filenames(): file_liststore.append([pixbuf, fname]) dialog.destroy() # # Callback when delete button is clicked # def delete_button_clicked(self, button): file_list_view = self.builder.get_object('file_list_view') file_liststore = self.builder.get_object('file_liststore') selection = file_list_view.get_selection() while True: (unused, paths) = selection.get_selected_rows() if paths == []: break file_liststore.remove( file_liststore.get_iter(paths[0]) ) # # Callback when cancel button is clicked # def cancel_button_clicked(self,button): Gtk.main_quit() # # Callback when cancel button is clicked # def execute_button_clicked(self,widget): count = 0 file_liststore = self.builder.get_object('file_liststore') ts = rpm.TransactionSet() newer_installed = [] treeiter = file_liststore.get_iter_first() while treeiter != None: filename = str(file_liststore[treeiter][1]) fd = os.open(filename, os.O_RDONLY) h = None try: h = ts.hdrFromFdno(fd) installed_info = self.check_installed(h) if installed_info == None: ts.addInstall(h, filename, 'u') h = None os.close(fd) count = count + 1 else: newer_installed.append(installed_info) except rpm.error, e: print str(e) treeiter = file_liststore.iter_next(treeiter) if len(newer_installed) > 0: dialog = installed.InstalledDialog(newer_installed) dialog.run() if count > 0: if self.possibility_of_installation(ts): ts.order() dialog = progress.ProgressDialog(self.window, ts) response = dialog.run() else: dialog = Gtk.MessageDialog(self.window, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, _("No package is selected.")) dialog.run() dialog.destroy() # # check installed version # def check_installed(self, h): ts = rpm.TransactionSet() pkg_ds = h.dsOfHeader() for inst_h in ts.dbMatch('name', h['name']): inst_ds = inst_h.dsOfHeader() if pkg_ds.EVR() <= inst_ds.EVR(): return (h['name'], pkg_ds.EVR(), inst_ds.EVR()) else: return None # # check dependency # def possibility_of_installation(self, ts): unresolved_dependencies = ts.check() if not unresolved_dependencies: return True else: dialog = dependdialog.DependDialog(unresolved_dependencies) dialog.run () return False # # get installable pattern list # def get_installable_pattern_list(self): pattern_list = [ '*.noarch.rpm' ] arch = rpm.expandMacro('%{_arch}') if arch == 'i386': pattern_list.append('*.i?86.rpm') elif arch == 'x86_64': pattern_list.append('*.i?86.rpm') pattern_list.append('*.x86_64.rpm') else: pattern_list.append('*.' + arch + '.rpm') return pattern_list # # Callback when Gui is destroied # def destroy(window, self): Gtk.main_quit()