Merge lp:~mvo/software-center/spinner-while-agent-runs-5.2 into lp:software-center/5.2

Proposed by Michael Vogt
Status: Work in progress
Proposed branch: lp:~mvo/software-center/spinner-while-agent-runs-5.2
Merge into: lp:software-center/5.2
Diff against target: 202 lines (+75/-21)
4 files modified
softwarecenter/db/database.py (+32/-0)
softwarecenter/ui/gtk3/app.py (+1/-18)
softwarecenter/ui/gtk3/views/appdetailsview.py (+22/-2)
test/gtk3/test_appdetailsview.py (+20/-1)
To merge this branch: bzr merge lp:~mvo/software-center/spinner-while-agent-runs-5.2
Reviewer Review Type Date Requested Status
Gary Lasker (community) Approve
Review via email: mp+118978@code.launchpad.net

Description of the change

This branch adds a spinner that is displayed if a app is not found but there is a update going on in the background. No string change as this is targeted for precise.

To post a comment you must log in.
Revision history for this message
Michael Vogt (mvo) wrote :

We could use the "In Progress..." string that we have already, but there is really no good one in our pot.

3079. By Michael Vogt

softwarecenter/ui/gtk3/widgets/spinner.py: remove spurious change

Revision history for this message
Gary Lasker (gary-lasker) wrote :

Hi Michael, thanks for this! The code looks fine to me. I especially like that you moved the update-software-center-agent code out of app.py and into the backend.

I know that there was some discussion today about the UI implementation, and I believe that as a result of this you plan to do more work on this branch. I just wanted to approve it as it is in case you decide to stick with it. If you make further changes, I'll be happy to review them.

I do have one question. I noticed that the spinner is only displayed in the application's icon area and the text area to the right still prominently displays the "Not found" message. Would it be better to just show a spinner for the entire view instead? Just wondering what you think about that (since we can't change strings for the SRU, as you mentioned).

review: Approve

Unmerged revisions

3079. By Michael Vogt

softwarecenter/ui/gtk3/widgets/spinner.py: remove spurious change

3078. By Michael Vogt

add test for spinner

3077. By Michael Vogt

fix pep8

3076. By Michael Vogt

add "update-software-center-agent-finished" signal to the db

3075. By Michael Vogt

softwarecenter/ui/gtk3/views/appdetailsview.py: ensure the spinner is updated

3074. By Michael Vogt

add self.app_icon_spinner to be able to show the spinner

3073. By Michael Vogt

softwarecenter/db/database.py: fix datadir

3072. By Michael Vogt

