Merge lp:~mvo/software-center/recommender_uuid_consolidation into lp:software-center

Proposed by Michael Vogt
Status: Rejected
Rejected by: Michael Vogt
Proposed branch: lp:~mvo/software-center/recommender_uuid_consolidation
Merge into: lp:software-center
Diff against target: 169 lines (+51/-39)
4 files modified
softwarecenter/backend/recagent.py (+31/-13)
softwarecenter/ui/gtk3/app.py (+0/-26)
softwarecenter/ui/gtk3/widgets/recommendations.py (+7/-0)
test/test_recagent.py (+13/-0)
To merge this branch: bzr merge lp:~mvo/software-center/recommender_uuid_consolidation
Reviewer Review Type Date Requested Status
Gary Lasker (community) Needs Fixing
Review via email: mp+95322@code.launchpad.net

Description of the change

This branch does some cleanup in the way we store the recommender_uuid.

All usage from app.py is removed as its currently not used or needed there. We only use it to write it in the config
but that can be done in the recagent.py as well.

The RecommenderAgent.recommender_uuid is a property to ensure its always in sync with the (global singelton)
SoftwareCenterConfig. This ensures that on close SoftwareCenterConfig.write() will include the recommender_uuid
value.

Plus a test to ensure that the property is calling the SoftwareCenterConfig in the expected way.

To post a comment you must log in.
Revision history for this message
Gary Lasker (gary-lasker) wrote :
Download full text (4.3 KiB)

Hi mvo, thanks for this! I think it's a good idea to consolidate the UUID stuff more, however, there are two reasons why I left the connection to app.py (with the signal). The first is because I planned to add an opt-out menu item (which will be a dead-simple change). The second is that I thought it best to keep all of the code that writes to the main config file in one place, that is, in app.py. Else somebody else will have to search if they want to explain where this mysterious other field is coming from in the main config file.

In any case, I am seeing two problems with it the current branch. One is a failure in the unit test, the other occurs when running the app itself (specifically, soemthing that would occur during a first run in a new install, further details below).

First, the unit test:

======================================================================
ERROR: test_mocked_recagent_post_submit_profile (__main__.TestRecommenderAgent)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_recagent.py", line 48, in test_mocked_recagent_post_submit_profile
    recommender_agent.post_submit_profile(db)
  File "/home/tremolux/Projects/precise/software-center_review_mvo_recommender_uuid_consolidation/software-center/softwarecenter/backend/recagent.py", line 98, in post_submit_profile
    self.recommender_uuid = get_uuid()
  File "/home/tremolux/Projects/precise/software-center_review_mvo_recommender_uuid_consolidation/software-center/softwarecenter/backend/recagent.py", line 236, in _set_recommender_uuid
    config.set("general", "recommender_uuid", self.recommender_uuid)
  File "/usr/lib/python2.7/ConfigParser.py", line 753, in set
    ConfigParser.set(self, section, option, value)
  File "/usr/lib/python2.7/ConfigParser.py", line 396, in set
    raise NoSectionError(section)
NoSectionError: No section: 'general'

======================================================================
FAIL: test_recagent_recommender_uuid_property (__main__.TestRecommenderAgent)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_recagent.py", line 161, in test_recagent_recommender_uuid_property
    self.assertEqual(recommender_agent.recommender_uuid, "foxy-uuid")
AssertionError: '' != 'foxy-uuid'

----------------------------------------------------------------------
Ran 7 tests in 6.296s

FAILED (failures=1, errors=1)

---

And the failure with the app itself occurs in the case where we have not yet made the cfg file (you can see this with a 'rm .config/software-center/softwarecenter.cfg'). This would happen on first run of software-center for a new install, for instance, and if the user opt-in to recommendations then. What happens in the UI is that the "Uploading user profile" spinner hangs.

Traceback (most recent call last):
  File "/home/tremolux/Projects/precise/software-center_review_mvo_recommender_uuid_consolidation/software-center/softwarecenter/ui/gtk3/widgets/recommendations.py", line 127, in _on_opt_in_button_clicked
    self._upload_user_profile_and_get_recommendations()
  File "/home/tremolux/Projects/precis...

Read more...

review: Needs Fixing
Revision history for this message
Michael Vogt (mvo) wrote :

I set this to rejected as it no longer applies with the recent changes.

Unmerged revisions

2799. By Michael Vogt

