1# ##### BEGIN GPL LICENSE BLOCK ##### 2# 3# This program is free software; you can redistribute it and/or 4# modify it under the terms of the GNU General Public License 5# as published by the Free Software Foundation; either version 2 6# of the License, or (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program; if not, write to the Free Software Foundation, 15# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16# 17# ##### END GPL LICENSE BLOCK ##### 18 19import bpy, os, sys, tempfile, shutil 20from blenderkit import tasks_queue, ui 21 22_presets = os.path.join(bpy.utils.user_resource('SCRIPTS'), "presets") 23BLENDERKIT_LOCAL = "http://localhost:8001" 24BLENDERKIT_MAIN = "https://www.blenderkit.com" 25BLENDERKIT_DEVEL = "https://devel.blenderkit.com" 26BLENDERKIT_API = "/api/v1/" 27BLENDERKIT_REPORT_URL = "usage_report/" 28BLENDERKIT_USER_ASSETS = "/my-assets" 29BLENDERKIT_PLANS = "/plans/pricing/" 30BLENDERKIT_MANUAL = "https://youtu.be/1hVgcQhIAo8" 31BLENDERKIT_MODEL_UPLOAD_INSTRUCTIONS_URL = "https://www.blenderkit.com/docs/upload/" 32BLENDERKIT_MATERIAL_UPLOAD_INSTRUCTIONS_URL = "https://www.blenderkit.com/docs/uploading-material/" 33BLENDERKIT_BRUSH_UPLOAD_INSTRUCTIONS_URL = "https://www.blenderkit.com/docs/uploading-brush/" 34BLENDERKIT_LOGIN_URL = "https://www.blenderkit.com/accounts/login" 35BLENDERKIT_OAUTH_LANDING_URL = "/oauth-landing/" 36BLENDERKIT_SIGNUP_URL = "https://www.blenderkit.com/accounts/register" 37BLENDERKIT_SETTINGS_FILENAME = os.path.join(_presets, "bkit.json") 38 39def cleanup_old_folders(): 40 '''function to clean up any historical folders for BlenderKit. By now removes the temp folder.''' 41 orig_temp = os.path.join(os.path.expanduser('~'), 'blenderkit_data', 'temp') 42 if os.path.isdir(orig_temp): 43 try: 44 shutil.rmtree(orig_temp) 45 except Exception as e: 46 print(e) 47 print("couldn't delete old temp directory") 48 49def get_bkit_url(): 50 # bpy.app.debug_value = 2 51 d = bpy.app.debug_value 52 # d = 2 53 if d == 1: 54 url = BLENDERKIT_LOCAL 55 elif d == 2: 56 url = BLENDERKIT_DEVEL 57 else: 58 url = BLENDERKIT_MAIN 59 return url 60 61 62def find_in_local(text=''): 63 fs = [] 64 for p, d, f in os.walk('.'): 65 for file in f: 66 if text in file: 67 fs.append(file) 68 return fs 69 70 71def get_api_url(): 72 return get_bkit_url() + BLENDERKIT_API 73 74 75def get_oauth_landing_url(): 76 return get_bkit_url() + BLENDERKIT_OAUTH_LANDING_URL 77 78def get_author_gallery_url(author_id): 79 return f'{get_bkit_url()}/asset-gallery?query=author_id:{author_id}' 80 81 82def default_global_dict(): 83 from os.path import expanduser 84 home = expanduser("~") 85 return home + os.sep + 'blenderkit_data' 86 87 88def get_categories_filepath(): 89 tempdir = get_temp_dir() 90 return os.path.join(tempdir, 'categories.json') 91 92 93def get_temp_dir(subdir=None): 94 user_preferences = bpy.context.preferences.addons['blenderkit'].preferences 95 96 # tempdir = user_preferences.temp_dir 97 tempdir = os.path.join(tempfile.gettempdir(), 'bkit_temp') 98 if tempdir.startswith('//'): 99 tempdir = bpy.path.abspath(tempdir) 100 try: 101 if not os.path.exists(tempdir): 102 os.makedirs(tempdir) 103 if subdir is not None: 104 tempdir = os.path.join(tempdir, subdir) 105 if not os.path.exists(tempdir): 106 os.makedirs(tempdir) 107 cleanup_old_folders() 108 except: 109 tasks_queue.add_task((ui.add_report, ('Cache directory not found. Resetting Cache folder path.',))) 110 111 p = default_global_dict() 112 if p == user_preferences.global_dir: 113 message = 'Global dir was already default, plese set a global directory in addon preferences to a dir where you have write permissions.' 114 tasks_queue.add_task((ui.add_report, (message,))) 115 return None 116 user_preferences.global_dir = p 117 tempdir = get_temp_dir(subdir = subdir) 118 return tempdir 119 120 121def get_download_dirs(asset_type): 122 ''' get directories where assets will be downloaded''' 123 subdmapping = {'brush': 'brushes', 'texture': 'textures', 'model': 'models', 'scene': 'scenes', 124 'material': 'materials'} 125 126 user_preferences = bpy.context.preferences.addons['blenderkit'].preferences 127 dirs = [] 128 if user_preferences.directory_behaviour == 'BOTH' or 'GLOBAL': 129 ddir = user_preferences.global_dir 130 if ddir.startswith('//'): 131 ddir = bpy.path.abspath(ddir) 132 if not os.path.exists(ddir): 133 os.makedirs(ddir) 134 135 subdirs = ['brushes', 'textures', 'models', 'scenes', 'materials'] 136 for subd in subdirs: 137 subdir = os.path.join(ddir, subd) 138 if not os.path.exists(subdir): 139 os.makedirs(subdir) 140 if subdmapping[asset_type] == subd: 141 dirs.append(subdir) 142 if ( 143 user_preferences.directory_behaviour == 'BOTH' or user_preferences.directory_behaviour == 'LOCAL') and bpy.data.is_saved: # it's important local get's solved as second, since for the linking process only last filename will be taken. For download process first name will be taken and if 2 filenames were returned, file will be copied to the 2nd path. 144 ddir = user_preferences.project_subdir 145 if ddir.startswith('//'): 146 ddir = bpy.path.abspath(ddir) 147 if not os.path.exists(ddir): 148 os.makedirs(ddir) 149 150 subdirs = ['textures', 'models', 'scenes', 'materials'] # brushes get stored only globally. 151 for subd in subdirs: 152 subdir = os.path.join(ddir, subd) 153 if not os.path.exists(subdir): 154 os.makedirs(subdir) 155 if subdmapping[asset_type] == subd: 156 dirs.append(subdir) 157 158 return dirs 159 160 161def slugify(slug): 162 """ 163 Normalizes string, converts to lowercase, removes non-alpha characters, 164 and converts spaces to hyphens. 165 """ 166 import unicodedata, re 167 slug = slug.lower() 168 slug = slug.replace('.', '_') 169 slug = slug.replace('"', '') 170 slug = slug.replace(' ', '_') 171 # import re 172 # slug = unicodedata.normalize('NFKD', slug) 173 # slug = slug.encode('ascii', 'ignore').lower() 174 slug = re.sub(r'[^a-z0-9]+.- ', '-', slug).strip('-') 175 slug = re.sub(r'[-]+', '-', slug) 176 slug = re.sub(r'/', '_', slug) 177 return slug 178 179 180def extract_filename_from_url(url): 181 if url is not None: 182 imgname = url.split('/')[-1] 183 imgname = imgname.split('?')[0] 184 return imgname 185 return '' 186 187 188def get_download_filenames(asset_data): 189 dirs = get_download_dirs(asset_data['assetType']) 190 file_names = [] 191 # fn = asset_data['file_name'].replace('blend_', '') 192 if asset_data.get('url') is not None: 193 # this means asset is already in scene and we don't need to check 194 195 fn = extract_filename_from_url(asset_data['url']) 196 fn.replace('_blend', '') 197 n = slugify(asset_data['name']) + '_' + fn 198 # n = 'x.blend' 199 # strs = (n, asset_data['name'], asset_data['file_name']) 200 for d in dirs: 201 file_name = os.path.join(d, n) 202 file_names.append(file_name) 203 return file_names 204 205 206def delete_asset_debug(asset_data): 207 from blenderkit import download 208 user_preferences = bpy.context.preferences.addons['blenderkit'].preferences 209 api_key = user_preferences.api_key 210 211 download.get_download_url(asset_data, download.get_scene_id(), api_key) 212 213 file_names = get_download_filenames(asset_data) 214 for f in file_names: 215 if os.path.isfile(f): 216 try: 217 print(f) 218 os.remove(f) 219 except: 220 e = sys.exc_info()[0] 221 print(e) 222 pass; 223 224 225def get_clean_filepath(): 226 script_path = os.path.dirname(os.path.realpath(__file__)) 227 subpath = "blendfiles" + os.sep + "cleaned.blend" 228 cp = os.path.join(script_path, subpath) 229 return cp 230 231 232def get_thumbnailer_filepath(): 233 script_path = os.path.dirname(os.path.realpath(__file__)) 234 # fpath = os.path.join(p, subpath) 235 subpath = "blendfiles" + os.sep + "thumbnailer.blend" 236 return os.path.join(script_path, subpath) 237 238 239def get_material_thumbnailer_filepath(): 240 script_path = os.path.dirname(os.path.realpath(__file__)) 241 # fpath = os.path.join(p, subpath) 242 subpath = "blendfiles" + os.sep + "material_thumbnailer_cycles.blend" 243 return os.path.join(script_path, subpath) 244 """ 245 for p in bpy.utils.script_paths(): 246 testfname= os.path.join(p, subpath)#p + '%saddons%sobject_fracture%sdata.blend' % (s,s,s) 247 if os.path.isfile( testfname): 248 fname=testfname 249 return(fname) 250 return None 251 """ 252 253 254def get_addon_file(subpath=''): 255 script_path = os.path.dirname(os.path.realpath(__file__)) 256 # fpath = os.path.join(p, subpath) 257 return os.path.join(script_path, subpath) 258 259 260def get_addon_thumbnail_path(name): 261 script_path = os.path.dirname(os.path.realpath(__file__)) 262 # fpath = os.path.join(p, subpath) 263 ext = name.split('.')[-1] 264 next = '' 265 if not (ext == 'jpg' or ext == 'png'): # already has ext? 266 next = '.jpg' 267 subpath = "thumbnails" + os.sep + name + next 268 return os.path.join(script_path, subpath) 269