Exemple #1
0
class RecommendationsPanelCategory(RecommendationsPanel):
    """
    Panel for use in the category view that displays recommended apps for
    the given category
    """

    __gsignals__ = {"more-button-clicked": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_PYOBJECT,))}

    def __init__(self, db, properties_helper, subcategory):
        RecommendationsPanel.__init__(self)
        self.db = db
        self.properties_helper = properties_helper
        self.subcategory = subcategory
        if self.subcategory:
            self.set_header_label(
                GLib.markup_escape_text(utf8(_("Recommended For You in %s")) % utf8(self.subcategory.name))
            )
        self.recommended_for_you_content = None
        if self.recommender_agent.is_opted_in():
            self._update_recommended_for_you_content()
        else:
            self.hide()

    def _update_recommended_for_you_content(self):
        # destroy the old content to ensure we don't see it twice
        if self.recommended_for_you_content:
            self.recommended_for_you_content.destroy()
        # add the new stuff
        self.recommended_for_you_content = TileGrid()
        self.recommended_for_you_content.connect("application-activated", self._on_application_activated)
        self.add(self.recommended_for_you_content)
        self.spinner_notebook.show_spinner(_(u"Receiving recommendations…"))
        # get the recommendations from the recommender agent
        self.recommended_for_you_cat = RecommendedForYouCategory(self.db, subcategory=self.subcategory)
        self.recommended_for_you_cat.connect("needs-refresh", self._on_recommended_for_you_agent_refresh)
        self.recommended_for_you_cat.connect("recommender-agent-error", self._on_recommender_agent_error)

    def _on_recommended_for_you_agent_refresh(self, cat):
        self.header_implements_more_button()
        self.more.connect("clicked", self._on_more_button_clicked, self.recommended_for_you_cat)
        docs = cat.get_documents(self.db)
        # display the recommendations
        if len(docs) > 0:
            self.recommended_for_you_content.add_tiles(
                self.properties_helper, docs, LOBBY_RECOMMENDATIONS_CAROUSEL_LIMIT
            )
            self.recommended_for_you_content.show_all()
            self.spinner_notebook.hide_spinner()
            self.header.queue_draw()
            self.show_all()
        else:
            # hide the panel if we have no recommendations to show
            self.hide()

    def _on_more_button_clicked(self, btn, category):
        self.emit("more-button-clicked", category)
Exemple #2
0
 def test_recommends_category(self, AgentMockCls):
     # ensure we use the same instance in test and code
     agent_mock_instance = AgentMockCls.return_value
     recommends_cat = RecommendedForYouCategory(self.db)
     docids = recommends_cat.get_documents(self.db)
     self.assertEqual(docids, [])
     self.assertTrue(agent_mock_instance.query_recommend_me.called)
     # ensure we get a query when the callback is called
     recommends_cat._recommend_me_result(
                             None,
                             make_recommender_agent_recommend_me_dict())
     self.assertNotEqual(recommends_cat.get_documents(self.db), [])
 def test_recommends_in_category_category(self, AgentMockCls):
     # ensure we use the same instance in test and code
     parser = CategoriesParser(self.db)
     cats = parser.parse_applications_menu("./data")
     # "2" is a multimedia query
     #     see ./test/data/desktop/software-center.menu
     recommends_cat = RecommendedForYouCategory(cats[2])
     # ensure we get a query when the callback is called
     recommends_cat._recommend_me_result(
         None, make_recommender_agent_recommend_me_dict())
     recommendations_in_cat = recommends_cat.get_documents(self.db)
     print recommendations_in_cat
     self.assertNotEqual(recommendations_in_cat, [])
class RecommendationsPanelCategory(RecommendationsPanel):
    """
    Panel for use in the category view that displays recommended apps for
    the given category
    """
    def __init__(self, catview, subcategory):
        RecommendationsPanel.__init__(self, catview)
        self.subcategory = subcategory
        if self.subcategory:
            self.set_header_label(GObject.markup_escape_text(utf8(
                _("Recommended For You in %s")) % utf8(self.subcategory.name)))
        self.recommended_for_you_content = None
        if self.recommender_agent.is_opted_in():
            self._update_recommended_for_you_content()
        else:
            self._hide_recommended_for_you_panel()

    def _update_recommended_for_you_content(self):
        # destroy the old content to ensure we don't see it twice
        if self.recommended_for_you_content:
            self.recommended_for_you_content.destroy()
        # add the new stuff
        self.recommended_for_you_content = FlowableGrid()
        self.add(self.recommended_for_you_content)
        self.spinner_notebook.show_spinner(_(u"Receiving recommendations…"))
        # get the recommendations from the recommender agent
        self.recommended_for_you_cat = RecommendedForYouCategory(
                                            subcategory=self.subcategory)
        self.recommended_for_you_cat.connect(
                                    'needs-refresh',
                                    self._on_recommended_for_you_agent_refresh)
        self.recommended_for_you_cat.connect('recommender-agent-error',
                                             self._on_recommender_agent_error)

    def _on_recommended_for_you_agent_refresh(self, cat):
        self.header_implements_more_button()
        docs = cat.get_documents(self.catview.db)
        # display the recommendedations
        if len(docs) > 0:
            self.catview._add_tiles_to_flowgrid(docs,
                                        self.recommended_for_you_content, 12)
            self.recommended_for_you_content.show_all()
            self.spinner_notebook.hide_spinner()
            self.more.connect('clicked',
                              self.catview.on_category_clicked,
                              cat)
            self.header.queue_draw()
            self.show_all()
        else:
            # hide the panel if we have no recommendations to show
            self._hide_recommended_for_you_panel()
