def execute(self, context): bpy.ops.object.blenderkit_auto_tags() props = utils.get_upload_props() # in case of name change, we have to reupload everything, since the name is stored in blender file, # and is used for linking to scene if props.name_changed: # TODO: this needs to be replaced with new double naming scheme (metadata vs blend data) # print('has to reupload whole data, name has changed.') self.main_file = True props.name_changed = False upload_set = [] if not self.reupload: upload_set = ['METADATA', 'THUMBNAIL', 'MAINFILE'] else: if self.metadata: upload_set.append('METADATA') if self.thumbnail: upload_set.append('THUMBNAIL') if self.main_file: upload_set.append('MAINFILE') result = start_upload(self, context, self.asset_type, self.reupload, upload_set) return result
def draw(self, context): props = utils.get_upload_props() layout = self.layout if self.reupload: # layout.prop(self, 'metadata') layout.prop(self, 'main_file') layout.prop(self, 'thumbnail') if props.asset_base_id != '' and not self.reupload: layout.label(text="Really upload as new? ") layout.label( text="Do this only when you create a new asset from an old one." ) layout.label( text="For updates of thumbnail or model use reupload.") if props.is_private == 'PUBLIC': utils.label_multiline( layout, text='public assets are validated several hours' ' or days after upload. Remember always to ' 'test download your asset to a clean file' ' to see if it uploaded correctly.', width=300)
def invoke(self, context, event): props = utils.get_upload_props() if self.as_new or props.is_private == 'PUBLIC': return context.window_manager.invoke_props_dialog(self) else: return self.execute(context)
def execute(self, context): bpy.ops.object.blenderkit_auto_tags() props = utils.get_upload_props() # in case of name change, we have to reupload everything, since the name is stored in blender file, # and is used for linking to scene # if props.name_changed: # # TODO: this needs to be replaced with new double naming scheme (metadata vs blend data) # # print('has to reupload whole data, name has changed.') # self.main_file = True # props.name_changed = False upload_set = [] if not self.reupload: upload_set = ['METADATA', 'THUMBNAIL', 'MAINFILE'] else: if self.metadata: upload_set.append('METADATA') if self.thumbnail: upload_set.append('THUMBNAIL') if self.main_file: upload_set.append('MAINFILE') # this is accessed later in get_upload_data and needs to be written. # should pass upload_set all the way to it probably if 'MAINFILE' in upload_set: self.main_file = True result = start_upload(self, context, self.asset_type, self.reupload, upload_set=upload_set, ) if props.report != '': # self.report({'ERROR_INVALID_INPUT'}, props.report) self.report({'ERROR_INVALID_CONTEXT'}, props.report) return result
def draw(self, context): props = utils.get_upload_props() layout = self.layout if self.reupload: # layout.prop(self, 'metadata') layout.prop(self, 'main_file') layout.prop(self, 'thumbnail') if props.asset_base_id != '' and not self.reupload: layout.label(text="Really upload as new? ") layout.label(text="Do this only when you create a new asset from an old one.") layout.label(text="For updates of thumbnail or model use reupload.") if props.is_private == 'PUBLIC': if self.asset_type == 'MODEL': utils.label_multiline(layout, text='You marked the asset as public.\n' 'This means it will be validated by our team.\n\n' 'Please test your upload after it finishes:\n' '- Open a new file\n' '- Find the asset and download it\n' '- Check if it snaps correctly to surfaces\n' '- Check if it has all textures and renders as expected\n' '- Check if it has correct size in world units (for models)' , width=400) else: utils.label_multiline(layout, text='You marked the asset as public.\n' 'This means it will be validated by our team.\n\n' 'Please test your upload after it finishes:\n' '- Open a new file\n' '- Find the asset and download it\n' '- Check if it works as expected\n' , width=400)
def auto_fix(asset_type=''): #this applies various procedures to ensure coherency in the database. asset = utils.get_active_asset() props = utils.get_upload_props() if asset_type == 'MATERIAL': overrides.ensure_eevee_transparency(asset) asset.name = props.name
def invoke(self, context, event): props = utils.get_upload_props() if not utils.user_logged_in(): ui_panels.draw_not_logged_in(self, message='To upload assets you need to login/signup.') return {'CANCELLED'} if props.is_private == 'PUBLIC': return context.window_manager.invoke_props_dialog(self) else: return self.execute(context)
def draw(self, context): props = utils.get_upload_props() layout = self.layout if self.as_new: layout.label(text="Really upload as new? ") layout.label(text="Do this only when you create a new asset from an old one.") layout.label(text="For updates of thumbnail or model use reupload.") if props.is_private == 'PUBLIC': ui_panels.label_multiline(layout, text='Since this version (1.0.24), ' 'PUBLIC ASSETS ARE VALIDATED AUTOMATICALLY ' ' after upload. ' 'Click Ok to proceed.')
def execute(self, context): bpy.ops.object.blenderkit_auto_tags() props = utils.get_upload_props() # in case of name change, we have to reupload everything, since the name is stored in blender file, # and is used for linking to scene metadata_only = self.metadata_only if props.name_changed: # print('has to reupload whole data, name has changed.') self.metadata_only = False props.name_changed = False result = start_upload(self, context, self.asset_type, self.as_new, self.metadata_only) return result
def execute(self, context): s = bpy.context.scene cls = bpy.ops.object.convert.__class__ # first do the easy stuff...TODO all cases. props = utils.get_upload_props() if self.process_type == 'UPLOAD': props.uploading = False if self.process_type == 'THUMBNAILER': props.is_generating_thumbnail = False global blenderkit_bg_process # print('killing', self.process_source, self.process_type) # then go kill the process. this wasn't working for unsetting props and that was the reason for changing to the method above. processes = bg_processes for p in processes: tcom = p[1] # print(tcom.process_type, self.process_type) if tcom.process_type == self.process_type: source = eval(tcom.eval_path) kill = False #TODO HDR - add killing of process if source.bl_rna.name == 'Object' and self.process_source == 'MODEL': if source.name == bpy.context.active_object.name: kill = True if source.bl_rna.name == 'Scene' and self.process_source == 'SCENE': if source.name == bpy.context.scene.name: kill = True if source.bl_rna.name == 'Image' and self.process_source == 'HDR': ui_props = bpy.context.scene.blenderkitUI if source.name == ui_props.hdr_upload_image.name: kill = False if source.bl_rna.name == 'Material' and self.process_source == 'MATERIAL': if source.name == bpy.context.active_object.active_material.name: kill = True if source.bl_rna.name == 'Brush' and self.process_source == 'BRUSH': brush = utils.get_active_brush() if brush is not None and source.name == brush.name: kill = True if kill: estring = tcom.eval_path_computing + ' = False' exec(estring) processes.remove(p) tcom.proc.kill() return {'FINISHED'}
def execute(self, context): s = bpy.context.scene cls = bpy.ops.object.convert.__class__ # first do the easy stuff...TODO all cases. props = utils.get_upload_props() if self.process_type == 'UPLOAD': props.uploading = False if self.process_type == 'THUMBNAILER': props.is_generating_thumbnail = False global blenderkit_bg_process # print('killing', self.process_source, self.process_type) # then go kill the process. this wasn't working for unsetting props and that was the reason for changing to the method above. processes = bg_processes for p in processes: tcom = p[1] # print(tcom.process_type, self.process_type) if tcom.process_type == self.process_type: source = eval(tcom.eval_path) print(source.bl_rna.name, self.process_source) print(source.name) kill = False if source.bl_rna.name == 'Object' and self.process_source == 'MODEL': if source.name == bpy.context.active_object.name: kill = True if source.bl_rna.name == 'Material' and self.process_source == 'MATERIAL': if source.name == bpy.context.active_object.active_material.name: kill = True if source.bl_rna.name == 'Brush' and self.process_source == 'BRUSH': brush = utils.get_active_brush() if brush is not None and source.name == brush.name: kill = True if kill: estring = tcom.eval_path_computing + ' = False' exec (estring) processes.remove(p) tcom.proc.kill() return {'FINISHED'}
def mark_for_validation(self, context, asset_type): props = utils.get_upload_props() props.upload_state = 'marking for validation' user_preferences = bpy.context.preferences.addons['blenderkit'].preferences upload_data = { "verificationStatus": "ready" } url = paths.get_bkit_url() + 'assets/' headers = {"accept": "application/json", "Authorization": "Bearer %s" % user_preferences.api_key} url += props.id + '/' try: r = requests.patch(url, json=upload_data, headers=headers, verify=True) # files = files, props.upload_state = 'marked for validation' except requests.exceptions.RequestException as e: props.upload_state = str(e) props.uploading = False return {'CANCELLED'} return {'FINISHED'}
def poll(cls, context): props = utils.get_upload_props() return bpy.context.active_object is not None and props.asset_base_id != ''
def start_upload(self, context, asset_type, as_new, metadata_only): '''start upload process, by processing data''' props = utils.get_upload_props() storage_quota_ok = check_storage_quota(props) if not storage_quota_ok: self.report({'ERROR_INVALID_INPUT'}, props.report) return {'CANCELLED'} location = get_upload_location(props) props.upload_state = 'preparing upload' auto_fix(asset_type = asset_type) # do this for fixing long tags in some upload cases props.tags = props.tags[:] props.name = props.name.strip() # TODO move this to separate function # check for missing metadata if asset_type == 'MODEL': get_missing_data_model(props) if asset_type == 'SCENE': get_missing_data_scene(props) elif asset_type == 'MATERIAL': get_missing_data_material(props) elif asset_type == 'BRUSH': get_missing_data_brush(props) if props.report != '': self.report({'ERROR_INVALID_INPUT'}, props.report) return {'CANCELLED'} if as_new: props.asset_base_id = '' props.id = '' export_data, upload_data, eval_path_computing, eval_path_state, eval_path, props = get_upload_data(self, context, asset_type) # utils.pprint(upload_data) upload_data['parameters'] = params_to_dict( upload_data['parameters']) # weird array conversion only for upload, not for tooltips. binary_path = bpy.app.binary_path script_path = os.path.dirname(os.path.realpath(__file__)) basename, ext = os.path.splitext(bpy.data.filepath) # if not basename: # basename = os.path.join(basename, "temp") if not ext: ext = ".blend" tempdir = tempfile.mkdtemp() source_filepath = os.path.join(tempdir, "export_blenderkit" + ext) clean_file_path = paths.get_clean_filepath() data = { 'clean_file_path': clean_file_path, 'source_filepath': source_filepath, 'temp_dir': tempdir, 'export_data': export_data, 'upload_data': upload_data, 'debug_value': bpy.app.debug_value, } datafile = os.path.join(tempdir, BLENDERKIT_EXPORT_DATA_FILE) # check if thumbnail exists: if not os.path.exists(export_data["thumbnail_path"]): props.upload_state = 'Thumbnail not found' props.uploading = False return {'CANCELLED'} # first upload metadata to server, so it can be saved inside the current file url = paths.get_api_url() + 'assets/' headers = utils.get_headers(upload_data['token']) # upload_data['license'] = 'ovejajojo' json_metadata = upload_data # json.dumps(upload_data, ensure_ascii=False).encode('utf8') global reports if props.asset_base_id == '': try: r = requests.post(url, json=json_metadata, headers=headers, verify=True) # files = files, props.upload_state = 'uploaded metadata' utils.p(r.text) except requests.exceptions.RequestException as e: print(e) props.upload_state = str(e) props.uploading = False return {'CANCELLED'} else: url += props.id + '/' try: if not metadata_only: json_metadata["verificationStatus"] = "uploading" r = requests.put(url, json=json_metadata, headers=headers, verify=True) # files = files, props.upload_state = 'uploaded metadata' # parse the reqest # print('uploaded metadata') # print(r.text) except requests.exceptions.RequestException as e: print(e) props.upload_state = str(e) props.uploading = False return {'CANCELLED'} # props.upload_state = 'step 1' if metadata_only: props.uploading = False return {'FINISHED'} try: rj = r.json() if props.asset_base_id == '': props.asset_base_id = rj['assetBaseId'] props.id = rj['id'] upload_data['assetBaseId'] = props.asset_base_id upload_data['id'] = props.id bpy.ops.wm.save_mainfile() # fa props.uploading = True # save a copy of actual scene but don't interfere with the users models bpy.ops.wm.save_as_mainfile(filepath=source_filepath, compress=False, copy=True) with open(datafile, 'w') as s: json.dump(data, s) proc = subprocess.Popen([ binary_path, "--background", "-noaudio", clean_file_path, "--python", os.path.join(script_path, "upload_bg.py"), "--", datafile # ,filepath, tempdir ], bufsize=5000, stdout=subprocess.PIPE, stdin=subprocess.PIPE) bg_blender.add_bg_process(eval_path_computing=eval_path_computing, eval_path_state=eval_path_state, eval_path=eval_path, process_type='UPLOAD', process=proc, location=location) except Exception as e: props.upload_state = str(e) props.uploading = False return {'CANCELLED'} return {'FINISHED'}
def start_upload(self, context, asset_type, as_new, metadata_only): props = utils.get_upload_props() location = get_upload_location(props) props.upload_state = 'preparing upload' # do this for fixing long tags in some upload cases props.tags = props.tags[:] props.name = props.name.strip() # TODO move this to separate function # check for missing metadata if asset_type == 'MODEL': get_missing_data_model(props) if asset_type == 'SCENE': get_missing_data_scene(props) elif asset_type == 'MATERIAL': get_missing_data_material(props) elif asset_type == 'BRUSH': get_missing_data_brush(props) if props.report != '': self.report({'ERROR_INVALID_INPUT'}, props.report) return {'CANCELLED'} if as_new: props.asset_base_id = '' props.id = '' export_data, upload_data, eval_path_computing, eval_path_state, eval_path, props = get_upload_data(self, context, asset_type) # utils.pprint(upload_data) upload_data['parameters'] = params_to_dict( upload_data['parameters']) # weird array conversion only for upload, not for tooltips. binary_path = bpy.app.binary_path script_path = os.path.dirname(os.path.realpath(__file__)) basename, ext = os.path.splitext(bpy.data.filepath) # if not basename: # basename = os.path.join(basename, "temp") if not ext: ext = ".blend" tempdir = tempfile.mkdtemp() source_filepath = os.path.join(tempdir, "export_blenderkit" + ext) clean_file_path = paths.get_clean_filepath() data = { 'clean_file_path': clean_file_path, 'source_filepath': source_filepath, 'temp_dir': tempdir, 'export_data': export_data, 'upload_data': upload_data, 'debug_value': bpy.app.debug_value, } datafile = os.path.join(tempdir, BLENDERKIT_EXPORT_DATA_FILE) # check if thumbnail exists: if not os.path.exists(export_data["thumbnail_path"]): props.upload_state = 'Thumbnail not found' props.uploading = False return {'CANCELLED'} # first upload metadata to server, so it can be saved inside the current file url = paths.get_bkit_url() + 'assets/' headers = {"accept": "application/json", "Authorization": "Bearer %s" % upload_data['token']} # upload_data['license'] = 'ovejajojo' json_metadata = upload_data # json.dumps(upload_data, ensure_ascii=False).encode('utf8') global reports if props.asset_base_id == '': try: r = requests.post(url, json=json_metadata, headers=headers, verify=True) # files = files, props.upload_state = 'uploaded metadata' except requests.exceptions.RequestException as e: print(e) props.upload_state = str(e) props.uploading = False return {'CANCELLED'} else: url += props.id + '/' try: if not metadata_only: json_metadata["verificationStatus"] = "uploading" r = requests.put(url, json=json_metadata, headers=headers, verify=True) # files = files, props.upload_state = 'uploaded metadata' # parse the reqest # print('uploaded metadata') # print(r.text) except requests.exceptions.RequestException as e: print(e) props.upload_state = str(e) props.uploading = False return {'CANCELLED'} # props.upload_state = 'step 1' if metadata_only: props.uploading = False return {'FINISHED'} try: rj = r.json() if props.asset_base_id == '': props.asset_base_id = rj['assetBaseId'] props.id = rj['id'] upload_data['assetBaseId'] = props.asset_base_id upload_data['id'] = props.id bpy.ops.wm.save_mainfile() # fa props.uploading = True # save a copy of actual scene but don't interfere with the users models bpy.ops.wm.save_as_mainfile(filepath=source_filepath, compress=False, copy=True) with open(datafile, 'w') as s: json.dump(data, s) proc = subprocess.Popen([ binary_path, "--background", "-noaudio", clean_file_path, "--python", os.path.join(script_path, "upload_bg.py"), "--", datafile # ,filepath, tempdir ], bufsize=5000, stdout=subprocess.PIPE, stdin=subprocess.PIPE) bg_blender.add_bg_process(eval_path_computing=eval_path_computing, eval_path_state=eval_path_state, eval_path=eval_path, process_type='UPLOAD', process=proc, location=location) except Exception as e: props.upload_state = str(e) props.uploading = False return {'CANCELLED'} return {'FINISHED'}
def start_upload(self, context, asset_type, reupload, upload_set): '''start upload process, by processing data, then start a thread that cares about the rest of the upload.''' # fix the name first utils.name_update() props = utils.get_upload_props() storage_quota_ok = check_storage_quota(props) if not storage_quota_ok: self.report({'ERROR_INVALID_INPUT'}, props.report) return {'CANCELLED'} location = get_upload_location(props) props.upload_state = 'preparing upload' auto_fix(asset_type=asset_type) # do this for fixing long tags in some upload cases props.tags = props.tags[:] # check for missing metadata check_missing_data(asset_type, props) # if previous check did find any problems then if props.report != '': self.report({'ERROR_INVALID_INPUT'}, props.report) return {'CANCELLED'} if not reupload: props.asset_base_id = '' props.id = '' export_data, upload_data = get_upload_data(caller=self, context=context, asset_type=asset_type) # print(export_data) # print(upload_data) # check if thumbnail exists, generate for HDR: if 'THUMBNAIL' in upload_set: if asset_type == 'HDR': image_utils.generate_hdr_thumbnail() elif not os.path.exists(export_data["thumbnail_path"]): props.upload_state = 'Thumbnail not found' props.uploading = False return {'CANCELLED'} if upload_set == {'METADATA'}: props.upload_state = "Updating metadata. Please don't close Blender until upload finishes" else: props.upload_state = "Starting upload. Please don't close Blender until upload finishes" props.uploading = True # save a copy of the file for processing. Only for blend files basename, ext = os.path.splitext(bpy.data.filepath) if not ext: ext = ".blend" export_data['temp_dir'] = tempfile.mkdtemp() export_data['source_filepath'] = os.path.join(export_data['temp_dir'], "export_blenderkit" + ext) if asset_type != 'HDR': bpy.ops.wm.save_as_mainfile(filepath=export_data['source_filepath'], compress=False, copy=True) export_data['binary_path'] = bpy.app.binary_path export_data['debug_value'] = bpy.app.debug_value upload_thread = Uploader(upload_data=upload_data, export_data=export_data, upload_set=upload_set) upload_thread.start() upload_threads.append(upload_thread) return {'FINISHED'}