Beispiel #1
0
    def _show_other_details(self,
                            name,
                            contract=None,
                            start=None,
                            end=None,
                            account=None,
                            management=None,
                            support_level="",
                            support_type="",
                            virt_only=None,
                            products=None,
                            highlight=None,
                            sku=None,
                            reasons=[],
                            expiring=False):
        products = products or []
        reasons = reasons or []

        self._set(self.details_view, '\n'.join(reasons))

        # set background for GTK2
        self.start_end_date_text.modify_base(ga_Gtk.StateType.NORMAL,
                                             self._get_date_bg(end, expiring))
        # set background for GTK3
        self.start_end_date_text.modify_bg(ga_Gtk.StateType.NORMAL,
                                           self._get_date_bg(end, expiring))

        self._set(self.contract_number_text, contract)
        self._set(
            self.start_end_date_text, "%s - %s" %
            (managerlib.format_date(start), managerlib.format_date(end)))
        self._set(self.account_text, account)
        self._set(self.provides_management_text, management)
        self._set(self.virt_only_text, virt_only)
Beispiel #2
0
    def list(self, filter_string=None):
        """
        Method for listening installed products in the system.
        :param filter_string: String for filtering out products.
        :return: List of installed products.
        """
        product_status = []

        # It is important to gather data from certificates of installed
        # products at the first time: sorter = inj.require(inj.CERT_SORTER)
        # Data are stored in cache (json file:
        # /var/lib/rhsm/cache/installed_products.json)
        # Calculator use this cache (json file) for assembling request
        # sent to server. When following two lines of code are called in
        # reverse order, then request can be incomplete and result
        # needn't contain all data (especially startDate and endDate).
        # See BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1357152

        # FIXME: make following functions independent on order of calling
        sorter = inj.require(inj.CERT_SORTER)
        calculator = inj.require(inj.PRODUCT_DATE_RANGE_CALCULATOR, self.cp)

        cert_filter = None
        if filter_string:
            cert_filter = utils.ProductCertificateFilter(filter_string)

        # Instead of a dictionary because some legacy methods unpack this as a list
        ProductStatus = collections.namedtuple('ProductStatus',
            ['product_name', 'product_id', 'version', 'arch', 'status', 'status_details', 'starts', 'ends']
        )

        for installed_product in sorted(sorter.installed_products):
            product_cert = sorter.installed_products[installed_product]

            if cert_filter is None or cert_filter.match(product_cert):
                for product in product_cert.products:
                    begin = ""
                    end = ""
                    prod_status_range = calculator.calculate(product.id)

                    if prod_status_range:
                        # Format the date in user's local time as the date
                        # range is returned in GMT.
                        begin = managerlib.format_date(prod_status_range.begin())
                        end = managerlib.format_date(prod_status_range.end())

                    product_status.append(ProductStatus(
                        product.name,
                        installed_product,
                        product.version,
                        ",".join(product.architectures),
                        sorter.get_status(product.id),
                        sorter.reasons.get_product_reasons(product),
                        begin,
                        end
                    ))

        return product_status
    def _show_other_details(
        self,
        name,
        contract=None,
        start=None,
        end=None,
        account=None,
        management=None,
        support_level="",
        support_type="",
        virt_only=None,
        products=None,
        highlight=None,
        sku=None,
        reasons=[],
        expiring=False,
    ):
        products = products or []
        reasons = reasons or []

        self._set(self.details_view, "\n".join(reasons))

        self.start_end_date_text.modify_base(gtk.STATE_NORMAL, self._get_date_bg(end, expiring))

        self._set(self.contract_number_text, contract)
        self._set(self.start_end_date_text, "%s - %s" % (managerlib.format_date(start), managerlib.format_date(end)))
        self._set(self.account_text, account)
        self._set(self.provides_management_text, management)
        self._set(self.virt_only_text, virt_only)
    def _set_validity_status(self):
        """ Updates the entitlement validity status portion of the UI. """

        if ClassicCheck().is_registered_with_classic():
            self._set_status_icons(VALID_STATUS)
            self.subscription_status_label.set_text(
                get_branding().RHSMD_REGISTERED_TO_OTHER)
            return

        is_registered = self.identity.is_valid()
        self.set_registered(is_registered)

        warn_count = len(self.backend.cs.unentitled_products)

        if self.backend.cs.system_status == 'valid':
            self._set_status_icons(VALID_STATUS)
            if len(self.backend.cs.installed_products.keys()) == 0:
                # No product certs installed, thus no compliant until date:
                self.subscription_status_label.set_text(
                    # I18N: Please add newlines if translation is longer:
                    _("No installed products detected."))
            elif self.backend.cs.compliant_until:
                self.subscription_status_label.set_markup(
                    # I18N: Please add newlines if translation is longer:
                    _("System is properly subscribed through %s.") %
                    managerlib.format_date(self.backend.cs.compliant_until))
            else:
                log.warn("Server did not provide a compliant until date.")
                self.subscription_status_label.set_text(
                    _("System is properly subscribed."))
        elif self.backend.cs.system_status == 'partial':
            self._set_status_icons(PARTIAL_STATUS)
            self.subscription_status_label.set_markup(
                # I18N: Please add newlines if translation is longer:
                _("This system does not match subscription limits."))
        elif self.backend.cs.system_status == 'invalid':
            self._set_status_icons(INVALID_STATUS)
            if warn_count > 1:
                self.subscription_status_label.set_markup(
                    # I18N: Please add newlines if translation is longer:
                    _("%s installed products do not have valid subscriptions.")
                    % warn_count)
            else:
                self.subscription_status_label.set_markup(
                    # I18N: Please add newlines if translation is longer:
                    _("1 installed product does not have a valid subscription."
                      ))
        elif self.backend.cs.system_status == 'unknown':
            self._set_status_icons(UNKNOWN_STATUS)
            self.subscription_status_label.set_text(
                # I18N: Please add newlines if translation is longer:
                _("Keep your system up to date by registering."))
