~mvo/software-center/lp1045330

« back to all changes in this revision

Viewing changes to softwarecenter/backend/reviews/rnr.py

  • Committer: Michael Vogt
  • Date: 2012-09-03 09:31:29 UTC
  • mfrom: (2822.3.12 review-refactor)
  • Revision ID: michael.vogt@ubuntu.com-20120903093129-kkfaee0x13i5jx7l
merged lp:~aaronp/software-center/review-refactor, many thanks

Show diffs side-by-side

added added

removed removed

Lines of Context:
69
69
        self.rnrclient._offline_mode = not network_state_is_connected()
70
70
 
71
71
    # reviews
72
 
    def get_reviews(self, translated_app, callback, page=1,
 
72
    def get_reviews(self, translated_app, page=1,
73
73
                    language=None, sort=0, relaxed=False):
74
 
        """ public api, triggers fetching a review and calls callback
75
 
            when its ready
 
74
        """ public api, triggers fetching a review and emits
 
75
            get-reviews-finished signal when its ready
76
76
        """
77
77
        # its fine to use the translated appname here, we only submit the
78
78
        # pkgname to the server
100
100
                    origin = "lp-ppa-%s" % ppa.replace("/", "-")
101
101
            # if there is no origin, there is nothing to do
102
102
            if not origin:
103
 
                callback(app, [])
 
103
                self.emit("get-reviews-finished", app, [])
104
104
                return
105
105
            distroseries = self.distro.get_codename()
106
106
        # run the command and add watcher
115
115
              ]
116
116
        spawn_helper = SpawnHelper()
117
117
        spawn_helper.connect(
118
 
            "data-available", self._on_reviews_helper_data, app, callback)
 
118
            "data-available", self._on_reviews_helper_data, app)
119
119
        spawn_helper.run(cmd)
120
120
 
121
 
    def _on_reviews_helper_data(self, spawn_helper, piston_reviews, app,
122
 
        callback):
 
121
    def _on_reviews_helper_data(self, spawn_helper, piston_reviews, app):
123
122
        # convert into our review objects
124
123
        reviews = []
125
124
        for r in piston_reviews:
126
125
            reviews.append(Review.from_piston_mini_client(r))
127
 
        # add to our dicts and run callback
 
126
        # add to our dicts and emit signal
128
127
        self._reviews[app] = reviews
129
 
        callback(app, self._reviews[app])
 
128
        self.emit("get-reviews-finished", app, self._reviews[app])
130
129
        return False
131
130
 
132
131
    # stats
133
 
    def refresh_review_stats(self, callback):
 
132
    def refresh_review_stats(self):
134
133
        """ public api, refresh the available statistics """
135
134
        try:
136
135
            mtime = os.path.getmtime(self.REVIEW_STATS_CACHE_FILE)
145
144
        #origin = "any"
146
145
        #distroseries = self.distro.get_codename()
147
146
        spawn_helper = SpawnHelper()
148
 
        spawn_helper.connect("data-available", self._on_review_stats_data,
149
 
            callback)
 
147
        spawn_helper.connect("data-available", self._on_review_stats_data)
150
148
        if days_delta:
151
149
            spawn_helper.run_generic_piston_helper(
152
150
                "RatingsAndReviewsAPI", "review_stats", days=days_delta)
154
152
            spawn_helper.run_generic_piston_helper(
155
153
                "RatingsAndReviewsAPI", "review_stats")
156
154
 
157
 
    def _on_review_stats_data(self, spawn_helper, piston_review_stats,
158
 
        callback):
 
155
    def _on_review_stats_data(self, spawn_helper, piston_review_stats):
159
156
        """ process stdout from the helper """
160
157
        review_stats = self.REVIEW_STATS_CACHE
161
158
 
163
160
            piston_review_stats):
164
161
            self.REVIEW_STATS_CACHE = {}
165
162
            self.save_review_stats_cache_file()
166
 
            self.refresh_review_stats(callback)
 
163
            self.refresh_review_stats()
167
164
            return
168
165
 
169
166
        # convert to the format that s-c uses
178
175
            s.dampened_rating = calc_dr(s.rating_spread)
179
176
            review_stats[s.app] = s
180
177
        self.REVIEW_STATS_CACHE = review_stats
181
 
        callback(review_stats)
182
178
        self.emit("refresh-review-stats-finished", review_stats)
183
179
        self.save_review_stats_cache_file()
184
180
 
190
186
        return True
191
187
 
192
188
    # writing new reviews spawns external helper
193
 
    # FIXME: instead of the callback we should add proper gobject signals
194
189
    def spawn_write_new_review_ui(self, translated_app, version, iconname,
195
 
                                  origin, parent_xid, datadir, callback,
196
 
                                  done_callback=None):
 
190
                                  origin, parent_xid, datadir):
197
191
        """ this spawns the UI for writing a new review and
198
192
            adds it automatically to the reviews DB """
199
193
        app = translated_app.get_untranslated_app(self.db)
210
204
            cmd += ["--appname", utf8(app.appname)]
211
205
        spawn_helper = SpawnHelper(format="json")
212
206
        spawn_helper.connect(
213
 
            "data-available", self._on_submit_review_data, app, callback)
214
 
        if done_callback:
215
 
            spawn_helper.connect("exited", done_callback)
216
 
            spawn_helper.connect("error", done_callback)
 
207
            "data-available", self._on_submit_review_data, app)
 
208
        spawn_helper.connect("exited", self._on_exited_callback, app)
 
209
        spawn_helper.connect("error", self._on_error_callback, app)
217
210
        spawn_helper.run(cmd)
218
211
 
219
 
    def _on_submit_review_data(self, spawn_helper, review_json, app, callback):
 
212
    def _on_exited_callback(self, spawn_helper, return_code, app):
 
213
        # FIXME: send a proper error here instead!
 
214
        self.emit("get-reviews-finished", app, [])
 
215
 
 
216
    def _on_error_callback(self, spawn_helper, error_str, app):
 
217
        # FIXME: send a proper error here instead!
 
218
        self.emit("get-reviews-finished", app, [])
 
219
 
 
220
    def _on_submit_review_data(self, spawn_helper, review_json, app):
220
221
        """ called when submit_review finished, when the review was send
221
222
            successfully the callback is triggered with the new reviews
222
223
        """
229
230
        if not app in self._reviews:
230
231
            self._reviews[app] = []
231
232
        self._reviews[app].insert(0, Review.from_piston_mini_client(review))
232
 
        callback(app, self._reviews[app])
 
233
        self.emit("get-reviews-finished", app, self._reviews[app])
233
234
 
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):
235
236
        """ this spawns the UI for reporting a review as inappropriate
236
237
            and adds the review-id to the internal hide list. once the
237
 
            operation is complete it will call callback with the updated
 
238
            operation is complete it will emit remove-review with the updated
238
239
            review list
239
240
        """
240
241
        cmd = [os.path.join(datadir, RNRApps.REPORT_REVIEW),
245
246
        spawn_helper = SpawnHelper("json")
246
247
        spawn_helper.connect("exited",
247
248
                             self._on_report_abuse_finished,
248
 
                             review_id, callback)
 
249
                             review_id)
249
250
        spawn_helper.run(cmd)
250
251
 
251
 
    def _on_report_abuse_finished(self, spawn_helper, exitcode, review_id,
252
 
        callback):
 
252
    def _on_report_abuse_finished(self, spawn_helper, exitcode, review_id):
253
253
        """ called when report_absuse finished """
254
254
        LOG.debug("hide id %s " % review_id)
255
255
        if exitcode == 0:
258
258
                    if str(review.id) == str(review_id):
259
259
                        # remove the one we don't want to see anymore
260
260
                        self._reviews[app].remove(review)
261
 
                        callback(app, self._reviews[app], None, 'remove',
262
 
                            review)
 
261
                        self.emit("remove-review", app, review)
263
262
                        break
264
263
 
265
264
    def spawn_submit_usefulness_ui(self, review_id, is_useful, parent_xid,
266
 
        datadir, callback):
 
265
                                   datadir):
267
266
        cmd = [os.path.join(datadir, RNRApps.SUBMIT_USEFULNESS),
268
267
               "--review-id", "%s" % review_id,
269
268
               "--is-useful", "%s" % int(is_useful),
273
272
        spawn_helper = SpawnHelper(format="none")
274
273
        spawn_helper.connect("exited",
275
274
                             self._on_submit_usefulness_finished,
276
 
                             review_id, is_useful, callback)
 
275
                             review_id, is_useful)
277
276
        spawn_helper.connect("error",
278
277
                             self._on_submit_usefulness_error,
279
 
                             review_id, callback)
 
278
                             review_id)
280
279
        spawn_helper.run(cmd)
281
280
 
282
281
    def _on_submit_usefulness_finished(self, spawn_helper, res, review_id,
283
 
        is_useful, callback):
 
282
                                       is_useful):
284
283
        """ called when report_usefulness finished """
285
284
        # "Created", "Updated", "Not modified" -
286
285
        # once lp:~mvo/rnr-server/submit-usefulness-result-strings makes it
287
286
        response = spawn_helper._stdout
288
287
        if response == '"Not modified"':
289
 
            self._on_submit_usefulness_error(spawn_helper, response, review_id,
290
 
                callback)
 
288
            self._on_submit_usefulness_error(spawn_helper, response, review_id)
291
289
            return
292
290
 
293
291
        LOG.debug("usefulness id %s " % review_id)
301
299
                    review.usefulness_total = getattr(review,
302
300
                        "usefulness_total", 0) + 1
303
301
                    if is_useful:
304
 
                        review.usefulness_favorable = getattr(review,
305
 
                            "usefulness_favorable", 0) + 1
306
 
                        callback(app, self._reviews[app], useful_votes,
307
 
                            'replace', review)
308
 
                        break
309
 
 
310
 
    def _on_submit_usefulness_error(self, spawn_helper, error_str, review_id,
311
 
        callback):
312
 
        LOG.warn("submit usefulness id=%s failed with error: %s" %
313
 
                 (review_id, error_str))
314
 
        for (app, reviews) in self._reviews.items():
315
 
            for review in reviews:
316
 
                if str(review.id) == str(review_id):
317
 
                    review.usefulness_submit_error = True
318
 
                    callback(app, self._reviews[app], None, 'replace', review)
319
 
                    break
320
 
 
321
 
    def spawn_delete_review_ui(self, review_id, parent_xid, datadir, callback):
 
302
                        review.usefulness_favorable = getattr(
 
303
                            review, "usefulness_favorable", 0) + 1
 
304
                        self.emit("update-usefulness-votes", useful_votes)
 
305
                        self.emit("replace-review", app, review)
 
306
                        break
 
307
 
 
308
    def _on_submit_usefulness_error(self, spawn_helper, error_str, review_id):
 
309
            LOG.warn("submit usefulness id=%s failed with error: %s" %
 
310
                     (review_id, error_str))
 
311
            for (app, reviews) in self._reviews.items():
 
312
                for review in reviews:
 
313
                    if str(review.id) == str(review_id):
 
314
                        review.usefulness_submit_error = True
 
315
                        self.emit("replace-review", app, review)
 
316
                        break
 
317
 
 
318
    def spawn_delete_review_ui(self, review_id, parent_xid, datadir):
322
319
        cmd = [os.path.join(datadir, RNRApps.DELETE_REVIEW),
323
320
               "--review-id", "%s" % review_id,
324
321
               "--parent-xid", "%s" % parent_xid,
327
324
        spawn_helper = SpawnHelper(format="none")
328
325
        spawn_helper.connect("exited",
329
326
                             self._on_delete_review_finished,
330
 
                             review_id, callback)
 
327
                             review_id)
331
328
        spawn_helper.connect("error", self._on_delete_review_error,
332
 
                             review_id, callback)
 
329
                             review_id)
333
330
        spawn_helper.run(cmd)
334
331
 
335
 
    def _on_delete_review_finished(self, spawn_helper, res, review_id,
336
 
        callback):
 
332
    def _on_delete_review_finished(self, spawn_helper, res, review_id):
337
333
        """ called when delete_review finished"""
338
334
        LOG.debug("delete id %s " % review_id)
339
335
        for (app, reviews) in self._reviews.items():
341
337
                if str(review.id) == str(review_id):
342
338
                    # remove the one we don't want to see anymore
343
339
                    self._reviews[app].remove(review)
344
 
                    callback(app, self._reviews[app], None, 'remove', review)
 
340
                    self.emit("remove-review", app, review)
345
341
                    break
346
342
 
347
 
    def _on_delete_review_error(self, spawn_helper, error_str, review_id,
348
 
        callback):
 
343
    def _on_delete_review_error(self, spawn_helper, error_str, review_id):
349
344
        """called if delete review errors"""
350
345
        LOG.warn("delete review id=%s failed with error: %s" % (review_id,
351
346
            error_str))
353
348
            for review in reviews:
354
349
                if str(review.id) == str(review_id):
355
350
                    review.delete_error = True
356
 
                    callback(app, self._reviews[app], action='replace',
357
 
                             single_review=review)
 
351
                    self.emit("remove-review", app, review)
358
352
                    break
359
353
 
360
 
    def spawn_modify_review_ui(self, parent_xid, iconname, datadir, review_id,
361
 
        callback):
 
354
    def spawn_modify_review_ui(self, parent_xid, iconname, datadir, review_id):
362
355
        """ this spawns the UI for writing a new review and
363
356
            adds it automatically to the reviews DB """
364
357
        cmd = [os.path.join(datadir, RNRApps.MODIFY_REVIEW),
370
363
        spawn_helper = SpawnHelper(format="json")
371
364
        spawn_helper.connect("data-available",
372
365
                             self._on_modify_review_finished,
373
 
                             review_id, callback)
 
366
                             review_id)
374
367
        spawn_helper.connect("error", self._on_modify_review_error,
375
 
                             review_id, callback)
 
368
                             review_id)
376
369
        spawn_helper.run(cmd)
377
370
 
378
 
    def _on_modify_review_finished(self, spawn_helper, review_json, review_id,
379
 
        callback):
 
371
    def _on_modify_review_finished(self, spawn_helper, review_json, review_id):
380
372
        """called when modify_review finished"""
381
373
        LOG.debug("_on_modify_review_finished")
382
374
        #review_json = spawn_helper._stdout
388
380
                    self._reviews[app].remove(review)
389
381
                    new_review = Review.from_piston_mini_client(mod_review)
390
382
                    self._reviews[app].insert(0, new_review)
391
 
                    callback(app, self._reviews[app], action='replace',
392
 
                             single_review=new_review)
 
383
                    self.emit("replace-review", app, new_review)
393
384
                    break
394
385
 
395
 
    def _on_modify_review_error(self, spawn_helper, error_str, review_id,
396
 
        callback):
 
386
    def _on_modify_review_error(self, spawn_helper, error_str, review_id):
397
387
        """called if modify review errors"""
398
388
        LOG.debug("modify review id=%s failed with error: %s" %
399
389
            (review_id, error_str))
401
391
            for review in reviews:
402
392
                if str(review.id) == str(review_id):
403
393
                    review.modify_error = True
404
 
                    callback(app, self._reviews[app], action='replace',
405
 
                             single_review=review)
 
394
                    self.emit("replace-review", app, review)
406
395
                    break