From 85fd48c32cbdb42f81b26bfb81d411d83e0898b0 Mon Sep 17 00:00:00 2001
From: Vilem Duha <vilem.duha@gmail.com>
Date: Wed, 29 May 2019 15:01:01 +0200
Subject: [PATCH] BlenderKit: convert all imports to importlib + new Oauth
 script version (finished in next commit) +split login/signup buttons

---
 blenderkit/__init__.py              | 54 ++++++++++++++++-------------
 blenderkit/append_link.py           | 11 ++++--
 blenderkit/asset_inspector.py       | 15 ++++----
 blenderkit/autothumb.py             | 10 ++----
 blenderkit/autothumb_material_bg.py | 11 +++++-
 blenderkit/autothumb_model_bg.py    | 10 +++++-
 blenderkit/bg_blender.py            | 16 +++++----
 blenderkit/bkit_oauth.py            | 50 ++++++++++++++++++++------
 blenderkit/categories.py            | 29 +++++++++++++++-
 blenderkit/download.py              | 26 +++++++-------
 blenderkit/oauth.py                 | 14 ++++++--
 blenderkit/overrides.py             | 10 ++++--
 blenderkit/paths.py                 |  3 +-
 blenderkit/ratings.py               |  7 ++--
 blenderkit/search.py                | 19 +++++-----
 blenderkit/tasks_queue.py           | 26 +++++++++++++-
 blenderkit/ui.py                    | 20 ++++++-----
 blenderkit/ui_panels.py             | 30 +++++++++-------
 blenderkit/upload.py                | 27 +++++++--------
 blenderkit/upload_bg.py             | 13 +++++--
 blenderkit/utils.py                 |  8 +++--
 blenderkit/version_checker.py       |  9 ++++-
 22 files changed, 281 insertions(+), 137 deletions(-)

diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py
index 579c38963..33fdc15a4 100644
--- a/blenderkit/__init__.py
+++ b/blenderkit/__init__.py
@@ -30,19 +30,23 @@ bl_info = {
 }
 
 if "bpy" in locals():
-    import importlib
-
-    importlib.reload(asset_inspector)
-    importlib.reload(search)
-    importlib.reload(download)
-    importlib.reload(ratings)
-    importlib.reload(autothumb)
-    importlib.reload(ui)
-    importlib.reload(bg_blender)
-    importlib.reload(paths)
-    importlib.reload(utils)
-    importlib.reload(bkit_oauth)
-    importlib.reload(tasks_queue)
+    from importlib import reload
+
+    asset_inspector = reload(asset_inspector)
+    search = reload(search)
+    download = reload(download)
+    upload = reload(upload)
+    ratings = reload(ratings)
+    autothumb = reload(autothumb)
+    ui = reload(ui)
+    bg_blender = reload(bg_blender)
+    paths = reload(paths)
+    utils = reload(utils)
+    overrides = reload(overrides)
+    ui_panels = reload(ui_panels)
+    categories = reload(categories)
+    bkit_oauth = reload(bkit_oauth)
+    tasks_queue = reload(tasks_queue)
 else:
     from blenderkit import asset_inspector, search, download, upload, ratings, autothumb, ui, bg_blender, paths, utils, \
         overrides, ui_panels, categories, bkit_oauth, tasks_queue
@@ -73,6 +77,7 @@ from bpy.types import (
     PropertyGroup,
 )
 
+
 # logging.basicConfig(filename = 'blenderkit.log', level = logging.INFO,
 #                     format = '	%(asctime)s:%(filename)s:%(funcName)s:%(lineno)d:%(message)s')
 
@@ -86,6 +91,7 @@ def scene_load(context):
     preferences = bpy.context.preferences.addons['blenderkit'].preferences
     preferences.login_attempt = False
 
+
 licenses = (
     ('royalty_free', 'Royalty Free', 'royalty free commercial license'),
     ('cc_zero', 'Creative Commons Zero', 'Creative Commons Zero'),
@@ -457,7 +463,7 @@ class BlenderKitCommonUploadProps(object):
             ('PUBLIC', 'Public', '"Your asset will go into the validation process automatically')
         ),
         description="If not marked private, your asset will go into the validation process automatically\n"