REFACTOR: remove recommender_uuid from app.py as it does not need to know about this (the widget is self contained currently and the state can set set using the global get_config() config that will saved on s-c exit); also make recommender_uuid a property so that reads/writes are automatically stored in the global s-c config

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'softwarecenter/backend/recagent.py'
--- softwarecenter/backend/recagent.py 2012-02-28 20:27:50 +0000
+++ softwarecenter/backend/recagent.py 2012-03-01 09:12:23 +0000
@@ -75,8 +75,8 @@
75 def __init__(self, xid=None):75 def __init__(self, xid=None):
76 GObject.GObject.__init__(self)76 GObject.GObject.__init__(self)
77 self.xid = xid77 self.xid = xid
78 self.recommender_uuid = self._get_recommender_uuid()
7978
79 # methods
80 def query_server_status(self):80 def query_server_status(self):
81 # build the command81 # build the command
82 spawner = SpawnHelper()82 spawner = SpawnHelper()
@@ -202,18 +202,6 @@
202 def _on_recommend_top_data(self, spawner, piston_top_apps):202 def _on_recommend_top_data(self, spawner, piston_top_apps):
203 self.emit("recommend-top", piston_top_apps)203 self.emit("recommend-top", piston_top_apps)
204 204
205 def _get_recommender_uuid(self):
206 """ returns the recommender UUID value, which can be empty if it
207 has not yet been set (indicating that the user has not yet
208 opted-in to the recommender service)
209 """
210 config = get_config()
211 if config.has_option("general", "recommender_uuid"):
212 recommender_uuid = config.get("general", "recommender_uuid")
213 if recommender_uuid:
214 return recommender_uuid
215 return ""
216
217 def _generate_submit_profile_data(self, recommender_uuid, package_list):205 def _generate_submit_profile_data(self, recommender_uuid, package_list):
218 submit_profile_data = [206 submit_profile_data = [
219 {207 {
@@ -223,6 +211,36 @@
223 ]211 ]
224 return submit_profile_data212 return submit_profile_data
225213
214 # properties
215 def _get_recommender_uuid(self):
216 """ returns the recommender UUID value, which can be empty if it
217 has not yet been set (indicating that the user has not yet
218 opted-in to the recommender service)
219 """
220 if not hasattr(self, "_recommender_uuid"):
221 config = get_config()
222 if config.has_option("general", "recommender_uuid"):
223 self._recommender_uuid = config.get(
224 "general", "recommender_uuid")
225 else:
226 self._recommender_uuid = ""
227 return self._recommender_uuid
228
229 return self._recommender_uuid
230 def _set_recommender_uuid(self, value):
231 """ this sets the recommender UUID value, both internally for
232 this class and in the app wide software-center config
233 """
234 self._recommender_uuid = value
235 config = get_config()
236 config.set("general", "recommender_uuid", self.recommender_uuid)
237 recommender_uuid = property(
238 _get_recommender_uuid, _set_recommender_uuid, None,
239 """ The (persistent) recommender_uuid property that is stored
240 in the config under general/recommender_uuid
241 """)
242
243
226 244
227if __name__ == "__main__":245if __name__ == "__main__":
228 from gi.repository import Gtk246 from gi.repository import Gtk
229247
=== modified file 'softwarecenter/ui/gtk3/app.py'
--- softwarecenter/ui/gtk3/app.py 2012-02-29 17:23:24 +0000
+++ softwarecenter/ui/gtk3/app.py 2012-03-01 09:12:23 +0000
@@ -258,7 +258,6 @@
258 self.scagent = None258 self.scagent = None
259 self.sso = None259 self.sso = None
260 self.available_for_me_query = None260 self.available_for_me_query = None
261 self.recommender_uuid = ""
262261
263 Gtk.Window.set_default_icon_name("softwarecenter")262 Gtk.Window.set_default_icon_name("softwarecenter")
264263
@@ -468,25 +467,6 @@
468467
469 def on_available_pane_created(self, widget):468 def on_available_pane_created(self, widget):
470 self.available_pane.searchentry.grab_focus()469 self.available_pane.searchentry.grab_focus()
471 # connect a signal to monitor the recommendations opt-in state and
472 # persist the recommendations uuid on an opt-in
473 self.available_pane.cat_view.recommended_for_you_panel.connect(
474 "recommendations-opt-in",
475 self._on_recommendations_opt_in)
476 self.available_pane.cat_view.recommended_for_you_panel.connect(
477 "recommendations-opt-out",
478 self._on_recommendations_opt_out)
479
480 #~ def on_installed_pane_created(self, widget):
481 #~ pass
482
483 def _on_recommendations_opt_in(self, agent, recommender_uuid):
484 self.recommender_uuid = recommender_uuid
485
486 def _on_recommendations_opt_out(self):
487 # if the user opts back out of the recommender service, we
488 # reset the UUID to indicate it
489 self.recommender_uuid = ""
490 470
491 def _on_update_software_center_agent_finished(self, pid, condition):471 def _on_update_software_center_agent_finished(self, pid, condition):
492 LOG.info("software-center-agent finished with status %i" % os.WEXITSTATUS(condition))472 LOG.info("software-center-agent finished with status %i" % os.WEXITSTATUS(condition))
@@ -1231,9 +1211,6 @@
1231 else:1211 else:
1232 # initial default state is to add to launcher, per spec1212 # initial default state is to add to launcher, per spec
1233 self.available_pane.add_to_launcher_enabled = True1213 self.available_pane.add_to_launcher_enabled = True
1234 if self.config.has_option("general", "recommender_uuid"):
1235 self.recommender_uuid = self.config.get("general",
1236 "recommender_uuid")
12371214
1238 def save_state(self):1215 def save_state(self):
1239 LOG.debug("save_state")1216 LOG.debug("save_state")
@@ -1255,9 +1232,6 @@
1255 self.config.set("general", "add_to_launcher", "True")1232 self.config.set("general", "add_to_launcher", "True")
1256 else:1233 else:
1257 self.config.set("general", "add_to_launcher", "False")1234 self.config.set("general", "add_to_launcher", "False")
1258 self.config.set("general",
1259 "recommender_uuid",
1260 self.recommender_uuid)
1261 self.config.write()1235 self.config.write()
12621236
1263 def run(self, args):1237 def run(self, args):
12641238
=== modified file 'softwarecenter/ui/gtk3/widgets/recommendations.py'
--- softwarecenter/ui/gtk3/widgets/recommendations.py 2012-02-29 19:58:05 +0000
+++ softwarecenter/ui/gtk3/widgets/recommendations.py 2012-03-01 09:12:23 +0000
@@ -110,6 +110,13 @@
110 label.set_alignment(0, 0.5)110 label.set_alignment(0, 0.5)
111 label.set_line_wrap(True)111 label.set_line_wrap(True)
112 vbox.pack_start(label, False, False, 0)112 vbox.pack_start(label, False, False, 0)
113
114 # FIXME: there is no opt-out button yet!
115 def _on_opt_out_button_clicked(self, button):
116 # if the user opts back out of the recommender service, we
117 # reset the UUID to indicate it
118 self.recommender_agent.recommender_uuid = ""
119 self.emit("recommendations-opt-out")
113 120
114 def _on_opt_in_button_clicked(self, button):121 def _on_opt_in_button_clicked(self, button):
115 # we upload the user profile here, and only after this is finished122 # we upload the user profile here, and only after this is finished
116123
=== modified file 'test/test_recagent.py'
--- test/test_recagent.py 2012-03-01 00:14:51 +0000
+++ test/test_recagent.py 2012-03-01 09:12:23 +0000
@@ -152,6 +152,19 @@
152 self.loop.run()152 self.loop.run()
153 self.assertTrue(self.error)153 self.assertTrue(self.error)
154154
155 @patch('softwarecenter.config.SoftwareCenterConfig')
156 def test_recagent_recommender_uuid_property(self, mock_config_klass):
157 mock_config = mock_config_klass.return_value
158 mock_config.has_option.return_value = True
159 mock_config.get.return_value = "foxy-uuid"
160 recommender_agent = RecommenderAgent()
161 self.assertEqual(recommender_agent.recommender_uuid, "foxy-uuid")
162 recommender_agent.recommender_uuid = "new-value"
163 self.assertEqual(recommender_agent.recommender_uuid, "new-value")
164 self.assertTrue(mock_config.set.called)
165 mock_config.set.assertCalledWith("general","recommender_uuid",
166 "new-value")
167
155if __name__ == "__main__":168if __name__ == "__main__":
156 #import logging169 #import logging
157 #logging.basicConfig(level=logging.DEBUG)170 #logging.basicConfig(level=logging.DEBUG)

Subscribers

People subscribed via source and target branches