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

Proposed by Michael Vogt on 2012-08-09
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) 2012-08-09 Approve on 2012-08-14
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.
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 on 2012-08-10

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

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 on 2012-08-10

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

3078. By Michael Vogt on 2012-08-09

add test for spinner

3077. By Michael Vogt on 2012-08-09

fix pep8

3076. By Michael Vogt on 2012-08-09

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

3075. By Michael Vogt on 2012-08-09

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

3074. By Michael Vogt on 2012-08-09

add self.app_icon_spinner to be able to show the spinner

3073. By Michael Vogt on 2012-08-09

softwarecenter/db/database.py: fix datadir

3072. By Michael Vogt on 2012-08-09

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
1=== modified file 'softwarecenter/db/database.py'
2--- softwarecenter/db/database.py 2012-05-22 13:39:12 +0000
3+++ softwarecenter/db/database.py 2012-08-10 12:55:22 +0000
4@@ -135,6 +135,10 @@
5 "open": (GObject.SIGNAL_RUN_FIRST,
6 GObject.TYPE_NONE,
7 (GObject.TYPE_STRING,)),
8+ "update-software-center-agent-finished": (
9+ GObject.SIGNAL_RUN_FIRST,
10+ GObject.TYPE_NONE,
11+ (GObject.TYPE_BOOLEAN,)),
12 }
13
14 def __init__(self, pathname=None, cache=None):
15@@ -157,6 +161,7 @@
16 self._db_per_thread = {}
17 self._parser_per_thread = {}
18 self._axi_stamp_monitor = None
19+ self._software_center_agent_update_in_progress = False
20
21 @property
22 def xapiandb(self):
23@@ -584,6 +589,33 @@
24 matches.append(FakeMSetItem(match))
25 return matches
26
27+ # software-center-agent releated API
28+ def update_software_center_agent(self, delay=0):
29+ """ Update the list of available application from the net
30+ """
31+ self._software_center_agent_update_in_progress = True
32+ GObject.timeout_add_seconds(delay, self._run_software_center_agent)
33+
34+ def _run_software_center_agent(self):
35+ """ helper that triggers the update-software-center-agent helper """
36+ datadir = softwarecenter.paths.datadir
37+ sc_agent_update = os.path.join(
38+ datadir, "update-software-center-agent")
39+ (pid, stdin, stdout, stderr) = GObject.spawn_async(
40+ [sc_agent_update, "--datadir", datadir],
41+ flags=GObject.SPAWN_DO_NOT_REAP_CHILD)
42+ GObject.child_watch_add(
43+ pid, self._on_update_software_center_agent_finished)
44+
45+ def _on_update_software_center_agent_finished(self, pid, condition):
46+ LOG.info("software-center-agent finished with status %i" %
47+ os.WEXITSTATUS(condition))
48+ success = (os.WEXITSTATUS(condition) == 0)
49+ self._software_center_agent_update_in_progress = False
50+ if success:
51+ self.reopen()
52+ self.emit("update-software-center-agent-finished", success)
53+
54 def __len__(self):
55 """return the doc count of the database"""
56 return self.xapiandb.get_doccount()
57
58=== modified file 'softwarecenter/ui/gtk3/app.py'
59--- softwarecenter/ui/gtk3/app.py 2012-06-11 09:56:45 +0000
60+++ softwarecenter/ui/gtk3/app.py 2012-08-10 12:55:22 +0000
61@@ -462,8 +462,7 @@
62 if not (options.enable_lp or och):
63 self.menu_file.remove(self.separator_login)
64 else:
65- # running the agent will trigger a db reload so we do it later
66- GObject.timeout_add_seconds(3, self._run_software_center_agent)
67+ self.db.update_software_center_agent(delay=3)
68
69 # keep the cache clean
70 GObject.timeout_add_seconds(15, self._run_expunge_cache_helper)
71@@ -489,16 +488,6 @@
72 LOG.debug("launchpad integration error: '%s'" % e)
73
74 # helper
75- def _run_software_center_agent(self):
76- """ helper that triggers the update-software-center-agent helper """
77- sc_agent_update = os.path.join(
78- self.datadir, "update-software-center-agent")
79- (pid, stdin, stdout, stderr) = GObject.spawn_async(
80- [sc_agent_update, "--datadir", self.datadir],
81- flags=GObject.SPAWN_DO_NOT_REAP_CHILD)
82- GObject.child_watch_add(
83- pid, self._on_update_software_center_agent_finished)
84-
85 def _run_expunge_cache_helper(self):
86 """ helper that expires the piston-mini-client cache """
87 sc_expunge_cache = os.path.join(
88@@ -593,12 +582,6 @@
89 self._recommender_agent = RecommenderAgent()
90 return self._recommender_agent
91
92- def _on_update_software_center_agent_finished(self, pid, condition):
93- LOG.info("software-center-agent finished with status %i" %
94- os.WEXITSTATUS(condition))
95- if os.WEXITSTATUS(condition) == 0:
96- self.db.reopen()
97-
98 def on_review_stats_loaded(self, reviews):
99 LOG.debug("on_review_stats_loaded: '%s'" % len(reviews))
100
101
102=== modified file 'softwarecenter/ui/gtk3/views/appdetailsview.py'
103--- softwarecenter/ui/gtk3/views/appdetailsview.py 2012-06-28 08:10:33 +0000
104+++ softwarecenter/ui/gtk3/views/appdetailsview.py 2012-08-10 12:55:22 +0000
105@@ -64,6 +64,7 @@
106 from softwarecenter.ui.gtk3.widgets.containers import SmallBorderRadiusFrame
107 from softwarecenter.ui.gtk3.widgets.stars import Star, StarRatingsWidget
108 from softwarecenter.ui.gtk3.widgets.description import AppDescription
109+from softwarecenter.ui.gtk3.widgets.spinner import SpinnerNotebook
110 from softwarecenter.ui.gtk3.widgets.thumbnail import ScreenshotGallery
111 from softwarecenter.ui.gtk3.widgets.videoplayer import VideoPlayer
112 from softwarecenter.ui.gtk3.widgets.weblivedialog import (
113@@ -817,6 +818,9 @@
114 Viewport.__init__(self)
115 # basic stuff
116 self.db = db
117+ self.db.connect(
118+ "update-software-center-agent-finished",
119+ self._on_update_software_center_agent_finished)
120 self.distro = distro
121 self.icons = icons
122 self.cache = cache
123@@ -1144,9 +1148,11 @@
124 hb.set_spacing(StockEms.MEDIUM)
125 vb.pack_start(hb, False, False, 0)
126
127- # the app icon
128+ # the app icon / spinner combo
129 self.icon = Gtk.Image()
130- hb.pack_start(self.icon, False, False, 0)
131+ self.icon.show()
132+ self.app_icon_spinner = SpinnerNotebook(self.icon)
133+ hb.pack_start(self.app_icon_spinner, False, False, 0)
134
135 # the app title/summary
136 self.title = Gtk.Label()
137@@ -1356,6 +1362,9 @@
138 self.subtitle.set_markup(summary)
139
140 def _update_app_icon(self, app_details):
141+ # update the spinner
142+ self._update_spinner(app_details)
143+
144 pb = self._get_icon_as_pixbuf(app_details)
145 # should we show the green tick?
146 # self._show_overlay = app_details.pkg_state == PkgStates.INSTALLED
147@@ -1508,6 +1517,17 @@
148 # Update addons state bar
149 self.addons_statusbar.configure()
150
151+ def _on_update_software_center_agent_finished(self, database, result):
152+ if self.app_details:
153+ self._update_spinner(self.app_details)
154+
155+ def _update_spinner(self, app_details):
156+ if app_details.pkg_state is PkgStates.NOT_FOUND:
157+ if self.db._software_center_agent_update_in_progress:
158+ self.app_icon_spinner.show_spinner()
159+ else:
160+ self.app_icon_spinner.hide_spinner()
161+
162 def _update_all(self, app_details, skip_update_addons=False):
163 # reset view to top left
164 vadj = self.get_vadjustment()
165
166=== modified file 'test/gtk3/test_appdetailsview.py'
167--- test/gtk3/test_appdetailsview.py 2012-06-18 14:39:27 +0000
168+++ test/gtk3/test_appdetailsview.py 2012-08-10 12:55:22 +0000
169@@ -11,7 +11,11 @@
170 from mock import Mock, patch
171
172 from softwarecenter.db.application import Application
173-from softwarecenter.testutils import get_mock_app_from_real_app, do_events, make_recommend_app_data
174+from softwarecenter.testutils import (
175+ get_mock_app_from_real_app,
176+ do_events,
177+ make_recommend_app_data,
178+ do_events_with_sleep)
179 from softwarecenter.ui.gtk3.widgets.labels import HardwareRequirementsBox
180 from softwarecenter.ui.gtk3.views.appdetailsview import get_test_window_appdetails
181 from softwarecenter.enums import PkgStates
182@@ -264,6 +268,21 @@
183 self.view.show_app(self.view.app)
184 self.assertEqual(self.view.videoplayer.uri, video_url)
185
186+ def test_update_software_center_agent_spinner(self):
187+ # test that a spinner is shown while the agent is running
188+ self.view.db._software_center_agent_update_in_progress = True
189+ app = Application("", "no-such-app-really")
190+ self.view.show_app(app)
191+ do_events_with_sleep()
192+ self.assertEqual(self.view.app_icon_spinner.get_current_page(),
193+ self.view.app_icon_spinner.SPINNER_PAGE)
194+ # now switch
195+ self.view.db._software_center_agent_update_in_progress = False
196+ self.view.db.emit("update-software-center-agent-finished", True)
197+ do_events()
198+ self.assertEqual(self.view.app_icon_spinner.get_current_page(),
199+ self.view.app_icon_spinner.CONTENT_PAGE)
200+
201
202 class MultipleVersionsTestCase(unittest.TestCase):
203

Subscribers

People subscribed via source and target branches