-                                      "Private assets are limited by quota.",
+                    "Private assets are limited by quota.",
         default="PUBLIC",
     )
 
@@ -1076,7 +1082,7 @@ class BlenderKitModelSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
     )
 
     free_only: BoolProperty(name="Free only", description="Show only free models",
-                                  default=False)
+                            default=False)
 
     search_advanced: BoolProperty(name="Advanced Search Options", description="use advanced search properties",
                                   default=False)
@@ -1237,7 +1243,7 @@ class BlenderKitAddonPreferences(AddonPreferences):
 
     default_global_dict = paths.default_global_dict()
 
-    enable_oauth = False
+    enable_oauth = True
 
     api_key: StringProperty(
         name="BlenderKit API Key",
@@ -1320,12 +1326,11 @@ class BlenderKitAddonPreferences(AddonPreferences):
                                    min=0,
                                    max=20)
 
-    asset_counter:  IntProperty(name="Usage Counter",
-                                   description="Counts usages so it asks for registration only after reaching a limit",
-                                   default=0,
-                                   min=0,
-                                   max=20000)
-
+    asset_counter: IntProperty(name="Usage Counter",
+                               description="Counts usages so it asks for registration only after reaching a limit",
+                               default=0,
+                               min=0,
+                               max=20000)
 
     # allow_proximity : BoolProperty(
     #     name="allow proximity data reports",
@@ -1340,8 +1345,7 @@ class BlenderKitAddonPreferences(AddonPreferences):
 
         if self.api_key.strip() == '':
             if self.enable_oauth:
-                layout.operator("wm.blenderkit_login", text="Login/ Sign up",
-                            icon='URL')
+                ui_panels.draw_login_buttons(layout)
             else:
                 op = layout.operator("wm.url_open", text="Register online and get your API Key",
                                      icon='QUESTION')
@@ -1438,8 +1442,8 @@ def register():
 
     bpy.app.handlers.load_post.append(scene_load)
 
-def unregister():
 
+def unregister():
     ui.unregister_ui()
     search.unregister_search()
     asset_inspector.unregister_asset_inspector()
diff --git a/blenderkit/append_link.py b/blenderkit/append_link.py
index fef0c25f5..8b399986b 100644
--- a/blenderkit/append_link.py
+++ b/blenderkit/append_link.py
@@ -16,9 +16,16 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+
+if "bpy" in locals():
+    from importlib import reload
+
+    utils = reload(utils)
+else:
+    from blenderkit import utils
+
 import bpy
-import os, uuid
-from blenderkit import utils
+import uuid
 
 
 def append_brush(file_name, brushname=None, link=False, fake_user=True):
diff --git a/blenderkit/asset_inspector.py b/blenderkit/asset_inspector.py
index 35c4da213..b437a226c 100644
--- a/blenderkit/asset_inspector.py
+++ b/blenderkit/asset_inspector.py
@@ -16,18 +16,16 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+
 if "bpy" in locals():
-    import imp
+    from importlib import reload
 
-    imp.reload(utils)
+    utils = reload(utils)
 else:
     from blenderkit import utils
 
-import bpy, bmesh
-import mathutils
-import object_print3d_utils
+import bpy
 from object_print3d_utils import operators as ops
-from mathutils import Vector
 
 RENDER_OBTYPES = ['MESH', 'CURVE', 'SURFACE', 'METABALL', 'TEXT']
 
@@ -94,7 +92,6 @@ def check_render_engine(props, obs):
 
         props.engine = 'CYCLES'
 
-
         for mname in materials:
             m = bpy.data.materials[mname]
             if m is not None and m.node_tree is not None:
@@ -315,7 +312,7 @@ def check_modifiers(props, obs):
 def get_autotags():
     """ call all analysis functions """
     ui = bpy.context.scene.blenderkitUI
-    if ui.asset_type =='MODEL':
+    if ui.asset_type == 'MODEL':
         ob = utils.get_active_model()
         obs = utils.get_hierarchy(ob)
         props = ob.blenderkit
