Skip to content
Snippets Groups Projects
search.py 53.3 KiB
Newer Older
Vilem Duha's avatar
Vilem Duha committed
# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

Vilém Duha's avatar
Vilém Duha committed
from blenderkit import paths, utils, categories, ui, colors, bkit_oauth, version_checker, tasks_queue, rerequests, \
    resolutions
Vilem Duha's avatar
Vilem Duha committed
import blenderkit
from bpy.app.handlers import persistent

from bpy.props import (  # TODO only keep the ones actually used when cleaning
    IntProperty,
    FloatProperty,
    FloatVectorProperty,
    StringProperty,
    EnumProperty,
    BoolProperty,
    PointerProperty,
)
from bpy.types import (
    Operator,
    Panel,
    AddonPreferences,
    PropertyGroup,
    UIList
)

import requests, os, random
import time
import threading
import platform
Vilem Duha's avatar
Vilem Duha committed
import bpy
Vilém Duha's avatar
Vilém Duha committed
import copy
Vilém Duha's avatar
Vilém Duha committed
import json
import math
import logging
bk_logger = logging.getLogger('blenderkit')

Vilem Duha's avatar
Vilem Duha committed
search_start_time = 0
prev_time = 0

Vilem Duha's avatar
Vilem Duha committed
def check_errors(rdata):
    if rdata.get('statusCode') and int(rdata.get('statusCode')) > 299:
        utils.p(rdata)
Vilem Duha's avatar
Vilem Duha committed
        if rdata.get('detail') == 'Invalid token.':
            user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
            if user_preferences.api_key != '':
                if user_preferences.enable_oauth:
                    bkit_oauth.refresh_token_thread()
                return False, rdata.get('detail')
            return False, 'Use login panel to connect your profile.'
        else:
            return False, rdata.get('detail')
Vilem Duha's avatar
Vilem Duha committed
    return True, ''


search_threads = []
thumb_sml_download_threads = {}
thumb_full_download_threads = {}
reports = ''

rtips = ['Click or drag model or material in scene to link/append ',
         "Please rate responsively and plentifully. This helps us distribute rewards to the authors.",
         "Click on brushes to link them into scene.",
         "All materials and brushes are free.",
         "Storage for public assets is unlimited.",
         "Locked models are available if you subscribe to Full plan.",
         "Login to upload your own models, materials or brushes.",
         "Use 'A' key over asset bar to search assets by same author.",
         "Use 'W' key over asset bar to open Authors webpage.", ]

    ''' this timer gets run every time the token needs refresh. It refreshes tokens and also categories.'''
    utils.p('refresh timer')
    user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
    fetch_server_data()
    categories.load_categories()

    return max(3600, user_preferences.api_key_life - 3600)
def update_ad(ad):
    if not ad.get('assetBaseId'):
        try:
            ad['assetBaseId'] = ad['asset_base_id']  # this should stay ONLY for compatibility with older scenes
            ad['assetType'] = ad['asset_type']  # this should stay ONLY for compatibility with older scenes
Vilém Duha's avatar
Vilém Duha committed
            ad['verificationStatus'] = ad[
                'verification_status']  # this should stay ONLY for compatibility with older scenes
            ad['author'] = {}
            ad['author']['id'] = ad['author_id']  # this should stay ONLY for compatibility with older scenes
            ad['canDownload'] = ad['can_download']  # this should stay ONLY for compatibility with older scenes
        except Exception as e:
            bk_logger.error('BLenderKit failed to update older asset data')
    return ad
def update_assets_data():  # updates assets data on scene load.
    '''updates some properties that were changed on scenes with older assets.
    The properties were mainly changed from snake_case to CamelCase to fit the data that is coming from the server.
    '''
    data = bpy.data

    datablocks = [
        bpy.data.objects,
        bpy.data.materials,
        bpy.data.brushes,
    ]
    for dtype in datablocks:
        for block in dtype:
            if block.get('asset_data') != None:
                update_ad(block['asset_data'])

    dicts = [
        'assets used',
        # 'assets rated',# assets rated stores only true/false, not asset data.
Vilém Duha's avatar
Vilém Duha committed
    for s in bpy.data.scenes:
Vilém Duha's avatar
Vilém Duha committed
            if not d:
                continue;

            for asset_id in d.keys():
                update_ad(d[asset_id])
Vilém Duha's avatar
Vilém Duha committed
                # bpy.context.scene['assets used'][ad] = ad
Vilem Duha's avatar
Vilem Duha committed
@persistent
def scene_load(context):
    '''
    Loads categories , checks timers registration, and updates scene asset data.
    Should (probably)also update asset data from server (after user consent)
    '''
Vilem Duha's avatar
Vilem Duha committed
    wm = bpy.context.window_manager
    fetch_server_data()
    categories.load_categories()
    if not bpy.app.timers.is_registered(refresh_token_timer):
        bpy.app.timers.register(refresh_token_timer, persistent=True, first_interval=36000)
Vilem Duha's avatar
Vilem Duha committed


def fetch_server_data():
    ''' download categories , profile, and refresh token if needed.'''
    if not bpy.app.background:
        user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
        api_key = user_preferences.api_key
        # Only refresh new type of tokens(by length), and only one hour before the token timeouts.
        if user_preferences.enable_oauth and \
Vilém Duha's avatar
Vilém Duha committed
                len(user_preferences.api_key) < 38 and len(user_preferences.api_key) > 0 and \
                user_preferences.api_key_timeout < time.time() + 3600:
            bkit_oauth.refresh_token_thread()
        if api_key != '' and bpy.context.window_manager.get('bkit profile') == None:
        if bpy.context.window_manager.get('bkit_categories') is None:
            categories.fetch_categories_thread(api_key)
Vilém Duha's avatar
Vilém Duha committed
last_clipboard = ''
def check_clipboard():
    '''
    Checks clipboard for an exact string containing asset ID.
    The string is generated on www.blenderkit.com as for example here:
    https://www.blenderkit.com/get-blenderkit/54ff5c85-2c73-49e9-ba80-aec18616a408/
    '''

    # clipboard monitoring to search assets from web
    if platform.system() != 'Linux':
        global last_clipboard
        if bpy.context.window_manager.clipboard != last_clipboard:
            last_clipboard = bpy.context.window_manager.clipboard
            instr = 'asset_base_id:'
            # first check if contains asset id, then asset type
            if last_clipboard[:len(instr)] == instr:
                atstr = 'asset_type:'
                ati = last_clipboard.find(atstr)
                # this only checks if the asset_type keyword is there but let's the keywords update function do the parsing.
                if ati > -1:
Loading
Loading full blame...