Skip to content
Snippets Groups Projects
search.py 45.7 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 #####

Vilem Duha's avatar
Vilem Duha committed
if "bpy" in locals():
    from importlib import reload
    paths = reload(paths)
    utils = reload(utils)
    categories = reload(categories)
    ui = reload(ui)
    colors = reload(colors)
    bkit_oauth = reload(bkit_oauth)
    version_checker = reload(version_checker)
    tasks_queue = reload(tasks_queue)
    rerequests = reload(rerequests)
Vilem Duha's avatar
Vilem Duha committed
else:
    from blenderkit import paths, utils, categories, ui, colors, bkit_oauth, version_checker, tasks_queue, rerequests
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 tempfile
import json
import bpy

search_start_time = 0
prev_time = 0

Vilem Duha's avatar
Vilem Duha committed
def check_errors(rdata):
    if rdata.get('statusCode') == 401:
        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')
Vilem Duha's avatar
Vilem Duha committed
            return False, 'Missing or wrong api_key in addon preferences'
    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)
Vilem Duha's avatar
Vilem Duha committed
@persistent
def scene_load(context):
    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 and addon version'''
    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 \
                len(user_preferences.api_key) < 38 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 = ''
Vilem Duha's avatar
Vilem Duha committed
@bpy.app.handlers.persistent
    # this makes a first search after opening blender. showing latest assets.
    global first_time
    preferences = bpy.context.preferences.addons['blenderkit'].preferences
    if first_time:
        first_time = False
        if preferences.show_on_start:
            search()
        if preferences.tips_on_start:
            ui.get_largest_3dview()
            ui.update_ui_size(ui.active_area, ui.active_region)
            ui.add_report(text='BlenderKit Tip: ' + random.choice(rtips), timeout=12, color=colors.GREEN)
Vilém Duha's avatar
Vilém Duha committed
    # clipboard monitoring to search assets from web
    global last_clipboard
    if bpy.context.window_manager.clipboard != last_clipboard:
Vilém Duha's avatar
Vilém Duha committed
        last_clipboard =  bpy.context.window_manager.clipboard
Vilém Duha's avatar
Vilém Duha committed
        instr = 'asset_base_id:'
Vilém Duha's avatar
Vilém Duha committed
        # first check if contains asset id, then asset type
Vilém Duha's avatar
Vilém Duha committed
        if last_clipboard[:len(instr)] == instr:
            atstr = 'asset_type:'
            ati = last_clipboard.find(atstr)
Vilém Duha's avatar
Vilém Duha committed
            #this only checks if the asset_type keyword is there but let's the keywords update function do the parsing.
Vilém Duha's avatar
Vilém Duha committed
                search_props = utils.get_search_props()
                search_props.search_keywords = last_clipboard
                # don't run search after this - assigning to keywords runs the search_update function.
Vilém Duha's avatar
Vilém Duha committed

Vilem Duha's avatar
Vilem Duha committed
    global search_threads
Vilém Duha's avatar
Vilém Duha committed
    # don't do anything while dragging - this could switch asset during drag, and make results list length different,
    # causing a lot of throuble.
Vilem Duha's avatar
Vilem Duha committed
    if len(search_threads) == 0 or bpy.context.scene.blenderkitUI.dragging:
        return 1
Vilém Duha's avatar
Vilém Duha committed
    for thread in search_threads:
        # TODO this doesn't check all processes when one gets removed,
        # but most of the time only one is running anyway
Vilem Duha's avatar
Vilem Duha committed
        if not thread[0].is_alive():
            search_threads.remove(thread)  #
            icons_dir = thread[1]
            scene = bpy.context.scene
            # these 2 lines should update the previews enum and set the first result as active.
            s = bpy.context.scene
            asset_type = thread[2]
            if asset_type == 'model':
                props = scene.blenderkit_models
                json_filepath = os.path.join(icons_dir, 'model_searchresult.json')
                search_name = 'bkit model search'
            if asset_type == 'scene':
                props = scene.blenderkit_scene
                json_filepath = os.path.join(icons_dir, 'scene_searchresult.json')
                search_name = 'bkit scene search'
            if asset_type == 'material':
                props = scene.blenderkit_mat
                json_filepath = os.path.join(icons_dir, 'material_searchresult.json')
                search_name = 'bkit material search'
            if asset_type == 'brush':
                props = scene.blenderkit_brush
                json_filepath = os.path.join(icons_dir, 'brush_searchresult.json')
                search_name = 'bkit brush search'

            s[search_name] = []

            global reports
            if reports != '':
                props.report = str(reports)
                return .2
Loading
Loading full blame...