Exemple #5
0
 def test_recommends_in_category_category(self, AgentMockCls):
     # ensure we use the same instance in test and code
     parser = CategoriesParser(self.db)
     cats = parser.parse_applications_menu(DATA_DIR)
     # "2" is a multimedia query
     #     see ./test/data/desktop/software-center.menu
     recommends_cat = RecommendedForYouCategory(self.db,
                                                subcategory=cats[2])
     # ensure we get a query when the callback is called
     recommends_cat._recommend_me_result(
                             None,
                             make_recommender_agent_recommend_me_dict())
     recommendations_in_cat = recommends_cat.get_documents(self.db)
     self.assertNotEqual(recommendations_in_cat, [])
class RecommendationsPanelCategory(RecommendationsPanel):
    """
    Panel for use in the category view that displays recommended apps for
    the given category
    """
    def __init__(self, catview, subcategory):
        RecommendationsPanel.__init__(self, catview)
        self.subcategory = subcategory
        if self.subcategory:
            self.set_header_label(
                GObject.markup_escape_text(
                    utf8(_("Recommended For You in %s")) %
                    utf8(self.subcategory.name)))
        self.recommended_for_you_content = None
        if self.recommender_agent.is_opted_in():
            self._update_recommended_for_you_content()
        else:
            self._hide_recommended_for_you_panel()

    def _update_recommended_for_you_content(self):
        # destroy the old content to ensure we don't see it twice
        if self.recommended_for_you_content:
            self.recommended_for_you_content.destroy()
        # add the new stuff
        self.recommended_for_you_content = FlowableGrid()
        self.add(self.recommended_for_you_content)
        self.spinner_notebook.show_spinner(_(u"Receiving recommendations…"))
        # get the recommendations from the recommender agent
        self.recommended_for_you_cat = RecommendedForYouCategory(
            subcategory=self.subcategory)
        self.recommended_for_you_cat.connect(
            'needs-refresh', self._on_recommended_for_you_agent_refresh)
        self.recommended_for_you_cat.connect('recommender-agent-error',
                                             self._on_recommender_agent_error)

    def _on_recommended_for_you_agent_refresh(self, cat):
        self.header_implements_more_button()
        docs = cat.get_documents(self.catview.db)
        # display the recommendedations
        if len(docs) > 0:
            self.catview._add_tiles_to_flowgrid(
                docs, self.recommended_for_you_content, 12)
            self.recommended_for_you_content.show_all()
            self.spinner_notebook.hide_spinner()
            self.more.connect('clicked', self.catview.on_category_clicked, cat)
            self.header.queue_draw()
            self.show_all()
        else:
            # hide the panel if we have no recommendations to show
            self._hide_recommended_for_you_panel()
 def _update_recommended_for_you_content(self):
     # destroy the old content to ensure we don't see it twice
     if self.recommended_for_you_content:
         self.recommended_for_you_content.destroy()
     # add the new stuff
     self.recommended_for_you_content = FlowableGrid()
     self.add(self.recommended_for_you_content)
     self.spinner_notebook.show_spinner(_(u"Receiving recommendations…"))
     # get the recommendations from the recommender agent
     self.recommended_for_you_cat = RecommendedForYouCategory(
         subcategory=self.subcategory)
     self.recommended_for_you_cat.connect(
         'needs-refresh', self._on_recommended_for_you_agent_refresh)
     self.recommended_for_you_cat.connect('recommender-agent-error',
                                          self._on_recommender_agent_error)
