Merge lp:~aaronp/software-center/review-refactor into lp:software-center
- review-refactor
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 3146 |
Proposed branch: | lp:~aaronp/software-center/review-refactor |
Merge into: | lp:software-center |
Diff against target: |
756 lines (+175/-149) 7 files modified
run_against_testing_env.sh (+1/-1) softwarecenter/backend/reviews/__init__.py (+42/-16) softwarecenter/backend/reviews/rnr.py (+66/-77) softwarecenter/ui/gtk3/app.py (+4/-4) softwarecenter/ui/gtk3/views/appdetailsview.py (+47/-40) softwarecenter/ui/qml/reviewslist.py (+11/-7) tests/gtk3/test_appdetailsview.py (+4/-4) |
To merge this branch: | bzr merge lp:~aaronp/software-center/review-refactor |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Vogt | Approve | ||
Aaron Peachey | Needs Resubmitting | ||
Review via email: mp+122035@code.launchpad.net |
Commit message
Description of the change
This branch simply converts the existing callbacks for retrieval of review data and submission/
Michael Vogt (mvo) wrote : | # |
Aaron Peachey (aaronp) wrote : | # |
Thanks, I'll take a look at this and sort it out. cheers, Aaron.
On Aug 31, 2012 6:48 PM, "Michael Vogt" <email address hidden> wrote:
> Hey Aaron, thanks a lot for your work on this!
>
> I think this is good, there is just one issue with the tests
> that probably just needs updating:
> $ PYTHONPATH=. python tests/gtk3/
> ...
> =======
> ERROR: test_all_
> AppDetailsView.
> -------
> Traceback (most recent call last):
> File "/usr/lib/
> return func(*args, **keywargs)
> File "tests/
> test_all_
> application, callback = mock_get_
> ValueError: need more than 1 value to unpack
>
> =======
> ERROR: test_no_
> (__main_
> AppDetailsView.
> -------
> Traceback (most recent call last):
> File "/usr/lib/
> return func(*args, **keywargs)
> File "tests/
> test_no_
> application, callback = mock_get_
> ValueError: need more than 1 value to unpack
>
> -------
> Ran 23 tests in 135.414s
>
> I will try to get to it later today unless you want to tackle it (which
> would be very welcome
> of course as well :)
> --
>
> https:/
> You are the owner of lp:~aaronp/software-center/review-refactor.
>
- 2834. By Aaron Peachey
-
test/gtk3/
test_appdetails view.py: amended 2 failing tests that were using review callbacks to now pass using signals
Aaron Peachey (aaronp) wrote : | # |
Amended the two failing tests, as they were trying to use the callbacks that no longer exist. They now emit the relevant gobject signals instead and all tests pass.
Preview Diff
1 | === modified file 'run_against_testing_env.sh' | |||
2 | --- run_against_testing_env.sh 2012-03-14 19:53:59 +0000 | |||
3 | +++ run_against_testing_env.sh 2012-09-01 11:39:19 +0000 | |||
4 | @@ -1,6 +1,6 @@ | |||
5 | 1 | #!/bin/sh | 1 | #!/bin/sh |
6 | 2 | 2 | ||
8 | 3 | export SOFTWARE_CENTER_REVIEWS_HOST="http://184.82.116.62/reviews/api/1.0" | 3 | export SOFTWARE_CENTER_REVIEWS_HOST="https://reviews.staging.ubuntu.com/reviews/api/1.0/" |
9 | 4 | export SOFTWARE_CENTER_RECOMMENDER_HOST="http://rec.staging.ubuntu.com" | 4 | export SOFTWARE_CENTER_RECOMMENDER_HOST="http://rec.staging.ubuntu.com" |
10 | 5 | 5 | ||
11 | 6 | # sso | 6 | # sso |
12 | 7 | 7 | ||
13 | === modified file 'softwarecenter/backend/reviews/__init__.py' | |||
14 | --- softwarecenter/backend/reviews/__init__.py 2012-05-31 08:52:50 +0000 | |||
15 | +++ softwarecenter/backend/reviews/__init__.py 2012-09-01 11:39:19 +0000 | |||
16 | @@ -155,6 +155,7 @@ | |||
17 | 155 | 155 | ||
18 | 156 | class Review(object): | 156 | class Review(object): |
19 | 157 | """A individual review object """ | 157 | """A individual review object """ |
20 | 158 | |||
21 | 158 | def __init__(self, app): | 159 | def __init__(self, app): |
22 | 159 | # a softwarecenter.db.database.Application object | 160 | # a softwarecenter.db.database.Application object |
23 | 160 | self.app = app | 161 | self.app = app |
24 | @@ -230,8 +231,31 @@ | |||
25 | 230 | __gsignals__ = { | 231 | __gsignals__ = { |
26 | 231 | "refresh-review-stats-finished": (GObject.SIGNAL_RUN_LAST, | 232 | "refresh-review-stats-finished": (GObject.SIGNAL_RUN_LAST, |
27 | 232 | GObject.TYPE_NONE, | 233 | GObject.TYPE_NONE, |
28 | 234 | # review-stats list | ||
29 | 233 | (GObject.TYPE_PYOBJECT,), | 235 | (GObject.TYPE_PYOBJECT,), |
31 | 234 | ), | 236 | ), |
32 | 237 | "get-reviews-finished": (GObject.SIGNAL_RUN_LAST, | ||
33 | 238 | GObject.TYPE_NONE, | ||
34 | 239 | # application, reviewslist | ||
35 | 240 | (GObject.TYPE_PYOBJECT, | ||
36 | 241 | GObject.TYPE_PYOBJECT), | ||
37 | 242 | ), | ||
38 | 243 | "remove-review": (GObject.SIGNAL_RUN_LAST, | ||
39 | 244 | GObject.TYPE_NONE, | ||
40 | 245 | # app, the review | ||
41 | 246 | (GObject.TYPE_PYOBJECT, GObject.TYPE_PYOBJECT), | ||
42 | 247 | ), | ||
43 | 248 | "replace-review": (GObject.SIGNAL_RUN_LAST, | ||
44 | 249 | GObject.TYPE_NONE, | ||
45 | 250 | # app, the review | ||
46 | 251 | (GObject.TYPE_PYOBJECT, GObject.TYPE_PYOBJECT), | ||
47 | 252 | ), | ||
48 | 253 | "update-usefulness-votes": (GObject.SIGNAL_RUN_LAST, | ||
49 | 254 | GObject.TYPE_NONE, | ||
50 | 255 | # useful_votes | ||
51 | 256 | (GObject.TYPE_PYOBJECT, ), | ||
52 | 257 | ), | ||
53 | 258 | |||
54 | 235 | } | 259 | } |
55 | 236 | 260 | ||
56 | 237 | # cache the ReviewStats | 261 | # cache the ReviewStats |
57 | @@ -275,7 +299,7 @@ | |||
58 | 275 | return True | 299 | return True |
59 | 276 | return False | 300 | return False |
60 | 277 | 301 | ||
62 | 278 | def get_reviews(self, application, callback, page=1, language=None, | 302 | def get_reviews(self, application, page=1, language=None, |
63 | 279 | sort=0, relaxed=False): | 303 | sort=0, relaxed=False): |
64 | 280 | """run callback f(app, review_list) | 304 | """run callback f(app, review_list) |
65 | 281 | with list of review objects for the given | 305 | with list of review objects for the given |
66 | @@ -300,7 +324,7 @@ | |||
67 | 300 | except ValueError: | 324 | except ValueError: |
68 | 301 | pass | 325 | pass |
69 | 302 | 326 | ||
71 | 303 | def refresh_review_stats(self, callback): | 327 | def refresh_review_stats(self): |
72 | 304 | """ get the review statists and call callback when its there """ | 328 | """ get the review statists and call callback when its there """ |
73 | 305 | pass | 329 | pass |
74 | 306 | 330 | ||
75 | @@ -476,7 +500,7 @@ | |||
76 | 476 | def _random_summary(self): | 500 | def _random_summary(self): |
77 | 477 | return random.choice(self.SUMMARIES) | 501 | return random.choice(self.SUMMARIES) |
78 | 478 | 502 | ||
80 | 479 | def get_reviews(self, application, callback, page=1, language=None, | 503 | def get_reviews(self, application, page=1, language=None, |
81 | 480 | sort=0, relaxed=False): | 504 | sort=0, relaxed=False): |
82 | 481 | if not application in self._review_stats_cache: | 505 | if not application in self._review_stats_cache: |
83 | 482 | self.get_review_stats(application) | 506 | self.get_review_stats(application) |
84 | @@ -497,7 +521,7 @@ | |||
85 | 497 | reviews.append(review) | 521 | reviews.append(review) |
86 | 498 | self._reviews_cache[application] = reviews | 522 | self._reviews_cache[application] = reviews |
87 | 499 | reviews = self._reviews_cache[application] | 523 | reviews = self._reviews_cache[application] |
89 | 500 | callback(application, reviews) | 524 | self.emit("get-reviews-finished", application, reviews) |
90 | 501 | 525 | ||
91 | 502 | def get_review_stats(self, application): | 526 | def get_review_stats(self, application): |
92 | 503 | if not application in self._review_stats_cache: | 527 | if not application in self._review_stats_cache: |
93 | @@ -507,9 +531,9 @@ | |||
94 | 507 | self._review_stats_cache[application] = stat | 531 | self._review_stats_cache[application] = stat |
95 | 508 | return self._review_stats_cache[application] | 532 | return self._review_stats_cache[application] |
96 | 509 | 533 | ||
98 | 510 | def refresh_review_stats(self, callback): | 534 | def refresh_review_stats(self): |
99 | 511 | review_stats = [] | 535 | review_stats = [] |
101 | 512 | callback(review_stats) | 536 | self.emit("refresh-review-stats-finished", review_stats) |
102 | 513 | 537 | ||
103 | 514 | 538 | ||
104 | 515 | class ReviewLoaderFortune(ReviewLoaderFake): | 539 | class ReviewLoaderFortune(ReviewLoaderFake): |
105 | @@ -657,16 +681,16 @@ | |||
106 | 657 | self._review_stats_cache = {} | 681 | self._review_stats_cache = {} |
107 | 658 | self._reviews_cache = {} | 682 | self._reviews_cache = {} |
108 | 659 | 683 | ||
110 | 660 | def get_reviews(self, application, callback, page=1, language=None, | 684 | def get_reviews(self, application, page=1, language=None, |
111 | 661 | sort=0, relaxed=False): | 685 | sort=0, relaxed=False): |
113 | 662 | callback(application, []) | 686 | self.emit("get-reviews-finished", application, []) |
114 | 663 | 687 | ||
115 | 664 | def get_review_stats(self, application): | 688 | def get_review_stats(self, application): |
116 | 665 | pass | 689 | pass |
117 | 666 | 690 | ||
119 | 667 | def refresh_review_stats(self, callback): | 691 | def refresh_review_stats(self): |
120 | 668 | review_stats = [] | 692 | review_stats = [] |
122 | 669 | callback(review_stats) | 693 | self.emit("refresh-review-stats-finished", review_stats) |
123 | 670 | 694 | ||
124 | 671 | 695 | ||
125 | 672 | review_loader = None | 696 | review_loader = None |
126 | @@ -695,11 +719,11 @@ | |||
127 | 695 | return review_loader | 719 | return review_loader |
128 | 696 | 720 | ||
129 | 697 | if __name__ == "__main__": | 721 | if __name__ == "__main__": |
131 | 698 | def callback(app, reviews): | 722 | def callback(loader, app, reviews): |
132 | 699 | print "app callback:" | 723 | print "app callback:" |
133 | 700 | print app, reviews | 724 | print app, reviews |
134 | 701 | 725 | ||
136 | 702 | def stats_callback(stats): | 726 | def stats_callback(loader, stats): |
137 | 703 | print "stats callback:" | 727 | print "stats callback:" |
138 | 704 | print stats | 728 | print stats |
139 | 705 | 729 | ||
140 | @@ -719,8 +743,10 @@ | |||
141 | 719 | ReviewLoaderSpawningRNRClient | 743 | ReviewLoaderSpawningRNRClient |
142 | 720 | ) | 744 | ) |
143 | 721 | loader = ReviewLoaderSpawningRNRClient(cache, db) | 745 | loader = ReviewLoaderSpawningRNRClient(cache, db) |
146 | 722 | print loader.refresh_review_stats(stats_callback) | 746 | loader.connect("refresh-review-stats-finished", stats_callback) |
147 | 723 | print loader.get_reviews(app, callback) | 747 | loader.connect("get-reviews-finished", callback) |
148 | 748 | loader.refresh_review_stats() | ||
149 | 749 | print loader.get_reviews(app) | ||
150 | 724 | 750 | ||
151 | 725 | print "\n\n" | 751 | print "\n\n" |
152 | 726 | print "default loader, press ctrl-c for next loader" | 752 | print "default loader, press ctrl-c for next loader" |
153 | @@ -732,5 +758,5 @@ | |||
154 | 732 | app = Application("", "2vcard") | 758 | app = Application("", "2vcard") |
155 | 733 | loader = get_review_loader(cache, db) | 759 | loader = get_review_loader(cache, db) |
156 | 734 | loader.refresh_review_stats(stats_callback) | 760 | loader.refresh_review_stats(stats_callback) |
158 | 735 | loader.get_reviews(app, callback) | 761 | loader.get_reviews(app) |
159 | 736 | main.run() | 762 | main.run() |
160 | 737 | 763 | ||
161 | === modified file 'softwarecenter/backend/reviews/rnr.py' | |||
162 | --- softwarecenter/backend/reviews/rnr.py 2012-03-16 19:16:21 +0000 | |||
163 | +++ softwarecenter/backend/reviews/rnr.py 2012-09-01 11:39:19 +0000 | |||
164 | @@ -69,10 +69,10 @@ | |||
165 | 69 | self.rnrclient._offline_mode = not network_state_is_connected() | 69 | self.rnrclient._offline_mode = not network_state_is_connected() |
166 | 70 | 70 | ||
167 | 71 | # reviews | 71 | # reviews |
169 | 72 | def get_reviews(self, translated_app, callback, page=1, | 72 | def get_reviews(self, translated_app, page=1, |
170 | 73 | language=None, sort=0, relaxed=False): | 73 | language=None, sort=0, relaxed=False): |
173 | 74 | """ public api, triggers fetching a review and calls callback | 74 | """ public api, triggers fetching a review and emits |
174 | 75 | when its ready | 75 | get-reviews-finished signal when its ready |
175 | 76 | """ | 76 | """ |
176 | 77 | # its fine to use the translated appname here, we only submit the | 77 | # its fine to use the translated appname here, we only submit the |
177 | 78 | # pkgname to the server | 78 | # pkgname to the server |
178 | @@ -100,7 +100,7 @@ | |||
179 | 100 | origin = "lp-ppa-%s" % ppa.replace("/", "-") | 100 | origin = "lp-ppa-%s" % ppa.replace("/", "-") |
180 | 101 | # if there is no origin, there is nothing to do | 101 | # if there is no origin, there is nothing to do |
181 | 102 | if not origin: | 102 | if not origin: |
183 | 103 | callback(app, []) | 103 | self.emit("get-reviews-finished", app, []) |
184 | 104 | return | 104 | return |
185 | 105 | distroseries = self.distro.get_codename() | 105 | distroseries = self.distro.get_codename() |
186 | 106 | # run the command and add watcher | 106 | # run the command and add watcher |
187 | @@ -115,22 +115,21 @@ | |||
188 | 115 | ] | 115 | ] |
189 | 116 | spawn_helper = SpawnHelper() | 116 | spawn_helper = SpawnHelper() |
190 | 117 | spawn_helper.connect( | 117 | spawn_helper.connect( |
192 | 118 | "data-available", self._on_reviews_helper_data, app, callback) | 118 | "data-available", self._on_reviews_helper_data, app) |
193 | 119 | spawn_helper.run(cmd) | 119 | spawn_helper.run(cmd) |
194 | 120 | 120 | ||
197 | 121 | def _on_reviews_helper_data(self, spawn_helper, piston_reviews, app, | 121 | def _on_reviews_helper_data(self, spawn_helper, piston_reviews, app): |
196 | 122 | callback): | ||
198 | 123 | # convert into our review objects | 122 | # convert into our review objects |
199 | 124 | reviews = [] | 123 | reviews = [] |
200 | 125 | for r in piston_reviews: | 124 | for r in piston_reviews: |
201 | 126 | reviews.append(Review.from_piston_mini_client(r)) | 125 | reviews.append(Review.from_piston_mini_client(r)) |
203 | 127 | # add to our dicts and run callback | 126 | # add to our dicts and emit signal |
204 | 128 | self._reviews[app] = reviews | 127 | self._reviews[app] = reviews |
206 | 129 | callback(app, self._reviews[app]) | 128 | self.emit("get-reviews-finished", app, self._reviews[app]) |
207 | 130 | return False | 129 | return False |
208 | 131 | 130 | ||
209 | 132 | # stats | 131 | # stats |
211 | 133 | def refresh_review_stats(self, callback): | 132 | def refresh_review_stats(self): |
212 | 134 | """ public api, refresh the available statistics """ | 133 | """ public api, refresh the available statistics """ |
213 | 135 | try: | 134 | try: |
214 | 136 | mtime = os.path.getmtime(self.REVIEW_STATS_CACHE_FILE) | 135 | mtime = os.path.getmtime(self.REVIEW_STATS_CACHE_FILE) |
215 | @@ -145,8 +144,7 @@ | |||
216 | 145 | #origin = "any" | 144 | #origin = "any" |
217 | 146 | #distroseries = self.distro.get_codename() | 145 | #distroseries = self.distro.get_codename() |
218 | 147 | spawn_helper = SpawnHelper() | 146 | spawn_helper = SpawnHelper() |
221 | 148 | spawn_helper.connect("data-available", self._on_review_stats_data, | 147 | spawn_helper.connect("data-available", self._on_review_stats_data) |
220 | 149 | callback) | ||
222 | 150 | if days_delta: | 148 | if days_delta: |
223 | 151 | spawn_helper.run_generic_piston_helper( | 149 | spawn_helper.run_generic_piston_helper( |
224 | 152 | "RatingsAndReviewsAPI", "review_stats", days=days_delta) | 150 | "RatingsAndReviewsAPI", "review_stats", days=days_delta) |
225 | @@ -154,8 +152,7 @@ | |||
226 | 154 | spawn_helper.run_generic_piston_helper( | 152 | spawn_helper.run_generic_piston_helper( |
227 | 155 | "RatingsAndReviewsAPI", "review_stats") | 153 | "RatingsAndReviewsAPI", "review_stats") |
228 | 156 | 154 | ||
231 | 157 | def _on_review_stats_data(self, spawn_helper, piston_review_stats, | 155 | def _on_review_stats_data(self, spawn_helper, piston_review_stats): |
230 | 158 | callback): | ||
232 | 159 | """ process stdout from the helper """ | 156 | """ process stdout from the helper """ |
233 | 160 | review_stats = self.REVIEW_STATS_CACHE | 157 | review_stats = self.REVIEW_STATS_CACHE |
234 | 161 | 158 | ||
235 | @@ -163,7 +160,7 @@ | |||
236 | 163 | piston_review_stats): | 160 | piston_review_stats): |
237 | 164 | self.REVIEW_STATS_CACHE = {} | 161 | self.REVIEW_STATS_CACHE = {} |
238 | 165 | self.save_review_stats_cache_file() | 162 | self.save_review_stats_cache_file() |
240 | 166 | self.refresh_review_stats(callback) | 163 | self.refresh_review_stats() |
241 | 167 | return | 164 | return |
242 | 168 | 165 | ||
243 | 169 | # convert to the format that s-c uses | 166 | # convert to the format that s-c uses |
244 | @@ -178,7 +175,6 @@ | |||
245 | 178 | s.dampened_rating = calc_dr(s.rating_spread) | 175 | s.dampened_rating = calc_dr(s.rating_spread) |
246 | 179 | review_stats[s.app] = s | 176 | review_stats[s.app] = s |
247 | 180 | self.REVIEW_STATS_CACHE = review_stats | 177 | self.REVIEW_STATS_CACHE = review_stats |
248 | 181 | callback(review_stats) | ||
249 | 182 | self.emit("refresh-review-stats-finished", review_stats) | 178 | self.emit("refresh-review-stats-finished", review_stats) |
250 | 183 | self.save_review_stats_cache_file() | 179 | self.save_review_stats_cache_file() |
251 | 184 | 180 | ||
252 | @@ -190,10 +186,8 @@ | |||
253 | 190 | return True | 186 | return True |
254 | 191 | 187 | ||
255 | 192 | # writing new reviews spawns external helper | 188 | # writing new reviews spawns external helper |
256 | 193 | # FIXME: instead of the callback we should add proper gobject signals | ||
257 | 194 | def spawn_write_new_review_ui(self, translated_app, version, iconname, | 189 | def spawn_write_new_review_ui(self, translated_app, version, iconname, |
260 | 195 | origin, parent_xid, datadir, callback, | 190 | origin, parent_xid, datadir): |
259 | 196 | done_callback=None): | ||
261 | 197 | """ this spawns the UI for writing a new review and | 191 | """ this spawns the UI for writing a new review and |
262 | 198 | adds it automatically to the reviews DB """ | 192 | adds it automatically to the reviews DB """ |
263 | 199 | app = translated_app.get_untranslated_app(self.db) | 193 | app = translated_app.get_untranslated_app(self.db) |
264 | @@ -210,13 +204,20 @@ | |||
265 | 210 | cmd += ["--appname", utf8(app.appname)] | 204 | cmd += ["--appname", utf8(app.appname)] |
266 | 211 | spawn_helper = SpawnHelper(format="json") | 205 | spawn_helper = SpawnHelper(format="json") |
267 | 212 | spawn_helper.connect( | 206 | spawn_helper.connect( |
272 | 213 | "data-available", self._on_submit_review_data, app, callback) | 207 | "data-available", self._on_submit_review_data, app) |
273 | 214 | if done_callback: | 208 | spawn_helper.connect("exited", self._on_exited_callback, app) |
274 | 215 | spawn_helper.connect("exited", done_callback) | 209 | spawn_helper.connect("error", self._on_error_callback, app) |
271 | 216 | spawn_helper.connect("error", done_callback) | ||
275 | 217 | spawn_helper.run(cmd) | 210 | spawn_helper.run(cmd) |
276 | 218 | 211 | ||
278 | 219 | def _on_submit_review_data(self, spawn_helper, review_json, app, callback): | 212 | def _on_exited_callback(self, spawn_helper, return_code, app): |
279 | 213 | # FIXME: send a proper error here instead! | ||
280 | 214 | self.emit("get-reviews-finished", app, []) | ||
281 | 215 | |||
282 | 216 | def _on_error_callback(self, spawn_helper, error_str, app): | ||
283 | 217 | # FIXME: send a proper error here instead! | ||
284 | 218 | self.emit("get-reviews-finished", app, []) | ||
285 | 219 | |||
286 | 220 | def _on_submit_review_data(self, spawn_helper, review_json, app): | ||
287 | 220 | """ called when submit_review finished, when the review was send | 221 | """ called when submit_review finished, when the review was send |
288 | 221 | successfully the callback is triggered with the new reviews | 222 | successfully the callback is triggered with the new reviews |
289 | 222 | """ | 223 | """ |
290 | @@ -229,12 +230,12 @@ | |||
291 | 229 | if not app in self._reviews: | 230 | if not app in self._reviews: |
292 | 230 | self._reviews[app] = [] | 231 | self._reviews[app] = [] |
293 | 231 | self._reviews[app].insert(0, Review.from_piston_mini_client(review)) | 232 | self._reviews[app].insert(0, Review.from_piston_mini_client(review)) |
295 | 232 | callback(app, self._reviews[app]) | 233 | self.emit("get-reviews-finished", app, self._reviews[app]) |
296 | 233 | 234 | ||
298 | 234 | def spawn_report_abuse_ui(self, review_id, parent_xid, datadir, callback): | 235 | def spawn_report_abuse_ui(self, review_id, parent_xid, datadir): |
299 | 235 | """ this spawns the UI for reporting a review as inappropriate | 236 | """ this spawns the UI for reporting a review as inappropriate |
300 | 236 | and adds the review-id to the internal hide list. once the | 237 | and adds the review-id to the internal hide list. once the |
302 | 237 | operation is complete it will call callback with the updated | 238 | operation is complete it will emit remove-review with the updated |
303 | 238 | review list | 239 | review list |
304 | 239 | """ | 240 | """ |
305 | 240 | cmd = [os.path.join(datadir, RNRApps.REPORT_REVIEW), | 241 | cmd = [os.path.join(datadir, RNRApps.REPORT_REVIEW), |
306 | @@ -245,11 +246,10 @@ | |||
307 | 245 | spawn_helper = SpawnHelper("json") | 246 | spawn_helper = SpawnHelper("json") |
308 | 246 | spawn_helper.connect("exited", | 247 | spawn_helper.connect("exited", |
309 | 247 | self._on_report_abuse_finished, | 248 | self._on_report_abuse_finished, |
311 | 248 | review_id, callback) | 249 | review_id) |
312 | 249 | spawn_helper.run(cmd) | 250 | spawn_helper.run(cmd) |
313 | 250 | 251 | ||
316 | 251 | def _on_report_abuse_finished(self, spawn_helper, exitcode, review_id, | 252 | def _on_report_abuse_finished(self, spawn_helper, exitcode, review_id): |
315 | 252 | callback): | ||
317 | 253 | """ called when report_absuse finished """ | 253 | """ called when report_absuse finished """ |
318 | 254 | LOG.debug("hide id %s " % review_id) | 254 | LOG.debug("hide id %s " % review_id) |
319 | 255 | if exitcode == 0: | 255 | if exitcode == 0: |
320 | @@ -258,12 +258,11 @@ | |||
321 | 258 | if str(review.id) == str(review_id): | 258 | if str(review.id) == str(review_id): |
322 | 259 | # remove the one we don't want to see anymore | 259 | # remove the one we don't want to see anymore |
323 | 260 | self._reviews[app].remove(review) | 260 | self._reviews[app].remove(review) |
326 | 261 | callback(app, self._reviews[app], None, 'remove', | 261 | self.emit("remove-review", app, review) |
325 | 262 | review) | ||
327 | 263 | break | 262 | break |
328 | 264 | 263 | ||
329 | 265 | def spawn_submit_usefulness_ui(self, review_id, is_useful, parent_xid, | 264 | def spawn_submit_usefulness_ui(self, review_id, is_useful, parent_xid, |
331 | 266 | datadir, callback): | 265 | datadir): |
332 | 267 | cmd = [os.path.join(datadir, RNRApps.SUBMIT_USEFULNESS), | 266 | cmd = [os.path.join(datadir, RNRApps.SUBMIT_USEFULNESS), |
333 | 268 | "--review-id", "%s" % review_id, | 267 | "--review-id", "%s" % review_id, |
334 | 269 | "--is-useful", "%s" % int(is_useful), | 268 | "--is-useful", "%s" % int(is_useful), |
335 | @@ -273,21 +272,20 @@ | |||
336 | 273 | spawn_helper = SpawnHelper(format="none") | 272 | spawn_helper = SpawnHelper(format="none") |
337 | 274 | spawn_helper.connect("exited", | 273 | spawn_helper.connect("exited", |
338 | 275 | self._on_submit_usefulness_finished, | 274 | self._on_submit_usefulness_finished, |
340 | 276 | review_id, is_useful, callback) | 275 | review_id, is_useful) |
341 | 277 | spawn_helper.connect("error", | 276 | spawn_helper.connect("error", |
342 | 278 | self._on_submit_usefulness_error, | 277 | self._on_submit_usefulness_error, |
344 | 279 | review_id, callback) | 278 | review_id) |
345 | 280 | spawn_helper.run(cmd) | 279 | spawn_helper.run(cmd) |
346 | 281 | 280 | ||
347 | 282 | def _on_submit_usefulness_finished(self, spawn_helper, res, review_id, | 281 | def _on_submit_usefulness_finished(self, spawn_helper, res, review_id, |
349 | 283 | is_useful, callback): | 282 | is_useful): |
350 | 284 | """ called when report_usefulness finished """ | 283 | """ called when report_usefulness finished """ |
351 | 285 | # "Created", "Updated", "Not modified" - | 284 | # "Created", "Updated", "Not modified" - |
352 | 286 | # once lp:~mvo/rnr-server/submit-usefulness-result-strings makes it | 285 | # once lp:~mvo/rnr-server/submit-usefulness-result-strings makes it |
353 | 287 | response = spawn_helper._stdout | 286 | response = spawn_helper._stdout |
354 | 288 | if response == '"Not modified"': | 287 | if response == '"Not modified"': |
357 | 289 | self._on_submit_usefulness_error(spawn_helper, response, review_id, | 288 | self._on_submit_usefulness_error(spawn_helper, response, review_id) |
356 | 290 | callback) | ||
358 | 291 | return | 289 | return |
359 | 292 | 290 | ||
360 | 293 | LOG.debug("usefulness id %s " % review_id) | 291 | LOG.debug("usefulness id %s " % review_id) |
361 | @@ -301,24 +299,23 @@ | |||
362 | 301 | review.usefulness_total = getattr(review, | 299 | review.usefulness_total = getattr(review, |
363 | 302 | "usefulness_total", 0) + 1 | 300 | "usefulness_total", 0) + 1 |
364 | 303 | if is_useful: | 301 | if is_useful: |
383 | 304 | review.usefulness_favorable = getattr(review, | 302 | review.usefulness_favorable = getattr( |
384 | 305 | "usefulness_favorable", 0) + 1 | 303 | review, "usefulness_favorable", 0) + 1 |
385 | 306 | callback(app, self._reviews[app], useful_votes, | 304 | self.emit("update-usefulness-votes", useful_votes) |
386 | 307 | 'replace', review) | 305 | self.emit("replace-review", app, review) |
387 | 308 | break | 306 | break |
388 | 309 | 307 | ||
389 | 310 | def _on_submit_usefulness_error(self, spawn_helper, error_str, review_id, | 308 | def _on_submit_usefulness_error(self, spawn_helper, error_str, review_id): |
390 | 311 | callback): | 309 | LOG.warn("submit usefulness id=%s failed with error: %s" % |
391 | 312 | LOG.warn("submit usefulness id=%s failed with error: %s" % | 310 | (review_id, error_str)) |
392 | 313 | (review_id, error_str)) | 311 | for (app, reviews) in self._reviews.items(): |
393 | 314 | for (app, reviews) in self._reviews.items(): | 312 | for review in reviews: |
394 | 315 | for review in reviews: | 313 | if str(review.id) == str(review_id): |
395 | 316 | if str(review.id) == str(review_id): | 314 | review.usefulness_submit_error = True |
396 | 317 | review.usefulness_submit_error = True | 315 | self.emit("replace-review", app, review) |
397 | 318 | callback(app, self._reviews[app], None, 'replace', review) | 316 | break |
398 | 319 | break | 317 | |
399 | 320 | 318 | def spawn_delete_review_ui(self, review_id, parent_xid, datadir): | |
382 | 321 | def spawn_delete_review_ui(self, review_id, parent_xid, datadir, callback): | ||
400 | 322 | cmd = [os.path.join(datadir, RNRApps.DELETE_REVIEW), | 319 | cmd = [os.path.join(datadir, RNRApps.DELETE_REVIEW), |
401 | 323 | "--review-id", "%s" % review_id, | 320 | "--review-id", "%s" % review_id, |
402 | 324 | "--parent-xid", "%s" % parent_xid, | 321 | "--parent-xid", "%s" % parent_xid, |
403 | @@ -327,13 +324,12 @@ | |||
404 | 327 | spawn_helper = SpawnHelper(format="none") | 324 | spawn_helper = SpawnHelper(format="none") |
405 | 328 | spawn_helper.connect("exited", | 325 | spawn_helper.connect("exited", |
406 | 329 | self._on_delete_review_finished, | 326 | self._on_delete_review_finished, |
408 | 330 | review_id, callback) | 327 | review_id) |
409 | 331 | spawn_helper.connect("error", self._on_delete_review_error, | 328 | spawn_helper.connect("error", self._on_delete_review_error, |
411 | 332 | review_id, callback) | 329 | review_id) |
412 | 333 | spawn_helper.run(cmd) | 330 | spawn_helper.run(cmd) |
413 | 334 | 331 | ||
416 | 335 | def _on_delete_review_finished(self, spawn_helper, res, review_id, | 332 | def _on_delete_review_finished(self, spawn_helper, res, review_id): |
415 | 336 | callback): | ||
417 | 337 | """ called when delete_review finished""" | 333 | """ called when delete_review finished""" |
418 | 338 | LOG.debug("delete id %s " % review_id) | 334 | LOG.debug("delete id %s " % review_id) |
419 | 339 | for (app, reviews) in self._reviews.items(): | 335 | for (app, reviews) in self._reviews.items(): |
420 | @@ -341,11 +337,10 @@ | |||
421 | 341 | if str(review.id) == str(review_id): | 337 | if str(review.id) == str(review_id): |
422 | 342 | # remove the one we don't want to see anymore | 338 | # remove the one we don't want to see anymore |
423 | 343 | self._reviews[app].remove(review) | 339 | self._reviews[app].remove(review) |
425 | 344 | callback(app, self._reviews[app], None, 'remove', review) | 340 | self.emit("remove-review", app, review) |
426 | 345 | break | 341 | break |
427 | 346 | 342 | ||
430 | 347 | def _on_delete_review_error(self, spawn_helper, error_str, review_id, | 343 | def _on_delete_review_error(self, spawn_helper, error_str, review_id): |
429 | 348 | callback): | ||
431 | 349 | """called if delete review errors""" | 344 | """called if delete review errors""" |
432 | 350 | LOG.warn("delete review id=%s failed with error: %s" % (review_id, | 345 | LOG.warn("delete review id=%s failed with error: %s" % (review_id, |
433 | 351 | error_str)) | 346 | error_str)) |
434 | @@ -353,12 +348,10 @@ | |||
435 | 353 | for review in reviews: | 348 | for review in reviews: |
436 | 354 | if str(review.id) == str(review_id): | 349 | if str(review.id) == str(review_id): |
437 | 355 | review.delete_error = True | 350 | review.delete_error = True |
440 | 356 | callback(app, self._reviews[app], action='replace', | 351 | self.emit("remove-review", app, review) |
439 | 357 | single_review=review) | ||
441 | 358 | break | 352 | break |
442 | 359 | 353 | ||
445 | 360 | def spawn_modify_review_ui(self, parent_xid, iconname, datadir, review_id, | 354 | def spawn_modify_review_ui(self, parent_xid, iconname, datadir, review_id): |
444 | 361 | callback): | ||
446 | 362 | """ this spawns the UI for writing a new review and | 355 | """ this spawns the UI for writing a new review and |
447 | 363 | adds it automatically to the reviews DB """ | 356 | adds it automatically to the reviews DB """ |
448 | 364 | cmd = [os.path.join(datadir, RNRApps.MODIFY_REVIEW), | 357 | cmd = [os.path.join(datadir, RNRApps.MODIFY_REVIEW), |
449 | @@ -370,13 +363,12 @@ | |||
450 | 370 | spawn_helper = SpawnHelper(format="json") | 363 | spawn_helper = SpawnHelper(format="json") |
451 | 371 | spawn_helper.connect("data-available", | 364 | spawn_helper.connect("data-available", |
452 | 372 | self._on_modify_review_finished, | 365 | self._on_modify_review_finished, |
454 | 373 | review_id, callback) | 366 | review_id) |
455 | 374 | spawn_helper.connect("error", self._on_modify_review_error, | 367 | spawn_helper.connect("error", self._on_modify_review_error, |
457 | 375 | review_id, callback) | 368 | review_id) |
458 | 376 | spawn_helper.run(cmd) | 369 | spawn_helper.run(cmd) |
459 | 377 | 370 | ||
462 | 378 | def _on_modify_review_finished(self, spawn_helper, review_json, review_id, | 371 | def _on_modify_review_finished(self, spawn_helper, review_json, review_id): |
461 | 379 | callback): | ||
463 | 380 | """called when modify_review finished""" | 372 | """called when modify_review finished""" |
464 | 381 | LOG.debug("_on_modify_review_finished") | 373 | LOG.debug("_on_modify_review_finished") |
465 | 382 | #review_json = spawn_helper._stdout | 374 | #review_json = spawn_helper._stdout |
466 | @@ -388,12 +380,10 @@ | |||
467 | 388 | self._reviews[app].remove(review) | 380 | self._reviews[app].remove(review) |
468 | 389 | new_review = Review.from_piston_mini_client(mod_review) | 381 | new_review = Review.from_piston_mini_client(mod_review) |
469 | 390 | self._reviews[app].insert(0, new_review) | 382 | self._reviews[app].insert(0, new_review) |
472 | 391 | callback(app, self._reviews[app], action='replace', | 383 | self.emit("replace-review", app, new_review) |
471 | 392 | single_review=new_review) | ||
473 | 393 | break | 384 | break |
474 | 394 | 385 | ||
477 | 395 | def _on_modify_review_error(self, spawn_helper, error_str, review_id, | 386 | def _on_modify_review_error(self, spawn_helper, error_str, review_id): |
476 | 396 | callback): | ||
478 | 397 | """called if modify review errors""" | 387 | """called if modify review errors""" |
479 | 398 | LOG.debug("modify review id=%s failed with error: %s" % | 388 | LOG.debug("modify review id=%s failed with error: %s" % |
480 | 399 | (review_id, error_str)) | 389 | (review_id, error_str)) |
481 | @@ -401,6 +391,5 @@ | |||
482 | 401 | for review in reviews: | 391 | for review in reviews: |
483 | 402 | if str(review.id) == str(review_id): | 392 | if str(review.id) == str(review_id): |
484 | 403 | review.modify_error = True | 393 | review.modify_error = True |
487 | 404 | callback(app, self._reviews[app], action='replace', | 394 | self.emit("replace-review", app, review) |
486 | 405 | single_review=review) | ||
488 | 406 | break | 395 | break |
489 | 407 | 396 | ||
490 | === modified file 'softwarecenter/ui/gtk3/app.py' | |||
491 | --- softwarecenter/ui/gtk3/app.py 2012-08-30 12:13:13 +0000 | |||
492 | +++ softwarecenter/ui/gtk3/app.py 2012-09-01 11:39:19 +0000 | |||
493 | @@ -414,9 +414,9 @@ | |||
494 | 414 | # reviews | 414 | # reviews |
495 | 415 | with ExecutionTime("create review loader"): | 415 | with ExecutionTime("create review loader"): |
496 | 416 | self.review_loader = get_review_loader(self.cache, self.db) | 416 | self.review_loader = get_review_loader(self.cache, self.db) |
500 | 417 | # FIXME: add some kind of throttle, I-M-S here | 417 | self.review_loader.connect( |
501 | 418 | self.review_loader.refresh_review_stats( | 418 | "refresh-review-stats-finished", self.on_review_stats_loaded) |
502 | 419 | self.on_review_stats_loaded) | 419 | self.review_loader.refresh_review_stats() |
503 | 420 | #load usefulness votes from server when app starts | 420 | #load usefulness votes from server when app starts |
504 | 421 | self.useful_cache = UsefulnessCache(True) | 421 | self.useful_cache = UsefulnessCache(True) |
505 | 422 | self.setup_database_rebuilding_listener() | 422 | self.setup_database_rebuilding_listener() |
506 | @@ -603,7 +603,7 @@ | |||
507 | 603 | if os.WEXITSTATUS(condition) == 0: | 603 | if os.WEXITSTATUS(condition) == 0: |
508 | 604 | self.db.reopen() | 604 | self.db.reopen() |
509 | 605 | 605 | ||
511 | 606 | def on_review_stats_loaded(self, reviews): | 606 | def on_review_stats_loaded(self, loader, reviews): |
512 | 607 | LOG.debug("on_review_stats_loaded: '%s'" % len(reviews)) | 607 | LOG.debug("on_review_stats_loaded: '%s'" % len(reviews)) |
513 | 608 | 608 | ||
514 | 609 | def destroy(self): | 609 | def destroy(self): |
515 | 610 | 610 | ||
516 | === modified file 'softwarecenter/ui/gtk3/views/appdetailsview.py' | |||
517 | --- softwarecenter/ui/gtk3/views/appdetailsview.py 2012-08-20 09:56:39 +0000 | |||
518 | +++ softwarecenter/ui/gtk3/views/appdetailsview.py 2012-09-01 11:39:19 +0000 | |||
519 | @@ -824,6 +824,14 @@ | |||
520 | 824 | self.addons_to_remove = [] | 824 | self.addons_to_remove = [] |
521 | 825 | # reviews | 825 | # reviews |
522 | 826 | self.review_loader = get_review_loader(self.cache, self.db) | 826 | self.review_loader = get_review_loader(self.cache, self.db) |
523 | 827 | self.review_loader.connect( | ||
524 | 828 | "get-reviews-finished", self._on_reviews_ready_callback) | ||
525 | 829 | self.review_loader.connect( | ||
526 | 830 | "remove-review", self._on_remove_review_callback) | ||
527 | 831 | self.review_loader.connect( | ||
528 | 832 | "replace-review", self._on_replace_review_callback) | ||
529 | 833 | self.review_loader.connect("update-usefulness-votes", | ||
530 | 834 | self._on_update_usefulness_votes_callback) | ||
531 | 827 | 835 | ||
532 | 828 | # ui specific stuff | 836 | # ui specific stuff |
533 | 829 | self.set_shadow_type(Gtk.ShadowType.NONE) | 837 | self.set_shadow_type(Gtk.ShadowType.NONE) |
534 | @@ -881,6 +889,9 @@ | |||
535 | 881 | 889 | ||
536 | 882 | def _on_destroy(self, widget): | 890 | def _on_destroy(self, widget): |
537 | 883 | self.cache.disconnect_by_func(self._on_cache_ready) | 891 | self.cache.disconnect_by_func(self._on_cache_ready) |
538 | 892 | self.review_loader.disconnect_by_func(self._on_reviews_ready_callback) | ||
539 | 893 | self.review_loader.disconnect_by_func(self._on_remove_review_callback) | ||
540 | 894 | self.review_loader.disconnect_by_func(self._on_replace_review_callback) | ||
541 | 884 | 895 | ||
542 | 885 | def _cache_art_assets(self): | 896 | def _cache_art_assets(self): |
543 | 886 | global _asset_cache | 897 | global _asset_cache |
544 | @@ -947,18 +958,12 @@ | |||
545 | 947 | def _do_load_reviews(self): | 958 | def _do_load_reviews(self): |
546 | 948 | self.reviews.show_spinner_with_message(_('Checking for reviews...')) | 959 | self.reviews.show_spinner_with_message(_('Checking for reviews...')) |
547 | 949 | self.review_loader.get_reviews( | 960 | self.review_loader.get_reviews( |
549 | 950 | self.app, self._reviews_ready_callback, | 961 | self.app, |
550 | 951 | page=self._reviews_server_page, | 962 | page=self._reviews_server_page, |
551 | 952 | language=self._reviews_server_language, | 963 | language=self._reviews_server_language, |
552 | 953 | sort=self._review_sort_method, | 964 | sort=self._review_sort_method, |
553 | 954 | relaxed=self._reviews_relaxed) | 965 | relaxed=self._reviews_relaxed) |
554 | 955 | 966 | ||
555 | 956 | def _review_update_single(self, action, review): | ||
556 | 957 | if action == 'replace': | ||
557 | 958 | self.reviews.replace_review(review) | ||
558 | 959 | elif action == 'remove': | ||
559 | 960 | self.reviews.remove_review(review) | ||
560 | 961 | |||
561 | 962 | def _update_review_stats_widget(self, stats): | 967 | def _update_review_stats_widget(self, stats): |
562 | 963 | if stats: | 968 | if stats: |
563 | 964 | # ensure that the review UI knows about the stats | 969 | # ensure that the review UI knows about the stats |
564 | @@ -973,12 +978,23 @@ | |||
565 | 973 | def _submit_reviews_done_callback(self, spawner, error): | 978 | def _submit_reviews_done_callback(self, spawner, error): |
566 | 974 | self.reviews.new_review.enable() | 979 | self.reviews.new_review.enable() |
567 | 975 | 980 | ||
570 | 976 | def _reviews_ready_callback(self, app, reviews_data, my_votes=None, | 981 | def _on_remove_review_callback(self, loader, app, review): |
571 | 977 | action=None, single_review=None): | 982 | self.reviews.remove_review(review) |
572 | 983 | self.reviews.configure_reviews_ui() | ||
573 | 984 | |||
574 | 985 | def _on_replace_review_callback(self, loader, app, review): | ||
575 | 986 | self.reviews.replace_review(review) | ||
576 | 987 | self.reviews.configure_reviews_ui() | ||
577 | 988 | |||
578 | 989 | def _on_update_usefulness_votes_callback(self, loader, my_votes): | ||
579 | 990 | self.reviews.update_useful_votes(my_votes) | ||
580 | 991 | self.reviews.configure_reviews_ui() | ||
581 | 992 | |||
582 | 993 | def _on_reviews_ready_callback(self, loader, app, reviews_data): | ||
583 | 978 | """ callback when new reviews are ready, cleans out the | 994 | """ callback when new reviews are ready, cleans out the |
584 | 979 | old ones | 995 | old ones |
585 | 980 | """ | 996 | """ |
587 | 981 | LOG.debug("_review_ready_callback: %s" % app) | 997 | LOG.debug("_review_ready_callback: %s " % app) |
588 | 982 | # avoid possible race if we already moved to a new app when | 998 | # avoid possible race if we already moved to a new app when |
589 | 983 | # the reviews become ready | 999 | # the reviews become ready |
590 | 984 | # (we only check for pkgname currently to avoid breaking on | 1000 | # (we only check for pkgname currently to avoid breaking on |
591 | @@ -992,7 +1008,7 @@ | |||
592 | 992 | self._reviews_relaxed = True | 1008 | self._reviews_relaxed = True |
593 | 993 | self._reviews_server_page = 1 | 1009 | self._reviews_server_page = 1 |
594 | 994 | self.review_loader.get_reviews( | 1010 | self.review_loader.get_reviews( |
596 | 995 | self.app, self._reviews_ready_callback, | 1011 | self.app, |
597 | 996 | page=self._reviews_server_page, | 1012 | page=self._reviews_server_page, |
598 | 997 | language=self._reviews_server_language, | 1013 | language=self._reviews_server_language, |
599 | 998 | sort=self._review_sort_method, | 1014 | sort=self._review_sort_method, |
600 | @@ -1019,27 +1035,22 @@ | |||
601 | 1019 | # update global stats cache as well | 1035 | # update global stats cache as well |
602 | 1020 | self.review_loader.update_review_stats(app, stats) | 1036 | self.review_loader.update_review_stats(app, stats) |
603 | 1021 | 1037 | ||
606 | 1022 | if my_votes: | 1038 | curr_list = set(self.reviews.get_all_review_ids()) |
607 | 1023 | self.reviews.update_useful_votes(my_votes) | 1039 | retrieved_a_new_review = False |
608 | 1040 | for review in reviews_data: | ||
609 | 1041 | if not review.id in curr_list: | ||
610 | 1042 | retrieved_a_new_review = True | ||
611 | 1043 | self.reviews.add_review(review) | ||
612 | 1024 | 1044 | ||
631 | 1025 | if action: | 1045 | if reviews_data and not retrieved_a_new_review: |
632 | 1026 | self._review_update_single(action, single_review) | 1046 | # We retrieved data, but nothing new. Keep going. |
633 | 1027 | else: | 1047 | self._reviews_server_page += 1 |
634 | 1028 | curr_list = set(self.reviews.get_all_review_ids()) | 1048 | self.review_loader.get_reviews( |
635 | 1029 | retrieved_a_new_review = False | 1049 | self.app, |
636 | 1030 | for review in reviews_data: | 1050 | page=self._reviews_server_page, |
637 | 1031 | if not review.id in curr_list: | 1051 | language=self._reviews_server_language, |
638 | 1032 | retrieved_a_new_review = True | 1052 | sort=self._review_sort_method, |
639 | 1033 | self.reviews.add_review(review) | 1053 | relaxed=self._reviews_relaxed) |
622 | 1034 | if reviews_data and not retrieved_a_new_review: | ||
623 | 1035 | # We retrieved data, but nothing new. Keep going. | ||
624 | 1036 | self._reviews_server_page += 1 | ||
625 | 1037 | self.review_loader.get_reviews( | ||
626 | 1038 | self.app, self._reviews_ready_callback, | ||
627 | 1039 | page=self._reviews_server_page, | ||
628 | 1040 | language=self._reviews_server_language, | ||
629 | 1041 | sort=self._review_sort_method, | ||
630 | 1042 | relaxed=self._reviews_relaxed) | ||
640 | 1043 | 1054 | ||
641 | 1044 | self.reviews.configure_reviews_ui() | 1055 | self.reviews.configure_reviews_ui() |
642 | 1045 | 1056 | ||
643 | @@ -1785,35 +1796,31 @@ | |||
644 | 1785 | self.reviews.new_review.disable() | 1796 | self.reviews.new_review.disable() |
645 | 1786 | self.review_loader.spawn_write_new_review_ui( | 1797 | self.review_loader.spawn_write_new_review_ui( |
646 | 1787 | self.app, version, self.appdetails.icon, origin, | 1798 | self.app, version, self.appdetails.icon, origin, |
650 | 1788 | parent_xid, self.datadir, | 1799 | parent_xid, self.datadir) |
648 | 1789 | self._reviews_ready_callback, | ||
649 | 1790 | done_callback=self._submit_reviews_done_callback) | ||
651 | 1791 | 1800 | ||
652 | 1792 | def _review_report_abuse(self, review_id): | 1801 | def _review_report_abuse(self, review_id): |
653 | 1793 | parent_xid = '' | 1802 | parent_xid = '' |
654 | 1794 | #parent_xid = get_parent_xid(self) | 1803 | #parent_xid = get_parent_xid(self) |
655 | 1795 | self.review_loader.spawn_report_abuse_ui( | 1804 | self.review_loader.spawn_report_abuse_ui( |
657 | 1796 | review_id, parent_xid, self.datadir, self._reviews_ready_callback) | 1805 | review_id, parent_xid, self.datadir) |
658 | 1797 | 1806 | ||
659 | 1798 | def _review_submit_usefulness(self, review_id, is_useful): | 1807 | def _review_submit_usefulness(self, review_id, is_useful): |
660 | 1799 | parent_xid = '' | 1808 | parent_xid = '' |
661 | 1800 | #parent_xid = get_parent_xid(self) | 1809 | #parent_xid = get_parent_xid(self) |
662 | 1801 | self.review_loader.spawn_submit_usefulness_ui( | 1810 | self.review_loader.spawn_submit_usefulness_ui( |
665 | 1802 | review_id, is_useful, parent_xid, self.datadir, | 1811 | review_id, is_useful, parent_xid, self.datadir) |
664 | 1803 | self._reviews_ready_callback) | ||
666 | 1804 | 1812 | ||
667 | 1805 | def _review_modify(self, review_id): | 1813 | def _review_modify(self, review_id): |
668 | 1806 | parent_xid = '' | 1814 | parent_xid = '' |
669 | 1807 | #parent_xid = get_parent_xid(self) | 1815 | #parent_xid = get_parent_xid(self) |
670 | 1808 | self.review_loader.spawn_modify_review_ui( | 1816 | self.review_loader.spawn_modify_review_ui( |
673 | 1809 | parent_xid, self.appdetails.icon, self.datadir, review_id, | 1817 | parent_xid, self.appdetails.icon, self.datadir, review_id) |
672 | 1810 | self._reviews_ready_callback) | ||
674 | 1811 | 1818 | ||
675 | 1812 | def _review_delete(self, review_id): | 1819 | def _review_delete(self, review_id): |
676 | 1813 | parent_xid = '' | 1820 | parent_xid = '' |
677 | 1814 | #parent_xid = get_parent_xid(self) | 1821 | #parent_xid = get_parent_xid(self) |
678 | 1815 | self.review_loader.spawn_delete_review_ui( | 1822 | self.review_loader.spawn_delete_review_ui( |
680 | 1816 | review_id, parent_xid, self.datadir, self._reviews_ready_callback) | 1823 | review_id, parent_xid, self.datadir) |
681 | 1817 | 1824 | ||
682 | 1818 | # internal callbacks | 1825 | # internal callbacks |
683 | 1819 | def _on_cache_ready(self, cache): | 1826 | def _on_cache_ready(self, cache): |
684 | 1820 | 1827 | ||
685 | === modified file 'softwarecenter/ui/qml/reviewslist.py' | |||
686 | --- softwarecenter/ui/qml/reviewslist.py 2012-03-07 20:08:53 +0000 | |||
687 | +++ softwarecenter/ui/qml/reviewslist.py 2012-09-01 11:39:19 +0000 | |||
688 | @@ -46,6 +46,11 @@ | |||
689 | 46 | # FIXME: make this async | 46 | # FIXME: make this async |
690 | 47 | self.cache = get_pkg_info() | 47 | self.cache = get_pkg_info() |
691 | 48 | self.reviews = get_review_loader(self.cache) | 48 | self.reviews = get_review_loader(self.cache) |
692 | 49 | self.reviews.connect( | ||
693 | 50 | "refresh-review-stats-finished", | ||
694 | 51 | self._on_refresh_review_stats_finished) | ||
695 | 52 | self.reviews.connect( | ||
696 | 53 | "get-reviews-finished", self._on_reviews_ready_callback) | ||
697 | 49 | 54 | ||
698 | 50 | # QAbstractListModel code | 55 | # QAbstractListModel code |
699 | 51 | def rowCount(self, parent=QModelIndex()): | 56 | def rowCount(self, parent=QModelIndex()): |
700 | @@ -68,7 +73,7 @@ | |||
701 | 68 | self._reviews = [] | 73 | self._reviews = [] |
702 | 69 | self.endRemoveRows() | 74 | self.endRemoveRows() |
703 | 70 | 75 | ||
705 | 71 | def _on_reviews_ready_callback(self, loader, reviews): | 76 | def _on_reviews_ready_callback(self, loader, app, reviews): |
706 | 72 | self.beginInsertRows(QModelIndex(), | 77 | self.beginInsertRows(QModelIndex(), |
707 | 73 | self.rowCount(), # first | 78 | self.rowCount(), # first |
708 | 74 | self.rowCount() + len(reviews) - 1) # last | 79 | self.rowCount() + len(reviews) - 1) # last |
709 | @@ -87,16 +92,15 @@ | |||
710 | 87 | 92 | ||
711 | 88 | # load in the eventloop to ensure that animations are not delayed | 93 | # load in the eventloop to ensure that animations are not delayed |
712 | 89 | GObject.timeout_add( | 94 | GObject.timeout_add( |
715 | 90 | 10, self.reviews.get_reviews, app, | 95 | 10, self.reviews.get_reviews, app, page) |
714 | 91 | self._on_reviews_ready_callback, page) | ||
716 | 92 | 96 | ||
717 | 93 | # refresh review-stats (for qml) | 97 | # refresh review-stats (for qml) |
718 | 98 | def _on_refresh_review_stats_finished(self, loader, stats): | ||
719 | 99 | self.reviewStatsChanged.emit() | ||
720 | 100 | |||
721 | 94 | @pyqtSlot() | 101 | @pyqtSlot() |
722 | 95 | def refreshReviewStats(self): | 102 | def refreshReviewStats(self): |
727 | 96 | def _on_refresh_reviews_ready_callback(loader): | 103 | self.reviews.refresh_review_stats() |
724 | 97 | self.reviewStatsChanged.emit() | ||
725 | 98 | self.reviews.refresh_review_stats( | ||
726 | 99 | _on_refresh_reviews_ready_callback) | ||
728 | 100 | 104 | ||
729 | 101 | # FIXME: how is this signal actually used in the qml JS? | 105 | # FIXME: how is this signal actually used in the qml JS? |
730 | 102 | # signals | 106 | # signals |
731 | 103 | 107 | ||
732 | === modified file 'tests/gtk3/test_appdetailsview.py' | |||
733 | --- tests/gtk3/test_appdetailsview.py 2012-08-20 09:09:45 +0000 | |||
734 | +++ tests/gtk3/test_appdetailsview.py 2012-09-01 11:39:19 +0000 | |||
735 | @@ -203,8 +203,8 @@ | |||
736 | 203 | self.assertEqual(1, kwargs['page']) | 203 | self.assertEqual(1, kwargs['page']) |
737 | 204 | 204 | ||
738 | 205 | # Now we come back with no data | 205 | # Now we come back with no data |
741 | 206 | application, callback = mock_get_reviews.call_args[0] | 206 | application = mock_get_reviews.call_args[0][0] |
742 | 207 | callback(application, []) | 207 | self.view.review_loader.emit("get-reviews-finished", application, []) |
743 | 208 | 208 | ||
744 | 209 | self.assertEqual(2, mock_get_reviews.call_count) | 209 | self.assertEqual(2, mock_get_reviews.call_count) |
745 | 210 | kwargs = mock_get_reviews.call_args[1] | 210 | kwargs = mock_get_reviews.call_args[1] |
746 | @@ -237,8 +237,8 @@ | |||
747 | 237 | self.assertEqual(1, kwargs['page']) | 237 | self.assertEqual(1, kwargs['page']) |
748 | 238 | 238 | ||
749 | 239 | # Now we come back with no NEW data | 239 | # Now we come back with no NEW data |
752 | 240 | application, callback = mock_get_reviews.call_args[0] | 240 | application = mock_get_reviews.call_args[0][0] |
753 | 241 | callback(application, reviews) | 241 | self.view.review_loader.emit("get-reviews-finished", application, reviews) |
754 | 242 | 242 | ||
755 | 243 | self.assertEqual(2, mock_get_reviews.call_count) | 243 | self.assertEqual(2, mock_get_reviews.call_count) |
756 | 244 | kwargs = mock_get_reviews.call_args[1] | 244 | kwargs = mock_get_reviews.call_args[1] |
Hey Aaron, thanks a lot for your work on this!
I think this is good, there is just one issue with the tests test_appdetails view.py ======= ======= ======= ======= ======= ======= ======= ======= ======= duplicate_ reviews_ keeps_going (__main_ _.TestAppdetail sView) _reviews_ ready_callback will fetch another page if ------- ------- ------- ------- ------- ------- ------- ------- ------- python2. 7/dist- packages/ mock.py" , line 1224, in patched gtk3/test_ appdetailsview. py", line 240, in test_all_ duplicate_ reviews_ keeps_going reviews. call_args[ 0]
that probably just needs updating:
$ PYTHONPATH=. python tests/gtk3/
...
=======
ERROR: test_all_
AppDetailsView.
-------
Traceback (most recent call last):
File "/usr/lib/
return func(*args, **keywargs)
File "tests/
application, callback = mock_get_
ValueError: need more than 1 value to unpack
======= ======= ======= ======= ======= ======= ======= ======= ======= ======= reviews_ returned_ attempts_ relaxing (__main_ _.TestAppdetail sView) _reviews_ ready_callback will attempt to drop the ------- ------- ------- ------- ------- ------- ------- ------- ------- python2. 7/dist- packages/ mock.py" , line 1224, in patched gtk3/test_ appdetailsview. py", line 206, in test_no_ reviews_ returned_ attempts_ relaxing reviews. call_args[ 0]
ERROR: test_no_
AppDetailsView.
-------
Traceback (most recent call last):
File "/usr/lib/
return func(*args, **keywargs)
File "tests/
application, callback = mock_get_
ValueError: need more than 1 value to unpack
------- ------- ------- ------- ------- ------- ------- ------- ------- -------
Ran 23 tests in 135.414s
I will try to get to it later today unless you want to tackle it (which would be very welcome
of course as well :)