BlenderKit: upload reworked.

Don't save .blend file , some users didn't like this.
Re-upload enables only thumbnail updates.
Mark for validation operator removed(was removed from UI several versions ago)
ModelUploadOperator renamed to UploadOperator, since it's used for all asset types anyway.
Skip .blend preparation in case of thumbnail reupload only
This commit is contained in:
Vilém Duha 2019-08-10 23:37:57 +02:00
parent 2b787dcb98
commit 30660b7d90
3 changed files with 134 additions and 159 deletions

View File

@ -110,27 +110,27 @@ def draw_upload_common(layout, props, asset_type, context):
if props.asset_base_id == '':
optext = 'Upload %s' % asset_type.lower()
else:
optext = 'Reupload %s (with thumbnail)' % asset_type.lower()
op = layout.operator("object.blenderkit_upload", text=optext, icon='EXPORT')
op.asset_type = asset_type
op.as_new = False
op = layout.operator("object.blenderkit_upload", text=optext, icon='EXPORT')
op.asset_type = asset_type
if props.asset_base_id != '':
op = layout.operator("object.blenderkit_upload", text='Reupload only metadata', icon='EXPORT')
op = layout.operator("object.blenderkit_upload", text='Reupload asset', icon='EXPORT')
op.asset_type = asset_type
op.metadata_only = True
op.reupload = True
op = layout.operator("object.blenderkit_upload", text='Upload as new asset', icon='EXPORT')
op.asset_type = asset_type
op.as_new = True
# layout.label(text = 'asset id, overwrite only for reuploading')
if props.asset_base_id != '':
row = layout.row()
op.reupload = False
row.prop(props, 'asset_base_id', icon='FILE_TICK')
# layout.operator("object.blenderkit_mark_for_validation", icon='EXPORT')
# layout.label(text = 'asset id, overwrite only for reuploading')
row = layout.row()
row.enabled = False
row.prop(props, 'asset_base_id', icon='FILE_TICK')
row = layout.row()
row.enabled = False
row.prop(props, 'id', icon='FILE_TICK')
layout.prop(props, 'category')
if asset_type == 'MODEL' and props.subcategory != '': # by now block this for other asset types.

View File

