Skip to content
Snippets Groups Projects
upload.py 47 KiB
Newer Older
  • Learn to ignore specific revisions
  •                         "verificationStatus": "uploaded"
                        }
    
                        url = paths.get_api_url() + 'assets/'
    
                        headers = utils.get_headers(self.upload_data['token'])
    
                        url += self.upload_data["id"] + '/'
    
                        r = rerequests.patch(url, json=confirm_data, headers=headers, verify=True)  # files = files,
    
                    self.end_upload('Upload finished successfully')
                else:
                    self.end_upload('Upload failed')
            except Exception as e:
                self.end_upload(e)
                print(e)
                return {'CANCELLED'}
    
    
    def check_missing_data(asset_type, props):
        '''
        checks if user did everything allright for particular assets and notifies him back if not.
        Parameters
        ----------
        asset_type
        props
    
        Returns
        -------
    
        '''
        if asset_type == 'MODEL':
            check_missing_data_model(props)
        if asset_type == 'SCENE':
            check_missing_data_scene(props)
        elif asset_type == 'MATERIAL':
            check_missing_data_material(props)
        elif asset_type == 'BRUSH':
            check_missing_data_brush(props)
    
    
    
    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.'''
    
    Vilem Duha's avatar
    Vilem Duha committed
        props = utils.get_upload_props()
    
    
        utils.name_update(props)
    
    
        storage_quota_ok = check_storage_quota(props)
        if not storage_quota_ok:
            self.report({'ERROR_INVALID_INPUT'}, props.report)
            return {'CANCELLED'}
    
    
    Vilem Duha's avatar
    Vilem Duha committed
        location = get_upload_location(props)
        props.upload_state = 'preparing upload'
    
        auto_fix(asset_type=asset_type)
    
    Vilem Duha's avatar
    Vilem Duha committed
        # 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
    
    Vilem Duha's avatar
    Vilem Duha committed
        if props.report != '':
            self.report({'ERROR_INVALID_INPUT'}, props.report)
            return {'CANCELLED'}
    
        if not reupload:
    
    Vilem Duha's avatar
    Vilem Duha committed
            props.asset_base_id = ''
            props.id = ''
    
    
        export_data, upload_data = get_upload_data(caller=self, context=context, asset_type=asset_type)
    
        # 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)
    
    Vilem Duha's avatar
    Vilem Duha committed
        return {'FINISHED'}
    
    
    asset_types = (
    
        ('MODEL', 'Model', 'Set of objects'),
        ('SCENE', 'Scene', 'Scene'),
        ('HDR', 'HDR', 'HDR image'),
        ('MATERIAL', 'Material', 'Any .blend Material'),
        ('TEXTURE', 'Texture', 'A texture, or texture set'),
        ('BRUSH', 'Brush', 'Brush, can be any type of blender brush'),
        ('ADDON', 'Addon', 'Addnon'),
    
    class UploadOperator(Operator):
    
    Vilem Duha's avatar
    Vilem Duha committed
        """Tooltip"""
        bl_idname = "object.blenderkit_upload"
        bl_description = "Upload or re-upload asset + thumbnail + metadata"
    
        bl_label = "BlenderKit asset upload"
    
    Vilém Duha's avatar
    Vilém Duha committed
        bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
    
    Vilem Duha's avatar
    Vilem Duha committed
    
        # type of upload - model, material, textures, e.t.c.
        asset_type: EnumProperty(
            name="Type",
            items=asset_types,
            description="Type of upload",
            default="MODEL",
        )
    
    
        reupload: BoolProperty(
            name="reupload",
            description="reupload but also draw so that it asks what to reupload",
            default=False,
            options={'SKIP_SAVE'}
        )
    
        metadata: BoolProperty(
            name="metadata",
            default=True,
            options={'SKIP_SAVE'}
        )
    
        thumbnail: BoolProperty(
            name="thumbnail",
    
    Vilem Duha's avatar
    Vilem Duha committed
            default=False,
            options={'SKIP_SAVE'}
        )
    
    
        main_file: BoolProperty(
            name="main file",
    
    Vilem Duha's avatar
    Vilem Duha committed
            default=False,
            options={'SKIP_SAVE'}
        )
    
        @classmethod
        def poll(cls, context):
    
            return utils.uploadable_asset_poll()
    
    Vilem Duha's avatar
    Vilem Duha committed
    
        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, )
    
    Vilém Duha's avatar
    Vilém Duha committed
    
    
            return {'FINISHED'}
    
    Vilém Duha's avatar
    Vilém Duha committed
    
    
    Vilem Duha's avatar
    Vilem Duha committed
        def draw(self, context):
    
    Vilem Duha's avatar
    Vilem Duha committed
            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()
    
    
    Vilém Duha's avatar
    Vilém Duha committed
            if not utils.user_logged_in():
    
                ui_panels.draw_not_logged_in(self, message='To upload assets you need to login/signup.')
    
    Vilém Duha's avatar
    Vilém Duha committed
                return {'CANCELLED'}
    
    
            if props.is_private == 'PUBLIC':
    
    Vilem Duha's avatar
    Vilem Duha committed
                return context.window_manager.invoke_props_dialog(self)
            else:
                return self.execute(context)
    
    
    
    Vilém Duha's avatar
    Vilém Duha committed
    class AssetDebugPrint(Operator):
        """Change verification status"""
        bl_idname = "object.blenderkit_print_asset_debug"
        bl_description = "BlenderKit print asset data for debug purposes"
        bl_label = "BlenderKit print asset data"
        bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
    
        # type of upload - model, material, textures, e.t.c.
        asset_id: StringProperty(
            name="asset id",
        )
    
        @classmethod
        def poll(cls, context):
            return True
    
        def execute(self, context):
            preferences = bpy.context.preferences.addons['blenderkit'].preferences
    
    
            if not bpy.context.window_manager['search results']:
    
    Vilém Duha's avatar
    Vilém Duha committed
                print('no search results found')
                return {'CANCELLED'};
            # update status in search results for validator's clarity
    
            sr = bpy.context.window_manager['search results']
            sro = bpy.context.window_manager['search results orig']['results']
    
    Vilém Duha's avatar
    Vilém Duha committed
    
            result = None
            for r in sr:
                if r['id'] == self.asset_id:
                    result = r.to_dict()
            if not result:
                for r in sro:
                    if r['id'] == self.asset_id:
                        result = r.to_dict()
            if not result:
                ad = bpy.context.active_object.get('asset_data')
                if ad:
                    result = ad.to_dict()
            if result:
    
                t = bpy.data.texts.new(result['name'])
                t.write(json.dumps(result, indent=4, sort_keys=True))
    
    Vilém Duha's avatar
    Vilém Duha committed
                print(json.dumps(result, indent=4, sort_keys=True))
            return {'FINISHED'}
    
    
    
    class AssetVerificationStatusChange(Operator):
        """Change verification status"""
        bl_idname = "object.blenderkit_change_status"
        bl_description = "Change asset ststus"
        bl_label = "Change verification status"
    
    Vilém Duha's avatar
    Vilém Duha committed
        bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
    
    
        # type of upload - model, material, textures, e.t.c.
        asset_id: StringProperty(
            name="asset id",
        )
    
        state: StringProperty(
            name="verification_status",
    
            default='uploaded'
    
        @classmethod
        def poll(cls, context):
            return True
    
        def draw(self, context):
            layout = self.layout
    
            # if self.state == 'deleted':
    
            layout.label(text='Really delete asset from BlenderKit online storage?')
            # layout.prop(self, 'state')
    
        def execute(self, context):
    
            preferences = bpy.context.preferences.addons['blenderkit'].preferences
    
    
            if not bpy.context.window_manager['search results']:
    
                return {'CANCELLED'};
    
    Vilém Duha's avatar
    Vilém Duha committed
            # update status in search results for validator's clarity
    
            sr = bpy.context.window_manager['search results']
            sro = bpy.context.window_manager['search results orig']['results']
    
    Vilém Duha's avatar
    Vilém Duha committed
    
            for r in sr:
                if r['id'] == self.asset_id:
    
                    r['verificationStatus'] = self.state
    
    Vilém Duha's avatar
    Vilém Duha committed
            for r in sro:
                if r['id'] == self.asset_id:
                    r['verificationStatus'] = self.state
    
    
            thread = threading.Thread(target=verification_status_change_thread,
                                      args=(self.asset_id, self.state, preferences.api_key))
            thread.start()
            return {'FINISHED'}
    
    
        def invoke(self, context, event):
    
            # print(self.state)
    
            if self.state == 'deleted':
    
                wm = context.window_manager
                return wm.invoke_props_dialog(self)
    
            return {'RUNNING_MODAL'}
    
    Vilem Duha's avatar
    Vilem Duha committed
    def register_upload():
    
        bpy.utils.register_class(UploadOperator)
    
        # bpy.utils.register_class(FastMetadataMenu)
        bpy.utils.register_class(FastMetadata)
    
    Vilém Duha's avatar
    Vilém Duha committed
        bpy.utils.register_class(AssetDebugPrint)
    
        bpy.utils.register_class(AssetVerificationStatusChange)
    
    Vilem Duha's avatar
    Vilem Duha committed
    
    
    def unregister_upload():
    
        bpy.utils.unregister_class(UploadOperator)
    
        # bpy.utils.unregister_class(FastMetadataMenu)
        bpy.utils.unregister_class(FastMetadata)
    
    Vilém Duha's avatar
    Vilém Duha committed
        bpy.utils.unregister_class(AssetDebugPrint)
    
        bpy.utils.unregister_class(AssetVerificationStatusChange)