Exemple #8
0
 def _update_recommended_for_you_content(self):
     # destroy the old content to ensure we don't see it twice
     if self.recommended_for_you_content:
         self.recommended_for_you_content.destroy()
     # add the new stuff
     self.recommended_for_you_content = TileGrid()
     self.recommended_for_you_content.connect("application-activated", self._on_application_activated)
     self.add(self.recommended_for_you_content)
     self.spinner_notebook.show_spinner(_(u"Receiving recommendations…"))
     # get the recommendations from the recommender agent
     self.recommended_for_you_cat = RecommendedForYouCategory(self.db, subcategory=self.subcategory)
     self.recommended_for_you_cat.connect("needs-refresh", self._on_recommended_for_you_agent_refresh)
     self.recommended_for_you_cat.connect("recommender-agent-error", self._on_recommender_agent_error)
 def test_recommends_category(self, AgentMockCls):
     # ensure we use the same instance in test and code
     agent_mock_instance = AgentMockCls.return_value
     recommends_cat = RecommendedForYouCategory()
     docids = recommends_cat.get_documents(self.db)
     self.assertEqual(docids, [])
     self.assertTrue(agent_mock_instance.query_recommend_me.called)
     # ensure we get a query when the callback is called
     recommends_cat._recommend_me_result(
         None, make_recommender_agent_recommend_me_dict())
     self.assertNotEqual(recommends_cat.get_documents(self.db), [])
Exemple #10
0
 def _update_recommended_for_you_content(self):
     # destroy the old content to ensure we don't see it twice
     # (also removes the opt-in panel if it was there)
     if self.recommended_for_you_content:
         self.recommended_for_you_content.destroy()
     # add the new stuff
     self.header_implements_more_button()
     self.recommended_for_you_content = FlowableGrid()
     self.add(self.recommended_for_you_content)
     self.spinner_notebook.show_spinner(_(u"Receiving recommendations…"))
     # get the recommendations from the recommender agent
     self.recommended_for_you_cat = RecommendedForYouCategory()
     self.recommended_for_you_cat.connect(
                                 'needs-refresh',
                                 self._on_recommended_for_you_agent_refresh)
     self.recommended_for_you_cat.connect('recommender-agent-error',
                                          self._on_recommender_agent_error)
Exemple #11
0
class RecommendationsPanelCategory(RecommendationsPanel):
    """
    Panel for use in the category view that displays recommended apps for
    the given category
    """

    __gsignals__ = {
        "more-button-clicked": (GObject.SignalFlags.RUN_LAST,
                                None,
                                (GObject.TYPE_PYOBJECT, ),
                                ),
    }

    def __init__(self, db, properties_helper, subcategory):
        RecommendationsPanel.__init__(self)
        self.db = db
        self.properties_helper = properties_helper
        self.subcategory = subcategory
        if self.subcategory:
            self.set_header_label(GLib.markup_escape_text(utf8(
                _("Recommended For You in %s")) % utf8(self.subcategory.name)))
        self.recommended_for_you_content = None
        if self.recommender_agent.is_opted_in():
            self._update_recommended_for_you_content()
        else:
            self.hide()

    def _update_recommended_for_you_content(self):
        # destroy the old content to ensure we don't see it twice
        if self.recommended_for_you_content:
            self.recommended_for_you_content.destroy()
        # add the new stuff
        self.recommended_for_you_content = TileGrid()
        self.recommended_for_you_content.connect(
                    "application-activated", self._on_application_activated)
        self.add(self.recommended_for_you_content)
        self.spinner_notebook.show_spinner(_(u"Receiving recommendations…"))
        # get the recommendations from the recommender agent
        self.recommended_for_you_cat = RecommendedForYouCategory(
                                            self.db,
                                            subcategory=self.subcategory)
        self.recommended_for_you_cat.connect(
                                    'needs-refresh',
                                    self._on_recommended_for_you_agent_refresh)
        self.recommended_for_you_cat.connect('recommender-agent-error',
                                             self._on_recommender_agent_error)

    def _on_recommended_for_you_agent_refresh(self, cat):
        self.header_implements_more_button()
        self.more.connect("clicked",
                          self._on_more_button_clicked,
                          self.recommended_for_you_cat)
        docs = cat.get_documents(self.db)
        # display the recommendations
        if len(docs) > 0:
            self.recommended_for_you_content.add_tiles(
                    self.properties_helper,
                    docs,
                    LOBBY_RECOMMENDATIONS_CAROUSEL_LIMIT)
            self.recommended_for_you_content.show_all()
            self.spinner_notebook.hide_spinner()
            self.header.queue_draw()
            self.show_all()
        else:
            # hide the panel if we have no recommendations to show
            self.hide()

    def _on_more_button_clicked(self, btn, category):
        self.emit("more-button-clicked", category)
