Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVilem Duha <vilem.duha@gmail.com>2019-05-21 00:01:41 +0300
committerVilem Duha <vilem.duha@gmail.com>2019-05-21 00:03:01 +0300
commit3778680f22bef286234434e22ca03481c7ef0495 (patch)
tree6b0f777600a2e403972b9012cdb00283779ee125 /blenderkit
parent01500c966186519c9a0dc1287022c58e92e0a07e (diff)
BlenderKit: Downloads can now be cancelled
- converted main download thread into object with stop-ability.
Diffstat (limited to 'blenderkit')
-rw-r--r--blenderkit/download.py121
-rw-r--r--blenderkit/search.py1
-rw-r--r--blenderkit/ui_panels.py4
3 files changed, 85 insertions, 41 deletions
diff --git a/blenderkit/download.py b/blenderkit/download.py
index c8695f5e..7bc04481 100644
--- a/blenderkit/download.py
+++ b/blenderkit/download.py
@@ -290,7 +290,7 @@ def append_asset(asset_data, **kwargs): # downloaders=[], location=None,
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
if user_preferences.api_key == '':
- user_preferences.asset_counter+=1
+ user_preferences.asset_counter += 1
if asset_data['asset_type'] == 'scene':
scene = append_link.append_scene(file_names[0], link=False, fake_user=False)
@@ -507,41 +507,69 @@ def timer_update(): # TODO might get moved to handle all blenderkit stuff, not
return .2
-def main_thread(asset_data, tcom, scene_id, api_key):
- '''try to download file from blenderkit'''
-
- # TODO get real link here...
- get_download_url(asset_data, scene_id, api_key, tcom=tcom)
- if tcom.error:
- return
- # only now we can check if the file allready exists. This should have 2 levels, for materials and for brushes
- # different than for the non free content. delete is here when called after failed append tries.
- if check_existing(asset_data) and not tcom.passargs.get('delete'):
- # this sends the thread for processing, where another check should occur, since the file might be corrupted.
- tcom.downloaded = 100
- print('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])
-
- with open(file_name, "wb") as f:
- print("Downloading %s" % file_name)
- headers = utils.get_headers(api_key)
-
- response = requests.get(asset_data['url'], stream=True)
- total_length = response.headers.get('Content-Length')
-
- if total_length is None: # no content length header
- f.write(response.content)
- else:
- tcom.file_size = int(total_length)
- dl = 0
- for data in response.iter_content(chunk_size=4096):
- dl += len(data)
- tcom.downloaded = dl
- tcom.progress = int(100 * tcom.downloaded / tcom.file_size)
- f.write(data)
+class Downloader(threading.Thread):
+ def __init__(self, asset_data, tcom, scene_id, api_key):
+ super(Downloader, self).__init__()
+ self.asset_data = asset_data
+ self.tcom = tcom
+ self.scene_id = scene_id
+ self.api_key = api_key
+ self._stop_event = threading.Event()
+
+ def stop(self):
+ self._stop_event.set()
+
+ def stopped(self):
+ return self._stop_event.is_set()
+
+ # def main_download_thread(asset_data, tcom, scene_id, api_key):
+ def run(self):
+ '''try to download file from blenderkit'''
+ asset_data = self.asset_data
+ tcom = self.tcom
+ scene_id = self.scene_id
+ api_key = self.api_key
+
+ # TODO get real link here...
+ get_download_url(asset_data, scene_id, api_key, tcom=tcom)
+ if tcom.error:
+ return
+ # only now we can check if the file allready exists. This should have 2 levels, for materials and for brushes
+ # different than for the non free content. delete is here when called after failed append tries.
+ if check_existing(asset_data) and not tcom.passargs.get('delete'):
+ # this sends the thread for processing, where another check should occur, since the file might be corrupted.
+ tcom.downloaded = 100
+ print('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])
+ if self.stopped():
+ utils.p('stopping download: ' + asset_data['name'])
+ return;
+
+ with open(file_name, "wb") as f:
+ print("Downloading %s" % file_name)
+ headers = utils.get_headers(api_key)
+
+ response = requests.get(asset_data['url'], stream=True)
+ total_length = response.headers.get('Content-Length')
+
+ if total_length is None: # no content length header
+ f.write(response.content)
+ else:
+ tcom.file_size = int(total_length)
+ dl = 0
+ for data in response.iter_content(chunk_size=4096):
+ dl += len(data)
+ tcom.downloaded = dl
+ tcom.progress = int(100 * tcom.downloaded / tcom.file_size)
+ f.write(data)
+ if self.stopped():
+ utils.p('stopping download: ' + asset_data['name'])
+ f.close()
+ os.remove(file_name)
+ return;
class ThreadCom: # object passed to threads to read background process stdout info
@@ -572,8 +600,7 @@ def download(asset_data, **kwargs):
else:
asset_data = asset_data.to_dict()
- # main_thread(asset_data, tcom, scene_id, api_key)
- readthread = threading.Thread(target=main_thread, args=([asset_data, tcom, scene_id, api_key]), daemon=True)
+ readthread = Downloader(asset_data, tcom, scene_id, api_key)
readthread.start()
global download_threads
@@ -761,6 +788,22 @@ asset_types = (
)
+class BlenderkitKillDownloadOperator(bpy.types.Operator):
+ """Kill a download."""
+ bl_idname = "scene.blenderkit_download_kill"
+ bl_label = "BlenderKit Kill Asset Download"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ thread_index: IntProperty(name="Thread index", description='index of the thread to kill', default=-1)
+
+ def execute(self, context):
+ global download_threads
+ td = download_threads[self.thread_index]
+ download_threads.remove(td)
+ td[0].stop()
+ return {'FINISHED'}
+
+
class BlenderkitDownloadOperator(bpy.types.Operator):
"""Download and link asset to scene. Only link if asset allready available locally."""
bl_idname = "scene.blenderkit_download"
@@ -820,6 +863,7 @@ class BlenderkitDownloadOperator(bpy.types.Operator):
def register_download():
bpy.utils.register_class(BlenderkitDownloadOperator)
+ bpy.utils.register_class(BlenderkitKillDownloadOperator)
bpy.app.handlers.load_post.append(scene_load)
bpy.app.handlers.save_pre.append(scene_save)
# bpy.app.timers.register(timer_update, persistent = True)
@@ -827,6 +871,7 @@ def register_download():
def unregister_download():
bpy.utils.unregister_class(BlenderkitDownloadOperator)
+ bpy.utils.unregister_class(BlenderkitKillDownloadOperator)
bpy.app.handlers.load_post.remove(scene_load)
bpy.app.handlers.save_pre.remove(scene_save)
# bpy.app.timers.unregister(timer_update)
diff --git a/blenderkit/search.py b/blenderkit/search.py
index 8e40dd17..452ec434 100644
--- a/blenderkit/search.py
+++ b/blenderkit/search.py
@@ -952,7 +952,6 @@ def add_search_process(query, params):
tempdir = paths.get_temp_dir('%s_search' % query['asset_type'])
thread = Searcher(query, params)
- # thread = threading.Thread(target=Searcher, args=([query]), daemon=True)
thread.start()
search_threads.append([thread, tempdir, query['asset_type']])
diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py
index 664aa0c8..88d14386 100644
--- a/blenderkit/ui_panels.py
+++ b/blenderkit/ui_panels.py
@@ -288,7 +288,7 @@ def draw_panel_model_search(self, context):
# layout.prop(props, 'append_link', expand=True, icon_only=False)
# layout.prop(props, 'import_as', expand=True, icon_only=False)
- #layout.prop(props, "search_advanced")
+ # layout.prop(props, "search_advanced")
if props.search_advanced:
layout.separator()
@@ -589,7 +589,6 @@ class VIEW3D_PT_blenderkit_unified(Panel):
layout.prop(user_preferences, 'api_key', text='')
layout.separator()
if bpy.data.filepath == '':
-
label_multiline(layout, text="It's better to save the file first.", width=w)
layout.separator()
if wm.get('bkit_update'):
@@ -802,6 +801,7 @@ class VIEW3D_PT_blenderkit_downloads(Panel):
row = layout.row()
row.label(text=asset_data['name'])
row.label(text=str(int(tcom.progress)) + ' %')
+ row.operator('scene.blenderkit_download_kill', text='', icon='CANCEL')
classess = (