@@ -339,7 +336,7 @@ def get_autotags():
         check_meshprops(props, obs)
         check_modifiers(props, obs)
         countObs(props, obs)
-    elif ui.asset_type =='MATERIAL':
+    elif ui.asset_type == 'MATERIAL':
         # reset some properties here, because they might not get re-filled at all when they aren't needed anymore.
 
         mat = utils.get_active_asset()
diff --git a/blenderkit/autothumb.py b/blenderkit/autothumb.py
index 004456294..2d05c5ee4 100644
--- a/blenderkit/autothumb.py
+++ b/blenderkit/autothumb.py
@@ -16,17 +16,13 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
-import importlib
 
 if "bpy" in locals():
     from importlib import reload
 
-    if "paths" in locals():
-        reload(paths)
-    if "utils" in locals():
-        reload(utils)
-    if "bg_blender" in locals():
-        reload(bg_blender)
+    paths = reload(paths)
+    utils = reload(utils)
+    bg_blender = reload(bg_blender)
 else:
     from blenderkit import paths, utils, bg_blender
 
diff --git a/blenderkit/autothumb_material_bg.py b/blenderkit/autothumb_material_bg.py
index 6d30f0ff5..16308433f 100644
--- a/blenderkit/autothumb_material_bg.py
+++ b/blenderkit/autothumb_material_bg.py
@@ -16,10 +16,19 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+
+if "bpy" in locals():
+    from importlib import reload
+
+    utils = reload(utils)
+    append_link = reload(append_link)
+    bg_blender = reload(bg_blender)
+else:
+    from blenderkit import utils, append_link, bg_blender
+
 import sys, json, math
 import bpy
 from pathlib import Path
-from blenderkit import utils, append_link, bg_blender
 
 BLENDERKIT_EXPORT_TEMP_DIR = sys.argv[-1]
 BLENDERKIT_THUMBNAIL_PATH = sys.argv[-2]
diff --git a/blenderkit/autothumb_model_bg.py b/blenderkit/autothumb_model_bg.py
index 64f10d830..5df0738b7 100644
--- a/blenderkit/autothumb_model_bg.py
+++ b/blenderkit/autothumb_model_bg.py
@@ -17,10 +17,18 @@
 # ##### END GPL LICENSE BLOCK #####
 
 
+if "bpy" in locals():
+    from importlib import reload
+
+    utils = reload(utils)
+    append_link = reload(append_link)
+    bg_blender = reload(bg_blender)
+else:
+    from blenderkit import utils, append_link, bg_blender
+
 import sys, json, math
 from pathlib import Path
 import bpy
-from blenderkit import utils, append_link, bg_blender
 import mathutils
 
 BLENDERKIT_EXPORT_TEMP_DIR = sys.argv[-1]
diff --git a/blenderkit/bg_blender.py b/blenderkit/bg_blender.py
index f1681831a..4a7afd929 100644
--- a/blenderkit/bg_blender.py
+++ b/blenderkit/bg_blender.py
@@ -16,6 +16,12 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+if "bpy" in locals():
+    from importlib import reload
+
+    utils = reload(utils)
+else:
+    from blenderkit import utils
 
 import bpy
 import sys, threading, os
@@ -25,8 +31,6 @@ from bpy.props import (
     EnumProperty,
 )
 
-from blenderkit import utils
-
 bg_processes = []
 
 
@@ -112,19 +116,19 @@ def bg_update():
             # readthread.
             if tcom.error:
                 estring = tcom.eval_path_computing + ' = False'
-                exec (estring)
+                exec(estring)
 
             tcom.lasttext = tcom.outtext
             if tcom.outtext != '':
                 tcom.outtext = ''
                 estring = tcom.eval_path_state + ' = tcom.lasttext'
 
-                exec (estring)
+                exec(estring)
             # print(tcom.lasttext)
             if 'finished successfully' in tcom.lasttext:
                 bg_processes.remove(p)
                 estring = tcom.eval_path_computing + ' = False'