move the update-software-center-agent functionality from the app.py into the DB

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'softwarecenter/db/database.py'
--- softwarecenter/db/database.py 2012-05-22 13:39:12 +0000
+++ softwarecenter/db/database.py 2012-08-10 12:55:22 +0000
@@ -135,6 +135,10 @@
135 "open": (GObject.SIGNAL_RUN_FIRST,135 "open": (GObject.SIGNAL_RUN_FIRST,
136 GObject.TYPE_NONE,136 GObject.TYPE_NONE,
137 (GObject.TYPE_STRING,)),137 (GObject.TYPE_STRING,)),
138 "update-software-center-agent-finished": (
139 GObject.SIGNAL_RUN_FIRST,
140 GObject.TYPE_NONE,
141 (GObject.TYPE_BOOLEAN,)),
138 }142 }
139143
140 def __init__(self, pathname=None, cache=None):144 def __init__(self, pathname=None, cache=None):
@@ -157,6 +161,7 @@
157 self._db_per_thread = {}161 self._db_per_thread = {}
158 self._parser_per_thread = {}162 self._parser_per_thread = {}
159 self._axi_stamp_monitor = None163 self._axi_stamp_monitor = None
164 self._software_center_agent_update_in_progress = False
160165
161 @property166 @property
162 def xapiandb(self):167 def xapiandb(self):
@@ -584,6 +589,33 @@
584 matches.append(FakeMSetItem(match))589 matches.append(FakeMSetItem(match))
585 return matches590 return matches
586591
592 # software-center-agent releated API
593 def update_software_center_agent(self, delay=0):
594 """ Update the list of available application from the net
595 """
596 self._software_center_agent_update_in_progress = True
597 GObject.timeout_add_seconds(delay, self._run_software_center_agent)
598
599 def _run_software_center_agent(self):
600 """ helper that triggers the update-software-center-agent helper """
601 datadir = softwarecenter.paths.datadir
602 sc_agent_update = os.path.join(
603 datadir, "update-software-center-agent")
604 (pid, stdin, stdout, stderr) = GObject.spawn_async(
605 [sc_agent_update, "--datadir", datadir],
606 flags=GObject.SPAWN_DO_NOT_REAP_CHILD)
607 GObject.child_watch_add(
608 pid, self._on_update_software_center_agent_finished)
609
610 def _on_update_software_center_agent_finished(self, pid, condition):
611 LOG.info("software-center-agent finished with status %i" %
612 os.WEXITSTATUS(condition))
613 success = (os.WEXITSTATUS(condition) == 0)
614 self._software_center_agent_update_in_progress = False
615 if success:
616 self.reopen()
617 self.emit("update-software-center-agent-finished", success)
618
587 def __len__(self):619 def __len__(self):
588 """return the doc count of the database"""620 """return the doc count of the database"""
589 return self.xapiandb.get_doccount()621 return self.xapiandb.get_doccount()
590622
=== modified file 'softwarecenter/ui/gtk3/app.py'
--- softwarecenter/ui/gtk3/app.py 2012-06-11 09:56:45 +0000
+++ softwarecenter/ui/gtk3/app.py 2012-08-10 12:55:22 +0000
@@ -462,8 +462,7 @@
462 if not (options.enable_lp or och):462 if not (options.enable_lp or och):
463 self.menu_file.remove(self.separator_login)463 self.menu_file.remove(self.separator_login)
464 else:464 else:
465 # running the agent will trigger a db reload so we do it later465 self.db.update_software_center_agent(delay=3)
466 GObject.timeout_add_seconds(3, self._run_software_center_agent)
467466
468 # keep the cache clean467 # keep the cache clean
469 GObject.timeout_add_seconds(15, self._run_expunge_cache_helper)468 GObject.timeout_add_seconds(15, self._run_expunge_cache_helper)
@@ -489,16 +488,6 @@
489 LOG.debug("launchpad integration error: '%s'" % e)488 LOG.debug("launchpad integration error: '%s'" % e)
490489
491 # helper490 # helper
492 def _run_software_center_agent(self):
493 """ helper that triggers the update-software-center-agent helper """
494 sc_agent_update = os.path.join(
495 self.datadir, "update-software-center-agent")
496 (pid, stdin, stdout, stderr) = GObject.spawn_async(
497 [sc_agent_update, "--datadir", self.datadir],
498 flags=GObject.SPAWN_DO_NOT_REAP_CHILD)
499 GObject.child_watch_add(
500 pid, self._on_update_software_center_agent_finished)
501
502 def _run_expunge_cache_helper(self):491 def _run_expunge_cache_helper(self):
503 """ helper that expires the piston-mini-client cache """492 """ helper that expires the piston-mini-client cache """
504 sc_expunge_cache = os.path.join(493 sc_expunge_cache = os.path.join(
@@ -593,12 +582,6 @@
593 self._recommender_agent = RecommenderAgent()582 self._recommender_agent = RecommenderAgent()
594 return self._recommender_agent583 return self._recommender_agent
595584
596 def _on_update_software_center_agent_finished(self, pid, condition):
597 LOG.info("software-center-agent finished with status %i" %
598 os.WEXITSTATUS(condition))
599 if os.WEXITSTATUS(condition) == 0:
600 self.db.reopen()
601
602 def on_review_stats_loaded(self, reviews):585 def on_review_stats_loaded(self, reviews):
603 LOG.debug("on_review_stats_loaded: '%s'" % len(reviews))586 LOG.debug("on_review_stats_loaded: '%s'" % len(reviews))
604587
605588
=== modified file 'softwarecenter/ui/gtk3/views/appdetailsview.py'
--- softwarecenter/ui/gtk3/views/appdetailsview.py 2012-06-28 08:10:33 +0000
+++ softwarecenter/ui/gtk3/views/appdetailsview.py 2012-08-10 12:55:22 +0000
@@ -64,6 +64,7 @@
64from softwarecenter.ui.gtk3.widgets.containers import SmallBorderRadiusFrame64from softwarecenter.ui.gtk3.widgets.containers import SmallBorderRadiusFrame
65from softwarecenter.ui.gtk3.widgets.stars import Star, StarRatingsWidget65from softwarecenter.ui.gtk3.widgets.stars import Star, StarRatingsWidget
66from softwarecenter.ui.gtk3.widgets.description import AppDescription66from softwarecenter.ui.gtk3.widgets.description import AppDescription
67from softwarecenter.ui.gtk3.widgets.spinner import SpinnerNotebook
67from softwarecenter.ui.gtk3.widgets.thumbnail import ScreenshotGallery68from softwarecenter.ui.gtk3.widgets.thumbnail import ScreenshotGallery
68from softwarecenter.ui.gtk3.widgets.videoplayer import VideoPlayer69from softwarecenter.ui.gtk3.widgets.videoplayer import VideoPlayer
69from softwarecenter.ui.gtk3.widgets.weblivedialog import (70from softwarecenter.ui.gtk3.widgets.weblivedialog import (
@@ -817,6 +818,9 @@
817 Viewport.__init__(self)818 Viewport.__init__(self)
818 # basic stuff819 # basic stuff
819 self.db = db820 self.db = db
821 self.db.connect(
822 "update-software-center-agent-finished",
823 self._on_update_software_center_agent_finished)
820 self.distro = distro824 self.distro = distro
821 self.icons = icons825 self.icons = icons
822 self.cache = cache826 self.cache = cache
@@ -1144,9 +1148,11 @@
1144 hb.set_spacing(StockEms.MEDIUM)1148 hb.set_spacing(StockEms.MEDIUM)
1145 vb.pack_start(hb, False, False, 0)1149 vb.pack_start(hb, False, False, 0)
11461150
1147 # the app icon1151 # the app icon / spinner combo
1148 self.icon = Gtk.Image()1152 self.icon = Gtk.Image()
1149 hb.pack_start(self.icon, False, False, 0)1153 self.icon.show()
1154 self.app_icon_spinner = SpinnerNotebook(self.icon)
1155 hb.pack_start(self.app_icon_spinner, False, False, 0)
11501156
1151 # the app title/summary1157 # the app title/summary
1152 self.title = Gtk.Label()1158 self.title = Gtk.Label()
@@ -1356,6 +1362,9 @@
1356 self.subtitle.set_markup(summary)1362 self.subtitle.set_markup(summary)
13571363
1358 def _update_app_icon(self, app_details):1364 def _update_app_icon(self, app_details):
1365 # update the spinner
1366 self._update_spinner(app_details)
1367
1359 pb = self._get_icon_as_pixbuf(app_details)1368 pb = self._get_icon_as_pixbuf(app_details)
1360 # should we show the green tick?1369 # should we show the green tick?
1361# self._show_overlay = app_details.pkg_state == PkgStates.INSTALLED1370# self._show_overlay = app_details.pkg_state == PkgStates.INSTALLED
@@ -1508,6 +1517,17 @@
1508 # Update addons state bar1517 # Update addons state bar
1509 self.addons_statusbar.configure()1518 self.addons_statusbar.configure()
15101519
1520 def _on_update_software_center_agent_finished(self, database, result):
1521 if self.app_details:
1522 self._update_spinner(self.app_details)
1523
1524 def _update_spinner(self, app_details):
1525 if app_details.pkg_state is PkgStates.NOT_FOUND:
1526 if self.db._software_center_agent_update_in_progress:
1527 self.app_icon_spinner.show_spinner()
1528 else:
1529 self.app_icon_spinner.hide_spinner()
1530
1511 def _update_all(self, app_details, skip_update_addons=False):1531 def _update_all(self, app_details, skip_update_addons=False):
1512 # reset view to top left1532 # reset view to top left
1513 vadj = self.get_vadjustment()1533 vadj = self.get_vadjustment()
15141534
=== modified file 'test/gtk3/test_appdetailsview.py'
--- test/gtk3/test_appdetailsview.py 2012-06-18 14:39:27 +0000
+++ test/gtk3/test_appdetailsview.py 2012-08-10 12:55:22 +0000
@@ -11,7 +11,11 @@
11from mock import Mock, patch11from mock import Mock, patch
1212
13from softwarecenter.db.application import Application13from softwarecenter.db.application import Application
14from softwarecenter.testutils import get_mock_app_from_real_app, do_events, make_recommend_app_data14from softwarecenter.testutils import (
15 get_mock_app_from_real_app,
16 do_events,
17 make_recommend_app_data,
18 do_events_with_sleep)
15from softwarecenter.ui.gtk3.widgets.labels import HardwareRequirementsBox19from softwarecenter.ui.gtk3.widgets.labels import HardwareRequirementsBox
16from softwarecenter.ui.gtk3.views.appdetailsview import get_test_window_appdetails20from softwarecenter.ui.gtk3.views.appdetailsview import get_test_window_appdetails
17from softwarecenter.enums import PkgStates21from softwarecenter.enums import PkgStates
@@ -264,6 +268,21 @@
264 self.view.show_app(self.view.app)268 self.view.show_app(self.view.app)
265 self.assertEqual(self.view.videoplayer.uri, video_url)269 self.assertEqual(self.view.videoplayer.uri, video_url)
266270
271 def test_update_software_center_agent_spinner(self):
272 # test that a spinner is shown while the agent is running
273 self.view.db._software_center_agent_update_in_progress = True
274 app = Application("", "no-such-app-really")
275 self.view.show_app(app)
276 do_events_with_sleep()
277 self.assertEqual(self.view.app_icon_spinner.get_current_page(),
278 self.view.app_icon_spinner.SPINNER_PAGE)
279 # now switch
280 self.view.db._software_center_agent_update_in_progress = False
281 self.view.db.emit("update-software-center-agent-finished", True)
282 do_events()
283 self.assertEqual(self.view.app_icon_spinner.get_current_page(),
284 self.view.app_icon_spinner.CONTENT_PAGE)
285
267286
268class MultipleVersionsTestCase(unittest.TestCase):287class MultipleVersionsTestCase(unittest.TestCase):
269288

Subscribers

People subscribed via source and target branches