3434 IntProperty ,
3535 PointerProperty )
3636
37- from .io import *
38- from .io .imp .gltf2_io_gltf import *
39- from .blender .imp .gltf2_blender_gltf import *
40- from .blender .blender_version import Version
41-
42-
43- # Blender 2.79 has been shipped with openssl version 0.9.8 which uses a TLS protocol
44- # that is now blocked for security reasons on websites (github.com for example)
45- # In order to allow communication with github.com and other websites, the code will intend
46- # to use the updated openssl version distributed with the addon.
47- # Note: Blender 2.8 will have a more recent openssl version. This fix is only for 2.79 and olders
48- if bpy .app .version < (2 , 80 , 0 ) and not bpy .app .build_platform == b'Windows' :
49- try :
50- sslib_path = None
51- if bpy .app .build_platform == b'Darwin' :
52- sslib_path = os .path .join (os .path .dirname (__file__ ), 'dependencies/_ssl.cpython-35m-darwin.so' )
53- elif bpy .app .build_platform == b'Linux' :
54- sslib_path = os .path .join (os .path .dirname (__file__ ), '/io_sketchfab_plugin/_ssl.cpython-35m-x86_64-linux-gnu.so' )
55-
56- import importlib .util
57- spec = importlib .util .spec_from_file_location ("_ssl" , sslib_path )
58- new_ssl = importlib .util .module_from_spec (spec )
59- spec .loader .exec_module (new_ssl )
60-
61-
62- from importlib import reload
63- import ssl
64- reload (ssl )
65- from requests .packages .urllib3 .util import ssl_
66- reload (ssl_ )
67- print ('SSL python module has been successfully overriden by Sketchfab addon' )
68- print ('It might fix other addons having the same refused TLS protocol issue' )
69- except Exception as e :
70- print (e )
71- print ("Failed to override SSL lib. The plugin will not be able to check for updates" )
72-
73-
7437bl_info = {
7538 'name' : 'Sketchfab Plugin' ,
7639 'description' : 'Browse and download free Sketchfab downloadable models' ,
7740 'author' : 'Sketchfab' ,
7841 'license' : 'APACHE2' ,
7942 'deps' : '' ,
80- 'version' : (1 , 5 , 0 ),
43+ 'version' : (1 , 6 , 0 ),
8144 "blender" : (2 , 80 , 0 ),
8245 'location' : 'View3D > Tools > Sketchfab' ,
8346 'warning' : '' ,
@@ -105,8 +68,8 @@ class Config:
10568 SKETCHFAB_REPORT_URL = 'https://help.sketchfab.com/hc/en-us/requests/new?type=exporters&subject=Blender+Plugin'
10669
10770 SKETCHFAB_URL = 'https://sketchfab.com'
108- DUMMY_CLIENTID = 'hGC7unF4BHyEB0s7Orz5E1mBd3LluEG0ILBiZvF9'
109- SKETCHFAB_OAUTH = SKETCHFAB_URL + '/oauth2/token/?grant_type=password&client_id=' + DUMMY_CLIENTID
71+ CLIENTID = 'hGC7unF4BHyEB0s7Orz5E1mBd3LluEG0ILBiZvF9'
72+ SKETCHFAB_OAUTH = SKETCHFAB_URL + '/oauth2/token/'
11073 SKETCHFAB_API = 'https://api.sketchfab.com'
11174 SKETCHFAB_SEARCH = SKETCHFAB_API + '/v3/search'
11275 SKETCHFAB_MODEL = SKETCHFAB_API + '/v3/models'
@@ -244,12 +207,6 @@ def get_thumbnail_url(thumbnails_json):
244207 return min_thumbnail
245208 return best_thumbnail
246209
247- def make_model_name (gltf_data ):
248- if 'title' in gltf_data .asset .extras :
249- return gltf_data .asset .extras ['title' ]
250-
251- return 'GLTFModel'
252-
253210 def setup_plugin ():
254211 if not os .path .exists (Config .SKETCHFAB_THUMB_DIR ):
255212 os .makedirs (Config .SKETCHFAB_THUMB_DIR )
@@ -432,6 +389,7 @@ def __init__(self):
432389 self .next_results_url = None
433390 self .prev_results_url = None
434391 self .user_orgs = []
392+ self .user_has_orgs = False
435393 self .active_org = None
436394 self .use_org_profile = False
437395
@@ -473,6 +431,7 @@ def logout(self):
473431 #pprops.search_domain = "DEFAULT"
474432
475433 self .user_orgs = []
434+ self .user_has_orgs = False
476435 self .active_org = None
477436 self .use_org_profile = False
478437 props .use_org_profile = False
@@ -495,7 +454,7 @@ def parse_user_info(self, r, *args, **kargs):
495454 self .username = user_data ['username' ]
496455 self .display_name = user_data ['displayName' ]
497456 self .plan_type = user_data ['account' ]
498- requests .get (Config .SKETCHFAB_ME + "/orgs" , headers = self .headers , hooks = {'response' : self .parse_orgs_info })
457+ requests .get (Config .SKETCHFAB_ME + "/orgs" , headers = self .headers , hooks = {'response' : self .on_user_orgs_check })
499458 else :
500459 print ('\n Invalid access or API token\n You can get your API token here:\n https://sketchfab.com/settings/password\n ' )
501460 set_login_status ('ERROR' , 'Failed to authenticate' )
@@ -504,6 +463,14 @@ def parse_user_info(self, r, *args, **kargs):
504463 self .api_token = ''
505464 self .headers = {}
506465
466+ def request_user_orgs (self ):
467+ if not self .active_org :
468+ requests .get (Config .SKETCHFAB_ME + "/orgs" , headers = self .headers , hooks = {'response' : self .parse_orgs_info })
469+ pass
470+
471+ def on_user_orgs_check (self , r , * args , ** kargs ):
472+ self .user_has_orgs = bool ((r .status_code == 200 ) and len (r .json ().get ("results" , [])))
473+
507474 def parse_orgs_info (self , r , * args , ** kargs ):
508475 """
509476 Get and store information about user's orgs, and its orgs projects
@@ -564,6 +531,7 @@ def parse_projects_info(r, *args, **kargs):
564531 # Set the first org as active
565532 if len (self .user_orgs ):
566533 self .active_org = self .user_orgs [0 ]
534+ self .user_has_orgs = True
567535
568536 # Iterate on all orgs (not just the 24 first)
569537 if orgs_data ["next" ] is not None :
@@ -716,9 +684,11 @@ def handle_download(self, r, *args, **kwargs):
716684 skfb_model .download_url = gltf ['url' ]
717685 skfb_model .time_url_requested = time .time ()
718686 skfb_model .url_expires = gltf ['expires' ]
719- self .get_archive (gltf ['url' ])
687+ self .get_archive (gltf ['url' ], skfb_model .title )
688+ else :
689+ ShowMessage ("ERROR" , "Cannot retrieve information for this model" , "" )
720690
721- def get_archive (self , url ):
691+ def get_archive (self , url , title ):
722692 if url is None :
723693 print ('Url is None' )
724694 return
@@ -755,7 +725,7 @@ def get_archive(self, url):
755725 gltf_path , gltf_zip = unzip_archive (archive_path )
756726 if gltf_path :
757727 try :
758- import_model (gltf_path , uid )
728+ import_model (gltf_path , uid , title )
759729 except Exception as e :
760730 import traceback
761731 print (traceback .format_exc ())
@@ -826,6 +796,8 @@ def update_tr(self, context):
826796
827797def get_user_orgs (self , context ):
828798 api = get_sketchfab_props ().skfb_api
799+ if not api .user_has_orgs :
800+ api .request_user_orgs ()
829801 return [(org ["uid" ], org ["displayName" ], "" ) for org in api .user_orgs ]
830802
831803def get_org_projects (self , context ):
@@ -837,7 +809,7 @@ def get_available_search_domains(self, context):
837809
838810 search_domains = [domain for domain in Config .SKETCHFAB_SEARCH_DOMAIN ]
839811
840- if len ( api .user_orgs ) and api .use_org_profile :
812+ if api .user_has_orgs and api .use_org_profile :
841813 search_domains = [
842814 ("ACTIVE_ORG" , "Active Organization" , api .active_org ["displayName" ], 0 )
843815 ]
@@ -856,6 +828,12 @@ def refresh_orgs(self, context):
856828 api = props .skfb_api
857829
858830 api .use_org_profile = pprops .use_org_profile
831+
832+ if api .user_has_orgs and not api .active_org :
833+ bpy .context .window .cursor_set ("WAIT" )
834+ api .request_user_orgs ()
835+ bpy .context .window .cursor_set ("DEFAULT" )
836+
859837 orgs = [org for org in api .user_orgs if org ["uid" ] == pprops .active_org ]
860838 api .active_org = orgs [0 ] if len (orgs ) else None
861839
@@ -875,7 +853,7 @@ def refresh_orgs(self, context):
875853
876854def get_sorting_options (self , context ):
877855 api = get_sketchfab_props ().skfb_api
878- if len ( api .user_orgs ) and api .use_org_profile :
856+ if api .user_has_orgs and api .use_org_profile :
879857 return (
880858 ('RELEVANCE' , "Relevance" , "" ),
881859 ('RECENT' , "Recent" , "" )
@@ -1183,8 +1161,8 @@ def async_func(*args, **kwargs):
11831161 return async_func
11841162
11851163
1186- def import_model (gltf_path , uid ):
1187- bpy .ops .wm .import_modal ('INVOKE_DEFAULT' , gltf_path = gltf_path , uid = uid )
1164+ def import_model (gltf_path , uid , title ):
1165+ bpy .ops .wm .import_modal ('INVOKE_DEFAULT' , gltf_path = gltf_path , uid = uid , title = title )
11881166
11891167
11901168def build_search_request (query , pbr , animated , staffpick , face_count , category , sort_by ):
@@ -1378,8 +1356,13 @@ def invoke(self, context, event):
13781356 context .window_manager .modal_handler_add (self )
13791357 login_props = get_sketchfab_login_props ()
13801358 if (login_props .use_mail ):
1381- url = '{}&username={}&password={}' .format (Config .SKETCHFAB_OAUTH , urllib .parse .quote_plus (login_props .email ), urllib .parse .quote_plus (login_props .password ))
1382- requests .post (url , hooks = {'response' : self .handle_mail_login })
1359+ data = {
1360+ 'grant_type' : 'password' ,
1361+ 'client_id' : Config .CLIENTID ,
1362+ 'username' : login_props .email ,
1363+ 'password' : login_props .password ,
1364+ }
1365+ requests .post (Config .SKETCHFAB_OAUTH , data = data , hooks = {'response' : self .handle_mail_login })
13831366 else :
13841367 self .handle_token_login (login_props .api_token )
13851368 except Exception as e :
@@ -1397,33 +1380,28 @@ class ImportModalOperator(bpy.types.Operator):
13971380
13981381 gltf_path : StringProperty ()
13991382 uid : StringProperty ()
1383+ title : StringProperty ()
14001384
14011385 def execute (self , context ):
14021386 print ('IMPORT' )
14031387 return {'FINISHED' }
14041388
14051389 def modal (self , context , event ):
14061390 if bpy .context .scene .render .engine not in ["CYCLES" , "BLENDER_EEVEE" ]:
1407- bpy .context .scene .render .engine = Version .ENGINE
1408- gltf_importer = glTFImporter (self .gltf_path )
1409- gltf_importer .read ()
1410-
1391+ bpy .context .scene .render .engine = "BLENDER_EEVEE"
14111392 try :
14121393 old_objects = [o .name for o in bpy .data .objects ] # Get the current objects inorder to find the new node hierarchy
1413- BlenderGlTF . create ( gltf_importer )
1394+ bpy . ops . import_scene . gltf ( filepath = self . gltf_path )
14141395 set_import_status ('' )
14151396 Utils .clean_downloaded_model_dir (self .uid )
1416- root_name = Utils .make_model_name (gltf_importer .data )
1417- Utils .clean_node_hierarchy ([o for o in bpy .data .objects if o .name not in old_objects ], root_name )
1397+ Utils .clean_node_hierarchy ([o for o in bpy .data .objects if o .name not in old_objects ], self .title )
14181398 return {'FINISHED' }
14191399 except Exception :
14201400 import traceback
14211401 print (traceback .format_exc ())
14221402 set_import_status ('' )
14231403 return {'FINISHED' }
14241404
1425- return {'RUNNING_MODAL' }
1426-
14271405 def invoke (self , context , event ):
14281406 context .window_manager .modal_handler_add (self )
14291407 set_import_status ('Importing...' )
@@ -1524,7 +1502,7 @@ def draw(self, context):
15241502
15251503 self .layout .enabled = get_plugin_enabled () and api .is_user_logged ()
15261504
1527- if not api .user_orgs :
1505+ if not api .user_has_orgs :
15281506 self .layout .label (text = "You are not part of an organization" , icon = 'INFO' )
15291507 self .layout .operator ("wm.url_open" , text = 'Learn about Sketchfab for Teams' ).url = "https://sketchfab.com/features/teams"
15301508 else :
@@ -2134,7 +2112,7 @@ def upload(filepath, filename):
21342112 else :
21352113
21362114 # Org or not
2137- if len ( api .user_orgs ) and api .use_org_profile :
2115+ if api .user_has_orgs and api .use_org_profile :
21382116 uploadUrl = "%s/%s/models" % (Config .SKETCHFAB_ORGS , api .active_org ["uid" ])
21392117 _data ["orgProject" ] = props .active_project
21402118 else :
@@ -2395,7 +2373,7 @@ def check_plugin_version(request, *args, **kwargs):
23952373
23962374def register ():
23972375 sketchfab_icon = bpy .utils .previews .new ()
2398- icons_dir = os .path .join ( os . path . dirname (__file__ ), "resources" )
2376+ icons_dir = os .path .dirname (__file__ )
23992377 sketchfab_icon .load ("skfb" , os .path .join (icons_dir , "logo.png" ), 'IMAGE' )
24002378 sketchfab_icon .load ("0" , os .path .join (icons_dir , "placeholder.png" ), 'IMAGE' )
24012379
0 commit comments