Exemple #12
0
class RecommendationsPanelLobby(RecommendationsPanel):
    """
    Panel for use in the lobby view that manages the recommendations
    experience, includes the initial opt-in screen and display of
    recommendations once they have been received from the recommender agent
    """
    __gsignals__ = {
        "recommendations-opt-in": (GObject.SIGNAL_RUN_LAST,
                                   GObject.TYPE_NONE,
                                   (GObject.TYPE_STRING,),
                                  ),
        "recommendations-opt-out": (GObject.SIGNAL_RUN_LAST,
                                    GObject.TYPE_NONE,
                                    (),
                                   ),
        }

    def __init__(self, catview):
        RecommendationsPanel.__init__(self, catview)
        self.set_header_label(_(u"Recommended for You"))

        # if we already have a recommender UUID, then the user is already
        # opted-in to the recommender service
        self.recommended_for_you_content = None
        if self.recommender_agent.recommender_uuid:
            self._update_recommended_for_you_content()
        else:
            self._show_opt_in_view()

    def _show_opt_in_view(self):
        # opt in box
        vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, StockEms.MEDIUM)
        vbox.set_border_width(StockEms.LARGE)
        self.opt_in_vbox = vbox  # for tests
        self.recommended_for_you_content = vbox  # hook it up to the rest

        self.add(self.recommended_for_you_content)

        # opt in button
        button = Gtk.Button(_("Turn On Recommendations"))
        button.connect("clicked", self._on_opt_in_button_clicked)
        hbox = Gtk.Box(Gtk.Orientation.HORIZONTAL)
        hbox.pack_start(button, False, False, 0)
        vbox.pack_start(hbox, False, False, 0)
        self.opt_in_button = button  # for tests

        # opt in text
        text = _("To make recommendations, Ubuntu Software Center "
                 "will occasionally send to Canonical an anonymous list "
                 "of software currently installed.")
        label = Gtk.Label(text)
        label.set_alignment(0, 0.5)
        label.set_line_wrap(True)
        vbox.pack_start(label, False, False, 0)

    def _on_opt_in_button_clicked(self, button):
        # we upload the user profile here, and only after this is finished
        # do we fire the request for recommendations and finally display
        # them here -- a spinner is shown for this process (the spec
        # wants a progress bar, but we don't have access to real-time
        # progress info)
        self._upload_user_profile_and_get_recommendations()

    def _upload_user_profile_and_get_recommendations(self):
        # initiate upload of the user profile here
        self._upload_user_profile()

    def _upload_user_profile(self):
        self.spinner_notebook.show_spinner(_(u"Submitting inventory…"))
        self.recommender_agent.connect("submit-profile-finished",
                                  self._on_profile_submitted)
        self.recommender_agent.connect("error",
                                  self._on_profile_submitted_error)
        self.recommender_agent.post_submit_profile(self.catview.db)

    def _on_profile_submitted(self, agent, profile, recommender_uuid):
        # after the user profile data has been uploaded, make the request
        # and load the the recommended_for_you content
        LOG.debug("The recommendations profile has been successfully "
                  "submitted to the recommender agent")
        self.emit("recommendations-opt-in", recommender_uuid)
        self._update_recommended_for_you_content()

    def _on_profile_submitted_error(self, agent, msg):
        LOG.warn("Error while submitting the recommendations profile to the "
                 "recommender agent: %s" % msg)
        # TODO: handle this! display an error message in the panel
        self._hide_recommended_for_you_panel()

    def _update_recommended_for_you_content(self):
        # destroy the old content to ensure we don't see it twice
        # (also removes the opt-in panel if it was there)
        if self.recommended_for_you_content:
            self.recommended_for_you_content.destroy()
        # add the new stuff
        self.header_implements_more_button()
        self.recommended_for_you_content = FlowableGrid()
        self.add(self.recommended_for_you_content)
        self.spinner_notebook.show_spinner(_(u"Receiving recommendations…"))
        # get the recommendations from the recommender agent
        self.recommended_for_you_cat = RecommendedForYouCategory()
        self.recommended_for_you_cat.connect(
                                    'needs-refresh',
                                    self._on_recommended_for_you_agent_refresh)
        self.recommended_for_you_cat.connect('recommender-agent-error',
                                             self._on_recommender_agent_error)

    def _on_recommended_for_you_agent_refresh(self, cat):
        docs = cat.get_documents(self.catview.db)
        # display the recommendedations
        if len(docs) > 0:
            self.catview._add_tiles_to_flowgrid(docs,
                                        self.recommended_for_you_content, 8)
            self.recommended_for_you_content.show_all()
            self.spinner_notebook.hide_spinner()
            self.more.connect('clicked',
                              self.catview.on_category_clicked,
                              cat)
        else:
            # TODO: this test for zero docs is temporary and will not be
            # needed once the recommendation agent is up and running
            self._hide_recommended_for_you_panel()

    def _on_recommender_agent_error(self, agent, msg):
        LOG.warn("Error while accessing the recommender agent for the "
                 "lobby recommendations: %s" % msg)
        # TODO: temporary, instead we will display cached recommendations here
        self._hide_recommended_for_you_panel()

    def _hide_recommended_for_you_panel(self):
        # and hide the pane
        self.hide()