@ -537,7 +537,7 @@ def auto_fix(asset_type=''):
asset.name = props.name
def start_upload(self, context, asset_type, as_new, metadata_only):
def start_upload(self, context, asset_type, reupload, upload_set):
'''start upload process, by processing data'''
props = utils.get_upload_props()
storage_quota_ok = check_storage_quota(props)
@ -569,7 +569,7 @@ def start_upload(self, context, asset_type, as_new, metadata_only):
self.report({'ERROR_INVALID_INPUT'}, props.report)
return {'CANCELLED'}
if as_new:
if not reupload:
props.asset_base_id = ''
props.id = ''
export_data, upload_data, eval_path_computing, eval_path_state, eval_path, props = get_upload_data(self, context,
@ -595,11 +595,12 @@ def start_upload(self, context, asset_type, as_new, metadata_only):
'export_data': export_data,
'upload_data': upload_data,
'debug_value': bpy.app.debug_value,
'upload_set': upload_set,
}
datafile = os.path.join(tempdir, BLENDERKIT_EXPORT_DATA_FILE)
# check if thumbnail exists:
if not metadata_only:
if 'THUMBNAIL' in upload_set:
if not os.path.exists(export_data["thumbnail_path"]):
props.upload_state = 'Thumbnail not found'
props.uploading = False
@ -616,7 +617,7 @@ def start_upload(self, context, asset_type, as_new, metadata_only):
if props.asset_base_id == '':
try:
r = requests.post(url, json=json_metadata, headers=headers, verify=True) # files = files,
props.upload_state = 'uploaded metadata'
ui.add_report('uploaded metadata')
utils.p(r.text)
except requests.exceptions.RequestException as e:
print(e)
@ -627,10 +628,10 @@ def start_upload(self, context, asset_type, as_new, metadata_only):
else:
url += props.id + '/'
try:
if not metadata_only:
if upload_set != ['METADATA']:
json_metadata["verificationStatus"] = "uploading"
r = requests.put(url, json=json_metadata, headers=headers, verify=True) # files = files,
props.upload_state = 'uploaded metadata'
ui.add_report('uploaded metadata')
# parse the request
# print('uploaded metadata')
# print(r.text)
@ -641,7 +642,7 @@ def start_upload(self, context, asset_type, as_new, metadata_only):
return {'CANCELLED'}
# props.upload_state = 'step 1'
if metadata_only:
if upload_set == ['METADATA']:
props.uploading = False
return {'FINISHED'}
@ -658,7 +659,9 @@ def start_upload(self, context, asset_type, as_new, metadata_only):
upload_data['assetBaseId'] = props.asset_base_id
upload_data['id'] = props.id
bpy.ops.wm.save_mainfile()
# bpy.ops.wm.save_mainfile()
# bpy.ops.wm.save_as_mainfile(filepath=filepath, compress=False, copy=True)
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)
@ -697,7 +700,7 @@ asset_types = (
)
class ModelUploadOperator(Operator):
class UploadOperator(Operator):
"""Tooltip"""
bl_idname = "object.blenderkit_upload"
bl_description = "Upload or re-upload asset + thumbnail + metadata"
@ -712,16 +715,27 @@ class ModelUploadOperator(Operator):
default="MODEL",
)
as_new: BoolProperty(
name="upload as new",
description="deletes asset id and uploads as new file",
reupload: BoolProperty(
name="reupload",
description="reupload but also draw so that it asks what to reupload",
default=False,
options={'SKIP_SAVE'}
)
metadata_only: BoolProperty(
name="upload metadata",
description="update only metadata",
metadata: BoolProperty(
name="metadata",
default=True,
options={'SKIP_SAVE'}
)
thumbnail: BoolProperty(
name="thumbnail",
default=False,
options={'SKIP_SAVE'}
)
main_file: BoolProperty(
name="main file",
default=False,
options={'SKIP_SAVE'}
)
@ -736,13 +750,24 @@ class ModelUploadOperator(Operator):
# 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:
# 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.metadata_only = False
self.main_file = True
props.name_changed = False
result = start_upload(self, context, self.asset_type, self.as_new, self.metadata_only)
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
@ -750,84 +775,32 @@ class ModelUploadOperator(Operator):
props = utils.get_upload_props()
layout = self.layout
if self.as_new:
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':
ui_panels.label_multiline(layout, text='Since version 1.0.24: '
'PUBLIC ASSETS ARE VALIDATED AUTOMATICALLY '
' after upload. '
'Click Ok to proceed.')
ui_panels.label_multiline(layout, text='public assets are validated several hours'
' or days after upload. ', width = 300)
def invoke(self, context, event):
props = utils.get_upload_props()
if self.as_new or props.is_private == 'PUBLIC':
if props.is_private == 'PUBLIC':
return context.window_manager.invoke_props_dialog(self)
else:
return self.execute(context)
class ModelMarkForValidation(Operator):
"""Tooltip"""
bl_idname = "object.blenderkit_mark_for_validation"
bl_description = "After this, model can be validated by our validators and \n then be part of the public database"
bl_label = "Mark for validation"
# type of upload - model, material, textures, e.t.c.
asset_type: EnumProperty(
name="type",
items=asset_types,
description="Type of upload",
default="MODEL",
)
@classmethod
def poll(cls, context):
props = utils.get_upload_props()
return bpy.context.active_object is not None and props.asset_base_id != ''
def execute(self, context):
result = mark_for_validation(self, context, self.asset_type)
return result
# TODO this is for upldating by creators, if they edit metadata on server or want to upload from older file version.
# class GetMetadataFromServer(Operator):
# """Tooltip"""
# bl_idname = "object.blenderkit_get_from_server"
# bl_description ="After this, model can be validated by our validators and \n then be part of the public database"
#
# bl_label = "Mark for validation"
#
# # type of upload - model, material, textures, e.t.c.
# asset_type : EnumProperty(
# name="type",
# items=asset_types,
# description="Type of upload",
# default="MODEL",
# )
#
# @classmethod
# def poll(cls, context):
# props = utils.get_upload_props()
# return bpy.context.active_object is not None and props.asset_base_id != ''
#
# def execute(self, context):
# result = mark_for_validation(self, context, self.asset_type)
#
# return result
def register_upload():
bpy.utils.register_class(ModelUploadOperator)
bpy.utils.register_class(ModelMarkForValidation)
bpy.utils.register_class(UploadOperator)
def unregister_upload():
bpy.utils.unregister_class(ModelUploadOperator)
bpy.utils.unregister_class(ModelMarkForValidation)
bpy.utils.unregister_class(UploadOperator)

View File

@ -73,57 +73,57 @@ class upload_in_chunks(object):
return self.totalsize
def upload_files(filepath, upload_data, files):
def upload_file(upload_data, f):
headers = utils.get_headers(upload_data['token'])
version_id = upload_data['id']
bg_blender.progress('uploading %s' % f['type'])
upload_info = {
'assetId': version_id,
'fileType': f['type'],
'fileIndex': f['index'],
'originalFilename': os.path.basename(f['file_path'])
}
upload_create_url = paths.get_api_url() + 'uploads/'
upload = requests.post(upload_create_url, json=upload_info, headers=headers, verify=True)
upload = upload.json()
chunk_size = 1024 * 256
# file gets uploaded here:
uploaded = False
# s3 upload is now the only option
for a in range(0, 5):
if not uploaded:
try:
upload_response = requests.put(upload['s3UploadUrl'],
data=upload_in_chunks(f['file_path'], chunk_size, f['type']),
stream=True, verify=True)
if upload_response.status_code == 200:
uploaded = True
else:
bg_blender.progress(f'Upload failed, retry. {a}')
except Exception as e:
bg_blender.progress('Upload %s failed, retrying' % f['type'])
time.sleep(1)
# confirm single file upload to bkit server
upload_done_url = paths.get_api_url() + 'uploads_s3/' + upload['id'] + '/upload-file/'
upload_response = requests.post(upload_done_url, headers=headers, verify=True)
bg_blender.progress('finished uploading')
return uploaded
def upload_files(upload_data, files):
uploaded_all = True
for f in files:
bg_blender.progress('uploading %s' % f['type'])
upload_info = {
'assetId': version_id,
'fileType': f['type'],
'fileIndex': f['index'],
'originalFilename': os.path.basename(f['file_path'])
}
upload_create_url = paths.get_api_url() + 'uploads/'
upload = requests.post(upload_create_url, json=upload_info, headers=headers, verify=True)
upload = upload.json()
# upheaders = {
# "accept": "application/json",
# "Authorization": "Bearer %s" % upload_data['token'],
# "Content-Type": "multipart/form-data",
# "Content-Disposition": 'form-data; name="file"; filename=%s' % f['file_path']
#
# }
chunk_size = 1024 * 256
# file gets uploaded here:
uploaded = False
# s3 upload is now the only option
for a in range(0, 5):
if not uploaded:
try:
upload_response = requests.put(upload['s3UploadUrl'],
data=upload_in_chunks(f['file_path'], chunk_size, f['type']),
stream=True, verify=True)
if upload_response.status_code == 200:
uploaded = True
else:
bg_blender.progress(f'Upload failed, retry. {a}')
except Exception as e:
bg_blender.progress('Upload %s failed, retrying' % f['type'])
time.sleep(1)
# confirm single file upload to bkit server
upload_done_url = paths.get_api_url() + 'uploads_s3/' + upload['id'] + '/upload-file/'
upload_response = requests.post(upload_done_url, headers=headers, verify=True)
uploaded = upload_file(upload_data, f)
if not uploaded:
uploaded_all = False
bg_blender.progress('finished uploading')
return uploaded_all
@ -134,15 +134,16 @@ if __name__ == "__main__":
if s.name != 'upload':
bpy.data.scenes.remove(s)
try:
# bg_blender.progress('preparing scene')
bg_blender.progress('preparing scene - link objects')
bg_blender.progress('preparing scene - append data')
with open(BLENDERKIT_EXPORT_DATA, 'r') as s:
data = json.load(s)
bpy.app.debug_value = data.get('debug_value', 0)
export_data = data['export_data']
upload_data = data['upload_data']
bpy.app.debug_value = data.get('debug_value', 0)
export_data = data['export_data']
upload_data = data['upload_data']
upload_set = data['upload_set']
if 'MAINFILE' in upload_set:
if export_data['type'] == 'MODEL':
obnames = export_data['models']
main_source, allobs = append_link.append_objects(file_name=data['source_filepath'],
@ -166,32 +167,33 @@ if __name__ == "__main__":
brushname = export_data['brush']
main_source = append_link.append_brush(file_name=data['source_filepath'], brushname=brushname)
bpy.ops.file.pack_all()
bpy.ops.file.pack_all()
# TODO fetch asset_id here
asset_id = main_source.blenderkit.asset_base_id
main_source.blenderkit.uploading = False
main_source.blenderkit.uploading = False
fpath = os.path.join(data['temp_dir'], upload_data['assetBaseId'] + '.blend')
fpath = os.path.join(data['temp_dir'], asset_id + '.blend')
bpy.ops.wm.save_as_mainfile(filepath=fpath, compress=True, copy=False)
os.remove(data['source_filepath'])
bpy.ops.wm.save_as_mainfile(filepath=fpath, compress=True, copy=False)
os.remove(data['source_filepath'])
bg_blender.progress('preparing scene - open files')
files = [{
files = []
if 'THUMBNAIL' in upload_set:
files.append({
"type": "thumbnail",
"index": 0,
"file_path": export_data["thumbnail_path"]
}, {
"type": "blend",
"index": 0,
"file_path": fpath
}]
})
if 'MAINFILE' in upload_set:
files.append({
"type": "blend",
"index": 0,
"file_path": fpath
})
bg_blender.progress('uploading')
uploaded = upload_files(fpath, upload_data, files)
uploaded = upload_files(upload_data, files)
if uploaded:
# mark on server as uploaded