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)
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()
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)
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), [])
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)
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)
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()