Fix #123682: extension repo URL/access token changes don't re-sync
When changing the URL or access token, re-synchronize remote data automatically. This changes automatic synchronization to use a background task that runs based on a timer instead of a modal operator since the operator is more intrusive and not so well suited to running based on changes to RNA.
This commit is contained in:
parent
2cc6de8f7e
commit
4712aca2a8
@ -269,41 +269,39 @@ def repos_to_notify():
|
||||
# Handlers
|
||||
|
||||
@bpy.app.handlers.persistent
|
||||
def extenion_repos_sync(*_):
|
||||
def extenion_repos_sync(repo, *_):
|
||||
# Ignore in background mode as this is for the UI to stay in sync.
|
||||
# Automated tasks must sync explicitly.
|
||||
if bpy.app.background:
|
||||
return
|
||||
|
||||
# This is called from operators (create or an explicit call to sync)
|
||||
# so calling a modal operator is "safe".
|
||||
if (active_repo := repo_active_or_none()) is None:
|
||||
return
|
||||
|
||||
print_debug("SYNC:", active_repo.name)
|
||||
print_debug("SYNC:", repo.name)
|
||||
# There may be nothing to upgrade.
|
||||
|
||||
if not active_repo.use_remote_url:
|
||||
if not repo.use_remote_url:
|
||||
return
|
||||
if not bpy.app.online_access:
|
||||
if not repo.remote_url.startswith("file://"):
|
||||
return
|
||||
|
||||
# NOTE: both `extensions.repo_sync_all` and `bl_extension_notify.update_non_blocking` can be used here.
|
||||
# Call the modal operator in this case as this handler is called after adding a repository.
|
||||
# The operator has the benefit of showing a progress bar and reporting errors.
|
||||
# Since this function is used after adding a new repository, it's important the user is aware of any
|
||||
# errors synchronizing data as there may be connection/access issues they need to resolve.
|
||||
if not bpy.ops.extensions.repo_sync_all.poll():
|
||||
print("skipping sync, poll failed")
|
||||
# Call the non-blocking update because the updates are queued and can be de-duplicated.
|
||||
# They're less intrusive as they don't use a modal operator.
|
||||
from .bl_extension_notify import update_non_blocking
|
||||
from .bl_extension_ops import extension_repos_read
|
||||
|
||||
repos_all = extension_repos_read()
|
||||
repos_notify = [repo_iter for repo_iter in repos_all if repo_iter.name == repo.name]
|
||||
|
||||
# The repository may be disabled or invalid for some other reason, in this case skip an update.
|
||||
if not repos_notify:
|
||||
return
|
||||
|
||||
from contextlib import redirect_stdout
|
||||
import io
|
||||
stdout = io.StringIO()
|
||||
update_non_blocking(repos_fn=lambda: [(repo_iter, True) for repo_iter in repos_notify], immediate=True)
|
||||
|
||||
with redirect_stdout(stdout):
|
||||
bpy.ops.extensions.repo_sync_all('INVOKE_DEFAULT', use_active_only=True)
|
||||
|
||||
if text := stdout.getvalue():
|
||||
repo_status_text.from_message("Sync \"{:s}\"".format(active_repo.name), text)
|
||||
# Without this the preferences wont show update text.
|
||||
from .bl_extension_ui import notify_info
|
||||
notify_info.update_show_in_preferences()
|
||||
|
||||
|
||||
@bpy.app.handlers.persistent
|
||||
|
@ -715,6 +715,23 @@ class notify_info:
|
||||
notify_info._update_state = True
|
||||
return in_progress
|
||||
|
||||
def update_show_in_preferences():
|
||||
"""
|
||||
An update was triggered externally (not from the interface).
|
||||
Without this call, the message in the preferences UI will not display.
|
||||
"""
|
||||
# Skip checking updates when:
|
||||
# - False, updates are running already no need to request displaying again.
|
||||
# - None, updates have not yet run, meaning they will be displayed when the preferences are next drawn.
|
||||
if notify_info._update_state is not True:
|
||||
return
|
||||
|
||||
# NOTE: we could assert `bl_extension_notify.update_in_progress` since it is expected
|
||||
# this function is called when updates have been started, however it's functionally a NOP
|
||||
# where this case is detected and the notification state will switch to being "complete"
|
||||
# (when `update_ensure` runs).
|
||||
notify_info._update_state = False
|
||||
|
||||
|
||||
def extensions_panel_draw_online_extensions_request_impl(
|
||||
self,
|
||||
|
@ -375,9 +375,13 @@ static int preferences_extension_repo_add_exec(bContext *C, wmOperator *op)
|
||||
U.active_extension_repo = BLI_findindex(&U.extension_repos, new_repo);
|
||||
U.runtime.is_dirty = true;
|
||||
|
||||
BKE_callback_exec_null(bmain, BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST);
|
||||
{
|
||||
PointerRNA new_repo_ptr = RNA_pointer_create(nullptr, &RNA_UserExtensionRepo, new_repo);
|
||||
PointerRNA *pointers[] = {&new_repo_ptr};
|
||||
|
||||
BKE_callback_exec_null(bmain, BKE_CB_EVT_EXTENSION_REPOS_SYNC);
|
||||
BKE_callback_exec_null(bmain, BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST);
|
||||
BKE_callback_exec(bmain, pointers, ARRAY_SIZE(pointers), BKE_CB_EVT_EXTENSION_REPOS_SYNC);
|
||||
}
|
||||
|
||||
/* There's no dedicated notifier for the Preferences. */
|
||||
WM_event_add_notifier(C, NC_WINDOW, nullptr);
|
||||
|
@ -349,6 +349,18 @@ static void rna_userdef_asset_library_path_set(PointerRNA *ptr, const char *valu
|
||||
BKE_preferences_asset_library_path_set(library, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use sparingly as a sync may be time consuming.
|
||||
* Any change that may cause loading remote data to change behavior
|
||||
* (such as the URL or access token) must use this update function.
|
||||
*/
|
||||
static void rna_userdef_extension_sync_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr)
|
||||
{
|
||||
BKE_callback_exec(bmain, &ptr, 1, BKE_CB_EVT_EXTENSION_REPOS_SYNC);
|
||||
WM_main_add_notifier(NC_WINDOW, nullptr);
|
||||
USERDEF_TAG_DIRTY;
|
||||
}
|
||||
|
||||
static void rna_userdef_extension_repo_name_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
bUserExtensionRepo *repo = (bUserExtensionRepo *)ptr->data;
|
||||
@ -6832,7 +6844,7 @@ static void rna_def_userdef_filepaths_extension_repo(BlenderRNA *brna)
|
||||
"Remote URL to the extension repository, "
|
||||
"the file-system may be referenced using the file URI scheme: \"file://\"");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_EDITOR_FILEBROWSER);
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_extension_sync_update");
|
||||
|
||||
prop = RNA_def_property(srna, "access_token", PROP_STRING, PROP_PASSWORD);
|
||||
RNA_def_property_ui_text(
|
||||
@ -6841,6 +6853,7 @@ static void rna_def_userdef_filepaths_extension_repo(BlenderRNA *brna)
|
||||
"rna_userdef_extension_repo_access_token_get",
|
||||
"rna_userdef_extension_repo_access_token_length",
|
||||
"rna_userdef_extension_repo_access_token_set");
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_extension_sync_update");
|
||||
|
||||
prop = RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, source_type_items);
|
||||
@ -6874,7 +6887,7 @@ static void rna_def_userdef_filepaths_extension_repo(BlenderRNA *brna)
|
||||
prop = RNA_def_property(srna, "use_access_token", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", USER_EXTENSION_REPO_FLAG_USE_ACCESS_TOKEN);
|
||||
RNA_def_property_ui_text(prop, "Requires Access Token", "Repository requires an access token");
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_extension_sync_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_custom_directory", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(
|
||||
|
Loading…
Reference in New Issue
Block a user