-                exec (estring)
+                exec(estring)
             else:
                 readthread = threading.Thread(target=threadread, args=([tcom]), daemon=True)
                 readthread.start()
@@ -205,7 +209,7 @@ class KillBgProcess(bpy.types.Operator):
                         kill = True
                 if kill:
                     estring = tcom.eval_path_computing + ' = False'
-                    exec (estring)
+                    exec(estring)
                     processes.remove(p)
                     tcom.proc.kill()
 
diff --git a/blenderkit/bkit_oauth.py b/blenderkit/bkit_oauth.py
index f679807ce..b68e982e1 100644
--- a/blenderkit/bkit_oauth.py
+++ b/blenderkit/bkit_oauth.py
@@ -16,25 +16,46 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+if "bpy" in locals():
+    from importlib import reload
+
+    tasks_queue = reload(tasks_queue)
+    utils = reload(utils)
+    paths = reload(paths)
+    search = reload(search)
+    categories = reload(categories)
+    oauth = reload(oauth)
+else:
+    from blenderkit import tasks_queue, utils, paths, search, categories, oauth
+
 import bpy
 
 import threading
-import blenderkit
-from blenderkit import tasks_queue, utils, paths, search, categories, oauth
+
+from bpy.props import (
+    BoolProperty,
+)
 
 CLIENT_ID = "IdFRwa3SGA8eMpzhRVFMg5Ts8sPK93xBjif93x0F"
 PORTS = [62485, 1234]
 
-def login_thread():
-    thread = threading.Thread(target=login, args=([]), daemon=True)
+
+def login_thread(signup=False):
+    thread = threading.Thread(target=login, args=([signup]), daemon=True)
     thread.start()
 
 
-def login():
-    authenticator = oauth.SimpleOAuthAuthenticator(server_url=paths.get_bkit_url(), client_id=CLIENT_ID, ports=PORTS)
+def login(signup):
+    if signup:
+        r_url = paths.BLENDERKIT_SIGNUP_URL
+    else:
+        r_url = paths.BLENDERKIT_LOGIN_URL
+
+    authenticator = oauth.SimpleOAuthAuthenticator(server_url=paths.get_bkit_url(), client_id=CLIENT_ID, ports=PORTS,
+                                                   redirect_url=r_url)
     auth_token, refresh_token = authenticator.get_new_token()
     utils.p('tokens retrieved')
-    tasks_queue.add_task((write_tokens , (auth_token, refresh_token)))
+    tasks_queue.add_task((write_tokens, (auth_token, refresh_token)))
 
 
 def refresh_token_thread():
@@ -45,10 +66,11 @@ def refresh_token_thread():
 
 
 def refresh_token(api_key_refresh):
