Ejemplo n.º 1
0
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
#  USA.
""" Changelog fetcher functionality """

import logging
import urllib2

from threading import Thread

from UpdateManager.Util.enum import Enum

LOG = logging.getLogger('UpdateManager.DistSpecific.changelog')

CHANGELOG_FETCH_STATUS = Enum(FAILED="Fetching failed",
                              DONE="Fetching finished")
""" Changelog fetcher status """


class ChangelogFetcherException(Exception):
    """ Changelog fetcher exception """
    pass


class ChangelogHandler(object):
    """ Changelog result handler """
    def changelog_finished(self, pkg_info, raw_changelog):
        """ Changelog fetching finished notification

        :param pkg_info: :class:`UpdateManager.Backend.PackageInfoBase` object
        :param raw_changelog: The last changelog entry as a string
Ejemplo n.º 2
0
 def test3_9_in_name(self):
     try:
         enum = Enum('NAME_WITH_9', ANOTHER_9='Name with 9')
     except TypeError, te:
         self.fail('9 not accepted in name')
Ejemplo n.º 3
0
        return self._categories.copy()

    def get_package_list(self):
        """ Gets a list of packages.

        :returns: A list of :class:`PackageInfoBase` objects.
        """
        return self._packages.values()

    def resolve_dependencies(self):
        """ Resolves dependencies of all packages. """
        for pkg_info in self._packages.values():
            pkg_info._resolve_dependencies(self)


DEP_RELATION = Enum('EQ', 'LT', 'GT', 'GTE', 'LTE')


class PackageDependencyBase(object):
    """ Package dependency representation """
    def __init__(self, name, relation, version):
        self._name = name
        self._relation = relation
        self._version = version
        if not relation or not version:
            self._inst_version_matches = True
        else:
            self._inst_version_matches = False

    def is_strict(self):
        """ Returns whether the dependency is a strict one.
Ejemplo n.º 4
0
 def test2_z_in_name(self):
     try:
         enum = Enum('NAME_WITH_Z', ANOTHER_Z='Name with z')
     except TypeError, te:
         self.fail('Z not accepted in name')
Ejemplo n.º 5
0
 def test1_enum_doc(self):
     enum = Enum(TEST0='Test0', TEST1='Test1')
     self.assertTrue(enum.TEST0 >= 0)
     self.assertTrue(enum.TEST0 < 2)
     self.assertTrue(enum.TEST1 >= 0)
     self.assertTrue(enum.TEST1 < 2)
Ejemplo n.º 6
0
 def test0_enum_nodoc(self):
     enum = Enum('TEST0', 'TEST1')
     self.assertEquals(enum.TEST0, 0)
     self.assertEquals(enum.TEST1, 1)