Beispiel #5
0
    def do_set_property(self, prop, value):
        """
        called to set the date property for rendering in a cell.
        we convert to display in the user's locale, then pass on to the cell
        renderer.
        """

        if value:
            date = managerlib.format_date(value)
        else:
            date = value

        ga_Gtk.CellRendererText.set_property(self, 'text', date)
    def do_set_property(self, prop, value):
        """
        called to set the date property for rendering in a cell.
        we convert to display in the user's locale, then pass on to the cell
        renderer.
        """

        if value:
            date = managerlib.format_date(value)
        else:
            date = value

        ga_Gtk.CellRendererText.set_property(self, 'text', date)
    def _set_validity_status(self):
        """ Updates the entitlement validity status portion of the UI. """

        if ClassicCheck().is_registered_with_classic():
            self._set_status_icons(VALID_STATUS)
            self.subscription_status_label.set_text(
                get_branding().RHSMD_REGISTERED_TO_OTHER)
            return

        is_registered = self.identity.is_valid()
        self.set_registered(is_registered)

        warn_count = len(self.backend.cs.unentitled_products)

        if self.backend.cs.system_status == 'valid':
            self._set_status_icons(VALID_STATUS)
            if len(self.backend.cs.installed_products.keys()) == 0:
                # No product certs installed, thus no compliant until date:
                self.subscription_status_label.set_text(
                        # I18N: Please add newlines if translation is longer:
                        _("No installed products detected."))
            elif self.backend.cs.compliant_until:
                self.subscription_status_label.set_markup(
                        # I18N: Please add newlines if translation is longer:
                        _("System is properly subscribed through %s.") %
                        managerlib.format_date(self.backend.cs.compliant_until))
            else:
                log.warn("Server did not provide a compliant until date.")
                self.subscription_status_label.set_text(
                    _("System is properly subscribed."))
        elif self.backend.cs.system_status == 'partial':
            self._set_status_icons(PARTIAL_STATUS)
            self.subscription_status_label.set_markup(
                    # I18N: Please add newlines if translation is longer:
                    _("This system does not match subscription limits."))
        elif self.backend.cs.system_status == 'invalid':
            self._set_status_icons(INVALID_STATUS)
            if warn_count > 1:
                self.subscription_status_label.set_markup(
                        # I18N: Please add newlines if translation is longer:
                        _("%s installed products do not have valid subscriptions.")
                        % warn_count)
            else:
                self.subscription_status_label.set_markup(
                        # I18N: Please add newlines if translation is longer:
                        _("1 installed product does not have a valid subscription."))
        elif self.backend.cs.system_status == 'unknown':
            self._set_status_icons(UNKNOWN_STATUS)
            self.subscription_status_label.set_text(
                # I18N: Please add newlines if translation is longer:
                _("Keep your system up to date by registering."))
    def _set_validity_status(self):
        """ Updates the entitlement validity status portion of the UI. """

        if ClassicCheck().is_registered_with_classic():
            self._set_status_icons(VALID_STATUS)
            self.subscription_status_label.set_text(
                get_branding().RHSMD_REGISTERED_TO_OTHER)
            return

        is_registered = self.identity.is_valid()
        self.set_registered(is_registered)

        warn_count = len(self.backend.cs.expired_products) + \
                len(self.backend.cs.unentitled_products)

        if self.backend.cs.system_status == 'valid':
            self._set_status_icons(VALID_STATUS)
            if self.backend.cs.first_invalid_date:
                self.subscription_status_label.set_markup(
                        # I18N: Please add newlines if translation is longer:
                        _("System is properly subscribed through %s.") %
                        managerlib.format_date(self.backend.cs.first_invalid_date))
            else:
                # No product certs installed, no first invalid date, and
                # the subscription assistant can't do anything, so we'll disable
                # the button to launch it:
                self.subscription_status_label.set_text(
                        # I18N: Please add newlines if translation is longer:
                        _("No installed products detected."))
        elif self.backend.cs.system_status == 'partial':
            self._set_status_icons(PARTIAL_STATUS)
            self.subscription_status_label.set_markup(
                    # I18N: Please add newlines if translation is longer:
                    _("This system does not match subscription limits."))
        elif self.backend.cs.system_status == 'invalid':
            self._set_status_icons(INVALID_STATUS)
            if warn_count > 1:
                self.subscription_status_label.set_markup(
                        # I18N: Please add newlines if translation is longer:
                        _("%s installed products do not have valid subscriptions.")
                        % warn_count)
            else:
                self.subscription_status_label.set_markup(
                        # I18N: Please add newlines if translation is longer:
                        _("1 installed product does not have a valid subscription."))
        elif self.backend.cs.system_status == 'unknown':
            self._set_status_icons(UNKNOWN_STATUS)
            self.subscription_status_label.set_text(
                # I18N: Please add newlines if translation is longer:
                _("Keep your system up to date by registering."))
