home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / site-packages / GDebi / GDebi.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-08-31  |  23.0 KB  |  626 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. import sys
  5. import os
  6. import string
  7. import apt
  8. import apt_pkg
  9. import pygtk
  10. pygtk.require('2.0')
  11. import gtk
  12. import gtk.glade as gtk
  13. import pango
  14. import gobject
  15. import vte
  16. import urllib
  17. import fcntl
  18. import posix
  19. import time
  20. import thread
  21. import re
  22. from DebPackage import DebPackage, MyCache
  23. from SimpleGladeApp import SimpleGladeApp
  24. from apt.progress import InstallProgress
  25. from gettext import gettext as _
  26.  
  27. def utf8(str):
  28.     return unicode(str, 'latin1').encode('utf-8')
  29.  
  30.  
  31. class GDebi(SimpleGladeApp):
  32.     
  33.     def __init__(self, datadir, options, file = ''):
  34.         localesApp = 'gdebi'
  35.         localesDir = '/usr/share/locale'
  36.         gtk.glade.bindtextdomain(localesApp, localesDir)
  37.         gtk.glade.textdomain(localesApp)
  38.         SimpleGladeApp.__init__(self, domain = 'gdebi', path = datadir + '/gdebi.glade')
  39.         icons = gtk.icon_theme_get_default()
  40.         logo = icons.load_icon('gnome-mime-application-x-deb', 48, 0)
  41.         if logo != '':
  42.             gtk.window_set_default_icon_list(logo)
  43.         
  44.         img = gtk.Image()
  45.         img.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON)
  46.         self.button_install.set_image(img)
  47.         self.context = self.statusbar_main.get_context_id('context_main_window')
  48.         self.statusbar_main.push(self.context, _('Loading...'))
  49.         self.window_main.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP, [
  50.             ('text/uri-list', 0, 0)], gtk.gdk.ACTION_COPY)
  51.         self.window_main.set_sensitive(False)
  52.         self.notebook_details.set_sensitive(False)
  53.         self.hbox_main.set_sensitive(False)
  54.         self.window_main.show()
  55.         self.cprogress = self.CacheProgressAdapter(self.progressbar_cache)
  56.         self._cache = MyCache(self.cprogress)
  57.         if self._cache._depcache.BrokenCount > 0:
  58.             err_header = _('Broken dependencies')
  59.             err_body = _("Your system has broken dependencies. This application can not continue until this is fixed. To fix it run 'sudo synaptic' or 'sudo apt-get install -f' in a terminal window.")
  60.             self.show_alert(gtk.MESSAGE_ERROR, err_header, err_body)
  61.             sys.exit(1)
  62.         
  63.         self.statusbar_main.push(self.context, '')
  64.         self._options = options
  65.         self.details_list = gtk.ListStore(gobject.TYPE_STRING)
  66.         column = gtk.TreeViewColumn('')
  67.         render = gtk.CellRendererText()
  68.         column.pack_start(render, True)
  69.         column.add_attribute(render, 'markup', 0)
  70.         self.treeview_details.append_column(column)
  71.         self.treeview_details.set_model(self.details_list)
  72.         if file != '' and os.path.exists(file):
  73.             self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
  74.             while gtk.events_pending():
  75.                 gtk.main_iteration()
  76.             self.open(file)
  77.             self.window_main.window.set_cursor(None)
  78.         
  79.         self.window_main.set_sensitive(True)
  80.  
  81.     
  82.     def _get_file_path_from_dnd_dropped_uri(self, uri):
  83.         ''' helper to get a useful path from a drop uri'''
  84.         path = urllib.url2pathname(uri)
  85.         path = path.strip('\r\n\x00')
  86.         if path.startswith('file:\\\\\\'):
  87.             path = path[8:]
  88.         elif path.startswith('file://'):
  89.             path = path[7:]
  90.         elif path.startswith('file:'):
  91.             path = path[5:]
  92.         
  93.         return path
  94.  
  95.     
  96.     def on_window_main_drag_data_received(self, widget, context, x, y, selection, target_type, timestamp):
  97.         ''' call when we got a drop event '''
  98.         uri = selection.data.strip()
  99.         uri_splitted = uri.split()
  100.         for uri in uri_splitted:
  101.             path = self._get_file_path_from_dnd_dropped_uri(uri)
  102.             if path.endswith('.deb'):
  103.                 self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
  104.                 while gtk.events_pending():
  105.                     gtk.main_iteration()
  106.                 self.open(path)
  107.                 self.window_main.window.set_cursor(None)
  108.                 continue
  109.         
  110.  
  111.     
  112.     def open(self, file):
  113.         
  114.         try:
  115.             self._deb = DebPackage(self._cache, file)
  116.         except (IOError, SystemError):
  117.             e = None
  118.             err_header = _("Could not open '%s'" % os.path.basename(file))
  119.             err_body = _('The package might be corrupted or you are not allowed to open the file. Check the permissions of the file.')
  120.             self.show_alert(gtk.MESSAGE_ERROR, err_header, err_body)
  121.             return False
  122.  
  123.         self.statusbar_main.push(self.context, '')
  124.         self.window_main.set_sensitive(True)
  125.         self.window_main.set_title(_('Package Installer - %s') % self._deb.pkgName)
  126.         self.label_name.set_markup(self._deb.pkgName)
  127.         self.notebook_details.set_sensitive(True)
  128.         self.hbox_main.set_sensitive(True)
  129.         buf = self.textview_description.get_buffer()
  130.         
  131.         try:
  132.             long_desc = ''
  133.             raw_desc = string.split(utf8(self._deb['Description']), '\n')
  134.             summary = raw_desc[0]
  135.             raw_desc[0] = ''
  136.             long_desc = '%s\n' % summary
  137.             for line in raw_desc:
  138.                 tmp = string.strip(line)
  139.                 if tmp == '.':
  140.                     long_desc += '\n'
  141.                     continue
  142.                 long_desc += tmp + '\n'
  143.             
  144.             p = re.compile('^(\\s|\\t)*(\\*|0|-)', re.MULTILINE)
  145.             long_desc = p.sub('\n*', long_desc)
  146.             p = re.compile('\\n', re.MULTILINE)
  147.             long_desc = p.sub(' ', long_desc)
  148.             p = re.compile('\\s\\s+', re.MULTILINE)
  149.             long_desc = p.sub('\n', long_desc)
  150.             buf.set_text(long_desc)
  151.             tag = buf.create_tag(None, weight = pango.WEIGHT_BOLD)
  152.             iter = buf.get_iter_at_offset(0)
  153.             (start, end) = iter.forward_search('\n', gtk.TEXT_SEARCH_TEXT_ONLY, None)
  154.             buf.apply_tag(tag, iter, end)
  155.         except KeyError:
  156.             buf.set_text('No description is available')
  157.  
  158.         self.label_version.set_text(self._deb['Version'])
  159.         self.label_maintainer.set_text(utf8(self._deb['Maintainer']))
  160.         self.label_priority.set_text(self._deb['Priority'])
  161.         self.label_section.set_text(utf8(self._deb['Section']))
  162.         self.label_size.set_text(self._deb['Installed-Size'] + ' KB')
  163.         buf = self.textview_filelist.get_buffer()
  164.         buf.set_text('\n'.join(self._deb.filelist))
  165.         if not self._deb.checkDeb():
  166.             self.label_status.set_markup('<span foreground="red" weight="bold">' + 'Error: ' + self._deb._failureString + '</span>')
  167.             self.button_install.set_label(_('_Install Package'))
  168.             self.button_install.set_sensitive(False)
  169.             self.button_details.hide()
  170.             return None
  171.         
  172.         if self._deb.compareToVersionInCache() == DebPackage.VERSION_SAME:
  173.             self.label_status.set_text(_('Same version is already installed'))
  174.             self.button_install.set_label(_('_Reinstall Package'))
  175.             self.button_install.grab_default()
  176.             self.button_install.set_sensitive(True)
  177.             self.button_details.hide()
  178.             return None
  179.         
  180.         res = self._deb.compareToVersionInCache(useInstalled = False)
  181.         if not (self._options.non_interactive) and res != DebPackage.NO_VERSION:
  182.             pkg = self._cache[self._deb.pkgName]
  183.             title = msg = ''
  184.             if res == DebPackage.VERSION_SAME:
  185.                 if self._cache.downloadable(pkg, useCandidate = True):
  186.                     title = _('Same version is available in a software channel')
  187.                     msg = _('You are recommended to install the software from the channel instead.')
  188.                 
  189.             elif res == DebPackage.VERSION_IS_NEWER:
  190.                 if self._cache.downloadable(pkg, useCandidate = True):
  191.                     title = _('An older version is available in a software channel')
  192.                     msg = _('Generally you are recommended to install the version from the software channel, since it is usually better supported.')
  193.                 
  194.             elif res == DebPackage.VERSION_OUTDATED:
  195.                 if self._cache.downloadable(pkg, useCandidate = True):
  196.                     title = _('A later version is available in a software channel')
  197.                     msg = _('You are strongly advised to install the version from the software channel, since it is usually better supported.')
  198.                 
  199.             
  200.             if title != '' and msg != '':
  201.                 msg = '<big><b>%s</b></big>\n\n%s' % (title, msg)
  202.                 dialog = gtk.MessageDialog(parent = self.window_main, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_INFO, buttons = gtk.BUTTONS_CLOSE)
  203.                 dialog.set_markup(msg)
  204.                 dialog.run()
  205.                 dialog.destroy()
  206.             
  207.         
  208.         (install, remove, unauthenticated) = self._deb.requiredChanges
  209.         deps = ''
  210.         if len(install) == len(install):
  211.             pass
  212.         elif len(install) == 0:
  213.             deps = _('All dependencies are satisfied')
  214.             self.button_details.hide()
  215.         else:
  216.             self.button_details.show()
  217.         if len(remove) > 0:
  218.             deps += _('Requires the <b>removal</b> of %s packages\n') % len(remove)
  219.         
  220.         if len(install) > 0:
  221.             deps += _('Requires the installation of %s packages') % len(install)
  222.         
  223.         self.label_status.set_markup(deps)
  224.         img = gtk.Image()
  225.         img.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON)
  226.         self.button_install.set_image(img)
  227.         self.button_install.set_label(_('_Install Package'))
  228.         self.button_install.set_sensitive(True)
  229.         self.button_install.grab_default()
  230.  
  231.     
  232.     def on_button_details_clicked(self, widget):
  233.         (install, remove, unauthenticated) = self._deb.requiredChanges
  234.         self.details_list.clear()
  235.         for rm in remove:
  236.             self.details_list.append([
  237.                 _('<b>To be removed: %s</b>') % rm])
  238.         
  239.         for inst in install:
  240.             self.details_list.append([
  241.                 _('To be installed: %s') % inst])
  242.         
  243.         self.dialog_details.set_transient_for(self.window_main)
  244.         self.dialog_details.run()
  245.         self.dialog_details.hide()
  246.  
  247.     
  248.     def on_open_activate(self, widget):
  249.         fs = gtk.FileChooserDialog(parent = self.window_main, buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK), action = gtk.FILE_CHOOSER_ACTION_OPEN, title = _('Open Software Package'))
  250.         fs.set_default_response(gtk.RESPONSE_OK)
  251.         filter = gtk.FileFilter()
  252.         filter.add_pattern('*.deb')
  253.         filter.set_name(_('Software packages'))
  254.         fs.set_filter(filter)
  255.         if fs.run() == gtk.RESPONSE_OK:
  256.             self.open(fs.get_filename())
  257.         
  258.         fs.destroy()
  259.  
  260.     
  261.     def on_about_activate(self, widget):
  262.         VERSION = VERSION
  263.         import Version
  264.         self.dialog_about.set_version(VERSION)
  265.         self.dialog_about.run()
  266.         self.dialog_about.hide()
  267.  
  268.     
  269.     def on_button_install_clicked(self, widget):
  270.         self.statusbar_main.push(self.context, _('Installing package file...'))
  271.         (install, remove, unauthenticated) = self._deb.requiredChanges
  272.         if widget != None and len(unauthenticated) > 0:
  273.             primary = _('Install unauthenticated software?')
  274.             secondary = _('Malicous software can damage your data and take control of your system.\n\nThe packages below are not authenticated and could therefor be of malicous nature.')
  275.             msg = '<big><b>%s</b></big>\n\n%s' % (primary, secondary)
  276.             dialog = gtk.MessageDialog(parent = self.dialog_deb_install, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_WARNING, buttons = gtk.BUTTONS_YES_NO)
  277.             dialog.set_markup(msg)
  278.             dialog.set_border_width(6)
  279.             scrolled = gtk.ScrolledWindow()
  280.             textview = gtk.TextView()
  281.             textview.set_cursor_visible(False)
  282.             textview.set_editable(False)
  283.             buf = textview.get_buffer()
  284.             buf.set_text('\n'.join(unauthenticated))
  285.             scrolled.add(textview)
  286.             scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
  287.             scrolled.show()
  288.             dialog.vbox.pack_start(scrolled)
  289.             textview.show()
  290.             res = dialog.run()
  291.             dialog.destroy()
  292.             if res != gtk.RESPONSE_YES:
  293.                 return None
  294.             
  295.         
  296.         if os.getuid() != 0:
  297.             os.execl('/usr/bin/gksu', 'gksu', '--desktop', '/usr/share/applications/gdebi.desktop', '--', 'gdebi-gtk', '--non-interactive', self._deb.file)
  298.             return None
  299.         
  300.         
  301.         try:
  302.             apt_pkg.PkgSystemLock()
  303.         except SystemError:
  304.             header = _('Only one software management tool is allowed to run at the same time')
  305.             body = _("Please close the other application e.g. 'Update Manager', 'aptitude' or 'Synaptic' first.")
  306.             self.show_alert(gtk.MESSAGE_ERROR, header, body)
  307.             return None
  308.  
  309.         apt_pkg.PkgSystemUnLock()
  310.         self.window_main.set_sensitive(False)
  311.         self.button_deb_install_close.set_sensitive(False)
  312.         self.dialog_deb_install.set_transient_for(self.window_main)
  313.         self.dialog_deb_install.show_all()
  314.         if len(install) > 0 or len(remove) > 0:
  315.             
  316.             try:
  317.                 apt_pkg.PkgSystemLock()
  318.             except SystemError:
  319.                 header = _('Only one software management tool is allowed to run at the same time')
  320.                 body = _("Please close the other application e.g. 'Update Manager', 'aptitude' or 'Synaptic' first.")
  321.                 self.show_alert(gtk.MESSAGE_ERROR, header, body)
  322.                 self.dialog_deb_install.hide()
  323.                 self.window_main.set_sensitive(True)
  324.                 return None
  325.  
  326.             fprogress = self.FetchProgressAdapter(self.progressbar_install, self.label_action, self.dialog_deb_install)
  327.             iprogress = self.InstallProgressAdapter(self.progressbar_install, self._term, self.label_action, self.expander_install)
  328.             errMsg = None
  329.             
  330.             try:
  331.                 res = self._cache.commit(fprogress, iprogress)
  332.             except IOError:
  333.                 msg = None
  334.                 res = False
  335.                 errMsg = '%s' % msg
  336.                 header = _('Could not download all required files')
  337.                 body = _('Please check your internet connection or installation medium.')
  338.             except SystemError:
  339.                 msg = None
  340.                 res = False
  341.                 header = (_('Could not install all dependencies'),)
  342.                 body = _('Usually this is related to an error of the software distributor. See the terminal window for more details.')
  343.  
  344.             if not res:
  345.                 self.show_alert(gtk.MESSAGE_ERROR, header, body, msg)
  346.                 self.label_install_status.set_markup('<span foreground="red" weight="bold">%s</span>' % primary)
  347.                 self.button_deb_install_close.set_sensitive(True)
  348.                 self.button_deb_install_close.grab_default()
  349.                 self.statusbar_main.push(self.context, _('Failed to install package file'))
  350.                 return None
  351.             
  352.         
  353.         self.label_action.set_markup('<b><big>' + _('Installing package file') + '</big></b>')
  354.         dprogress = self.DpkgInstallProgress(self._deb.file, self.label_install_status, self.progressbar_install, self._term, self.expander_install)
  355.         dprogress.commit()
  356.         self.button_deb_install_close.set_sensitive(True)
  357.         self.button_deb_install_close.grab_default()
  358.         self.label_action.set_markup('<b><big>' + _('Installation finished') + '</big></b>')
  359.         if dprogress.exitstatus == 0:
  360.             self.label_install_status.set_markup('<i>' + _("Package '%s' was installed") % os.path.basename(self._deb.file) + '</i>')
  361.         else:
  362.             self.label_install_status.set_markup('<b>' + _("Failed to install package '%s'") % os.path.basename(self._deb.file) + '</b>')
  363.             self.expander_install.set_expanded(True)
  364.         self.statusbar_main.push(self.context, _('Installation complete'))
  365.         self._cache = MyCache()
  366.         if self._cache._depcache.BrokenCount > 0:
  367.             err_header = _('Failed to completely install all dependencies')
  368.             err_body = _("To fix this run 'sudo apt-get install -f' in a terminal window.")
  369.             self.show_alert(gtk.MESSAGE_ERROR, err_header, err_body)
  370.         
  371.         self.open(self._deb.file)
  372.  
  373.     
  374.     def on_button_deb_install_close_clicked(self, widget):
  375.         self.dialog_deb_install.hide()
  376.         self.window_main.set_sensitive(True)
  377.  
  378.     
  379.     def on_window_main_delete_event(self, *args):
  380.         if self.window_main.get_property('sensitive'):
  381.             gtk.main_quit()
  382.             return False
  383.         else:
  384.             return True
  385.  
  386.     
  387.     def create_vte(self, arg1, arg2, arg3, arg4):
  388.         self._term = vte.Terminal()
  389.         self._term.set_font_from_string('monospace 10')
  390.         return self._term
  391.  
  392.     
  393.     def show_alert(self, type, header, body = None, details = None):
  394.         self.dialog_hig.set_transient_for(self.window_main)
  395.         message = '<b><big>%s</big></b>' % header
  396.         if not body == None:
  397.             message = '%s\n\n%s' % (message, body)
  398.         
  399.         self.label_hig.set_markup(message)
  400.         if not details == None:
  401.             buffer = self.textview_hig.get_buffer()
  402.             buffer.set_text(details)
  403.             self.expander_hig.set_expanded(False)
  404.             self.expander_hig.show()
  405.         
  406.         if type == gtk.MESSAGE_ERROR:
  407.             self.image_hig.set_property('stock', 'gtk-dialog-error')
  408.         elif type == gtk.MESSAGE_WARNING:
  409.             self.image_hig.set_property('stock', 'gtk-dialog-warning')
  410.         elif type == gtk.MESSAGE_INFO:
  411.             self.image_hig.set_property('stock', 'gtk-dialog-info')
  412.         
  413.         res = self.dialog_hig.run()
  414.         self.dialog_hig.hide()
  415.         if res == gtk.RESPONSE_CLOSE:
  416.             return True
  417.         
  418.  
  419.     
  420.     class DpkgInstallProgress(object):
  421.         
  422.         def __init__(self, debfile, status, progress, term, expander):
  423.             self.debfile = debfile
  424.             self.status = status
  425.             self.progress = progress
  426.             self.term = term
  427.             self.expander = expander
  428.             self.expander.set_expanded(False)
  429.  
  430.         
  431.         def commit(self):
  432.             
  433.             def finish_dpkg(term, pid, status, lock):
  434.                 ''' helper '''
  435.                 self.exitstatus = posix.WEXITSTATUS(status)
  436.                 lock.release()
  437.  
  438.             lock = thread.allocate_lock()
  439.             lock.acquire()
  440.             self.status.set_markup('<i>' + _("Installing '%s'...") % os.path.basename(self.debfile) + '</i>')
  441.             self.progress.pulse()
  442.             self.progress.set_text('')
  443.             (readfd, writefd) = os.pipe()
  444.             fcntl.fcntl(readfd, fcntl.F_SETFL, os.O_NONBLOCK)
  445.             cmd = '/usr/bin/dpkg'
  446.             argv = [
  447.                 cmd,
  448.                 '--status-fd',
  449.                 '%s' % writefd,
  450.                 '-i',
  451.                 self.debfile]
  452.             env = [
  453.                 'VTE_PTY_KEEP_FD=%s' % writefd]
  454.             reaper = vte.reaper_get()
  455.             reaper.connect('child-exited', finish_dpkg, lock)
  456.             pid = self.term.fork_command(command = cmd, argv = argv, envv = env)
  457.             read = ''
  458.             while lock.locked():
  459.                 while True:
  460.                     
  461.                     try:
  462.                         read += os.read(readfd, 1)
  463.                     except OSError:
  464.                         (errno, errstr) = None
  465.                         if errno != 11:
  466.                             print errstr
  467.                         
  468.                         break
  469.  
  470.                     if read.endswith('\n'):
  471.                         statusl = string.split(read, ':')
  472.                         if len(statusl) < 2:
  473.                             print "got garbage from dpkg: '%s'" % read
  474.                             read = ''
  475.                             break
  476.                         
  477.                         status = statusl[2].strip()
  478.                         if status == 'error' or status == 'conffile-prompt':
  479.                             self.expander.set_expanded(True)
  480.                         
  481.                         read = ''
  482.                         continue
  483.                 self.progress.pulse()
  484.                 while gtk.events_pending():
  485.                     gtk.main_iteration()
  486.                 time.sleep(0.20000000000000001)
  487.             self.progress.set_fraction(1.0)
  488.  
  489.  
  490.     
  491.     class InstallProgressAdapter(InstallProgress):
  492.         
  493.         def __init__(self, progress, term, label, term_expander):
  494.             InstallProgress.__init__(self)
  495.             self.progress = progress
  496.             self.term = term
  497.             self.term_expander = term_expander
  498.             self.finished = False
  499.             self.action = label
  500.             reaper = vte.reaper_get()
  501.             reaper.connect('child-exited', self.child_exited)
  502.             self.env = [
  503.                 'VTE_PTY_KEEP_FD=%s' % self.writefd,
  504.                 'DEBIAN_FRONTEND=gnome',
  505.                 'APT_LISTCHANGES_FRONTEND=gtk']
  506.  
  507.         
  508.         def child_exited(self, term, pid, status):
  509.             self.apt_status = posix.WEXITSTATUS(status)
  510.             self.finished = True
  511.  
  512.         
  513.         def error(self, pkg, errormsg):
  514.             self.term_expander.set_expanded(True)
  515.  
  516.         
  517.         def conffile(self, current, new):
  518.             self.term_expander.set_expanded(True)
  519.  
  520.         
  521.         def startUpdate(self):
  522.             apt_pkg.PkgSystemUnLock()
  523.             self.action.set_markup('<i>' + _('Installing dependencies...') + '</i>')
  524.             self.progress.set_fraction(0.0)
  525.  
  526.         
  527.         def statusChange(self, pkg, percent, status):
  528.             self.progress.set_fraction(percent / 100.0)
  529.             self.progress.set_text(status)
  530.  
  531.         
  532.         def updateInterface(self):
  533.             InstallProgress.updateInterface(self)
  534.             while gtk.events_pending():
  535.                 gtk.main_iteration()
  536.  
  537.         
  538.         def fork(self):
  539.             return self.term.forkpty(envv = self.env)
  540.  
  541.         
  542.         def waitChild(self):
  543.             while not self.finished:
  544.                 self.updateInterface()
  545.             return self.apt_status
  546.  
  547.  
  548.     
  549.     class FetchProgressAdapter(apt.progress.FetchProgress):
  550.         
  551.         def __init__(self, progress, action, main):
  552.             self.progress = progress
  553.             self.action = action
  554.             self.main = main
  555.  
  556.         
  557.         def start(self):
  558.             self.action.set_markup('<i>' + _('Downloading additional package files...') + '</i>')
  559.             self.progress.set_fraction(0)
  560.  
  561.         
  562.         def stop(self):
  563.             pass
  564.  
  565.         
  566.         def pulse(self):
  567.             self.progress.set_text(_('File %s of %s at %s/s' % (self.currentItems, self.totalItems, apt_pkg.SizeToStr(self.currentCPS))))
  568.             self.progress.set_fraction(self.currentBytes / self.totalBytes)
  569.             while gtk.events_pending():
  570.                 gtk.main_iteration()
  571.             return True
  572.  
  573.         
  574.         def mediaChange(self, medium, drive):
  575.             msg = _("Please insert '%s' into the drive '%s'" % (medium, drive))
  576.             dialog = gtk.MessageDialog(parent = self.main, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_QUESTION, buttons = gtk.BUTTONS_OK_CANCEL)
  577.             dialog.set_markup(msg)
  578.             res = dialog.run()
  579.             dialog.destroy()
  580.             if res == gtk.RESPONSE_OK:
  581.                 return True
  582.             
  583.             return False
  584.  
  585.  
  586.     
  587.     class CacheProgressAdapter(apt.progress.FetchProgress):
  588.         
  589.         def __init__(self, progressbar):
  590.             self.progressbar = progressbar
  591.  
  592.         
  593.         def update(self, percent):
  594.             self.progressbar.show()
  595.             self.progressbar.set_fraction(percent / 100.0)
  596.             while gtk.events_pending():
  597.                 gtk.main_iteration()
  598.  
  599.         
  600.         def done(self):
  601.             self.progressbar.hide()
  602.  
  603.  
  604.  
  605. if __name__ == '__main__':
  606.     app = GDebi('data/', None)
  607.     pkgs = [
  608.         '3ddesktop']
  609.     for pkg in pkgs:
  610.         print 'installing %s' % pkg
  611.         app._cache[pkg].markInstall()
  612.     
  613.     for pkg in app._cache:
  614.         if pkg.markedInstall or pkg.markedUpgrade:
  615.             print pkg.name
  616.         
  617.     
  618.     apt_pkg.PkgSystemLock()
  619.     app.dialog_deb_install.set_transient_for(app.window_main)
  620.     app.dialog_deb_install.show_all()
  621.     fprogress = app.FetchProgressAdapter(app.progressbar_install)
  622.     iprogress = app.InstallProgressAdapter(app.progressbar_install, app._term)
  623.     res = app._cache.commit(fprogress, iprogress)
  624.     print 'commit retured: %s' % res
  625.  
  626.