Ejemplo n.º 7
0
class GtkListProgress(BackendProgressHandlerObject):
    """ Gtk list progress handler implementation """
    LIST_COL = Enum('PERCENTAGE', 'SOURCE', 'FILE_NAME', 'PART_SIZE',
                    'FILE_SIZE')
    MODE = Enum(UNKNOWN="Unknown mode",
                DOWNLOAD_PKG="Package download mode",
                DOWNLOAD_LIST="List download mode",
                HIDDEN="Hidden mode",
                INSTALL="Install mode",
                INSTALL_FINISHED="Install finished mode")

    def __init__(self, host_window, progressbar, summary, status, expander,
                 cancel_button, treeview, vb_details, scrolled, parent):
        BackendProgressHandlerObject.__init__(self)
        self._mode = self.MODE.HIDDEN
        self._scrolled = scrolled
        self._summary = summary
        self._progressbar = progressbar
        self._status = status
        self._parent = parent
        self._treeview = treeview
        self._expander = expander
        self._vb_details = vb_details
        self._cancel_button = cancel_button
        self._window = host_window
        self._store = gtk.ListStore(int, str, str, int, int)
        self._treeview.set_model(self._store)
        self._treeview.set_headers_clickable(False)
        self._download_size = 0
        self._package_count = 0
        self._download_count = 0
        self._packages_finished = 0
        self._installed_count = 0
        self._cur_install_package = None

        self._expander.connect("notify::expanded", self._expander_toggled)

        # List columns
        progress_renderer = gtk.CellRendererProgress()
        column_progress = gtk.TreeViewColumn(_("Progress"), progress_renderer)
        column_progress.set_cell_data_func(progress_renderer,
                                           self._progress_col_data_func)
        column_source = gtk.TreeViewColumn(_("Source"),
                                           gtk.CellRendererText(),
                                           markup=self.LIST_COL.SOURCE)
        column_file = gtk.TreeViewColumn(_("File name"),
                                         gtk.CellRendererText(),
                                         markup=self.LIST_COL.FILE_NAME)
        partial_renderer = gtk.CellRendererText()
        column_partial = gtk.TreeViewColumn(_("Downloaded"), partial_renderer)
        column_partial.set_cell_data_func(partial_renderer,
                                          self._partial_col_data_func)

        size_renderer = gtk.CellRendererText()
        column_size = gtk.TreeViewColumn(_("Size"), size_renderer)
        column_size.set_cell_data_func(size_renderer, self._size_col_data_func)

        self._treeview.append_column(column_progress)
        self._treeview.append_column(column_source)
        self._treeview.append_column(column_file)
        self._treeview.append_column(column_partial)
        self._treeview.append_column(column_size)

        self._window.set_title(_('Checking for updates'))
        self._status.set_markup('')

        self._window.realize()
        self._window.window.set_functions(gtk.gdk.FUNC_MOVE
                                          | gtk.gdk.FUNC_RESIZE)
        self._window.set_transient_for(parent.window_main)
        self._finish_event = threading.Event()
        self._finish_event.clear()
        self._store_map = {}
        self._terminal = vte.Terminal()
        self._current_items = {}

        # Connect list signals
        self.connect("list_begin", self._sig_list_begin)
        self.connect("list_finished", self._sig_list_finished)
        self.connect("list_aborted", self._sig_list_aborted)
        self.connect("list_failed", self._sig_list_failed)
        self.connect("list_update", self._sig_list_update)
        self.connect("list_item_update", self._sig_item_update)
        self.connect("list_item_finished", self._sig_item_finished)

        # Connect download signals
        self.connect('download_begin', self._sig_download_begin)
        self.connect('download_update', self._sig_download_update)
        self.connect('download_finished', self._sig_download_finished)
        self.connect('download_aborted', self._sig_download_aborted)
        self.connect('download_failed', self._sig_download_failed)
        self.connect('download_item_finished', self._sig_item_finished)
        self.connect('download_item_update', self._sig_item_update)

        # Connect install signals
        self.connect('preparation_begin', self._sig_preparation_begin)
        self.connect('requires_removal_or_installation',
                     self._sig_removal_or_install)
        self.connect('install_begin', self._sig_install_begin)
        self.connect('install_finished', self._sig_install_finished)
        self.connect('install_failed', self._sig_install_failed)
        self.connect('install_update', self._sig_install_update)

        self._cancel_button.connect("clicked", self._sig_cancel_clicked)
        self._change_mode(reload_cache=False)

    def _partial_col_data_func(self, cell_layout, renderer, model, iterator):
        """ Column data function for partial size column """
        part_size = self._store.get_value(iterator, self.LIST_COL.PART_SIZE)
        if part_size != 0:
            size_str = humanize_size(part_size)
        else:
            size_str = _("Unknown")
        renderer.set_property("text", size_str)

    def _progress_col_data_func(self, cell_layout, renderer, model, iterator):
        """ Column data function for progress column """
        percentage = self._store.get_value(iterator, self.LIST_COL.PERCENTAGE)
        renderer.set_property("value", percentage)
        renderer.set_property("text", '%.0f%%' % (percentage))

    def _size_col_data_func(self, cell_layout, renderer, model, iterator):
        """ Data function for the size column.

        Invokes :func:`humanize_size` if the file size is known for
        a row and shows the result of the function call.
        """
        file_size = self._store.get_value(iterator, self.LIST_COL.FILE_SIZE)
        if file_size != 0:
            size_str = humanize_size(file_size)
        else:
            size_str = _("Unknown")
        renderer.set_property("text", size_str)

    def _expander_toggled(self, expander, data):
        """ Expander toggle handler """
        expanded = self._expander.get_expanded()

        self._vb_details.set_child_packing(self._expander, expanded, expanded,
                                           0, gtk.PACK_END)

    def _set_status(self, time_remaining, download_speed=None):
        """ Status label setter function
        
        :param time_remaining: Time remaining in seconds (integer)
        :param download_speed: Current download speed in bytes per second.
        """
        text = ''
        if download_speed:
            # TRANSLATORS: This is the download rate in bytes, kilobytes
            # or megabytes per second (hence the trailing /s).
            text = _('Download rate: %s/s') % (humanize_size(download_speed))

        if time_remaining:
            if time_remaining < 5:
                text += '\n' + ('Less than 5 seconds remaining')
            else:
                eta_string = humanize_seconds(time_remaining)
                text += '\n' + ('About %s remaining') % (eta_string)

        self._status.set_markup(text)

    def _sig_cancel_clicked(self, widget):
        """ Cancel button click signal handler """
        if self._cancel_button.get_label() == 'gtk-close':
            self._mode = self.MODE.HIDDEN
            self._cancel_button.set_label('gtk-cancel')

            def reload_cache_helper():
                self._parent._application.reload_cache()

            gobject.idle_add(reload_cache_helper)
            self._change_mode()
            self._terminal.reset(True, True)
        else:
            self._parent._application.abort_operation()

    def _sig_list_begin(self, src):
        """ List begin signal handler """
        self._mode = self.MODE.DOWNLOAD_LIST
        self._set_status(0)
        self._summary.set_markup('<b>%s</b>' % _('Checking for updates...'))
        self._progressbar.set_text('')
        self._progressbar.pulse()
        self._finish_event.clear()
        self._store.clear()
        self._change_mode()
        gobject.timeout_add(150,
                            self._pulsate,
                            priority=gobject.PRIORITY_DEFAULT_IDLE)

    @classmethod
    def _is_remote_uri(cls, item_uri):
        """ Helper classmethod that checks whether a given URI is remote or
        local.

        :param item_uri: Item URI
        """
        if item_uri.startswith('gpgv:/') or item_uri.startswith('bzip2:/') \
               or item_uri.startswith('gzip:/') \
               or item_uri.startswith('rred:/'):
            return False
        return True

    def _sig_list_finished(self, src):
        """ List finished signal handler """
        self._mode = self.MODE.HIDDEN
        self._change_mode()
        self._finish_event.set()
        self._store.clear()
        self._store_map = {}
        self._current_items = {}

    def _sig_list_aborted(self, src):
        """ List aborted signal handler """
        self._sig_list_finished(src)

    def _sig_list_failed(self, src, message):
        """ List failed signal handler """
        md = gtk.MessageDialog(parent=self._window,
                               flags=gtk.DIALOG_MODAL,
                               type=gtk.MESSAGE_ERROR,
                               buttons=gtk.BUTTONS_OK)
        md.set_markup("<b>%s</b>" %\
                      _("An internal error has occured and the operation has been aborted."))

        md.format_secondary_markup("<b>%s</b>\n%s" %\
                                   (_("Error message:"),
                                    message))
        md.run()
        md.hide()
        md.unrealize()
        self._sig_list_finished(src)

    def _sig_list_update(self, src, download_speed, eta_seconds):
        """ List update signal handler
        :param download_speed: Current download speed
        :param eta_seconds: ETA
        """
        self._set_status(eta_seconds, download_speed)

    def _sig_item_update(self, src, item_uri, item_size, item_partial_size):
        """ List item update signal handler

        :param item_uri: Item URI
        :param item_size: File size in bytes
        :param item_partial_size: Number of bytes already downloaded
        """
        self._handle_first_download_item()
        if item_size:
            percent = int(float(item_partial_size) / item_size * 100)
            self._current_items[item_uri] = percent
        else:
            percent = 0

        if self._is_remote_uri(item_uri):
            if not item_uri in self._store_map:
                try:
                    uri_source, uri_file = item_uri.rsplit('/', 1)
                    if uri_file.endswith('Release') or \
                       uri_file.endswith('Release.gpg') or \
                       uri_file.endswith('Index'):
                        return False
                    uri_source += '/'
                    it = self._store.prepend([
                        percent, uri_source, uri_file, item_partial_size,
                        item_size
                    ])
                    self._store_map[item_uri] = it
                except ValueError, v_err:
                    LOG.debug('Splitting uri %s failed: %s', item_uri,
                              v_err.message)
            else:
                it = self._store_map[item_uri]
                percent_old = self._store.get_value(it,
                                                    self.LIST_COL.PERCENTAGE)
                if percent_old < percent:
                    self._store.set_value(it, self.LIST_COL.PERCENTAGE,
                                          percent)
                    self._store.set_value(it, self.LIST_COL.PART_SIZE,
                                          item_partial_size)
                    self._store.set_value(it, self.LIST_COL.FILE_SIZE,
                                          item_size)
            self._update_percent()
        else:
Ejemplo n.º 8
0
#  This program 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, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
#  USA.
""" Exceptions module """

from UpdateManager.Util.enum import Enum

EXIT_STATUS_CODES = Enum(
    NO_ERROR="No error occured",
    LOADING_FAILED="Loading of a module failed",
    INVALID_BASE_CLASS="An invalid base class was specified",
)


class ExitProgramException(Exception):
    """ Program is about to exit """
    def __init__(self, status, msg="Program exited"):
        self.status = status
        Exception.__init__(self, msg)


class LoadingFailedException(ExitProgramException):
    """ Loading of a module failed """
    def __init__(self, module_name):
        msg = "%s could not be loaded" % (module_name)