diff options
author | Vilem Duha <vilem.duha@gmail.com> | 2021-05-21 15:44:11 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2021-08-09 09:40:44 +0300 |
commit | 6a81558b63d579a58de4df39def083bb34defca7 (patch) | |
tree | d19c1d325158075b78fbc5124a0a1977cb4f77a3 | |
parent | 40112c2d3720745b0d52b3225d9619e4dac3d126 (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 | 3 | ||||
-rw-r--r-- | blenderkit/ratings_utils.py | 138 | ||||
-rw-r--r-- | blenderkit/search.py | 19 | ||||
-rw-r--r-- | blenderkit/ui.py | 31 |
4 files changed, 119 insertions, 72 deletions
diff --git a/blenderkit/ratings.py b/blenderkit/ratings.py index 2a3ac76b..10d815ba 100644 --- a/blenderkit/ratings.py +++ b/blenderkit/ratings.py @@ -58,6 +58,9 @@ def upload_review_thread(url, reviews, headers): # print('reviews upload failed: %s' % str(e)) + + + def upload_rating(asset): user_preferences = bpy.context.preferences.addons['blenderkit'].preferences api_key = user_preferences.api_key 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 310d1138..0d3d73b0 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 @@ -428,6 +428,7 @@ def search_timer(): rdata = thread[0].result result_field = [] + ok, error = check_errors(rdata) if ok: ui_props = bpy.context.scene.blenderkitUI @@ -435,22 +436,18 @@ def search_timer(): if not ui_props.assetbar_on: 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) - # Get ratings from BlenderKit server - user_preferences = bpy.context.preferences.addons['blenderkit'].preferences - api_key = user_preferences.api_key - headers = utils.get_headers(api_key) - if utils.profile_is_validator(): - for r in rdata['results']: - if ratings_utils.get_rating_local(asset_data['id']) is None: - rating_thread = threading.Thread(target=ratings_utils.get_rating, args=([r['id'], headers]), daemon=True) - rating_thread.start() + 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 diff --git a/blenderkit/ui.py b/blenderkit/ui.py index 580a66e5..73a11154 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 @@ -387,7 +384,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') @@ -399,7 +396,7 @@ def draw_tooltip_with_author(asset_data, x, y): 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) @@ -700,6 +697,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) @@ -1271,7 +1274,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'} @@ -1424,7 +1427,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') |