Beispiel #9
0
    def update(self):
        entries = []
        range_calculator = inj.require(inj.PRODUCT_DATE_RANGE_CALCULATOR,
                self.backend.cp_provider.get_consumer_auth_cp())
        for product_cert in self.product_dir.list():
            for product in product_cert.products:
                product_id = product.id
                status = self.backend.cs.get_status(product_id)

                entry = {}
                entry['product'] = product.name
                entry['version'] = product.version
                entry['product_id'] = product_id
                entry['arch'] = ",".join(product.architectures)
                # Common properties
                entry['align'] = 0.5

                # TODO:  Pull this date logic out into a separate lib!
                #        This is also used in mysubstab...
                if status != NOT_SUBSCRIBED:

                    compliant_range = range_calculator.calculate(product.id)
                    start = ''
                    end = ''
                    if compliant_range:
                        start = compliant_range.begin()
                        end = compliant_range.end()

                    contract_ids, sub_names = self._calc_subs_providing(
                            product_id, compliant_range)
                    contract = friendly_join(contract_ids)
                    num_of_contracts = len(contract_ids)

                    entry['subscription'] = list(sub_names)

                    entry['start_date'] = start
                    entry['expiration_date'] = end

                    if status == FUTURE_SUBSCRIBED:
                        entry['image'] = self._render_icon('red')
                        entry['status'] = _('Future Subscription')
                        entry['validity_note'] = _("Future Subscribed")
                    elif status == EXPIRED:
                        entry['image'] = self._render_icon('red')
                        entry['status'] = _('Expired')
                        sub_numbers = set([])
                        for ent_cert in self.entitlement_dir.list_for_product(product_id):
                            order = ent_cert.order
                            # FIXME:  getSubscription() seems to always be None...?
                            if order.subscription:
                                sub_numbers.add(order.subscription)
                        subs_str = ', '.join(sub_numbers)

                        entry['validity_note'] = \
                             _('Subscription %s is expired') % subs_str
                    elif status == PARTIALLY_SUBSCRIBED:
                        entry['image'] = self._render_icon('yellow')
                        entry['status'] = _('Partially Subscribed')
                        entry['validity_note'] = _("Partially Subscribed")
                    elif status == UNKNOWN:
                        entry['image'] = self._render_icon('unknown')
                        entry['status'] = _('Unknown')
                        if not self.backend.cs.is_registered():
                            entry['validity_note'] = _("System is not registered.")
                        else:
                            # System must be registered but unable to reach server:
                            entry['validity_note'] = _("Entitlement server is unreachable.")
                    else:
                        entry['image'] = self._render_icon('green')
                        entry['status'] = _('Subscribed')
                        entry['validity_note'] = \
                            gettext.ngettext("Covered by contract %s through %s",
                                             'Covered by contracts %s through %s',
                                             num_of_contracts) % \
                            (contract,
                             managerlib.format_date(entry['expiration_date']))
                else:
                    entry['image'] = self._render_icon('red')
                    entry['status'] = _('Not Subscribed')
                    entry['validity_note'] = _("Not Subscribed")
                entries.append(entry)
        self._entries = entries
    def test_system_est(self, mock_tz):
        mock_tz.return_value = tzstr('EST5EDT')
        test = datetime(2014, 12, 21, 4, 59, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '12/20/2014')
        test = datetime(2014, 12, 21, 5, 0, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '12/21/2014')
        test = datetime(2014, 12, 21, 5, 1, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '12/21/2014')
        test = datetime(2014, 12, 21, 3, 49, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '12/20/2014')
        test = datetime(2014, 12, 21, 4, 0, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '12/20/2014')
        test = datetime(2014, 12, 21, 4, 1, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '12/20/2014')

        test = datetime(2014, 5, 21, 4, 59, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '05/21/2014')
        test = datetime(2014, 5, 21, 5, 0, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '05/21/2014')
        test = datetime(2014, 5, 21, 5, 1, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '05/21/2014')
        test = datetime(2014, 5, 21, 3, 59, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '05/20/2014')
        test = datetime(2014, 5, 21, 4, 0, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '05/21/2014')
        test = datetime(2014, 5, 21, 4, 1, 0, tzinfo=tzutc())
        self.assertEquals(managerlib.format_date(test), '05/21/2014')
    def test_system_est(self, mock_tz):
        mock_tz.return_value = tzstr("EST5EDT")
        test = datetime(2014, 12, 21, 4, 59, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "12/20/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-12-21")
        test = datetime(2014, 12, 21, 5, 0, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "12/21/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-12-21")
        test = datetime(2014, 12, 21, 5, 1, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "12/21/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-12-21")
        test = datetime(2014, 12, 21, 3, 49, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "12/20/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-12-21")
        test = datetime(2014, 12, 21, 4, 0, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "12/20/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-12-21")
        test = datetime(2014, 12, 21, 4, 1, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "12/20/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-12-21")

        test = datetime(2014, 5, 21, 4, 59, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "05/21/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-05-21")
        test = datetime(2014, 5, 21, 5, 0, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "05/21/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-05-21")
        test = datetime(2014, 5, 21, 5, 1, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "05/21/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-05-21")
        test = datetime(2014, 5, 21, 3, 59, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "05/20/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-05-21")
        test = datetime(2014, 5, 21, 4, 0, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "05/21/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-05-21")
        test = datetime(2014, 5, 21, 4, 1, 0, tzinfo=tzutc())
        self.assertEqual(managerlib.format_date(test), "05/21/2014")
        self.assertEqual(managerlib.format_iso8601_date(test), "2014-05-21")
