From 8618e9b59605db8eaaae413fa32a138b1ed9f22b Mon Sep 17 00:00:00 2001 From: meta-androcto Date: Mon, 2 Sep 2019 19:50:04 +1000 Subject: space_view3d_spacebar_menu: fix for edit particle select --- space_view3d_spacebar_menu/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/space_view3d_spacebar_menu/__init__.py b/space_view3d_spacebar_menu/__init__.py index 201b9506..467eaa62 100644 --- a/space_view3d_spacebar_menu/__init__.py +++ b/space_view3d_spacebar_menu/__init__.py @@ -645,10 +645,8 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu): layout.menu("VIEW3D_MT_InteractiveMode", icon='VIEW3D') UseSeparator(self, context) layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL') - layout.menu("VIEW3D_MT_Select_Particle", - icon='RESTRICT_SELECT_OFF') layout.menu("VIEW3D_MT_select_particle", - text="Select and Display Mode", icon='PARTICLE_PATH') + text="Select", icon='PARTICLE_PATH') UseSeparator(self, context) layout.menu("VIEW3D_MT_TransformMenu", icon='EMPTY_ARROWS') layout.menu("VIEW3D_MT_mirror", icon='MOD_MIRROR') -- cgit v1.2.3 From 6ed2b0e2b5b30d88b2dc10ac4c399837111e2ffc Mon Sep 17 00:00:00 2001 From: meta-androcto Date: Mon, 2 Sep 2019 20:12:04 +1000 Subject: space_view3d_brush_menus: add default spacebar menu actions: T68350 --- space_view3d_brush_menus/brush_menu.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/space_view3d_brush_menus/brush_menu.py b/space_view3d_brush_menus/brush_menu.py index 28caf747..85d77bcd 100644 --- a/space_view3d_brush_menus/brush_menu.py +++ b/space_view3d_brush_menus/brush_menu.py @@ -42,7 +42,11 @@ class BrushOptionsMenu(Menu): has_brush = utils_core.get_brush_link(context, types="brush") icons = brushes.brush_icon[mode][has_brush.sculpt_tool] if \ has_brush else "BRUSH_DATA" + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') + layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') + layout.separator() layout.row().menu("VIEW3D_MT_sv3_brushes_menu", icon=icons) @@ -65,7 +69,11 @@ class BrushOptionsMenu(Menu): icons = brushes.brush_icon[mode][has_brush.vertex_tool] if \ has_brush else "BRUSH_DATA" + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') + layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') + layout.separator() if mode == 'VERTEX_PAINT': layout.row().operator(ColorPickerPopup.bl_idname, icon="COLOR") @@ -118,7 +126,10 @@ class BrushOptionsMenu(Menu): layout.row().label(text="Missing Data", icon='ERROR') layout.row().label(text="See Mask Properties", icon='FORWARD') layout.row().separator() + layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') + layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') + layout.row().separator() layout.row().menu("VIEW3D_MT_sv3_brushes_menu", icon=icons) @@ -128,7 +139,11 @@ class BrushOptionsMenu(Menu): layout.row().label(text="Missing Data", icon="INFO") else: + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') + layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') + layout.separator() if has_brush and has_brush.image_tool in {'DRAW', 'FILL'} and \ has_brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'}: @@ -160,7 +175,11 @@ class BrushOptionsMenu(Menu): def particle(self, layout, context): particle_edit = context.tool_settings.particle_edit + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM') layout.operator("wm.toolbar", text="Tools", icon='TOOL_SETTINGS') + layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART') + layout.separator() layout.row().menu("VIEW3D_MT_sv3_brushes_menu", icon="BRUSH_DATA") -- cgit v1.2.3 From e529809cf6513748776a878338109ecf960d1326 Mon Sep 17 00:00:00 2001 From: meta-androcto Date: Mon, 2 Sep 2019 21:31:44 +1000 Subject: development_edit_operator: returned to release: T63750 c983a2472846 T68541 --- development_edit_operator.py | 337 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 337 insertions(+) create mode 100644 development_edit_operator.py diff --git a/development_edit_operator.py b/development_edit_operator.py new file mode 100644 index 00000000..08e91d87 --- /dev/null +++ b/development_edit_operator.py @@ -0,0 +1,337 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + + +bl_info = { + "name": "Edit Operator Source", + "author": "scorpion81", + "version": (1, 2, 2), + "blender": (2, 80, 0), + "location": "Text Editor > Edit > Edit Operator", + "description": "Opens source file of chosen operator or call locations, if source not available", + "warning": "", + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/" + "Py/Scripts/Development/Edit_Operator_Source", + "category": "Development"} + +import bpy +import sys +import os +import inspect +from bpy.types import ( + Operator, + Panel, + Header, + Menu, + PropertyGroup + ) +from bpy.props import ( + EnumProperty, + StringProperty, + IntProperty + ) + +def stdlib_excludes(): + #need a handy list of modules to avoid walking into + import distutils.sysconfig as sysconfig + excludes = [] + std_lib = sysconfig.get_python_lib(standard_lib=True) + for top, dirs, files in os.walk(std_lib): + for nm in files: + if nm != '__init__.py' and nm[-3:] == '.py': + excludes.append(os.path.join(top, nm)[len(std_lib)+1:-3].replace('\\','.')) + + return excludes + +def make_loc(prefix, c): + #too long and not helpful... omitting for now + space = "" + #if hasattr(c, "bl_space_type"): + # space = c.bl_space_type + + region = "" + #if hasattr(c, "bl_region_type"): + # region = c.bl_region_type + + label = "" + if hasattr(c, "bl_label"): + label = c.bl_label + + return prefix+": " + space + " " + region + " " + label + +def walk_module(opname, mod, calls=[], exclude=[]): + + for name, m in inspect.getmembers(mod): + if inspect.ismodule(m): + if m.__name__ not in exclude: + #print(name, m.__name__) + walk_module(opname, m, calls, exclude) + elif inspect.isclass(m): + if (issubclass(m, Panel) or \ + issubclass(m, Header) or \ + issubclass(m, Menu)) and mod.__name__ != "bl_ui": + if hasattr(m, "draw"): + loc = "" + file = "" + line = -1 + src, n = inspect.getsourcelines(m.draw) + for i, s in enumerate(src): + if opname in s: + file = mod.__file__ + line = n + i + + if issubclass(m, Panel) and name != "Panel": + loc = make_loc("Panel", m) + calls.append([opname, loc, file, line]) + if issubclass(m, Header) and name != "Header": + loc = make_loc("Header", m) + calls.append([opname, loc, file, line]) + if issubclass(m, Menu) and name != "Menu": + loc = make_loc("Menu", m) + calls.append([opname, loc, file, line]) + + +def getclazz(opname): + opid = opname.split(".") + opmod = getattr(bpy.ops, opid[0]) + op = getattr(opmod, opid[1]) + id = op.get_rna_type().bl_rna.identifier + try: + clazz = getattr(bpy.types, id) + return clazz + except AttributeError: + return None + + +def getmodule(opname): + addon = True + clazz = getclazz(opname) + + if clazz is None: + return "", -1, False + + modn = clazz.__module__ + + try: + line = inspect.getsourcelines(clazz)[1] + except IOError: + line = -1 + except TypeError: + line = -1 + + if modn == 'bpy.types': + mod = 'C operator' + addon = False + elif modn != '__main__': + mod = sys.modules[modn].__file__ + else: + addon = False + mod = modn + + return mod, line, addon + + +def get_ops(): + allops = [] + opsdir = dir(bpy.ops) + for opmodname in opsdir: + opmod = getattr(bpy.ops, opmodname) + opmoddir = dir(opmod) + for o in opmoddir: + name = opmodname + "." + o + clazz = getclazz(name) + #if (clazz is not None) :# and clazz.__module__ != 'bpy.types'): + allops.append(name) + del opmoddir + + # add own operator name too, since its not loaded yet when this is called + allops.append("text.edit_operator") + l = sorted(allops) + del allops + del opsdir + + return [(y, y, "", x) for x, y in enumerate(l)] + +class OperatorEntry(PropertyGroup): + + label : StringProperty( + name="Label", + description="", + default="" + ) + + path : StringProperty( + name="Path", + description="", + default="" + ) + + line : IntProperty( + name="Line", + description="", + default=-1 + ) + +class TEXT_OT_EditOperator(Operator): + bl_idname = "text.edit_operator" + bl_label = "Edit Operator" + bl_description = "Opens the source file of operators chosen from Menu" + bl_property = "op" + + items = get_ops() + + op : EnumProperty( + name="Op", + description="", + items=items + ) + + path : StringProperty( + name="Path", + description="", + default="" + ) + + line : IntProperty( + name="Line", + description="", + default=-1 + ) + + def show_text(self, context, path, line): + found = False + + for t in bpy.data.texts: + if t.filepath == path: + #switch to the wanted text first + context.space_data.text = t + ctx = context.copy() + ctx['edit_text'] = t + bpy.ops.text.jump(ctx, line=line) + found = True + break + + if (found is False): + self.report({'INFO'}, + "Opened file: " + path) + bpy.ops.text.open(filepath=path) + bpy.ops.text.jump(line=line) + + def show_calls(self, context): + import bl_ui + import addon_utils + + exclude = stdlib_excludes() + exclude.append("bpy") + exclude.append("sys") + + calls = [] + walk_module(self.op, bl_ui, calls, exclude) + + for m in addon_utils.modules(): + try: + mod = sys.modules[m.__name__] + walk_module(self.op, mod, calls, exclude) + except KeyError: + continue + + for c in calls: + cl = context.scene.calls.add() + cl.name = c[0] + cl.label = c[1] + cl.path = c[2] + cl.line = c[3] + + def invoke(self, context, event): + context.window_manager.invoke_search_popup(self) + return {'PASS_THROUGH'} + + def execute(self, context): + if self.path != "" and self.line != -1: + #invocation of one of the "found" locations + self.show_text(context, self.path, self.line) + return {'FINISHED'} + else: + context.scene.calls.clear() + path, line, addon = getmodule(self.op) + + if addon: + self.show_text(context, path, line) + + #add convenient "source" button, to toggle back from calls to source + c = context.scene.calls.add() + c.name = self.op + c.label = "Source" + c.path = path + c.line = line + + self.show_calls(context) + context.area.tag_redraw() + + return {'FINISHED'} + else: + + self.report({'WARNING'}, + "Found no source file for " + self.op) + + self.show_calls(context) + context.area.tag_redraw() + + return {'FINISHED'} + + +class TEXT_PT_EditOperatorPanel(Panel): + bl_space_type = 'TEXT_EDITOR' + bl_region_type = 'UI' + bl_label = "Edit Operator" + bl_category = "Text" + + def draw(self, context): + layout = self.layout + op = layout.operator("text.edit_operator") + op.path = "" + op.line = -1 + + if len(context.scene.calls) > 0: + box = layout.box() + box.label(text="Calls of: " + context.scene.calls[0].name) + box.operator_context = 'EXEC_DEFAULT' + for c in context.scene.calls: + op = box.operator("text.edit_operator", text=c.label) + op.path = c.path + op.line = c.line + op.op = c.name + + +def register(): + bpy.utils.register_class(OperatorEntry) + bpy.types.Scene.calls = bpy.props.CollectionProperty(name="Calls", + type=OperatorEntry) + bpy.utils.register_class(TEXT_OT_EditOperator) + bpy.utils.register_class(TEXT_PT_EditOperatorPanel) + + +def unregister(): + bpy.utils.unregister_class(TEXT_PT_EditOperatorPanel) + bpy.utils.unregister_class(TEXT_OT_EditOperator) + del bpy.types.Scene.calls + bpy.utils.unregister_class(OperatorEntry) + + +if __name__ == "__main__": + register() -- cgit v1.2.3 From db4f7e2dc66d437b205f8097c2bdf9097b5c8834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vil=C3=A9m=20Duha?= Date: Mon, 2 Sep 2019 13:50:06 +0200 Subject: BlenderKit: rerequests library this library basically ensures that no server requests should fail if the token is after it's lifetime. it refreshes token and re-tries the request in such cases. --- blenderkit/bkit_oauth.py | 4 +- blenderkit/categories.py | 5 ++- blenderkit/download.py | 14 +++---- blenderkit/ratings.py | 7 ++-- blenderkit/rerequests.py | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ blenderkit/search.py | 41 +++++++-------------- blenderkit/upload.py | 9 +++-- blenderkit/upload_bg.py | 18 ++++----- blenderkit/utils.py | 2 +- 9 files changed, 138 insertions(+), 57 deletions(-) create mode 100644 blenderkit/rerequests.py diff --git a/blenderkit/bkit_oauth.py b/blenderkit/bkit_oauth.py index f435d95d..57d3389f 100644 --- a/blenderkit/bkit_oauth.py +++ b/blenderkit/bkit_oauth.py @@ -74,7 +74,7 @@ def refresh_token(api_key_refresh, url): auth_token, refresh_token = authenticator.get_refreshed_token(api_key_refresh) if auth_token is not None and refresh_token is not None: tasks_queue.add_task((write_tokens, (auth_token, refresh_token))) - + return auth_token, refresh_token def write_tokens(auth_token, refresh_token): utils.p('writing tokens') @@ -85,7 +85,7 @@ def write_tokens(auth_token, refresh_token): props = utils.get_search_props() if props is not None: props.report = '' - ui.add_report('BlenderKit Login success') + ui.add_report('BlenderKit Re-Login success') search.get_profile() categories.fetch_categories_thread(auth_token) diff --git a/blenderkit/categories.py b/blenderkit/categories.py index 6407b050..1d411499 100644 --- a/blenderkit/categories.py +++ b/blenderkit/categories.py @@ -22,8 +22,9 @@ if "bpy" in locals(): paths = reload(paths) utils = reload(utils) tasks_queue = reload(tasks_queue) + rerequests = reload(rerequests) else: - from blenderkit import paths, utils, tasks_queue + from blenderkit import paths, utils, tasks_queue, rerequests import requests import json @@ -114,7 +115,7 @@ def fetch_categories(API_key): categories_filepath = os.path.join(tempdir, 'categories.json') try: - r = requests.get(url, headers=headers) + r = rerequests.get(url, headers=headers) rdata = r.json() categories = rdata['results'] fix_category_counts(categories) diff --git a/blenderkit/download.py b/blenderkit/download.py index 366081ca..9f5f0314 100644 --- a/blenderkit/download.py +++ b/blenderkit/download.py @@ -25,8 +25,9 @@ if "bpy" in locals(): ui = reload(ui) colors = reload(colors) tasks_queue = reload(tasks_queue) + rerequests = reload(rerequests) else: - from blenderkit import paths, append_link, utils, ui, colors, tasks_queue + from blenderkit import paths, append_link, utils, ui, colors, tasks_queue, rerequests import threading import time @@ -266,7 +267,7 @@ def report_usages(): scene['assets rated'][k] = scene['assets rated'].get(k, False) thread = threading.Thread(target=utils.requests_post_thread, args=(url, usage_report, headers)) thread.start() - # r = requests.post(url, headers=headers, json=usage_report) + # r = rerequests.post(url, headers=headers, json=usage_report) mt = time.time() - mt print('report generation: ', mt) @@ -551,6 +552,7 @@ class Downloader(threading.Thread): tcom.downloaded = 100 utils.p('not downloading, trying to append again') return; + file_name = paths.get_download_filenames(asset_data)[0] # prefer global dir if possible. # for k in asset_data: # print(asset_data[k]) @@ -617,7 +619,6 @@ def download(asset_data, **kwargs): asset_data = copy.deepcopy(asset_data) else: asset_data = asset_data.to_dict() - readthread = Downloader(asset_data, tcom, scene_id, api_key) readthread.start() @@ -730,7 +731,7 @@ def get_download_url(asset_data, scene_id, api_key, tcom=None): } r = None try: - r = requests.get(asset_data['download_url'], params=data, headers=headers) + r = rerequests.get(asset_data['download_url'], params=data, headers=headers) except Exception as e: print(e) if tcom is not None: @@ -755,10 +756,6 @@ def get_download_url(asset_data, scene_id, api_key, tcom=None): tasks_queue.add_task((ui.add_report, (r1, 5, colors.RED))) tcom.error = True - if r.status_code == 401: - tcom.report = 'Invalid API key' - tcom.error = True - return 'Invalid API key' elif r.status_code >= 500: tcom.report = 'Server error' tcom.error = True @@ -833,7 +830,6 @@ class BlenderkitDownloadOperator(bpy.types.Operator): bl_label = "BlenderKit Asset Download" bl_options = {'REGISTER', 'UNDO', 'INTERNAL'} - asset_type: EnumProperty( name="Type", items=asset_types, diff --git a/blenderkit/ratings.py b/blenderkit/ratings.py index ddf01e6c..7684d017 100644 --- a/blenderkit/ratings.py +++ b/blenderkit/ratings.py @@ -21,8 +21,9 @@ if "bpy" in locals(): paths = reload(paths) utils = reload(utils) + rerequests = reload(rerequests) else: - from blenderkit import paths, utils + from blenderkit import paths, utils, rerequests import bpy import requests, threading @@ -67,14 +68,14 @@ def uplaod_rating_thread(url, ratings, headers): } try: - r = requests.put(rating_url, data=data, verify=True, headers=headers) + r = rerequests.put(rating_url, data=data, verify=True, headers=headers) except requests.exceptions.RequestException as e: print('ratings upload failed: %s' % str(e)) def uplaod_review_thread(url, reviews, headers): - r = requests.put(url, data=reviews, verify=True, headers=headers) + r = rerequests.put(url, data=reviews, verify=True, headers=headers) # except requests.exceptions.RequestException as e: # print('reviews upload failed: %s' % str(e)) diff --git a/blenderkit/rerequests.py b/blenderkit/rerequests.py new file mode 100644 index 00000000..d58214bc --- /dev/null +++ b/blenderkit/rerequests.py @@ -0,0 +1,95 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +if "bpy" in locals(): + from importlib import reload + + ui = reload(ui) + utils = reload(utils) + paths = reload(paths) + tasks_queue = reload(tasks_queue) + bkit_oauth = reload(bkit_oauth) +else: + from blenderkit import ui, utils, paths, tasks_queue, bkit_oauth + +import requests +import bpy + + +def rerequest(method, url, **kwargs): + # first get any additional args from kwargs + immediate = False + if kwargs.get('immediate'): + immediate = kwargs['immediate'] + kwargs.pop('immediate') + # first normal attempt + response = requests.request(method, url, **kwargs) + + utils.p(url) + utils.p(response.status_code) + + if response.status_code == 401: + try: + rdata = response.json() + except: + rdata = {} + + tasks_queue.add_task((ui.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: + tasks_queue.add_task((ui.add_report, ('refreshing token.',))) + refresh_url = paths.get_bkit_url() + auth_token, refresh_token = bkit_oauth.refresh_token(user_preferences.api_key_refresh, refresh_url) + + # utils.p(auth_token, refresh_token) + if auth_token is not None: + if immediate == True: + # this can write tokens occasionally into prefs. used e.g. in upload. Only possible + # in non-threaded tasks + bpy.context.preferences.addons['blenderkit'].preferences.api_key = auth_token + bpy.context.preferences.addons['blenderkit'].preferences.api_key_refresh = refresh_token + + kwargs['headers'] = utils.get_headers(auth_token) + response = requests.request(method, url, **kwargs) + utils.p('reresult', response.status_code) + if response.status_code >= 400: + utils.p('reresult', response.text) + return response + + +def get(url, **kwargs): + response = rerequest('get', url, **kwargs) + return response + + +def post(url, **kwargs): + response = rerequest('post', url, **kwargs) + return response + + +def put(url, **kwargs): + response = rerequest('put', url, **kwargs) + return response + + +def patch(url, **kwargs): + response = rerequest('patch', url, **kwargs) + return response diff --git a/blenderkit/search.py b/blenderkit/search.py index f19a019e..96c50a0e 100644 --- a/blenderkit/search.py +++ b/blenderkit/search.py @@ -27,8 +27,9 @@ if "bpy" in locals(): bkit_oauth = reload(bkit_oauth) version_checker = reload(version_checker) tasks_queue = reload(tasks_queue) + rerequests = reload(rerequests) else: - from blenderkit import paths, utils, categories, ui, bkit_oauth, version_checker, tasks_queue + from blenderkit import paths, utils, categories, ui, bkit_oauth, version_checker, tasks_queue, rerequests import blenderkit from bpy.app.handlers import persistent @@ -121,9 +122,11 @@ def timer_update(): # TODO might get moved to handle all blenderkit stuff. # causing a lot of throuble literally. if len(search_threads) == 0 or bpy.context.scene.blenderkitUI.dragging: return 1 - for thread in search_threads: # TODO this doesn't check all processess when removal... mostly 1 process will be running however. + for thread in search_threads: # TODO this doesn't check all processess when one gets removed, but most time only + # one is running anyway if not thread[0].is_alive(): + print('parsing') search_threads.remove(thread) # icons_dir = thread[1] scene = bpy.context.scene @@ -558,7 +561,7 @@ class ThumbDownloader(threading.Thread): return self._stop_event.is_set() def run(self): - r = requests.get(self.url, stream=False) + r = rerequests.get(self.url, stream=False) if r.status_code == 200: with open(self.path, 'wb') as f: f.write(r.content) @@ -581,7 +584,7 @@ def fetch_author(a_id, api_key): try: a_url = paths.get_api_url() + 'accounts/' + a_id + '/' headers = utils.get_headers(api_key) - r = requests.get(a_url, headers=headers) + r = rerequests.get(a_url, headers=headers) if r.status_code == 200: adata = r.json() if not hasattr(adata, 'id'): @@ -591,13 +594,14 @@ def fetch_author(a_id, api_key): if adata.get('gravatarHash') is not None: gravatar_path = paths.get_temp_dir(subdir='g/') + adata['gravatarHash'] + '.jpg' url = "https://www.gravatar.com/avatar/" + adata['gravatarHash'] + '?d=404' - r = requests.get(url, stream=False) + r = rerequests.get(url, stream=False) if r.status_code == 200: with open(gravatar_path, 'wb') as f: f.write(r.content) adata['gravatarImg'] = gravatar_path elif r.status_code == '404': adata['gravatarHash'] = None + utils.p('gravatar for author not available.') except Exception as e: utils.p(e) utils.p('finish fetch') @@ -635,7 +639,7 @@ def write_profile(adata): def request_profile(api_key): a_url = paths.get_api_url() + 'me/' headers = utils.get_headers(api_key) - r = requests.get(a_url, headers=headers) + r = rerequests.get(a_url, headers=headers) adata = r.json() if adata.get('user') is None: utils.p(adata) @@ -678,8 +682,7 @@ class Searcher(threading.Thread): return self._stop_event.is_set() def run(self): - maxthreads = 300 - maximages = 50 + maxthreads = 50 query = self.query params = self.params global reports @@ -731,7 +734,7 @@ class Searcher(threading.Thread): try: utils.p(urlquery) - r = requests.get(urlquery, headers=headers) + r = rerequests.get(urlquery, headers=headers) reports = '' # utils.p(r.text) except requests.exceptions.RequestException as e: @@ -1115,7 +1118,7 @@ class SearchOperator(Operator): description="get next page from previous search", default=False) - keywords = StringProperty( + keywords: StringProperty( name="Keywords", description="Keywords", default="") @@ -1132,9 +1135,8 @@ class SearchOperator(Operator): if self.keywords != '': 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() return {'FINISHED'} @@ -1163,18 +1165,3 @@ def unregister_search(): # bpy.app.timers.unregister(timer_update) - -''' -search - -build query -START THREAD -send query (bg already) -get result - metadata, small thumbnails, big thumbnails paths (now generate this?) -write metadata, possibly to -download small thumbnails first -start big thumbnails download. these don't have to be there on updates, if they aren't the Image in image editor doesn't get updated. -parse metadata, save it in json in the temp dir which gets read on each update of the search. -END THREAD -when download is triggered, get also this metadata from json. E -pass this single - item metadata in the download functions, threads. -''' diff --git a/blenderkit/upload.py b/blenderkit/upload.py index c9e767a4..75f203df 100644 --- a/blenderkit/upload.py +++ b/blenderkit/upload.py @@ -31,9 +31,10 @@ if "bpy" in locals(): ui = reload(ui) overrides = reload(overrides) colors = reload(colors) + rerequests = reload(rerequests) else: from blenderkit import asset_inspector, paths, utils, bg_blender, autothumb, version_checker, search, ui_panels, ui, \ - overrides, colors + overrides, colors, rerequests import tempfile, os, subprocess, json, re @@ -473,7 +474,7 @@ def verification_status_change(self, context, asset_id, state): url = paths.get_api_url() + 'assets/' + str(asset_id) + '/' headers = utils.get_headers(user_preferences.api_key) try: - r = requests.patch(url, json=upload_data, headers=headers, verify=True) # files = files, + r = rerequests.patch(url, json=upload_data, headers=headers, verify=True) # files = files, #print('changed status ') #print(r.text) except requests.exceptions.RequestException as e: @@ -609,7 +610,7 @@ def start_upload(self, context, asset_type, reupload, upload_set): global reports if props.asset_base_id == '': try: - r = requests.post(url, json=json_metadata, headers=headers, verify=True) # files = files, + r = rerequests.post(url, json=json_metadata, headers=headers, verify=True, immediate = True) # files = files, ui.add_report('uploaded metadata') utils.p(r.text) except requests.exceptions.RequestException as e: @@ -623,7 +624,7 @@ def start_upload(self, context, asset_type, reupload, upload_set): try: if upload_set != ['METADATA']: json_metadata["verificationStatus"] = "uploading" - r = requests.put(url, json=json_metadata, headers=headers, verify=True) # files = files, + r = rerequests.put(url, json=json_metadata, headers=headers, verify=True , immediate = True) # files = files, ui.add_report('uploaded metadata') # parse the request # print('uploaded metadata') diff --git a/blenderkit/upload_bg.py b/blenderkit/upload_bg.py index d951eac2..a9c9f19b 100644 --- a/blenderkit/upload_bg.py +++ b/blenderkit/upload_bg.py @@ -24,8 +24,9 @@ if "bpy" in locals(): append_link = reload(append_link) bg_blender = reload(bg_blender) utils = reload(utils) + rerequests = reload(rerequests) else: - from blenderkit import paths, append_link, bg_blender, utils + from blenderkit import paths, append_link, bg_blender, utils, rerequests import sys, json, os, time import requests @@ -84,7 +85,7 @@ def upload_file(upload_data, f): 'originalFilename': os.path.basename(f['file_path']) } upload_create_url = paths.get_api_url() + 'uploads/' - upload = requests.post(upload_create_url, json=upload_info, headers=headers, verify=True) + upload = rerequests.post(upload_create_url, json=upload_info, headers=headers, verify=True) upload = upload.json() chunk_size = 1024 * 256 @@ -109,7 +110,7 @@ def upload_file(upload_data, f): # confirm single file upload to bkit server upload_done_url = paths.get_api_url() + 'uploads_s3/' + upload['id'] + '/upload-file/' - upload_response = requests.post(upload_done_url, headers=headers, verify=True) + upload_response = rerequests.post(upload_done_url, headers=headers, verify=True) bg_blender.progress('finished uploading') @@ -117,7 +118,6 @@ def upload_file(upload_data, f): def upload_files(upload_data, files): - uploaded_all = True for f in files: uploaded = upload_file(upload_data, f) @@ -180,10 +180,10 @@ if __name__ == "__main__": files = [] if 'THUMBNAIL' in upload_set: files.append({ - "type": "thumbnail", - "index": 0, - "file_path": export_data["thumbnail_path"] - }) + "type": "thumbnail", + "index": 0, + "file_path": export_data["thumbnail_path"] + }) if 'MAINFILE' in upload_set: files.append({ "type": "blend", @@ -207,7 +207,7 @@ if __name__ == "__main__": url += upload_data["id"] + '/' - r = requests.patch(url, json=confirm_data, headers=headers, verify=True) # files = files, + r = rerequests.patch(url, json=confirm_data, headers=headers, verify=True) # files = files, bg_blender.progress('upload finished successfully') else: diff --git a/blenderkit/utils.py b/blenderkit/utils.py index 7c56ce8a..a6bb407d 100644 --- a/blenderkit/utils.py +++ b/blenderkit/utils.py @@ -385,7 +385,7 @@ def get_dimensions(obs): def requests_post_thread(url, json, headers): - r = requests.post(url, json=json, verify=True, headers=headers) + r = rerequests.post(url, json=json, verify=True, headers=headers) def get_headers(api_key): -- cgit v1.2.3