diff options
author | Vilem Duha <vilem.duha@gmail.com> | 2021-11-05 10:40:56 +0300 |
---|---|---|
committer | Vilem Duha <vilem.duha@gmail.com> | 2021-11-08 13:58:55 +0300 |
commit | 2259a24adb662c35ce0a9a3ee64e7e17c4a39d7c (patch) | |
tree | aa34c5a8abcf3666e399ca82ce22cbfe166e758d /blenderkit | |
parent | 64fcec250d2d9450ac64d8314af7092a6922a28b (diff) |
BlenderKit: new asset bar fixes and improvements
Reports are back and split in reports.py
Quality is drawn in tooltip
comments and notification improvements and fixes
Tips were updated
(cherry picked from commit 3222ff126c2193d7f9c8f0279d6459acd955f4c2)
Diffstat (limited to 'blenderkit')
-rw-r--r-- | blenderkit/__init__.py | 6 | ||||
-rw-r--r-- | blenderkit/asset_bar_op.py | 107 | ||||
-rw-r--r-- | blenderkit/bkit_oauth.py | 10 | ||||
-rw-r--r-- | blenderkit/bl_ui_widgets/bl_ui_draw_op.py | 9 | ||||
-rw-r--r-- | blenderkit/bl_ui_widgets/bl_ui_widget.py | 2 | ||||
-rw-r--r-- | blenderkit/categories.py | 4 | ||||
-rw-r--r-- | blenderkit/comments_utils.py | 11 | ||||
-rw-r--r-- | blenderkit/download.py | 10 | ||||
-rw-r--r-- | blenderkit/paths.py | 4 | ||||
-rw-r--r-- | blenderkit/ratings_utils.py | 5 | ||||
-rw-r--r-- | blenderkit/reports.py | 20 | ||||
-rw-r--r-- | blenderkit/rerequests.py | 10 | ||||
-rw-r--r-- | blenderkit/search.py | 46 | ||||
-rw-r--r-- | blenderkit/ui.py | 64 | ||||
-rw-r--r-- | blenderkit/ui_panels.py | 80 | ||||
-rw-r--r-- | blenderkit/upload.py | 16 | ||||
-rw-r--r-- | blenderkit/upload_bg.py | 12 | ||||
-rw-r--r-- | blenderkit/utils.py | 20 |
18 files changed, 261 insertions, 175 deletions
diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py index 3b35b912..22afd2a1 100644 --- a/blenderkit/__init__.py +++ b/blenderkit/__init__.py @@ -60,6 +60,7 @@ if "bpy" in locals(): upload = reload(upload) upload_bg = reload(upload_bg) utils = reload(utils) + reports = reload(reports) bl_ui_widget = reload(bl_ui_widget) bl_ui_label = reload(bl_ui_label) @@ -99,6 +100,7 @@ else: from blenderkit import upload from blenderkit import upload_bg from blenderkit import utils + from blenderkit import reports from blenderkit.bl_ui_widgets import bl_ui_widget from blenderkit.bl_ui_widgets import bl_ui_label @@ -270,7 +272,7 @@ def switch_search_results(self, context): wm['search results'] = wm.get('bkit brush search') wm['search results orig'] = wm.get('bkit brush search orig') if not (context.sculpt_object or context.image_paint_object): - ui.add_report( + reports.add_report( 'Switch to paint or sculpt mode to search in BlenderKit brushes.') # if wm['search results'] == None: # wm['search results'] = [] @@ -1658,7 +1660,7 @@ class BlenderKitAddonPreferences(AddonPreferences): tips_on_start: BoolProperty( name="Show tips when starting blender", description="Show tips when starting blender", - default=False + default=True ) search_in_header: BoolProperty( diff --git a/blenderkit/asset_bar_op.py b/blenderkit/asset_bar_op.py index 17638f4e..98b89f14 100644 --- a/blenderkit/asset_bar_op.py +++ b/blenderkit/asset_bar_op.py @@ -24,6 +24,7 @@ from bpy.props import ( StringProperty ) +active_area_pointer = 0 def get_area_height(self): if type(self.context) != dict: @@ -64,7 +65,7 @@ def modal_inside(self, context, event): self.finish() return {'FINISHED'} - self.update_timer +=1 + self.update_timer += 1 if self.update_timer > self.update_timer_limit: self.update_timer = 0 @@ -84,7 +85,6 @@ def modal_inside(self, context, event): else: asset_button.progress_bar.visible = False - if self.handle_widget_events(event): return {'RUNNING_MODAL'} @@ -124,11 +124,16 @@ def asset_bar_invoke(self, context, event): self.register_handlers(args, context) self.update_timer_limit = 30 - self.update_timer =0 + self.update_timer = 0 # print('adding timer') # self._timer = context.window_manager.event_timer_add(10.0, window=context.window) - + global active_area_pointer context.window_manager.modal_handler_add(self) + self.active_window_pointer = context.window.as_pointer() + self.active_area_pointer = context.area.as_pointer() + active_area_pointer = context.area.as_pointer() + self.active_region_pointer = context.region.as_pointer() + return {"RUNNING_MODAL"} @@ -188,7 +193,7 @@ def get_tooltip_data(asset_data): if rc: rcount = min(rc.get('quality', 0), rc.get('workingHours', 0)) if rcount > show_rating_threshold: - quality = round(asset_data['ratingsAverage'].get('quality')) + quality = str(round(asset_data['ratingsAverage'].get('quality'))) tooltip_data = { 'aname': aname, 'author_text': author_text, @@ -273,16 +278,32 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): self.authors_name = authors_name self.tooltip_widgets.append(authors_name) - gravatar_image = BL_UI_Image(self.tooltip_width - self.gravatar_size, self.tooltip_height - self.gravatar_size, 1, 1) + gravatar_image = BL_UI_Image(self.tooltip_width - self.gravatar_size, self.tooltip_height - self.gravatar_size, + 1, 1) img_path = paths.get_addon_thumbnail_path('thumbnail_notready.jpg') gravatar_image.set_image(img_path) gravatar_image.set_image_size((self.gravatar_size - 1 * self.margin, self.gravatar_size - 1 * self.margin)) gravatar_image.set_image_position((0, 0)) self.gravatar_image = gravatar_image self.tooltip_widgets.append(gravatar_image) - offset_y = 16 + self.margin - # label = self.new_text('Left click or drag to append/link. Right click for more options.', self.margin*2, labels_start + offset_y, - # text_size=14) + + quality_star = BL_UI_Image(self.margin, self.tooltip_height - self.margin - self.asset_name_text_size, + 1, 1) + img_path = paths.get_addon_thumbnail_path('star_grey.png') + quality_star.set_image(img_path) + quality_star.set_image_size((self.asset_name_text_size, self.asset_name_text_size)) + quality_star.set_image_position((0, 0)) + # self.quality_star = quality_star + self.tooltip_widgets.append(quality_star) + label = self.new_text('', 2*self.margin+self.asset_name_text_size, + self.tooltip_height - int(self.asset_name_text_size+ self.margin * .5), + text_size=self.asset_name_text_size) + self.tooltip_widgets.append(label) + self.quality_label = label + + # label = self.new_text('Right click for menu.', self.margin, + # self.tooltip_height - int(self.author_text_size) - self.margin, + # text_size=int(self.author_text_size*.7)) # self.tooltip_widgets.append(label) def hide_tooltip(self): @@ -383,7 +404,7 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): if not bpy.context.preferences.system.use_region_overlap: reg_multiplier = 0 for r in area.regions: - if r.type == 'UI' : + if r.type == 'UI': ui_width = r.width * reg_multiplier if r.type == 'TOOLS': tools_width = r.width * reg_multiplier @@ -409,13 +430,17 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): # self.bar_y = region.height - ui_props.bar_y_offset * ui_scale self.bar_y = ui_props.bar_y_offset * ui_scale if ui_props.down_up == 'UPLOAD': - self.reports_y = self.bar_y - 600 + self.reports_y = region.height - self.bar_y - 600 + ui_props.reports_y = region.height - self.bar_y - 600 self.reports_x = self.bar_x - else: - self.reports_y = self.bar_y - self.bar_height - 100 - self.reports_x = self.bar_x - + ui_props.reports_x = self.bar_x + else:#ui.bar_y - ui.bar_height - 100 + self.reports_y = region.height - self.bar_y - self.bar_height - 50 + ui_props.reports_y =region.height - self.bar_y - self.bar_height- 50 + self.reports_x = self.bar_x + ui_props.reports_x = self.bar_x + # print(self.bar_y, self.bar_height, region.height) def update_layout(self, context, event): # restarting asset_bar completely since the widgets are too hard to get working with updates. @@ -437,9 +462,10 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): self.tooltip_panel.width = self.tooltip_width self.tooltip_image.width = self.tooltip_width self.tooltip_image.set_image_size((self.tooltip_width, self.tooltip_height)) - self.gravatar_image.set_location(self.tooltip_width - self.gravatar_size, self.tooltip_height - self.gravatar_size) + self.gravatar_image.set_location(self.tooltip_width - self.gravatar_size, + self.tooltip_height - self.gravatar_size) self.authors_name.set_location(self.tooltip_width - self.gravatar_size - self.margin, - self.tooltip_height - self.author_text_size - self.margin) + self.tooltip_height - self.author_text_size - self.margin) # to hide arrows accordingly self.scroll_update() @@ -491,6 +517,12 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): new_button.progress_bar = progress_bar self.progress_bars.append(progress_bar) + if utils.profile_is_validator(): + red_alert = BL_UI_Widget(asset_x, asset_y, self.button_size, self.button_size) + red_alert.bg_color = (1.0, 0.0, 0.0, 0.0) + red_alert.visible = False + new_button.red_alert = red_alert + self.red_alerts.append(red_alert) # if result['downloaded'] > 0: # ui_bgl.draw_rect(x, y, int(ui_props.thumb_size * result['downloaded'] / 100.0), 2, green) @@ -506,6 +538,7 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): self.asset_buttons = [] self.validation_icons = [] self.progress_bars = [] + self.red_alerts = [] self.widgets_panel = [] self.panel = BL_UI_Drag_Panel(0, 0, self.bar_width, self.bar_height) @@ -608,6 +641,8 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): button.visible = False button.validation_icon.visible = False button.progress_bar.visible = False + if utils.profile_is_validator(): + button.red_alert.set_location(asset_x, asset_y) i += 1 for a in range(i, len(self.asset_buttons)): @@ -641,6 +676,7 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): widgets_panel.extend(self.asset_buttons) widgets_panel.extend(self.validation_icons) widgets_panel.extend(self.progress_bars) + widgets_panel.extend(self.red_alerts) widgets = [self.panel] @@ -702,6 +738,14 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): # to hide arrows accordingly self.scroll_update() + self.window = context.window + self.area = context.area + self.scene = bpy.context.scene + # global active_window_pointer, active_area_pointer, active_region_pointer + # ui.active_window_pointer = self.window.as_pointer() + # ui.active_area_pointer = self.area.as_pointer() + # ui.active_region_pointer = self.region.as_pointer() + return True def on_finish(self, context): @@ -754,7 +798,8 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): get_tooltip_data(asset_data) self.asset_name.text = asset_data['name'] self.authors_name.text = asset_data['tooltip_data']['author_text'] - + self.quality_label.text = asset_data['tooltip_data']['quality'] + # print(asset_data['tooltip_data']['quality']) gimg = asset_data['tooltip_data']['gimg'] if gimg is not None: gimg = bpy.data.images[gimg] @@ -817,11 +862,21 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): def update_validation_icon(self, asset_button, asset_data): if utils.profile_is_validator(): + ar = bpy.context.window_manager.get('asset ratings') + rating = ar.get(asset_data['id']) + if rating is not None: + rating = rating.to_dict() + v_icon = ui.verification_icons[asset_data.get('verificationStatus', 'validated')] if v_icon is not None: img_fp = paths.get_addon_thumbnail_path(v_icon) asset_button.validation_icon.set_image(img_fp) asset_button.validation_icon.visible = True + elif rating in (None, {}): + v_icon = 'star_grey.png' + img_fp = paths.get_addon_thumbnail_path(v_icon) + asset_button.validation_icon.set_image(img_fp) + asset_button.validation_icon.visible = True else: asset_button.validation_icon.visible = False else: @@ -854,8 +909,21 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): asset_button.set_image(img_filepath) self.update_validation_icon(asset_button, asset_data) + + if utils.profile_is_validator() and asset_data['verificationStatus'] == 'uploaded': + over_limit = utils.is_upload_old(asset_data) + if over_limit: + redness = min(over_limit * .05, 0.7) + asset_button.red_alert.bg_color = (1, 0, 0, redness) + asset_button.red_alert.visible = True + else: + asset_button.red_alert.visible = False + elif utils.profile_is_validator(): + asset_button.red_alert.visible = False else: asset_button.validation_icon.visible = False + if utils.profile_is_validator(): + asset_button.red_alert.visible = False def scroll_update(self): sr = bpy.context.window_manager.get('search results') @@ -869,7 +937,7 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): self.scroll_offset = min(self.scroll_offset, len(sr) - (self.wcount * self.hcount)) self.scroll_offset = max(self.scroll_offset, 0) self.update_images() - + # print(sro) if sro['count'] > len(sr) and len(sr) - self.scroll_offset < (self.wcount * self.hcount) + 15: self.search_more() @@ -898,6 +966,7 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator): def handle_key_input(self, event): if event.type == 'A': self.search_by_author(self.active_index) + return True return False def scroll_up(self, widget): diff --git a/blenderkit/bkit_oauth.py b/blenderkit/bkit_oauth.py index fa00e616..b4e944a3 100644 --- a/blenderkit/bkit_oauth.py +++ b/blenderkit/bkit_oauth.py @@ -17,7 +17,7 @@ # ##### END GPL LICENSE BLOCK ##### -from blenderkit import tasks_queue, utils, paths, search, categories, oauth, ui, ui_panels, colors +from blenderkit import tasks_queue, utils, paths, search, categories, oauth, ui, ui_panels, colors, reports import bpy @@ -25,6 +25,8 @@ import threading import requests import time import logging + + bk_logger = logging.getLogger('blenderkit') from bpy.props import ( @@ -52,7 +54,7 @@ def login(signup, url, r_url, authenticator): try: auth_token, refresh_token, oauth_response = authenticator.get_new_token(register=signup, redirect_url=r_url) except Exception as e: - tasks_queue.add_task((ui.add_report, (e, 20, colors.RED))) + tasks_queue.add_task((reports.add_report, (e, 20, colors.RED))) bk_logger.debug('tokens retrieved') tasks_queue.add_task((write_tokens, (auth_token, refresh_token, oauth_response))) @@ -66,7 +68,7 @@ def refresh_token_thread(): thread = threading.Thread(target=refresh_token, args=([preferences.api_key_refresh, url]), daemon=True) thread.start() else: - ui.add_report('Already Refreshing token, will be ready soon. If this fails, please login again in Login panel.') + reports.add_report('Already Refreshing token, will be ready soon. If this fails, please login again in Login panel.') def refresh_token(api_key_refresh, url): @@ -89,7 +91,7 @@ def write_tokens(auth_token, refresh_token, oauth_response): props = utils.get_search_props() if props is not None: props.report = '' - ui.add_report('BlenderKit Re-Login success') + reports.add_report('BlenderKit Re-Login success') search.get_profile() categories.fetch_categories_thread(auth_token, force = False) diff --git a/blenderkit/bl_ui_widgets/bl_ui_draw_op.py b/blenderkit/bl_ui_widgets/bl_ui_draw_op.py index 43a79111..bc2e9cb5 100644 --- a/blenderkit/bl_ui_widgets/bl_ui_draw_op.py +++ b/blenderkit/bl_ui_widgets/bl_ui_draw_op.py @@ -35,6 +35,10 @@ class BL_UI_OT_draw_operator(Operator): self.register_handlers(args, context) context.window_manager.modal_handler_add(self) + + self.active_window_pointer = context.window.as_pointer() + self.active_area_pointer = context.area.as_pointer() + self.active_region_pointer = context.region.as_pointer() return {"RUNNING_MODAL"} def register_handlers(self, args, context): @@ -80,8 +84,9 @@ class BL_UI_OT_draw_operator(Operator): # Draw handler to paint onto the screen def draw_callback_px(self, op, context): try: - for widget in self.widgets: - widget.draw() + if context.area.as_pointer() == self.active_area_pointer: + for widget in self.widgets: + widget.draw() except: pass; # context.window_manager.event_timer_remove(self.draw_event) diff --git a/blenderkit/bl_ui_widgets/bl_ui_widget.py b/blenderkit/bl_ui_widgets/bl_ui_widget.py index 4b98f154..90fefddf 100644 --- a/blenderkit/bl_ui_widgets/bl_ui_widget.py +++ b/blenderkit/bl_ui_widgets/bl_ui_widget.py @@ -125,7 +125,7 @@ class BL_UI_Widget: return False - elif event.value == 'PRESS' and (event.ascii != '' or event.type in self.get_input_keys()): + elif event.value == 'PRESS' and self.__inrect and (event.ascii != '' or event.type in self.get_input_keys()): return self.text_input(event) diff --git a/blenderkit/categories.py b/blenderkit/categories.py index 9a19c120..c97c339c 100644 --- a/blenderkit/categories.py +++ b/blenderkit/categories.py @@ -17,7 +17,7 @@ # ##### END GPL LICENSE BLOCK ##### -from blenderkit import paths, utils, tasks_queue, rerequests, ui, colors +from blenderkit import paths, utils, tasks_queue, rerequests, ui, colors, reports import requests import json @@ -261,7 +261,7 @@ def fetch_categories(API_key, force=False): tasks_queue.add_task((load_categories, ())) except Exception as e: t = 'BlenderKit failed to download fresh categories from the server' - tasks_queue.add_task((ui.add_report,(t, 15, colors.RED))) + tasks_queue.add_task((reports.add_report(),(t, 15, colors.RED))) bk_logger.debug(t) bk_logger.exception(e) if not os.path.exists(categories_filepath): diff --git a/blenderkit/comments_utils.py b/blenderkit/comments_utils.py index adca81ed..4be80bd8 100644 --- a/blenderkit/comments_utils.py +++ b/blenderkit/comments_utils.py @@ -110,11 +110,6 @@ def get_comments_thread(asset_id, api_key): thread = threading.Thread(target=get_comments, args=([asset_id, api_key]), daemon=True) thread.start() - -def get_comments_thread(asset_id, api_key): - thread = threading.Thread(target=get_comments, args=([asset_id, api_key]), daemon=True) - thread.start() - def get_comments(asset_id, api_key): ''' Retrieve comments from BlenderKit server. Can be run from a thread @@ -166,9 +161,9 @@ def count_all_notifications(): def check_notifications_read(): '''checks if all notifications were already read, and removes them if so''' notifications = bpy.context.window_manager.get('bkit notifications') - if notifications is None: + if notifications is None or notifications.get('count') == 0: return True - for n in notifications: + for n in notifications['results']: if n['unread'] == 1: return False bpy.context.window_manager['bkit notifications'] = None @@ -198,7 +193,7 @@ def get_notifications(api_key, all_count = 1000): r = rerequests.get(url, params=params, verify=True, headers=headers) if r.status_code ==200: rj = r.json() - print(rj) + # print(rj) # no new notifications? if all_count >= rj['allCount']: tasks_queue.add_task((store_notifications_count_local, ([rj['allCount']]))) diff --git a/blenderkit/download.py b/blenderkit/download.py index f33e636f..70ab8755 100644 --- a/blenderkit/download.py +++ b/blenderkit/download.py @@ -779,7 +779,7 @@ class Downloader(threading.Thread): if not has_url: tasks_queue.add_task( - (ui.add_report, ('Failed to obtain download URL for %s.' % asset_data['name'], 5, colors.RED))) + (reports.add_report, ('Failed to obtain download URL for %s.' % asset_data['name'], 5, colors.RED))) return; if tcom.error: return @@ -814,7 +814,7 @@ class Downloader(threading.Thread): else: # bk_logger.debug(total_length) if int(total_length) < 1000: # means probably no file returned. - tasks_queue.add_task((ui.add_report, (response.content, 20, colors.RED))) + tasks_queue.add_task((reports.add_report, (response.content, 20, colors.RED))) tcom.report = response.content @@ -875,7 +875,7 @@ def download(asset_data, **kwargs): sprops = utils.get_search_props() report = f"Maximum retries exceeded for {asset_data['name']}" sprops.report = report - ui.add_report(report, 5, colors.RED) + reports.add_report(report, 5, colors.RED) bk_logger.debug(sprops.report) return @@ -1122,12 +1122,12 @@ def get_download_url(asset_data, scene_id, api_key, tcom=None, resolution='blend return True # let's print it into UI - tasks_queue.add_task((ui.add_report, (str(r), 10, colors.RED))) + tasks_queue.add_task((reports.add_report, (str(r), 10, colors.RED))) if r.status_code == 403: report = 'You need Full plan to get this item.' # r1 = 'All materials and brushes are available for free. Only users registered to Standard plan can use all models.' - # tasks_queue.add_task((ui.add_report, (r1, 5, colors.RED))) + # tasks_queue.add_task((reports.add_report, (r1, 5, colors.RED))) if tcom is not None: tcom.report = report tcom.error = True diff --git a/blenderkit/paths.py b/blenderkit/paths.py index 08a4e492..ea7d35d8 100644 --- a/blenderkit/paths.py +++ b/blenderkit/paths.py @@ -129,12 +129,12 @@ def get_temp_dir(subdir=None): cleanup_old_folders() except: - tasks_queue.add_task((ui.add_report, ('Cache directory not found. Resetting Cache folder path.',))) + tasks_queue.add_task((reports.add_report, ('Cache directory not found. Resetting Cache folder path.',))) p = default_global_dict() if p == user_preferences.global_dir: message = 'Global dir was already default, plese set a global directory in addon preferences to a dir where you have write permissions.' - tasks_queue.add_task((ui.add_report, (message,))) + tasks_queue.add_task((reports.add_report, (message,))) return None user_preferences.global_dir = p tempdir = get_temp_dir(subdir=subdir) diff --git a/blenderkit/ratings_utils.py b/blenderkit/ratings_utils.py index eafa60fa..d813f444 100644 --- a/blenderkit/ratings_utils.py +++ b/blenderkit/ratings_utils.py @@ -78,7 +78,7 @@ def store_rating_local(asset_id, type='quality', value=0): context = bpy.context ar = context.window_manager['asset ratings'] ar[asset_id] = ar.get(asset_id, {}) - ar[asset_id]['type'] = value + ar[asset_id][type] = value def get_rating(asset_id, headers): @@ -101,6 +101,7 @@ def get_rating(asset_id, headers): if r.status_code == 200: rj = r.json() ratings = {} + print(rj) # store ratings - send them to task queue for r in rj['results']: ratings[r['ratingType']] = r['score'] @@ -353,6 +354,8 @@ class RatingsProperties(): def prefill_ratings(self): # pre-fill ratings ratings = get_rating_local(self.asset_id) + print('prefill ratings') + print(ratings) if ratings and ratings.get('quality'): self.rating_quality = ratings['quality'] if ratings and ratings.get('working_hours'): diff --git a/blenderkit/reports.py b/blenderkit/reports.py index 816ac791..7a455863 100644 --- a/blenderkit/reports.py +++ b/blenderkit/reports.py @@ -17,7 +17,11 @@ # ##### END GPL LICENSE BLOCK ##### import time -from blenderkit import colors +import bpy +from blenderkit import colors, asset_bar_op, ui_bgl, utils + +reports = [] + def add_report(text='', timeout=5, color=colors.GREEN): global reports @@ -26,18 +30,24 @@ def add_report(text='', timeout=5, color=colors.GREEN): if old_report.text == text: old_report.timeout = old_report.age + timeout return - report = Report(text=text, timeout=timeout, color=color) + report = Report(text=text, timeout=timeout, color=color) reports.append(report) class Report(): - def __init__(self, text='', timeout=5, color=(.5, 1, .5, 1)): + def __init__(self, area_pointer=0, text='', timeout=5, color=(.5, 1, .5, 1)): self.text = text self.timeout = timeout self.start_time = time.time() self.color = color self.draw_color = color self.age = 0 + if asset_bar_op.active_area_pointer == 0: + w, a, r = utils.get_largest_area(area_type='VIEW_3D') + + self.active_area_pointer = a.as_pointer() + else: + self.active_area_pointer = asset_bar_op.active_area_pointer def fade(self): fade_time = 1 @@ -53,5 +63,5 @@ class Report(): pass; def draw(self, x, y): - if bpy.context.area.as_pointer() == active_area_pointer: - ui_bgl.draw_text(self.text, x, y + 8, 16, self.draw_color)
\ No newline at end of file + if (bpy.context.area is not None and bpy.context.area.as_pointer() == self.active_area_pointer): + ui_bgl.draw_text(self.text, x, y + 8, 16, self.draw_color) diff --git a/blenderkit/rerequests.py b/blenderkit/rerequests.py index 735feb35..a9f3bacd 100644 --- a/blenderkit/rerequests.py +++ b/blenderkit/rerequests.py @@ -44,7 +44,7 @@ def rerequest(method, url, recursion=0, **kwargs): response = requests.request(method, url, **kwargs) except Exception as e: print(e) - tasks_queue.add_task((ui.add_report, ( + tasks_queue.add_task((reports.add_report, ( 'Connection error.', 10))) return FakeResponse() @@ -57,13 +57,13 @@ def rerequest(method, url, recursion=0, **kwargs): except: rdata = {} - tasks_queue.add_task((ui.add_report, (method + ' request Failed.' + str(rdata.get('detail')),))) + tasks_queue.add_task((reports.add_report, (method + ' request Failed.' + str(rdata.get('detail')),))) if rdata.get('detail') == 'Invalid token.': user_preferences = bpy.context.preferences.addons['blenderkit'].preferences if user_preferences.api_key != '': if user_preferences.enable_oauth and user_preferences.api_key_refresh != '': - tasks_queue.add_task((ui.add_report, ( + tasks_queue.add_task((reports.add_report, ( 'refreshing token. If this fails, please login in BlenderKit Login panel.', 10))) refresh_url = paths.get_bkit_url() auth_token, refresh_token, oauth_response = bkit_oauth.refresh_token( @@ -84,11 +84,11 @@ def rerequest(method, url, recursion=0, **kwargs): bk_logger.debug('reresult', response.status_code) if response.status_code >= 400: bk_logger.debug('reresult', response.text) - tasks_queue.add_task((ui.add_report, ( + tasks_queue.add_task((reports.add_report, ( response.text, 10))) else: - tasks_queue.add_task((ui.add_report, ( + tasks_queue.add_task((reports.add_report, ( 'Refreshing token failed.Please login manually.', 10))) # tasks_queue.add_task((bkit_oauth.write_tokens, ('', '', ''))) tasks_queue.add_task((bpy.ops.wm.blenderkit_login, ('INVOKE_DEFAULT',)), fake_context=True) diff --git a/blenderkit/search.py b/blenderkit/search.py index 9c19b25b..f86a9a5e 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, ratings_utils, comments_utils + resolutions, image_utils, ratings_utils, comments_utils, reports import blenderkit from bpy.app.handlers import persistent @@ -83,15 +83,22 @@ thumb_full_download_threads = queue.Queue() reports_queue = queue.Queue() all_thumbs_loaded = True -rtips = ['Click or drag model or material in scene to link/append ', - "Please rate responsively and plentifully. This helps us distribute rewards to the authors.", - "Click on brushes to link them into scene.", - "All materials are free.", - "Storage for public assets is unlimited.", - "Locked models are available if you subscribe to Full plan.", - "Login to upload your own models, materials or brushes.", - "Use 'A' key over asset bar to search assets by same author.", - "Use 'W' key over asset bar to open Authors webpage.", ] +rtips_string = """You can disable tips in the add-on preferences. +Ratings help us distribute funds to creators. +Creators also gain credits for free assets from subscribers. +Click or drag model or material in scene to link/append +Right click in the asset bar for more options +Use Append in import settings if you want to edit downloaded objects. +Please rate responsively and plentifully. This helps us distribute rewards to the authors. +All materials are free. +Storage for public assets is unlimited. +Locked models are available if you subscribe to Full plan. +Login to upload your own models, materials or brushes. +Use 'A' key over the asset bar to search assets by the same author. +Use semicolon - ; to hide or show the AssetBar. +Support the authors by subscribing to Full plan. +""" +rtips = rtips_string.splitlines() def refresh_token_timer(): @@ -192,7 +199,7 @@ def scene_load(context): bpy.app.timers.register(refresh_token_timer, persistent=True, first_interval=36000) if utils.experimental_enabled() and not bpy.app.timers.is_registered( refresh_notifications_timer) and not bpy.app.background: - bpy.app.timers.register(refresh_notifications_timer, persistent=True, first_interval=2) + bpy.app.timers.register(refresh_notifications_timer, persistent=True, first_interval=5) update_assets_data() @@ -211,7 +218,8 @@ def fetch_server_data(): get_profile() if bpy.context.window_manager.get('bkit_categories') is None: categories.fetch_categories_thread(api_key, force=False) - + all_notifications_count = comments_utils.count_all_notifications() + comments_utils.get_notifications_thread(api_key, all_count = all_notifications_count) first_time = True last_clipboard = '' @@ -374,7 +382,7 @@ def search_timer(): if preferences.tips_on_start: utils.get_largest_area() ui.update_ui_size(ui.active_area_pointer, ui.active_region_pointer) - ui.add_report(text='BlenderKit Tip: ' + random.choice(rtips), timeout=12, color=colors.GREEN) + reports.add_report(text='BlenderKit Tip: ' + random.choice(rtips), timeout=12, color=colors.GREEN) # utils.p('end search timer') return 3.0 @@ -481,7 +489,7 @@ def search_timer(): props.search_error = False props.report = 'Found %i results. ' % (wm['search results orig']['count']) if len(wm['search results']) == 0: - tasks_queue.add_task((ui.add_report, ('No matching results found.',))) + tasks_queue.add_task((reports.add_report, ('No matching results found.',))) # undo push # bpy.ops.wm.undo_push_context(message='Get BlenderKit search') # show asset bar automatically, but only on first page - others are loaded also when asset bar is hidden. @@ -740,7 +748,7 @@ def fetch_gravatar(adata = None): ''' # utils.p('fetch gravatar') - print(adata) + # print(adata) # fetch new avatars if available already if adata.get('avatar128') is not None: avatar_path = paths.get_temp_dir(subdir='bkit_g/') + adata['id'] + '.jpg' @@ -968,13 +976,13 @@ class Searcher(threading.Thread): if hasattr(r, 'text'): error_description = parse_html_formated_error(r.text) reports_queue.put(error_description) - tasks_queue.add_task((ui.add_report, (error_description, 10, colors.RED))) + tasks_queue.add_task((reports.add_report, (error_description, 10, colors.RED))) bk_logger.error(e) return mt('data parsed ') if not rdata.get('results'): - utils.pprint(rdata) + # utils.pprint(rdata) # if the result was converted to json and didn't return results, # it means it's a server error that has a clear message. # That's why it gets processed in the update timer, where it can be passed in messages to user. @@ -1437,7 +1445,7 @@ def search(category='', get_next=False, author_id=''): if orig_results is not None and get_next: params['next'] = orig_results['next'] add_search_process(query, params) - tasks_queue.add_task((ui.add_report, ('BlenderKit searching....', 2))) + tasks_queue.add_task((reports.add_report, ('BlenderKit searching....', 2))) props.report = 'BlenderKit searching....' @@ -1583,7 +1591,7 @@ class SearchOperator(Operator): sprops.search_keywords = self.keywords search(category=self.category, get_next=self.get_next, author_id=self.author_id) - # bpy.ops.view3d.blenderkit_asset_bar() + # bpy.ops.view3d.blenderkit_asset_bar_widget() return {'FINISHED'} diff --git a/blenderkit/ui.py b/blenderkit/ui.py index 70abd898..41c4feee 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, ratings_utils + ui_panels, icons, ratings_utils, reports import bpy @@ -51,8 +51,6 @@ active_area_pointer = None active_window_pointer = None active_region_pointer = None -reports = [] - mappingdict = { 'MODEL': 'model', 'SCENE': 'scene', @@ -101,43 +99,6 @@ def get_approximate_text_width(st): return size # Convert to picas -def add_report(text='', timeout=5, color=colors.GREEN): - global reports - # check for same reports and just make them longer by the timeout. - for old_report in reports: - if old_report.text == text: - old_report.timeout = old_report.age + timeout - return - report = Report(text=text, timeout=timeout, color=color) - reports.append(report) - - -class Report(): - def __init__(self, text='', timeout=5, color=(.5, 1, .5, 1)): - self.text = text - self.timeout = timeout - self.start_time = time.time() - self.color = color - self.draw_color = color - self.age = 0 - - def fade(self): - fade_time = 1 - self.age = time.time() - self.start_time - if self.age + fade_time > self.timeout: - alpha_multiplier = (self.timeout - self.age) / fade_time - self.draw_color = (self.color[0], self.color[1], self.color[2], self.color[3] * alpha_multiplier) - if self.age > self.timeout: - global reports - try: - reports.remove(self) - except Exception as e: - pass; - - def draw(self, x, y): - if bpy.context.area.as_pointer() == active_area_pointer: - ui_bgl.draw_text(self.text, x, y + 8, 16, self.draw_color) - def get_asset_under_mouse(mousex, mousey): s = bpy.context.scene @@ -528,8 +489,8 @@ def draw_callback_2d_progress(self, context): draw_progress(x, y - index * 30, '%s' % n + tcom.lasttext, tcom.progress) index += 1 - global reports - for report in reports: + for report in reports.reports: + # print('drawing reports', x, y, report.text) report.draw(x, y - index * 30) index += 1 report.fade() @@ -557,21 +518,6 @@ def draw_callback_2d_upload_preview(self, context): draw_tooltip(ui_props.bar_x, ui_props.bar_y, name=props.name, img=img) -def is_upload_old(asset_data): - ''' - estimates if the asset is far too long in the 'uploaded' state - This returns the number of days the validation is over the limit. - ''' - date_time_str = asset_data["created"][:10] - # date_time_str = 'Jun 28 2018 7:40AM' - date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d') - today = date_time_obj.today() - age = today - date_time_obj - old = datetime.timedelta(days=7) - if age > old: - return (age.days - old.days) - return 0 - def get_large_thumbnail_image(asset_data): '''Get thumbnail image from asset data''' @@ -705,7 +651,7 @@ def draw_asset_bar(self, context): # code to inform validators that the validation is waiting too long and should be done asap if result['verificationStatus'] == 'uploaded': if is_validator: - over_limit = is_upload_old(result) + over_limit = utils.is_upload_old(result) if over_limit: redness = min(over_limit * .05, 0.5) red = (1, 0, 0, redness) @@ -1903,7 +1849,7 @@ class RunAssetBarWithContext(bpy.types.Operator): C_dict = utils.get_fake_context(context) if C_dict.get('window'): # no 3d view, no asset bar. preferences = bpy.context.preferences.addons['blenderkit'].preferences - if 1:# preferences.experimental_features: + if 1:#preferences.experimental_features: bpy.ops.view3d.blenderkit_asset_bar_widget(C_dict, 'INVOKE_REGION_WIN', keep_running=self.keep_running, do_search=self.do_search) diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py index dbf5fcda..f8f08a21 100644 --- a/blenderkit/ui_panels.py +++ b/blenderkit/ui_panels.py @@ -334,7 +334,7 @@ def draw_assetbar_show_hide(layout, props): ttip = 'Click to Show Asset Bar' preferences = bpy.context.preferences.addons['blenderkit'].preferences - if 1: # preferences.experimental_features: + if 1:#preferences.experimental_features: op = layout.operator('view3d.blenderkit_asset_bar_widget', text='', icon=icon) else: op = layout.operator('view3d.blenderkit_asset_bar', text='', icon=icon) @@ -609,7 +609,7 @@ class MarkNotificationRead(bpy.types.Operator): def execute(self, context): notifications = bpy.context.window_manager['bkit notifications'] - for n in notifications: + for n in notifications['results']: if n['id'] == self.notification_id: n['unread'] = 0 comments_utils.check_notifications_read() @@ -634,7 +634,7 @@ class MarkAllNotificationsRead(bpy.types.Operator): user_preferences = bpy.context.preferences.addons['blenderkit'].preferences api_key = user_preferences.api_key notifications = bpy.context.window_manager['bkit notifications'] - for n in notifications: + for n in notifications.get('results'): if n['unread'] == 1: n['unread'] = 0 comments_utils.mark_notification_read_thread(api_key, n['id']) @@ -705,42 +705,54 @@ def draw_notification(self, notification, width=600): box = layout.box() firstline = f"{notification['actor']['string']} {notification['verb']} {notification['target']['string']}" box1 = box.box() - row = box1.row() - utils.label_multiline(row, text=firstline, width=width) + # row = box1.row() - op = row.operator("wm.blenderkit_mark_notification_read", text="", icon='CANCEL') - op.notification_id = notification['id'] + split_last = 0.7 if notification['description']: - rows = utils.label_multiline(box, text=notification['description'], width=width) - split = rows[-1].split(factor=0.8) + split_last = 0 + + + rows = utils.label_multiline(box1, text=firstline, width=width, split_last = split_last) + + + if notification['description']: + rows = utils.label_multiline(box, text=notification['description'], width=width, split_last = 0.7) + - else: - row = layout.row() - split = row.split(factor=0.8) - split.label(text='') - split = split.split() if notification['target']: # row = layout.row() # split = row.split(factor=.8) # split.label(text='') # split = split.split() - op = split.operator('wm.blenderkit_open_notification_target', text='Open page', icon='GREASEPENCIL') + # split = rows[-1].split(factor=0.8) + # split = split.split() + # split.alignment = 'RIGHT' + # row = split.row(align = True) + row = rows[-1] + row = row.row(align=False) + + # row = row.split(factor = 0.7) + + op = row.operator('wm.blenderkit_open_notification_target', text='Open page', icon='HIDE_OFF') op.tooltip = 'Open the browser on the asset page to comment' op.url = paths.get_bkit_url() + notification['target']['url'] op.notification_id = notification['id'] + # split = + op = row.operator("wm.blenderkit_mark_notification_read", text="", icon='CANCEL') + op.notification_id = notification['id'] def draw_notifications(self, context, width=600): layout = self.layout notifications = bpy.context.window_manager.get('bkit notifications') - if notifications is not None: + if notifications is not None and notifications.get('count')>0: row = layout.row() # row.alert = True split = row.split(factor = 0.7) split.label(text='') split = split.split() split.operator('wm.blenderkit_mark_notifications_read_all', text = 'Mark All Read', icon = 'CANCEL') - for notification in notifications: + for notification in notifications['results']: if notification['unread'] == 1: draw_notification(self, notification, width=width) @@ -778,7 +790,7 @@ class VIEW3D_PT_blenderkit_notifications(Panel): @classmethod def poll(cls, context): notifications = bpy.context.window_manager.get('bkit notifications') - if notifications is not None and len(notifications) > 0: + if notifications is not None and len(notifications['results']) > 0: return True return False @@ -1554,8 +1566,7 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False): if asset_data['assetType'] == 'model': op = layout.operator('object.blenderkit_regenerate_thumbnail', text='Regenerate thumbnail') op.asset_index = ui_props.active_index - - if asset_data['assetType'] == 'material': + elif asset_data['assetType'] == 'material': op = layout.operator('object.blenderkit_regenerate_material_thumbnail', text='Regenerate thumbnail') op.asset_index = ui_props.active_index # op.asset_id = asset_data['id'] @@ -2129,7 +2140,7 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): # name_row = name_row.row() for i, c in enumerate(cat_path): cat_name = cat_path_names[i] - op = name_row.operator('view3d.blenderkit_asset_bar', text=cat_name + ' >', emboss=True) + op = name_row.operator('view3d.blenderkit_asset_bar_widget', text=cat_name + ' >', emboss=True) op.do_search = True op.keep_running = True op.tooltip = f"Browse {cat_name} category" @@ -2225,13 +2236,30 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): tip_box = layout.box() tip_box.label(text=self.tip) # comments - if utils.profile_is_validator() and bpy.app.debug_value == 2: + if utils.profile_is_validator(): comments = bpy.context.window_manager.get('asset comments', {}) self.comments = comments.get(self.asset_data['assetBaseId'], []) if self.comments is not None: for comment in self.comments: self.draw_comment(context, layout, comment, width=self.width) + def prefill_ratings(self): + # pre-fill ratings + ratings = ratings_utils.get_rating_local(self.asset_id) + print('prefill ratings') + print(ratings) + if ratings and ratings.get('quality'): + self.rating_quality = ratings['quality'] + if ratings and ratings.get('working_hours'): + wh = 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 + def execute(self, context): wm = context.window_manager ui_props = context.window_manager.blenderkitUI @@ -2262,7 +2290,7 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): self.prefill_ratings() # get comments - if utils.profile_is_validator() and bpy.app.debug_value == 2: + if utils.profile_is_validator(): user_preferences = bpy.context.preferences.addons['blenderkit'].preferences api_key = user_preferences.api_key comments = comments_utils.get_comments_local(asset_data['assetBaseId']) @@ -2452,7 +2480,7 @@ def draw_panel_categories(self, context): cats = categories.get_category(wm['bkit_categories'], cat_path=acat) # draw freebies only in models parent category # if ui_props.asset_type == 'MODEL' and len(acat) == 1: - # op = col.operator('view3d.blenderkit_asset_bar', text='freebies') + # op = col.operator('view3d.blenderkit_asset_bar_widget', text='freebies') # op.free_only = True for c in cats['children']: @@ -2465,7 +2493,7 @@ def draw_panel_categories(self, context): ctext = '%s (%i)' % (c['name'], c['assetCount']) preferences = bpy.context.preferences.addons['blenderkit'].preferences - if 1: # preferences.experimental_features: + if 1:#preferences.experimental_features: op = row.operator('view3d.blenderkit_asset_bar_widget', text=ctext) else: op = row.operator('view3d.blenderkit_asset_bar', text=ctext) @@ -2570,7 +2598,7 @@ def header_search_draw(self, context): layout.popover(panel="VIEW3D_PT_blenderkit_advanced_HDR_search", text="", icon_value=icon_id) notifications = bpy.context.window_manager.get('bkit notifications') - if notifications is not None and len(notifications) > 0: + if notifications is not None and notifications['count'] > 0: layout.operator('wm.show_notifications', text="", icon_value=pcoll['bell'].icon_id) # layout.popover(panel="VIEW3D_PT_blenderkit_notifications", text="", icon_value=pcoll['bell'].icon_id) diff --git a/blenderkit/upload.py b/blenderkit/upload.py index 7c67d55f..dfca4d94 100644 --- a/blenderkit/upload.py +++ b/blenderkit/upload.py @@ -18,7 +18,7 @@ from blenderkit import asset_inspector, paths, utils, bg_blender, autothumb, version_checker, search, ui_panels, ui, \ - overrides, colors, rerequests, categories, upload_bg, tasks_queue, image_utils, asset_bar_op + overrides, colors, rerequests, categories, upload_bg, tasks_queue, image_utils, asset_bar_op, reports import tempfile, os, subprocess, json, re @@ -715,7 +715,7 @@ class FastMetadata(bpy.types.Operator): thread = threading.Thread(target=patch_individual_metadata, args=(self.asset_id, mdict, user_preferences.api_key)) thread.start() - tasks_queue.add_task((ui.add_report, (f'Uploading metadata for {self.name}. ' + tasks_queue.add_task((reports.add_report, (f'Uploading metadata for {self.name}. ' f'Refresh search results to see that changes applied correctly.', 8,))) return {'FINISHED'} @@ -871,7 +871,7 @@ class Uploader(threading.Thread): message = str(message).replace("'", "") # this adds a UI report but also writes above the upload panel fields. - tasks_queue.add_task((ui.add_report, (message,))) + tasks_queue.add_task((reports.add_report, (message,))) estring = f"{self.export_data['eval_path_state']} = '{message}'" tasks_queue.add_task((exec, (estring,))) @@ -895,14 +895,14 @@ class Uploader(threading.Thread): # self.upload_data['license'] = 'ovejajojo' json_metadata = self.upload_data # json.dumps(self.upload_data, ensure_ascii=False).encode('utf8') - # tasks_queue.add_task((ui.add_report, ('Posting metadata',))) + # tasks_queue.add_task((reports.add_report, ('Posting metadata',))) self.send_message('Posting metadata') if self.export_data['assetBaseId'] == '': try: r = rerequests.post(url, json=json_metadata, headers=headers, verify=True, immediate=True) # files = files, - # tasks_queue.add_task((ui.add_report, ('uploaded metadata',))) + # tasks_queue.add_task((reports.add_report, ('uploaded metadata',))) utils.p(r.text) self.send_message('uploaded metadata') @@ -920,7 +920,7 @@ class Uploader(threading.Thread): immediate=True) # files = files, self.send_message('uploaded metadata') - # tasks_queue.add_task((ui.add_report, ('uploaded metadata',))) + # tasks_queue.add_task((reports.add_report, ('uploaded metadata',))) # parse the request # print('uploaded metadata') print(r.text) @@ -938,10 +938,10 @@ class Uploader(threading.Thread): return {'FINISHED'} try: rj = r.json() - utils.pprint(rj) + # utils.pprint(rj) # if r.status_code not in (200, 201): # if r.status_code == 401: - # ###ui.add_report(r.detail, 5, colors.RED) + # ###reports.add_report(r.detail, 5, colors.RED) # return {'CANCELLED'} # if props.asset_base_id == '': # props.asset_base_id = rj['assetBaseId'] diff --git a/blenderkit/upload_bg.py b/blenderkit/upload_bg.py index 1f29d9ff..b0487417 100644 --- a/blenderkit/upload_bg.py +++ b/blenderkit/upload_bg.py @@ -50,7 +50,7 @@ class upload_in_chunks(object): break self.readsofar += len(data) percent = self.readsofar * 1e2 / self.totalsize - tasks_queue.add_task((ui.add_report, (f"Uploading {self.report_name} {percent}%",))) + tasks_queue.add_task((reports.add_report, (f"Uploading {self.report_name} {percent}%",))) # bg_blender.progress('uploading %s' % self.report_name, percent) # sys.stderr.write("\r{percent:3.0f}%".format(percent=percent)) @@ -65,7 +65,7 @@ def upload_file(upload_data, f): version_id = upload_data['id'] message = f"uploading {f['type']} {os.path.basename(f['file_path'])}" - tasks_queue.add_task((ui.add_report, (message,))) + tasks_queue.add_task((reports.add_report, (message,))) upload_info = { 'assetId': version_id, @@ -95,17 +95,17 @@ def upload_file(upload_data, f): upload_response = rerequests.post(upload_done_url, headers=headers, verify=True) # print(upload_response) # print(upload_response.text) - tasks_queue.add_task((ui.add_report, (f"Finished file upload: {os.path.basename(f['file_path'])}",))) + tasks_queue.add_task((reports.add_report, (f"Finished file upload: {os.path.basename(f['file_path'])}",))) return True else: print(upload_response.text) message = f"Upload failed, retry. File : {f['type']} {os.path.basename(f['file_path'])}" - tasks_queue.add_task((ui.add_report, (message,))) + tasks_queue.add_task((reports.add_report, (message,))) except Exception as e: print(e) message = f"Upload failed, retry. File : {f['type']} {os.path.basename(f['file_path'])}" - tasks_queue.add_task((ui.add_report, (message,))) + tasks_queue.add_task((reports.add_report, (message,))) time.sleep(1) # confirm single file upload to bkit server @@ -123,7 +123,7 @@ def upload_files(upload_data, files): uploaded = upload_file(upload_data, f) if not uploaded: uploaded_all = False - tasks_queue.add_task((ui.add_report, (f"Uploaded all files for asset {upload_data['name']}",))) + tasks_queue.add_task((reports.add_report, (f"Uploaded all files for asset {upload_data['name']}",))) return uploaded_all diff --git a/blenderkit/utils.py b/blenderkit/utils.py index 5bbe96af..79998c26 100644 --- a/blenderkit/utils.py +++ b/blenderkit/utils.py @@ -28,6 +28,7 @@ import shutil import logging import traceback import inspect +import datetime bk_logger = logging.getLogger('blenderkit') @@ -913,7 +914,7 @@ def get_fake_context(context, area_type='VIEW_3D'): # def is_url(text): -def label_multiline(layout, text='', icon='NONE', width=-1, max_lines=10): +def label_multiline(layout, text='', icon='NONE', width=-1, max_lines=10, split_last = 0): ''' draw a ui label, but try to split it in multiple lines. @@ -958,6 +959,8 @@ def label_multiline(layout, text='', icon='NONE', width=-1, max_lines=10): if li > max_lines: break; row = layout.row() + if split_last > 0: + row = row.split(factor=split_last) row.label(text=l, icon=icon) rows.append(row) icon = 'NONE' @@ -965,5 +968,20 @@ def label_multiline(layout, text='', icon='NONE', width=-1, max_lines=10): return rows +def is_upload_old(asset_data): + ''' + estimates if the asset is far too long in the 'uploaded' state + This returns the number of days the validation is over the limit. + ''' + date_time_str = asset_data["created"][:10] + # date_time_str = 'Jun 28 2018 7:40AM' + date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d') + today = date_time_obj.today() + age = today - date_time_obj + old = datetime.timedelta(days=5) + if age > old: + return (age.days - old.days) + return 0 + def trace(): traceback.print_stack() |