Beispiel #12
0
    def update(self):
        entries = []
        range_calculator = inj.require(
            inj.PRODUCT_DATE_RANGE_CALCULATOR,
            self.backend.cp_provider.get_consumer_auth_cp())

        installed_products = products.InstalledProducts(
            self.backend.cp_provider.get_consumer_auth_cp()).list()

        for product in installed_products:
            entry = {}
            entry['product'] = product[0]
            entry['product_id'] = product_id = product[1]
            entry['version'] = product[2]
            entry['arch'] = product[
                3]  # TODO: need to test, when more more architectures is supported
            status = product[4]

            # NOTE: following code cannot be used, because start_date and expiration_date
            # are stored in textual form in product and GUI requires datetime format.
            # entry['start_date'] = product[6]
            # entry['expiration_date'] = product[7]

            # Common properties
            entry['align'] = 0.5

            # TODO:  Pull this date logic out into a separate lib!
            #        This is also used in mysubstab...
            if status != NOT_SUBSCRIBED:

                compliant_range = range_calculator.calculate(product_id)
                start = ''
                end = ''
                if compliant_range:
                    start = compliant_range.begin()
                    end = compliant_range.end()
                entry['start_date'] = start
                entry['expiration_date'] = end

                contract_ids, sub_names = self._calc_subs_providing(
                    product_id, compliant_range)
                contract = friendly_join(contract_ids)
                num_of_contracts = len(contract_ids)

                entry['subscription'] = list(sub_names)

                if status == FUTURE_SUBSCRIBED:
                    entry['image'] = self._render_icon('red')
                    entry['status'] = _('Future Subscription')
                    entry['validity_note'] = _("Future Subscribed")
                elif status == EXPIRED:
                    entry['image'] = self._render_icon('red')
                    entry['status'] = _('Expired')
                    sub_numbers = set([])
                    for ent_cert in self.entitlement_dir.list_for_product(
                            product_id):
                        order = ent_cert.order
                        # FIXME:  getSubscription() seems to always be None...?
                        if order.subscription:
                            sub_numbers.add(order.subscription)
                    subs_str = ', '.join(sub_numbers)

                    entry['validity_note'] = \
                         _('Subscription %s is expired') % subs_str
                elif status == PARTIALLY_SUBSCRIBED:
                    entry['image'] = self._render_icon('yellow')
                    entry['status'] = _('Partially Subscribed')
                    entry['validity_note'] = _("Partially Subscribed")
                elif status == UNKNOWN:
                    entry['image'] = self._render_icon('unknown')
                    entry['status'] = _('Unknown')
                    if not self.backend.cs.is_registered():
                        entry['validity_note'] = _("System is not registered.")
                    else:
                        # System must be registered but unable to reach server:
                        entry['validity_note'] = _(
                            "Entitlement server is unreachable.")
                else:
                    entry['image'] = self._render_icon('green')
                    entry['status'] = _('Subscribed')
                    entry['validity_note'] = \
                        ungettext("Covered by contract %s through %s",
                                  'Covered by contracts %s through %s',
                                  num_of_contracts) % \
                        (contract,
                         managerlib.format_date(entry['expiration_date']))
            else:
                entry['image'] = self._render_icon('red')
                entry['status'] = _('Not Subscribed')
                entry['validity_note'] = _("Not Subscribed")
            entries.append(entry)
        self._entries = entries
