diff options
author | Vilem Duha <vilem.duha@gmail.com> | 2021-05-21 15:44:11 +0300 |
---|---|---|
committer | Vilem Duha <vilem.duha@gmail.com> | 2021-05-21 15:44:11 +0300 |
commit | 437ce51ab70d18668b699883299ff82d9ed5f4e7 (patch) | |
tree | 6c12b385a0a5f62f34e7ff2e3b5978c8d43bc5aa | |
parent | 85abebde4ff16a406fd05341bf7d0be009d5321c (diff) |
BlenderKit: fetch user's ratings from server
by now enabled only for validators, to test performance. Also shows to validator which assets were not yet rated by them.
-rw-r--r-- | blenderkit/ratings.py | 14 | ||||
-rw-r--r-- | blenderkit/ratings_utils.py | 138 | ||||
-rw-r--r-- | blenderkit/search.py | 13 | ||||
-rw-r--r-- | blenderkit/ui.py | 33 |
4 files changed, 121 insertions, 77 deletions
diff --git a/blenderkit/ratings.py b/blenderkit/ratings.py index cde57893..10d815ba 100644 --- a/blenderkit/ratings.py +++ b/blenderkit/ratings.py @@ -58,19 +58,7 @@ def upload_review_thread(url, reviews, headers): # print('reviews upload failed: %s' % str(e)) -def get_rating(asset_id): - # this function isn't used anywhere,should probably get removed. - user_preferences = bpy.context.preferences.addons['blenderkit'].preferences - api_key = user_preferences.api_key - headers = utils.get_headers(api_key) - rl = paths.get_api_url() + 'assets/' + asset['asset_data']['id'] + '/rating/' - rtypes = ['quality', 'working_hours'] - for rt in rtypes: - params = { - 'rating_type': rt - } - r = rerequests.get(r1, params=data, verify=True, headers=headers) - print(r.text) + def upload_rating(asset): diff --git a/blenderkit/ratings_utils.py b/blenderkit/ratings_utils.py index 26acb84c..fe2643e1 100644 --- a/blenderkit/ratings_utils.py +++ b/blenderkit/ratings_utils.py @@ -68,6 +68,12 @@ def send_rating_to_thread_work_hours(url, ratings, headers): thread.start() +def store_rating_local_empty(asset_id): + context = bpy.context + context.window_manager['asset ratings'] = context.window_manager.get('asset ratings', {}) + context.window_manager['asset ratings'][asset_id] = context.window_manager['asset ratings'].get(asset_id, {}) + + def store_rating_local(asset_id, type='quality', value=0): context = bpy.context context.window_manager['asset ratings'] = context.window_manager.get('asset ratings', {}) @@ -75,6 +81,36 @@ def store_rating_local(asset_id, type='quality', value=0): context.window_manager['asset ratings'][asset_id][type] = value +def get_rating(asset_id, headers): + ''' + Retrieve ratings from BlenderKit server. Can be run from a thread + Parameters + ---------- + asset_id + headers + + Returns + ------- + ratings - dict of type:value ratings + ''' + url = paths.get_api_url() + 'assets/' + asset_id + '/rating/' + params = {} + r = rerequests.get(url, params=params, verify=True, headers=headers) + print(r.text) + rj = r.json() + ratings = {} + # store ratings - send them to task queue + for r in rj['results']: + ratings[r['ratingType']] = r['score'] + tasks_queue.add_task((store_rating_local,(asset_id, r['ratingType'], r['score']))) + # store_rating_local(asset_id, type = r['ratingType'], value = r['score']) + + if len(rj['results'])==0: + # store empty ratings too, so that server isn't checked repeatedly + tasks_queue.add_task((store_rating_local_empty,(asset_id,))) + return ratings + + def get_rating_local(asset_id): context = bpy.context context.window_manager['asset ratings'] = context.window_manager.get('asset ratings', {}) @@ -246,61 +282,67 @@ class RatingsProperties(): high_rating_warning = "This is a high rating, please be sure to give such rating only to amazing assets" + possible_wh_values = [0,.5,1,2,3,4,5,6,8,10,15,20,30,50,100,150,200,250] + items_models = [('0', '0', ''), + ('.5', '0.5', ''), + ('1', '1', ''), + ('2', '2', ''), + ('3', '3', ''), + ('4', '4', ''), + ('5', '5', ''), + ('6', '6', ''), + ('8', '8', ''), + ('10', '10', ''), + ('15', '15', ''), + ('20', '20', ''), + ('30', '30', high_rating_warning), + ('50', '50', high_rating_warning), + ('100', '100', high_rating_warning), + ('150', '150', high_rating_warning), + ('200', '200', high_rating_warning), + ('250', '250', high_rating_warning), + ] rating_work_hours_ui: EnumProperty(name="Work Hours", description="How many hours did this work take?", - items=[('0', '0', ''), - ('.5', '0.5', ''), - ('1', '1', ''), - ('2', '2', ''), - ('3', '3', ''), - ('4', '4', ''), - ('5', '5', ''), - ('6', '6', ''), - ('8', '8', ''), - ('10', '10', ''), - ('15', '15', ''), - ('20', '20', ''), - ('30', '30', high_rating_warning), - ('50', '50', high_rating_warning), - ('100', '100', high_rating_warning), - ('150', '150', high_rating_warning), - ('200', '200', high_rating_warning), - ('250', '250', high_rating_warning), - ], + items=items_models, default='0', update=update_ratings_work_hours_ui, options={'SKIP_SAVE'} ) - + possible_wh_values_1_5 = [0,.2, .5,1,2,3,4,5] + + items_1_5 = [('0', '0', ''), + ('.2', '0.2', ''), + ('.5', '0.5', ''), + ('1', '1', ''), + ('2', '2', ''), + ('3', '3', ''), + ('4', '4', ''), + ('5', '5', '') + ] rating_work_hours_ui_1_5: EnumProperty(name="Work Hours", description="How many hours did this work take?", - items=[('0', '0', ''), - ('.2', '0.2', ''), - ('.5', '0.5', ''), - ('1', '1', ''), - ('2', '2', ''), - ('3', '3', ''), - ('4', '4', ''), - ('5', '5', '') - ], + items=items_1_5, default='0', update=update_ratings_work_hours_ui_1_5, options={'SKIP_SAVE'} ) - + possible_wh_values_1_10 = [0,1,2,3,4,5,6,7,8,9,10] + + items_1_10= [('0', '0', ''), + ('1', '1', ''), + ('2', '2', ''), + ('3', '3', ''), + ('4', '4', ''), + ('5', '5', ''), + ('6', '6', ''), + ('7', '7', ''), + ('8', '8', ''), + ('9', '9', ''), + ('10', '10', '') + ] rating_work_hours_ui_1_10: EnumProperty(name="Work Hours", description="How many hours did this work take?", - items=[('0', '0', ''), - ('1', '1', ''), - ('2', '2', ''), - ('3', '3', ''), - ('4', '4', ''), - ('5', '5', ''), - ('6', '6', ''), - ('7', '7', ''), - ('8', '8', ''), - ('9', '9', ''), - ('10', '10', '') - ], + items= items_1_10, default='0', update=update_ratings_work_hours_ui_1_10, options={'SKIP_SAVE'} @@ -313,8 +355,10 @@ class RatingsProperties(): self.rating_quality = ratings['quality'] if ratings and ratings.get('working_hours'): wh = int(ratings['working_hours']) - self.rating_work_hours_ui = str(wh) - if wh < 6: - self.rating_work_hours_ui_1_5 = str(int(ratings['working_hours'])) - if wh < 11: - self.rating_work_hours_ui_1_10 = str(int(ratings['working_hours'])) + whs = str(wh) + if wh in self.possible_wh_values: + self.rating_work_hours_ui = whs + if wh < 6 and wh in self.possible_wh_values_1_5: + self.rating_work_hours_ui_1_5 = whs + if wh < 11 and wh in self.possible_wh_values_1_10: + self.rating_work_hours_ui_1_10 = whs diff --git a/blenderkit/search.py b/blenderkit/search.py index cd89d3bd..f0d1fec6 100644 --- a/blenderkit/search.py +++ b/blenderkit/search.py @@ -17,7 +17,7 @@ # ##### END GPL LICENSE BLOCK ##### from blenderkit import paths, utils, categories, ui, colors, bkit_oauth, version_checker, tasks_queue, rerequests, \ - resolutions, image_utils + resolutions, image_utils, ratings_utils import blenderkit from bpy.app.handlers import persistent @@ -419,15 +419,24 @@ def timer_update(): rdata = thread[0].result result_field = [] + ok, error = check_errors(rdata) if ok: bpy.ops.object.run_assetbar_fix_context() + + user_preferences = bpy.context.preferences.addons['blenderkit'].preferences + api_key = user_preferences.api_key + headers = utils.get_headers(api_key) + for r in rdata['results']: asset_data = parse_result(r) if asset_data != None: result_field.append(asset_data) - # results = rdata['results'] + if utils.profile_is_validator() and ratings_utils.get_rating_local(asset_data['id']) is None: + thread = threading.Thread(target=ratings_utils.get_rating, args=([asset_data['id'], headers]), daemon=True) + thread.start() + wm[search_name] = result_field wm['search results'] = result_field wm[search_name + ' orig'] = copy.deepcopy(rdata) diff --git a/blenderkit/ui.py b/blenderkit/ui.py index 84deb24e..09a1f88e 100644 --- a/blenderkit/ui.py +++ b/blenderkit/ui.py @@ -18,7 +18,7 @@ from blenderkit import paths, ratings, utils, search, upload, ui_bgl, download, bg_blender, colors, tasks_queue, \ - ui_panels, icons + ui_panels, icons, ratings_utils import bpy @@ -272,7 +272,7 @@ def draw_text_block(x=0, y=0, width=40, font_size=10, line_height=15, text='', c ui_bgl.draw_text(l, x, ytext, font_size, color) -def draw_tooltip(x, y, name='', author='', quality = '-', img=None, gravatar=None): +def draw_tooltip(x, y, name='', author='', quality='-', img=None, gravatar=None): region = bpy.context.region scale = bpy.context.preferences.view.ui_scale t = time.time() @@ -282,12 +282,12 @@ def draw_tooltip(x, y, name='', author='', quality = '-', img=None, gravatar=Non x += 20 y -= 20 - #first get image size scaled + # first get image size scaled isizex = int(512 * scale * img.size[0] / min(img.size[0], img.size[1])) isizey = int(512 * scale * img.size[1] / min(img.size[0], img.size[1])) ttipmargin = 5 * scale - #then do recurrent re-scaling, to know where to fit the tooltip + # then do recurrent re-scaling, to know where to fit the tooltip estimated_height = 2 * ttipmargin + isizey if estimated_height > y: scaledown = y / (estimated_height) @@ -304,7 +304,6 @@ def draw_tooltip(x, y, name='', author='', quality = '-', img=None, gravatar=Non else: overlay_height_base = 70 - overlay_height = overlay_height_base * scale name_height = int(20 * scale) @@ -338,15 +337,14 @@ def draw_tooltip(x, y, name='', author='', quality = '-', img=None, gravatar=Non ui_bgl.draw_rect(x - ttipmargin, y - 2 * ttipmargin - isizey, isizex + ttipmargin * 2, - ttipmargin + overlay_height , + ttipmargin + overlay_height, background_overlay) - #draw name + # draw name name_x = x + textmargin name_y = y - isizey + overlay_height - textmargin - name_height ui_bgl.draw_text(name, name_x, name_y, name_height, textcol) - # draw gravatar author_x_text = x + isizex - textmargin gravatar_size = overlay_height - 2 * textmargin @@ -357,7 +355,7 @@ def draw_tooltip(x, y, name='', author='', quality = '-', img=None, gravatar=Non gravatar_y, # + textmargin, gravatar_size, gravatar_size, gravatar, 1) - #draw author's name + # draw author's name author_text_size = int(name_height * .7) ui_bgl.draw_text(author, author_x_text, gravatar_y, author_text_size, textcol, ralign=True) @@ -368,7 +366,6 @@ def draw_tooltip(x, y, name='', author='', quality = '-', img=None, gravatar=Non ui_bgl.draw_text(str(quality), name_x + quality_text_size + 5, gravatar_y, quality_text_size, textcol) - def draw_tooltip_with_author(asset_data, x, y): # TODO move this lazy loading into a function and don't duplicate through the code @@ -383,7 +380,7 @@ def draw_tooltip_with_author(asset_data, x, y): aname = asset_data['displayName'] aname = aname[0].upper() + aname[1:] - if len(aname)>36: + if len(aname) > 36: aname = f"{aname[:33]}..." rc = asset_data.get('ratingsCount') @@ -392,10 +389,10 @@ def draw_tooltip_with_author(asset_data, x, y): quality = '-' if rc: rcount = min(rc['quality'], rc['workingHours']) - if rcount>show_rating_threshold: + if rcount > show_rating_threshold: quality = round(asset_data['ratingsAverage'].get('quality')) - draw_tooltip(x, y, name=aname, author=f"by {a['firstName']} {a['lastName']}", quality= quality, img=img, + draw_tooltip(x, y, name=aname, author=f"by {a['firstName']} {a['lastName']}", quality=quality, img=img, gravatar=gimg) @@ -694,6 +691,12 @@ def draw_asset_bar(self, context): # pcoll = icons.icon_collections["main"] # v_icon = pcoll['rejected'] v_icon = verification_icons[result.get('verificationStatus', 'validated')] + + if v_icon is None and utils.profile_is_validator(): + # poke for validators to rate + if ratings_utils.get_rating_local(result['id']) in (None, {}): + v_icon = 'star_grey.png' + if v_icon is not None: img = utils.get_thumbnail(v_icon) ui_bgl.draw_image(x + ui_props.thumb_size - 26, y + 2, 24, 24, img, 1) @@ -1266,7 +1269,7 @@ class AssetBarOperator(bpy.types.Operator): export_data, upload_data = upload.get_upload_data(context=context, asset_type=ui_props.asset_type) if upload_data: # print(upload_data) - ui_props.tooltip = upload_data['displayName']#search.generate_tooltip(upload_data) + ui_props.tooltip = upload_data['displayName'] # search.generate_tooltip(upload_data) return {'PASS_THROUGH'} @@ -1419,7 +1422,7 @@ class AssetBarOperator(bpy.types.Operator): mx = event.mouse_x - r.x my = event.mouse_y - r.y - if event.value == 'PRESS' and mouse_in_asset_bar(mx, my) and ui_props.active_index>-1: + if event.value == 'PRESS' and mouse_in_asset_bar(mx, my) and ui_props.active_index > -1: # context.window.cursor_warp(event.mouse_x - 300, event.mouse_y - 10); bpy.ops.wm.blenderkit_asset_popup('INVOKE_DEFAULT') |