1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
20 from blenderkit
import paths
, utils
, tasks_queue
, rerequests
32 bk_logger
= logging
.getLogger('blenderkit')
35 def count_to_parent(parent
):
36 for c
in parent
['children']:
38 parent
['assetCount'] += c
['assetCount']
41 def fix_category_counts(categories
):
46 def filter_category(category
):
47 ''' filter categories with no assets, so they aren't shown in search panel'''
48 if category
['assetCount'] < 1:
52 for c
in category
['children']:
53 if filter_category(c
):
56 category
['children'].remove(c
)
59 def filter_categories(categories
):
60 for category
in categories
:
61 filter_category(category
)
64 def get_category_path(categories
, category
):
65 '''finds the category in all possible subcategories and returns the path to it'''
67 check_categories
= categories
[:]
69 while len(check_categories
) > 0:
70 ccheck
= check_categories
.pop()
71 # print(ccheck['name'])
72 if not ccheck
.get('children'):
75 for ch
in ccheck
['children']:
77 parents
[ch
['slug']] = ccheck
['slug']
79 if ch
['slug'] == category
:
80 category_path
= [ch
['slug']]
82 while parents
.get(slug
):
83 slug
= parents
.get(slug
)
85 category_path
.insert(0, slug
)
87 check_categories
.append(ch
)
90 def get_category(categories
, cat_path
=()):
91 for category
in cat_path
:
93 if c
['slug'] == category
:
94 categories
= c
['children']
95 if category
== cat_path
[-1]:
100 # def get_upload_asset_type(self):
102 # bpy.types.Object.blenderkit: 'model',
103 # bpy.types.Scene.blenderkit: 'scene',
104 # bpy.types.Image.blenderkit: 'hdr',
105 # bpy.types.Material.blenderkit: 'material',
106 # bpy.types.Brush.blenderkit: 'brush'
108 # asset_type = typemapper[type(self)]
111 def update_category_enums(self
, context
):
112 '''Fixes if lower level is empty - sets it to None, because enum value can be higher.'''
113 enums
= get_subcategory_enums(self
, context
)
114 if enums
[0][0] == 'NONE' and self
.subcategory
!= 'NONE':
115 self
.subcategory
= 'NONE'
118 def update_subcategory_enums(self
, context
):
119 '''Fixes if lower level is empty - sets it to None, because enum value can be higher.'''
120 enums
= get_subcategory1_enums(self
, context
)
121 if enums
[0][0] == 'NONE' and self
.subcategory1
!= 'NONE':
122 self
.subcategory1
= 'NONE'
125 def get_category_enums(self
, context
):
126 wm
= bpy
.context
.window_manager
127 props
= bpy
.context
.scene
.blenderkitUI
128 asset_type
= props
.asset_type
.lower()
129 # asset_type = self.asset_type#get_upload_asset_type(self)
130 asset_categories
= get_category(wm
['bkit_categories'], cat_path
=(asset_type
,))
132 for c
in asset_categories
['children']:
133 items
.append((c
['slug'], c
['name'], c
['description']))
135 items
.append(('NONE', '', 'no categories on this level defined'))
139 def get_subcategory_enums(self
, context
):
140 wm
= bpy
.context
.window_manager
141 props
= bpy
.context
.scene
.blenderkitUI
142 asset_type
= props
.asset_type
.lower()
144 if self
.category
!= '':
145 asset_categories
= get_category(wm
['bkit_categories'], cat_path
=(asset_type
, self
.category
,))
146 for c
in asset_categories
['children']:
147 items
.append((c
['slug'], c
['name'], c
['description']))
149 items
.append(('NONE', '', 'no categories on this level defined'))
150 # print('subcategory', items)
154 def get_subcategory1_enums(self
, context
):
155 wm
= bpy
.context
.window_manager
156 props
= bpy
.context
.scene
.blenderkitUI
157 asset_type
= props
.asset_type
.lower()
159 if self
.category
!= '' and self
.subcategory
!= '':
160 asset_categories
= get_category(wm
['bkit_categories'], cat_path
=(asset_type
, self
.category
, self
.subcategory
,))
162 for c
in asset_categories
['children']:
163 items
.append((c
['slug'], c
['name'], c
['description']))
165 items
.append(('NONE', '', 'no categories on this level defined'))
169 def copy_categories():
170 # this creates the categories system on only
171 tempdir
= paths
.get_temp_dir()
172 categories_filepath
= os
.path
.join(tempdir
, 'categories.json')
173 if not os
.path
.exists(categories_filepath
):
174 source_path
= paths
.get_addon_file(subpath
='data' + os
.sep
+ 'categories.json')
175 # print('attempt to copy categories from: %s to %s' % (categories_filepath, source_path))
177 shutil
.copy(source_path
, categories_filepath
)
179 print("couldn't copy categories file")
182 def load_categories():
184 tempdir
= paths
.get_temp_dir()
185 categories_filepath
= os
.path
.join(tempdir
, 'categories.json')
187 wm
= bpy
.context
.window_manager
189 with
open(categories_filepath
, 'r', encoding
='utf-8') as catfile
:
190 wm
['bkit_categories'] = json
.load(catfile
)
192 wm
['active_category'] = {
196 'MATERIAL': ['material'],
200 print('categories failed to read')
207 def fetch_categories(API_key
, force
=False):
208 url
= paths
.get_api_url() + 'categories/'
210 headers
= utils
.get_headers(API_key
)
212 tempdir
= paths
.get_temp_dir()
213 categories_filepath
= os
.path
.join(tempdir
, 'categories.json')
214 if os
.path
.exists(categories_filepath
):
215 catfile_age
= time
.time() - os
.path
.getmtime(categories_filepath
)
217 catfile_age
= 10000000
219 # global catfetch_counter
220 # catfetch_counter += 1
221 # bk_logger.debug('fetching categories: ', catfetch_counter)
222 # bk_logger.debug('age of cat file', catfile_age)
224 # read categories only once per day maximum, or when forced to do so.
225 if catfile_age
> 86400 or force
:
226 bk_logger
.debug('requesting categories from server')
227 r
= rerequests
.get(url
, headers
=headers
)
229 categories
= rdata
['results']
230 fix_category_counts(categories
)
231 # filter_categories(categories) #TODO this should filter categories for search, but not for upload. by now off.
232 with
open(categories_filepath
, 'w', encoding
='utf-8') as s
:
233 json
.dump(categories
, s
, ensure_ascii
=False, indent
=4)
234 tasks_queue
.add_task((load_categories
, ()))
235 except Exception as e
:
236 bk_logger
.debug('category fetching failed')
237 bk_logger
.exception(e
)
238 if not os
.path
.exists(categories_filepath
):
239 source_path
= paths
.get_addon_file(subpath
='data' + os
.sep
+ 'categories.json')
240 shutil
.copy(source_path
, categories_filepath
)
243 def fetch_categories_thread(API_key
, force
=False):
244 cat_thread
= threading
.Thread(target
=fetch_categories
, args
=([API_key
, force
]), daemon
=True)