Beispiel #13
0
    def get_consumed_product_pools(self, service_level=None, matches=None):
        # Use a named tuple so that the result can be unpacked into other functions
        ConsumedStatus = collections.namedtuple('ConsumedStatus', [
            'subscription_name',
            'provides',
            'sku',
            'contract',
            'account',
            'serial',
            'pool_id',
            'provides_management',
            'active',
            'quantity_used',
            'service_level',
            'service_type',
            'status_details',
            'subscription_type',
            'starts',
            'ends',
            'system_type',
        ])
        sorter = inj.require(inj.CERT_SORTER)
        cert_reasons_map = sorter.reasons.get_subscription_reasons_map()
        pooltype_cache = inj.require(inj.POOLTYPE_CACHE)

        consumed_statuses = []
        # FIXME: the cache of CertificateDirectory should be smart enough and refreshing
        # should not be necessary. When new certificate is installed/deleted and rhsm-service
        # is running, then list of certificate is not automatically refreshed ATM.
        self.entitlement_dir.refresh()
        certs = self.entitlement_dir.list()
        cert_filter = utils.EntitlementCertificateFilter(
            filter_string=matches, service_level=service_level)

        if service_level is not None or matches is not None:
            certs = list(filter(cert_filter.match, certs))

        # Now we need to transform the EntitlementCertificate object into
        # something JSON-like for consumption
        for cert in certs:
            # for some certs, order can be empty
            # so we default the values and populate them if
            # they exist. BZ974587
            name = ""
            sku = ""
            contract = ""
            account = ""
            quantity_used = ""
            service_level = ""
            service_type = ""
            system_type = ""
            provides_management = "No"

            order = cert.order

            if order:
                service_level = order.service_level or ""
                service_type = order.service_type or ""
                name = order.name
                sku = order.sku
                contract = order.contract or ""
                account = order.account or ""
                quantity_used = order.quantity_used
                if order.virt_only:
                    system_type = _("Virtual")
                else:
                    system_type = _("Physical")

                if order.provides_management:
                    provides_management = _("Yes")
                else:
                    provides_management = _("No")

            pool_id = _("Not Available")
            if hasattr(cert.pool, "id"):
                pool_id = cert.pool.id

            product_names = [p.name for p in cert.products]

            reasons = []
            pool_type = ''

            if inj.require(inj.CERT_SORTER).are_reasons_supported():
                if cert.subject and 'CN' in cert.subject:
                    if cert.subject['CN'] in cert_reasons_map:
                        reasons = cert_reasons_map[cert.subject['CN']]
                    pool_type = pooltype_cache.get(pool_id)

                # 1180400: Status details is empty when GUI is not
                if not reasons:
                    if cert in sorter.valid_entitlement_certs:
                        reasons.append(_("Subscription is current"))
                    else:
                        if cert.valid_range.end() < datetime.datetime.now(
                                certificate.GMT()):
                            reasons.append(_("Subscription is expired"))
                        else:
                            reasons.append(_("Subscription has not begun"))
            else:
                reasons.append(
                    _("Subscription management service doesn't support Status Details."
                      ))

            consumed_statuses.append(
                ConsumedStatus(
                    name, product_names, sku, contract,
                    account, cert.serial, pool_id, provides_management,
                    cert.is_valid(), quantity_used, service_level,
                    service_type, reasons, pool_type,
                    managerlib.format_date(cert.valid_range.begin()),
                    managerlib.format_date(cert.valid_range.end()),
                    system_type))
        return consumed_statuses
    def update_products(self):
        self.store.clear()
        range_calculator = inj.require(
            inj.PRODUCT_DATE_RANGE_CALCULATOR,
            self.backend.cp_provider.get_consumer_auth_cp())
        for product_cert in self.product_dir.list():
            for product in product_cert.products:
                product_id = product.id
                status = self.backend.cs.get_status(product_id)

                entry = {}
                entry['product'] = product.name
                entry['version'] = product.version
                entry['product_id'] = product_id
                entry['arch'] = ",".join(product.architectures)
                # Common properties
                entry['align'] = 0.5

                # TODO:  Pull this date logic out into a separate lib!
                #        This is also used in mysubstab...
                if status != NOT_SUBSCRIBED:

                    compliant_range = range_calculator.calculate(product.id)
                    start = ''
                    end = ''
                    if compliant_range:
                        start = compliant_range.begin()
                        end = compliant_range.end()

                    contract_ids, sub_names = self._calc_subs_providing(
                        product_id, compliant_range)
                    contract = friendly_join(contract_ids)
                    num_of_contracts = len(contract_ids)

                    entry['subscription'] = list(sub_names)

                    entry['start_date'] = start
                    entry['expiration_date'] = end

                    if status == FUTURE_SUBSCRIBED:
                        entry['image'] = self._render_icon('red')
                        entry['status'] = _('Future Subscription')
                        entry['validity_note'] = _("Future Subscribed")
                    elif status == EXPIRED:
                        entry['image'] = self._render_icon('red')
                        entry['status'] = _('Expired')
                        sub_numbers = set([])
                        for ent_cert in self.entitlement_dir.list_for_product(
                                product_id):
                            order = ent_cert.order
                            # FIXME:  getSubscription() seems to always be None...?
                            if order.subscription:
                                sub_numbers.add(order.subscription)
                        subs_str = ', '.join(sub_numbers)

                        entry['validity_note'] = \
                             _('Subscription %s is expired') % subs_str
                    elif status == PARTIALLY_SUBSCRIBED:
                        entry['image'] = self._render_icon('yellow')
                        entry['status'] = _('Partially Subscribed')
                        entry['validity_note'] = _("Partially Subscribed")
                    elif status == UNKNOWN:
                        entry['image'] = self._render_icon('unknown')
                        entry['status'] = _('Unknown')
                        if not self.backend.cs.is_registered():
                            entry['validity_note'] = _(
                                "System is not registered.")
                        else:
                            # System must be registered but unable to reach server:
                            entry['validity_note'] = _(
                                "Entitlement server is unreachable.")
                    else:
                        entry['image'] = self._render_icon('green')
                        entry['status'] = _('Subscribed')
                        entry['validity_note'] = \
                            gettext.ngettext("Covered by contract %s through %s",
                                             'Covered by contracts %s through %s',
                                             num_of_contracts) % \
                            (contract,
                             managerlib.format_date(entry['expiration_date']))
                else:
                    entry['image'] = self._render_icon('red')
                    entry['status'] = _('Not Subscribed')
                    entry['validity_note'] = _("Not Subscribed")

                # FIXME
                # TODO: fix mapped stores
                self.store.add_map(entry)
        # 811340: Select the first product in My Installed Products
        # table by default.
        selection = self.top_view.get_selection()
        selection.select_path(0)
    def get_consumed_product_pools(self, service_level=None, matches=None):
        # Use a named tuple so that the result can be unpacked into other functions
        ConsumedStatus = collections.namedtuple('ConsumedStatus', [
            'subscription_name',
            'provides',
            'sku',
            'contract',
            'account',
            'serial',
            'pool_id',
            'provides_management',
            'active',
            'quantity_used',
            'service_level',
            'service_type',
            'status_details',
            'subscription_type',
            'starts',
            'ends',
            'system_type',
        ])
        sorter = inj.require(inj.CERT_SORTER)
        cert_reasons_map = sorter.reasons.get_subscription_reasons_map()
        pooltype_cache = inj.require(inj.POOLTYPE_CACHE)

        consumed_statuses = []
        # FIXME: the cache of CertificateDirectory should be smart enough and refreshing
        # should not be necessary. When new certificate is installed/deleted and rhsm-service
        # is running, then list of certificate is not automatically refreshed ATM.
        self.entitlement_dir.refresh()
        certs = self.entitlement_dir.list()
        cert_filter = utils.EntitlementCertificateFilter(filter_string=matches, service_level=service_level)

        if service_level is not None or matches is not None:
            certs = list(filter(cert_filter.match, certs))

        # Now we need to transform the EntitlementCertificate object into
        # something JSON-like for consumption
        for cert in certs:
            # for some certs, order can be empty
            # so we default the values and populate them if
            # they exist. BZ974587
            name = ""
            sku = ""
            contract = ""
            account = ""
            quantity_used = ""
            service_level = ""
            service_type = ""
            system_type = ""
            provides_management = "No"

            order = cert.order

            if order:
                service_level = order.service_level or ""
                service_type = order.service_type or ""
                name = order.name
                sku = order.sku
                contract = order.contract or ""
                account = order.account or ""
                quantity_used = order.quantity_used
                if order.virt_only:
                    system_type = _("Virtual")
                else:
                    system_type = _("Physical")

                if order.provides_management:
                    provides_management = _("Yes")
                else:
                    provides_management = _("No")

            pool_id = _("Not Available")
            if hasattr(cert.pool, "id"):
                pool_id = cert.pool.id

            product_names = [p.name for p in cert.products]

            reasons = []
            pool_type = ''

            if inj.require(inj.CERT_SORTER).are_reasons_supported():
                if cert.subject and 'CN' in cert.subject:
                    if cert.subject['CN'] in cert_reasons_map:
                        reasons = cert_reasons_map[cert.subject['CN']]
                    pool_type = pooltype_cache.get(pool_id)

                # 1180400: Status details is empty when GUI is not
                if not reasons:
                    if cert in sorter.valid_entitlement_certs:
                        reasons.append(_("Subscription is current"))
                    else:
                        if cert.valid_range.end() < datetime.datetime.now(certificate.GMT()):
                            reasons.append(_("Subscription is expired"))
                        else:
                            reasons.append(_("Subscription has not begun"))
            else:
                reasons.append(_("Subscription management service doesn't support Status Details."))

            consumed_statuses.append(ConsumedStatus(
                name,
                product_names,
                sku,
                contract,
                account,
                cert.serial,
                pool_id,
                provides_management,
                cert.is_valid(),
                quantity_used,
                service_level,
                service_type,
                reasons,
                pool_type,
                managerlib.format_date(cert.valid_range.begin()),
                managerlib.format_date(cert.valid_range.end()),
                system_type))
        return consumed_statuses