-    authenticator = oauth.SimpleOAuthAuthenticator(server_url=paths.get_bkit_url(), client_id=CLIENT_ID, ports=PORTS)
+    authenticator = oauth.SimpleOAuthAuthenticator(server_url=paths.get_bkit_url(), client_id=CLIENT_ID, ports=PORTS,
+                                                   redirect_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((blenderkit.bkit_oauth.write_tokens , (auth_token, refresh_token)))
+        tasks_queue.add_task((blenderkit.bkit_oauth.write_tokens, (auth_token, refresh_token)))
 
 
 def write_tokens(auth_token, refresh_token):
@@ -70,6 +92,13 @@ class RegisterLoginOnline(bpy.types.Operator):
     bl_label = "BlenderKit login or signup"
     bl_options = {'REGISTER', 'UNDO'}
 
+    signup: BoolProperty(
+        name="create a new account",
+        description="True for register, otherwise login",
+        default=False,
+        options={'SKIP_SAVE'}
+    )
+
     @classmethod
     def poll(cls, context):
         return True
@@ -77,7 +106,7 @@ class RegisterLoginOnline(bpy.types.Operator):
     def execute(self, context):
         preferences = bpy.context.preferences.addons['blenderkit'].preferences
         preferences.login_attempt = True
-        login_thread()
+        login_thread(self.signup)
         return {'FINISHED'}
 
 
@@ -116,6 +145,7 @@ class CancelLoginOnline(bpy.types.Operator):
         preferences.login_attempt = False
         return {'FINISHED'}
 
+
 classess = (
     RegisterLoginOnline,
     CancelLoginOnline,
diff --git a/blenderkit/categories.py b/blenderkit/categories.py
index c2b37dd1d..ee20557c5 100644
--- a/blenderkit/categories.py
+++ b/blenderkit/categories.py
@@ -1,8 +1,35 @@
+# ##### 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
+
+    paths = reload(paths)
+    utils = reload(utils)
+    tasks_queue = reload(tasks_queue)
+else:
+    from blenderkit import paths, utils, tasks_queue
+
 import requests
 import json
 import os
 import bpy
-from blenderkit import paths, utils, tasks_queue
+
 import shutil
 import threading
 
diff --git a/blenderkit/download.py b/blenderkit/download.py
index 3eaa4e51f..7bdbc3c4e 100644
--- a/blenderkit/download.py
+++ b/blenderkit/download.py
@@ -16,23 +16,22 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+if "bpy" in locals():
+    from importlib import reload
+
+    paths = reload(paths)
+    append_link = reload(append_link)
+    utils = reload(utils)
+else:
+    from blenderkit import paths, append_link, utils
+
 import threading
 import time
 import requests
-import shutil, sys, os, math
-import random
+import shutil, sys, os
 import uuid
 import copy
 
-if "bpy" in locals():
-    import imp
-
-    imp.reload(paths)
-    imp.reload(append_link)
-    imp.reload(utils)
-
-else:
-    from blenderkit import paths, append_link, utils
 import bpy
 from bpy.props import (
     IntProperty,
@@ -492,7 +491,7 @@ def timer_update():  # TODO might get moved to handle all blenderkit stuff, not
                     done = try_finished_append(asset_data, **tcom.passargs)
                     if not done:
                         at = asset_data['asset_type']
-                        tcom.passargs['retry_counter'] = tcom.passargs.get('retry_counter',0) +1
+                        tcom.passargs['retry_counter'] = tcom.passargs.get('retry_counter', 0) + 1
                         if at in ('model', 'material'):
                             download(asset_data, **tcom.passargs)
                         elif asset_data['asset_type'] == 'material':
@@ -595,13 +594,12 @@ def download(asset_data, **kwargs):
     tcom = ThreadCom()
     tcom.passargs = kwargs
 
-    if kwargs.get('retry_counter',0) > 3:
+    if kwargs.get('retry_counter', 0) > 3:
         sprops = utils.get_search_props()
         sprops.report = f"Maximum retries exceeded for {asset_data['name']}"
         utils.p(sprops.report)
         return
 
-
     # incoming data can be either directly dict from python, or blender id property
     # (recovering failed downloads on reload)
     if type(asset_data) == dict:
diff --git a/blenderkit/oauth.py b/blenderkit/oauth.py
index 61d6a7e8b..e2846dabb 100644
--- a/blenderkit/oauth.py
+++ b/blenderkit/oauth.py
@@ -26,10 +26,11 @@ import requests
 
 
 class SimpleOAuthAuthenticator(object):
-    def __init__(self, server_url, client_id, ports):
+    def __init__(self, server_url, client_id, ports, redirect_url):
         self.server_url = server_url
         self.client_id = client_id
         self.ports = ports
+        self.redirect_url = redirect_url
 
     def _get_tokens(self, authorization_code=None, refresh_token=None, grant_type="authorization_code"):
         data = {
@@ -62,7 +63,14 @@ class SimpleOAuthAuthenticator(object):
                 if 'code' in self.path:
                     self.auth_code = self.path.split('=')[1]
                     # Display to the user that they no longer need the browser window
-                    self.wfile.write(bytes('<html><h1>You may now close this window.</h1></html>', 'utf-8'))
+                    self.wfile.write(bytes(
+                        '<html>'
+                        '<head><meta http-equiv="refresh" content="0;url=%(redirect_url)s"></head>'
+                        '<script> window.location.href="%(redirect_url)s"; </script>'
+                        '<h1>You may now close this window.</h1>'
+                        '</html>' % {'redirect_url': self.redirect_url},
+                        'utf-8',
+                    ))
                     qs = parse_qs(urlparse(self.path).query)
                     self.server.authorization_code = qs['code'][0]
 
@@ -82,4 +90,4 @@ class SimpleOAuthAuthenticator(object):
         return self._get_tokens(authorization_code=authorization_code)
 
     def get_refreshed_token(self, refresh_token):
-        return self._get_tokens(refresh_token=refresh_token, grant_type="refresh_token")
+        return self._get_tokens(refresh_token=refresh_token, grant_type="refresh_token")
\ No newline at end of file
diff --git a/blenderkit/overrides.py b/blenderkit/overrides.py
index d9fc8028c..348a3d213 100644
--- a/blenderkit/overrides.py
+++ b/blenderkit/overrides.py
@@ -16,12 +16,18 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+
+if "bpy" in locals():
+    from importlib import reload
+
+    utils = reload(utils)
+else:
+    from blenderkit import utils
+
 import bpy, mathutils
 from bpy.types import (
     Operator)
 
-from blenderkit import utils
-
 
 def getNodes(nt, node_type='OUTPUT_MATERIAL'):
     chnodes = nt.nodes[:]
diff --git a/blenderkit/paths.py b/blenderkit/paths.py
index 310d6ec19..cb460ff18 100644
--- a/blenderkit/paths.py
+++ b/blenderkit/paths.py
@@ -28,7 +28,8 @@ BLENDERKIT_PLANS = "https://www.blenderkit.com/plans/pricing/"
 BLENDERKIT_MANUAL = "https://youtu.be/1hVgcQhIAo8"
 BLENDERKIT_MODEL_UPLOAD_INSTRUCTIONS_URL = "https://www.blenderkit.com/docs/upload/"
 BLENDERKIT_MATERIAL_UPLOAD_INSTRUCTIONS_URL = "https://www.blenderkit.com/docs/uploading-material/"
-BLENDERKIT_SIGNUP_URL = "https://www.blenderkit.com/accounts/register/"
+BLENDERKIT_LOGIN_URL = "https://www.blenderkit.com/accounts/login"
+BLENDERKIT_SIGNUP_URL = "https://www.blenderkit.com/accounts/register"
 BLENDERKIT_ADDON_URL = "https://www.blenderkit.com/api/v1/assets/6923b215-7df0-46f3-95ae-a2b5ff44ddd5/"
 BLENDERKIT_ADDON_FILE_URL = "https://www.blenderkit.com/get-blenderkit/"
 _presets = os.path.join(bpy.utils.user_resource('SCRIPTS'), "presets")
diff --git a/blenderkit/ratings.py b/blenderkit/ratings.py
index 8220b1888..c3621df39 100644
--- a/blenderkit/ratings.py
+++ b/blenderkit/ratings.py
@@ -17,10 +17,10 @@
 # ##### END GPL LICENSE BLOCK #####
 
 if "bpy" in locals():
-    import imp
-
-    imp.reload(paths)
+    from importlib import reload
 
+    paths = reload(paths)
+    utils = reload(utils)
 else:
     from blenderkit import paths, utils
 
@@ -85,7 +85,6 @@ def upload_rating(asset):
     api_key = user_preferences.api_key
     headers = utils.get_headers(api_key)
 
-
     asset_data = asset['asset_data']
 
     bkit_ratings = asset.bkit_ratings
diff --git a/blenderkit/search.py b/blenderkit/search.py
index 5c1dc920e..eb1d28886 100644
--- a/blenderkit/search.py
+++ b/blenderkit/search.py
@@ -16,16 +16,17 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+
 if "bpy" in locals():
-    import imp
-
-    imp.reload(paths)
-    imp.reload(utils)
-    imp.reload(categories)
-    imp.reload(ui)
-    imp.reload(version_checker)
-    imp.reload(bkit_oauth)
-    imp.reload(tasks_queue)
+    from importlib import reload
+
+    paths = reload(paths)
+    utils = reload(utils)
+    categories = reload(categories)
+    ui = reload(ui)
+    bkit_oauth = reload(bkit_oauth)
+    version_checker = reload(version_checker)
+    tasks_queue = reload(tasks_queue)
 else:
     from blenderkit import paths, utils, categories, ui, bkit_oauth, version_checker, tasks_queue
 
diff --git a/blenderkit/tasks_queue.py b/blenderkit/tasks_queue.py
index d347ed461..eaa3bfa4f 100644
--- a/blenderkit/tasks_queue.py
+++ b/blenderkit/tasks_queue.py
@@ -1,9 +1,33 @@
+# ##### 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
+
+    utils = reload(utils)
+else:
+    from blenderkit import utils
+
 import bpy
 from bpy.app.handlers import persistent
 
 import queue
 
-from blenderkit import utils
 
 
 @persistent
diff --git a/blenderkit/ui.py b/blenderkit/ui.py
index d7253d462..f35b0f739 100644
--- a/blenderkit/ui.py
+++ b/blenderkit/ui.py
@@ -16,14 +16,18 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
-if "bpy" in locals():
-    import imp
 
-    imp.reload(paths)
-    imp.reload(ratings)
-    imp.reload(utils)
-    imp.reload(search)
-    imp.reload(upload)
+if "bpy" in locals():
+    import importlib
+
+    paths = importlib.reload(paths)
+    ratings = importlib.reload(ratings)
+    utils = importlib.reload(utils)
+    search = importlib.reload(search)
+    upload = importlib.reload(upload)
+    ui_bgl = importlib.reload(ui_bgl)
+    download = importlib.reload(download)
+    bg_blender = importlib.reload(bg_blender)
 else:
     from blenderkit import paths, ratings, utils, search, upload, ui_bgl, download, bg_blender
 
@@ -1425,7 +1429,7 @@ class AssetBarOperator(bpy.types.Operator):
             a = asset_data['author_id']
             if a is not None:
                 utils.p('author:', a)
-                search.search(author_id = a)
+                search.search(author_id=a)
             return {'RUNNING_MODAL'}
         if event.type == 'X' and ui_props.active_index != -3:
             sr = bpy.context.scene['search results']
diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py
index 20cba94c0..b74e3bbef 100644
--- a/blenderkit/ui_panels.py
+++ b/blenderkit/ui_panels.py
@@ -17,16 +17,15 @@
 # ##### END GPL LICENSE BLOCK #####
 
 if "bpy" in locals():
-    import imp
-
-    imp.reload(paths)
-    imp.reload(ratings)
-    imp.reload(utils)
-    imp.reload(download)
-    imp.reload(categories)
-    imp.reload(ui)
+    import importlib
+
+    paths = importlib.reload(paths)
+    ratings = importlib.reload(ratings)
+    utils = importlib.reload(utils)
+    download = importlib.reload(download)
+    categories = importlib.reload(categories)
 else:
-    from blenderkit import paths, ratings, utils, download, categories, ui
+    from blenderkit import paths, ratings, utils, download, categories
 
 from bpy.types import (
     Panel
@@ -411,8 +410,7 @@ class VIEW3D_PT_blenderkit_profile(Panel):
 
         if len(user_preferences.api_key) < 20:
             if user_preferences.enable_oauth:
-                layout.operator("wm.blenderkit_login", text="Login/ Sign up",
-                                icon='URL')
+                draw_login_buttons(layout)
         else:
             me = bpy.context.window_manager.get('bkit profile')
             if me is not None:
@@ -545,6 +543,13 @@ def draw_panel_brush_ratings(self, context):
     op.asset_type = 'BRUSH'
 
 
+def draw_login_buttons(layout):
+    layout.operator("wm.blenderkit_login", text="Login",
+                    icon='URL').signup = False
+    layout.operator("wm.blenderkit_login", text="Sign up",
+                    icon='URL').signup = True
+
+
 class VIEW3D_PT_blenderkit_unified(Panel):
     bl_category = "BlenderKit"
     bl_idname = "VIEW3D_PT_blenderkit_unified"
@@ -581,8 +586,7 @@ class VIEW3D_PT_blenderkit_unified(Panel):
 
         if len(user_preferences.api_key) < 20 and user_preferences.asset_counter > 20:
             if user_preferences.enable_oauth:
-                layout.operator("wm.blenderkit_login", text="Login/ Sign up",
-                                icon='URL')
+                draw_login_buttons(layout)
             else:
                 op = layout.operator("wm.url_open", text="Get your API Key",
                                      icon='QUESTION')
diff --git a/blenderkit/upload.py b/blenderkit/upload.py
index e3eaae482..4ef80aa87 100644
--- a/blenderkit/upload.py
+++ b/blenderkit/upload.py
@@ -16,19 +16,20 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+
 if "bpy" in locals():
-    import imp
-
-    imp.reload(asset_inspector)
-    imp.reload(paths)
-    imp.reload(utils)
-    imp.reload(search)
-    imp.reload(bg_blender)
-    imp.reload(autothumb)
-    imp.reload(version_checker)
-    imp.reload(ui_panels)
+    from importlib import reload
+
+    asset_inspector = reload(asset_inspector)
+    paths = reload(paths)
+    utils = reload(utils)
+    bg_blender = reload(bg_blender)
+    autothumb = reload(autothumb)
+    version_checker = reload(version_checker)
+    search = reload(searchr)
+    ui_panels = reload(ui_panels)
 else:
-    from blenderkit import asset_inspector, paths, utils, bg_blender, autothumb, version_checker, search,ui_panels
+    from blenderkit import asset_inspector, paths, utils, bg_blender, autothumb, version_checker, search, ui_panels
 
 import tempfile, os, subprocess, json, re
 
@@ -504,7 +505,7 @@ def get_upload_location(props):
 
 
 def check_storage_quota(props):
-    if props.is_private =='PUBLIC':
+    if props.is_private == 'PUBLIC':
         return True
 
     profile = bpy.context.window_manager.get('bkit profile')
@@ -739,8 +740,6 @@ class ModelUploadOperator(Operator):
                                                    ' after upload. '
                                                    'Click Ok to proceed.')
 
-
-
     def invoke(self, context, event):
         props = utils.get_upload_props()
 
diff --git a/blenderkit/upload_bg.py b/blenderkit/upload_bg.py
index a1cfaf11d..7a0dc28ca 100644
--- a/blenderkit/upload_bg.py
+++ b/blenderkit/upload_bg.py
@@ -16,13 +16,22 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+
+if "bpy" in locals():
+    from importlib import reload
+
+    paths = reload(paths)
+    append_link = reload(append_link)
+    bg_blender = reload(bg_blender)
+    utils = reload(utils)
+else:
+    from blenderkit import paths, append_link, bg_blender, utils
+
 import sys, json, os, time
 import requests
 import logging
 
 import bpy
-import addon_utils
-from blenderkit import paths, append_link, bg_blender, utils
 
 BLENDERKIT_EXPORT_DATA = sys.argv[-1]
 
diff --git a/blenderkit/utils.py b/blenderkit/utils.py
index bd2c7fa83..0cda06fbd 100644
--- a/blenderkit/utils.py
+++ b/blenderkit/utils.py
@@ -16,12 +16,14 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+
 if "bpy" in locals():
-    import imp
+    from importlib import reload
 
-    imp.reload(paths)
+    paths = reload(paths)
 else:
-    from blenderkit import paths, categories
+    from blenderkit import paths
+
 import bpy
 from mathutils import Vector
 import json
diff --git a/blenderkit/version_checker.py b/blenderkit/version_checker.py
index 055ab464c..f17f33741 100644
--- a/blenderkit/version_checker.py
+++ b/blenderkit/version_checker.py
@@ -16,8 +16,15 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+
+if "requests" in locals():
+    from importlib import reload
+
+    paths = reload(paths)
+else:
+    from blenderkit import paths
+
 import requests, os, json, threading
-from blenderkit import paths
 
 
 def get_addon_version():
-- 
GitLab